Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 100 lines (87 sloc) 4.375 kb
35f185c8 »
2009-09-16 Rewrite parser, separating out evaluation from parsing.
1 Copyright (C) 2009 Mathieu Boespflug <mboes@tweag.net>
2
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 3 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 > module Eval (eval) where
17 >
18 > import Parse
19 > import Control.Hmk
20 > import qualified Control.Hmk.IO as IO
21 >
22 > import Data.Sequence (Seq)
23 > import qualified Data.Sequence as Seq
24 > import qualified Data.Traversable as Seq
25 > import qualified Data.Foldable as Seq
26 > import Control.Applicative
27 > import Control.Monad.State
28 > import Data.List (intercalate)
29 >
acb074b3 »
2009-09-18 Make recipes spawn process with piped stdin.
30 > import System.IO
31 > import System.Process
35f185c8 »
2009-09-16 Rewrite parser, separating out evaluation from parsing.
32 > import System.Posix.Env
33 > import System.Posix.Process (getProcessID)
34
35
36 Variable references are substituted for their values, using the environment.
37
38 The environment is a variable store that can be updated in place. It is very
39 much not a persistent abstraction, so we implement it with an impure
40 structure. For simplicity that structure is the system environment, since
41 we'll need to communicate the environment to child processes using the system
42 environment anyways.
43
44 A list of tokens can be spliced, appended to, etc, to form a new list of
45 tokens. Freezing means turning a list of tokens into a string, which cannot be
46 manipulated any further. This string representation is used to export values
47 to the outside world, such as the system environment.
48
49 > freeze :: Seq String -> String
50 > freeze = intercalate " " . Seq.toList
51
52 Evaluation substitutes values for all variable references, using the system
53 environment as a variable store. Assignments are executed first, then PRule's
dfc16a0a »
2009-09-18 Comment.
54 are evaluated to Rule's, the data structure for rules used by Control.Hmk. The
55 return value is a sequence of functions mapping stems to rules. This is
56 because stems are synthesized as a by-product of meta-rule instantiaton, but
57 this instantiation is performed post evaluation.
35f185c8 »
2009-09-16 Rewrite parser, separating out evaluation from parsing.
58
59 > type Stem = String
60 >
ea6131dd »
2009-09-16 Remove file name argument. No error conditions as of yet.
61 > eval :: Mkfile -- ^ Result of the parser.
35f185c8 »
2009-09-16 Rewrite parser, separating out evaluation from parsing.
62 > -> IO (Seq (Stem -> Rule IO FilePath))
ea6131dd »
2009-09-16 Remove file name argument. No error conditions as of yet.
63 > eval (rules, assigns) = do
35f185c8 »
2009-09-16 Rewrite parser, separating out evaluation from parsing.
64 > Seq.mapM_ evalAssignment assigns
65 > Seq.msum <$> Seq.mapM evalRule rules
66 > where evalRule (PRule pt pps pr pcmp) = do
67 > ts <- Seq.mapM evalToken pt
68 > ps <- Seq.mapM evalToken pps
69 > -- xxx support user supplied compare.
70 > let f t stem = let r = fmap (evalRecipe ts t ps stem) pr
71 > in Rule t (Seq.toList ps) r IO.isStale
72 > return $ fmap f ts
73 > evalAssignment (Assign attr var value) = do
74 > -- xxx take into account attributes.
75 > lits <- Seq.mapM evalToken value
76 > setEnv var (freeze lits) True
77 > evalToken (Ref toks) = do
78 > var <- Seq.mapM evalToken toks
79 > maybe "" id <$> getEnv (freeze var)
80 > evalToken (Lit x) = return x
81 > evalRecipe alltarget target prereq stem text newprereq = do
82 > pid <- show <$> getProcessID
83 > setEnv "alltarget" (freeze alltarget) True
84 > setEnv "newprereq" (intercalate " " newprereq) True
85 > setEnv "newmember" "" True -- xxx aggregates not supported.
86 > setEnv "nproc" (show 0) True
87 > setEnv "pid" pid True
88 > setEnv "prereq" (freeze prereq) True
acb074b3 »
2009-09-18 Make recipes spawn process with piped stdin.
89 > setEnv "stem" stem True
35f185c8 »
2009-09-16 Rewrite parser, separating out evaluation from parsing.
90 > setEnv "target" target True
acb074b3 »
2009-09-18 Make recipes spawn process with piped stdin.
91 > (Just inh, _, _, ph) <-
92 > createProcess (proc "/bin/sh" ["-e"]) { std_in = CreatePipe }
93 > hSetBinaryMode inh False
94 > hPutStr inh text
95 > waitForProcess ph >>= IO.testExitCode
a81c662e »
2009-09-18 evalNoMeta.
96
97 Version of eval where stems are instantiated to the empty string.
98
99 > evalNoMeta :: Mkfile -> IO (Seq (Rule IO FilePath))
100 > evalNoMeta mkfile = fmap ($ "") <$> eval mkfile
Something went wrong with that request. Please try again.