Convert evaluator from continuation-passing-style to ordinary-style.
Chris Pressey
4 years ago
18 | 18 | -- Helper functions |
19 | 19 | -- |
20 | 20 | |
21 | evalAll env [] acc cc = | |
22 | cc $ List $ reverse acc | |
23 | evalAll env (head:tail) acc cc = | |
24 | eval env head (\value -> | |
25 | evalAll env tail (value:acc) cc) | |
26 | ||
27 | -- formals actuals origActuals env continuation | |
28 | evalArgs :: [Expr] -> [Expr] -> [Expr] -> Env -> (Env -> Expr) -> Expr | |
29 | evalArgs [] [] _ _ cc = | |
30 | cc empty | |
31 | evalArgs ((Symbol formal):formals) (actual:actuals) origActuals env cc = | |
32 | eval env actual (\value -> | |
33 | evalArgs formals actuals origActuals env (\nenv -> | |
34 | cc $ insert formal value nenv)) | |
35 | evalArgs _ _ origActuals env cc = | |
21 | evalAll env [] acc = | |
22 | List $ reverse acc | |
23 | evalAll env (head:tail) acc = | |
24 | let | |
25 | value = (eval env head) | |
26 | in | |
27 | evalAll env tail (value:acc) | |
28 | ||
29 | -- formals actuals origActuals env | |
30 | evalArgs :: [Expr] -> [Expr] -> [Expr] -> Env -> Expr | |
31 | evalArgs [] [] _ _ = | |
32 | empty | |
33 | evalArgs ((Symbol formal):formals) (actual:actuals) origActuals env = | |
34 | let | |
35 | value = eval env actual | |
36 | nenv = evalArgs formals actuals origActuals env | |
37 | in | |
38 | insert formal value nenv | |
39 | evalArgs _ _ origActuals env = | |
36 | 40 | errMsg "illegal-arguments" $ List origActuals |
37 | 41 | |
38 | 42 | |
39 | evalTwoNumbers :: (Int32 -> Int32 -> (Expr -> Expr) -> Expr) -> Evaluable | |
40 | evalTwoNumbers fn env (List [xexpr, yexpr]) cc = | |
41 | eval env xexpr (\x -> | |
42 | assertNumber env x (\(Number xv) -> | |
43 | eval env yexpr (\y -> | |
44 | assertNumber env y (\(Number yv) -> | |
45 | (fn xv yv cc))))) | |
46 | evalTwoNumbers fn env other cc = errMsg "illegal-arguments" other | |
43 | evalTwoNumbers :: (Int32 -> Int32 -> Expr) -> Evaluable | |
44 | evalTwoNumbers fn env (List [xexpr, yexpr]) = | |
45 | case (eval env xexpr, eval env yexpr) of | |
46 | (Number xv, Number yv) -> fn xv yv | |
47 | (other, Number yv) -> errMsg "expected-number" other | |
48 | (_, other) -> errMsg "expected-number" other | |
49 | evalTwoNumbers fn env other = errMsg "illegal-arguments" other | |
47 | 50 | |
48 | 51 | -- |
49 | 52 | -- `Small` |
54 | 57 | -- |
55 | 58 | |
56 | 59 | literal :: Evaluable |
57 | literal env (List (expr:_)) cc = | |
58 | cc expr | |
59 | literal env other cc = errMsg "illegal-arguments" other | |
60 | literal env (List (expr:_)) = expr | |
61 | literal env other = errMsg "illegal-arguments" other | |
60 | 62 | |
61 | 63 | list :: Evaluable |
62 | list env (List exprs) cc = | |
63 | evalAll env exprs [] cc | |
64 | list env (List exprs) = | |
65 | evalAll env exprs [] | |
64 | 66 | |
65 | 67 | env_ :: Evaluable |
66 | env_ env (List _) cc = | |
67 | cc $ env | |
68 | env_ env (List _) = env | |
68 | 69 | |
69 | 70 | choose :: Evaluable |
70 | choose env (List [(List [(Symbol "else"), branch])]) cc = | |
71 | eval env branch cc | |
72 | choose env (List ((List [test, branch]):rest)) cc = | |
73 | eval env test (\x -> | |
74 | case x of | |
75 | Boolean True -> | |
76 | eval env branch cc | |
77 | Boolean False -> | |
78 | choose env (List rest) cc) | |
79 | choose env other cc = errMsg "illegal-arguments" other | |
71 | choose env (List [(List [(Symbol "else"), branch])]) = | |
72 | eval env branch | |
73 | choose env (List ((List [test, branch]):rest)) = | |
74 | case eval env test of | |
75 | Boolean True -> | |
76 | eval env branch | |
77 | Boolean False -> | |
78 | choose env (List rest) | |
79 | choose env other = errMsg "illegal-arguments" other | |
80 | 80 | |
81 | 81 | bind :: Evaluable |
82 | bind env (List [(Symbol name), expr, body]) cc = | |
83 | eval env expr (\value -> | |
84 | eval (insert name value env) body cc) | |
85 | bind env other cc = errMsg "illegal-arguments" other | |
82 | bind env (List [(Symbol name), expr, body]) = | |
83 | let | |
84 | value = eval env expr | |
85 | env' = insert name value env | |
86 | in | |
87 | eval env' body | |
88 | bind env other = errMsg "illegal-arguments" other | |
86 | 89 | |
87 | 90 | let_ :: Evaluable |
88 | let_ env (List ((List bindings):body:_)) cc = | |
89 | bindAll bindings env (\env' -> | |
90 | eval env' body cc) | |
91 | where | |
92 | bindAll [] env cc = | |
93 | cc env | |
94 | bindAll (List ((Symbol name):sexpr:_):rest) env cc = | |
95 | eval env sexpr (\value -> | |
96 | bindAll rest (insert name value env) cc) | |
97 | bindAll (other:rest) env cc = | |
98 | errMsg "illegal-binding" other | |
99 | let_ env other cc = errMsg "illegal-arguments" other | |
91 | let_ env (List ((List bindings):body:_)) = | |
92 | let | |
93 | env' = bindAll bindings env | |
94 | in | |
95 | eval env' body | |
96 | where | |
97 | bindAll [] env = env | |
98 | bindAll (List ((Symbol name):expr:_):rest) env = | |
99 | let | |
100 | value = eval env expr | |
101 | env' = insert name value env | |
102 | in | |
103 | bindAll rest env' | |
104 | bindAll (other:rest) env = | |
105 | errMsg "illegal-binding" other | |
106 | let_ env other = errMsg "illegal-arguments" other | |
100 | 107 | |
101 | 108 | bindArgs :: Evaluable |
102 | bindArgs env (List [(List formals), givenArgs, givenEnvExpr, body]) cc = | |
103 | eval env givenArgs (\(List actuals) -> | |
104 | eval env givenEnvExpr (\outerEnvExpr -> | |
105 | evalArgs formals actuals actuals outerEnvExpr (\argEnv -> | |
106 | eval (mergeEnvs argEnv env) body cc))) | |
107 | bindArgs env other cc = errMsg "illegal-arguments" other | |
109 | bindArgs env (List [(List formals), givenArgs, givenEnvExpr, body]) = | |
110 | let | |
111 | List actuals = eval env givenArgs | |
112 | outerEnvExpr = eval env givenEnvExpr | |
113 | argEnv = evalArgs formals actuals actuals outerEnvExpr | |
114 | in | |
115 | eval (mergeEnvs argEnv env) body | |
116 | bindArgs env other = errMsg "illegal-arguments" other | |
108 | 117 | |
109 | 118 | fun :: Evaluable |
110 | fun closedEnv (List [(List formals), body]) cc = | |
111 | cc $ Operator "<lambda>" fun | |
112 | where | |
113 | fun env (List actuals) cc = | |
114 | evalArgs formals actuals actuals env (\argEnv -> | |
115 | eval (mergeEnvs argEnv closedEnv) body cc) | |
116 | fun env other cc = errMsg "illegal-arguments" other | |
119 | fun closedEnv (List [(List formals), body]) = | |
120 | let | |
121 | fun env (List actuals) = | |
122 | let | |
123 | argEnv = evalArgs formals actuals actuals env | |
124 | env' = mergeEnvs argEnv closedEnv | |
125 | in | |
126 | eval env' body | |
127 | in | |
128 | Operator "<lambda>" fun | |
129 | fun env other = errMsg "illegal-arguments" other | |
117 | 130 | |
118 | 131 | -- |
119 | 132 | -- `Arith` |
124 | 137 | -- |
125 | 138 | |
126 | 139 | gtP :: Evaluable |
127 | gtP = evalTwoNumbers (\x y cc -> cc $ Boolean (x > y)) | |
140 | gtP = evalTwoNumbers (\x y -> Boolean (x > y)) | |
128 | 141 | |
129 | 142 | gteP :: Evaluable |
130 | gteP = evalTwoNumbers (\x y cc -> cc $ Boolean (x >= y)) | |
143 | gteP = evalTwoNumbers (\x y -> Boolean (x >= y)) | |
131 | 144 | |
132 | 145 | ltP :: Evaluable |
133 | ltP = evalTwoNumbers (\x y cc -> cc $ Boolean (x < y)) | |
146 | ltP = evalTwoNumbers (\x y -> Boolean (x < y)) | |
134 | 147 | |
135 | 148 | lteP :: Evaluable |
136 | lteP = evalTwoNumbers (\x y cc -> cc $ Boolean (x <= y)) | |
137 | ||
138 | robinAbs :: Evaluable | |
139 | robinAbs env (List [expr]) cc = | |
140 | eval env expr (\x -> assertNumber env x (\(Number xv) -> cc (Number $ abs xv))) | |
141 | robinAbs env other cc = errMsg "illegal-arguments" other | |
149 | lteP = evalTwoNumbers (\x y -> Boolean (x <= y)) | |
150 | ||
151 | abs_ :: Evaluable | |
152 | abs_ env (List [expr]) = | |
153 | case eval env expr of | |
154 | Number xv -> Number $ abs xv | |
155 | other -> errMsg "expected-number" other | |
156 | abs_ env other = errMsg "illegal-arguments" other | |
142 | 157 | |
143 | 158 | add :: Evaluable |
144 | add = evalTwoNumbers (\x y cc -> cc $ Number (x + y)) | |
159 | add = evalTwoNumbers (\x y -> Number (x + y)) | |
145 | 160 | |
146 | 161 | multiply :: Evaluable |
147 | multiply = evalTwoNumbers (\x y cc -> cc $ Number (x * y)) | |
162 | multiply = evalTwoNumbers (\x y -> Number (x * y)) | |
148 | 163 | |
149 | 164 | divide :: Evaluable |
150 | divide = evalTwoNumbers (\x y cc -> case y of | |
165 | divide = evalTwoNumbers (\x y -> case y of | |
151 | 166 | 0 -> errMsg "division-by-zero" $ Number x |
152 | _ -> cc $ Number (x `div` y)) | |
167 | _ -> Number (x `div` y)) | |
153 | 168 | |
154 | 169 | remainder :: Evaluable |
155 | remainder = evalTwoNumbers (\x y cc -> case y of | |
170 | remainder = evalTwoNumbers (\x y -> case y of | |
156 | 171 | 0 -> errMsg "division-by-zero" $ Number x |
157 | _ -> cc $ Number (abs (x `mod` y))) | |
172 | _ -> Number (abs (x `mod` y))) | |
158 | 173 | |
159 | 174 | -- |
160 | 175 | -- Mapping of names to our functions, providing an evaluation environment. |
177 | 192 | ("lt?", ltP), |
178 | 193 | ("lte?", lteP), |
179 | 194 | |
180 | ("abs", robinAbs), | |
195 | ("abs", abs_), | |
181 | 196 | ("add", add), |
182 | 197 | ("multiply", multiply), |
183 | 198 | ("divide", divide), |
5 | 5 | -- |
6 | 6 | -- This evaluator is written in continuation-passing style. |
7 | 7 | -- |
8 | -- Every evaluation function has this signature: | |
8 | -- The evaluation function has this signature: | |
9 | 9 | -- |
10 | -- Env -> Expr -> (Expr -> Expr) -> Expr | |
10 | -- Env -> Expr -> Expr | |
11 | 11 | -- |
12 | 12 | -- (This is actually the `Evaluable` type from `Robin.Expr`.) |
13 | 13 | -- |
15 | 15 | -- (and modifiable, during `eval`) by the Robin program. |
16 | 16 | -- |
17 | 17 | -- The second argument is the expression to be evaluated. |
18 | -- | |
19 | -- The third argument is the continuation. Once the expression has been | |
20 | -- evaluated, the continuation will be applied with the result of the | |
21 | -- evaluation. | |
22 | 18 | -- |
23 | 19 | |
24 | 20 | eval :: Evaluable |
28 | 24 | -- value. Then continue the current continuation with that value. |
29 | 25 | -- |
30 | 26 | |
31 | eval env sym@(Symbol s) cc = | |
27 | eval env sym@(Symbol s) = | |
32 | 28 | case find s env of |
33 | 29 | Just value -> |
34 | cc value | |
30 | value | |
35 | 31 | Nothing -> |
36 | 32 | errMsg "unbound-identifier" sym |
37 | 33 | |
41 | 37 | -- operator. We then apply the operator, passing it the tail of the list. |
42 | 38 | -- |
43 | 39 | |
44 | eval env (List (applierExpr:actuals)) cc = | |
45 | eval env applierExpr (\applier -> | |
46 | case applier of | |
47 | Operator _ fun -> | |
48 | fun env (List actuals) cc | |
49 | other -> | |
50 | errMsg "inapplicable-object" other) | |
40 | eval env (List (applierExpr:actuals)) = | |
41 | case eval env applierExpr of | |
42 | Operator _ op -> | |
43 | op env (List actuals) | |
44 | other -> | |
45 | errMsg "inapplicable-object" other | |
51 | 46 | |
52 | 47 | -- |
53 | -- Everything else just evaluates to itself. Continue the current | |
54 | -- continuation with that value. | |
48 | -- Everything else just evaluates to itself. | |
55 | 49 | -- |
56 | 50 | |
57 | eval env e cc = | |
58 | cc e | |
51 | eval env e = e | |
59 | 52 | |
60 | 53 | -- |
61 | 54 | -- Helper functions |
66 | 59 | |
67 | 60 | makeMacro :: Expr -> Expr -> Expr -> Evaluable |
68 | 61 | makeMacro defineTimeEnv formals body = |
69 | \callTimeEnv actuals cc -> | |
62 | \callTimeEnv actuals -> | |
70 | 63 | let |
71 | 64 | env = makeMacroEnv callTimeEnv actuals defineTimeEnv formals |
72 | 65 | in |
73 | eval env body cc | |
66 | eval env body | |
74 | 67 | |
75 | 68 | makeMacroEnv callTimeEnv actuals defineTimeEnv argList = |
76 | 69 | let |
8 | 8 | -- (perhaps unsurprisingly?) to be the type of the evaluator function. |
9 | 9 | -- |
10 | 10 | |
11 | type Evaluable = Expr -> Expr -> (Expr -> Expr) -> Expr | |
12 | -- env args continuation result | |
11 | type Evaluable = Expr -> Expr -> Expr | |
12 | -- env args result | |
13 | 13 | |
14 | 14 | -- |
15 | 15 | -- Basic expressions in Robin. These may be evaluated, or they may be |
4 | 4 | import Language.Robin.Eval |
5 | 5 | |
6 | 6 | |
7 | head :: Evaluable | |
8 | head env (List [expr]) cc = | |
9 | eval env expr (\x -> | |
10 | assertList env x (\val -> | |
11 | case val of | |
12 | List (a:_) -> cc a | |
13 | other -> errMsg "expected-list" other)) | |
14 | head env other cc = errMsg "illegal-arguments" other | |
7 | head_ :: Evaluable | |
8 | head_ env (List [expr]) = | |
9 | case eval env expr of | |
10 | List (a:_) -> a | |
11 | other -> errMsg "expected-list" other | |
12 | head_ env other = errMsg "illegal-arguments" other | |
15 | 13 | |
16 | tail :: Evaluable | |
17 | tail env (List [expr]) cc = | |
18 | eval env expr (\x -> | |
19 | assertList env x (\val -> | |
20 | case val of | |
21 | List (_:b) -> cc (List b) | |
22 | other -> errMsg "expected-list" other)) | |
23 | tail env other cc = errMsg "illegal-arguments" other | |
14 | tail_ :: Evaluable | |
15 | tail_ env (List [expr]) = | |
16 | case eval env expr of | |
17 | List (_:b) -> (List b) | |
18 | other -> errMsg "expected-list" other | |
19 | tail_ env other = errMsg "illegal-arguments" other | |
24 | 20 | |
25 | 21 | prepend :: Evaluable |
26 | prepend env (List [e1, e2]) cc = | |
27 | eval env e1 (\x1 -> eval env e2 (\val -> | |
28 | case val of | |
29 | List x2 -> cc $ List (x1:x2) | |
30 | other -> errMsg "expected-list" other)) | |
31 | prepend env other cc = errMsg "illegal-arguments" other | |
22 | prepend env (List [e1, e2]) = | |
23 | case (eval env e1, eval env e2) of | |
24 | (x1, List x2) -> List (x1:x2) | |
25 | (_, other) -> errMsg "expected-list" other | |
26 | prepend env other = errMsg "illegal-arguments" other | |
32 | 27 | |
33 | 28 | equalP :: Evaluable |
34 | equalP env (List [e1, e2]) cc = | |
35 | eval env e1 (\x1 -> eval env e2 (\x2 -> cc $ Boolean (x1 == x2))) | |
36 | equalP env other cc = errMsg "illegal-arguments" other | |
29 | equalP env (List [e1, e2]) = | |
30 | let (x1, x2) = (eval env e1, eval env e2) in Boolean (x1 == x2) | |
31 | equalP env other = errMsg "illegal-arguments" other | |
37 | 32 | |
38 | predP pred env (List [expr]) cc = | |
39 | eval env expr (\x -> cc $ Boolean $ pred x) | |
40 | predP pred env other cc = errMsg "illegal-arguments" other | |
33 | predP pred env (List [expr]) = | |
34 | Boolean $ pred (eval env expr) | |
35 | predP pred env other = errMsg "illegal-arguments" other | |
41 | 36 | |
42 | 37 | symbolP = predP isSymbol |
43 | 38 | listP = predP isList |
44 | 39 | operatorP = predP isOperator |
45 | 40 | numberP = predP isNumber |
46 | 41 | |
47 | subtract :: Evaluable | |
48 | subtract env (List [xexpr, yexpr]) cc = | |
49 | eval env xexpr (\x -> | |
50 | assertNumber env x (\(Number xv) -> | |
51 | eval env yexpr (\y -> | |
52 | assertNumber env y (\(Number yv) -> | |
53 | cc (Number (xv - yv)))))) | |
54 | subtract env other cc = errMsg "illegal-arguments" other | |
42 | subtract_ :: Evaluable | |
43 | subtract_ env (List [xexpr, yexpr]) = | |
44 | case (eval env xexpr, eval env yexpr) of | |
45 | (Number xv, Number yv) -> Number (xv - yv) | |
46 | (other, Number yv) -> errMsg "expected-number" other | |
47 | (_, other) -> errMsg "expected-number" other | |
48 | subtract_ env other = errMsg "illegal-arguments" other | |
55 | 49 | |
56 | 50 | sign :: Evaluable |
57 | sign env (List [expr]) cc = | |
51 | sign env (List [expr]) = | |
58 | 52 | let |
59 | 53 | sgn x = if x == 0 then 0 else if x < 0 then -1 else 1 |
60 | 54 | in |
61 | eval env expr (\x -> | |
62 | assertNumber env x (\(Number xv) -> | |
63 | cc $ Number $ sgn xv)) | |
64 | sign env other cc = errMsg "illegal-arguments" other | |
55 | case eval env expr of | |
56 | Number xv -> Number $ sgn xv | |
57 | other -> errMsg "expected-number" other | |
58 | sign env other = errMsg "illegal-arguments" other | |
65 | 59 | |
66 | 60 | if_ :: Evaluable |
67 | if_ env (List [test, texpr, fexpr]) cc = | |
68 | eval env test (\x -> | |
69 | assertBoolean env x (\(Boolean b) -> | |
70 | if b then eval env texpr cc else eval env fexpr cc)) | |
71 | if_ env other cc = errMsg "illegal-arguments" other | |
61 | if_ env (List [test, texpr, fexpr]) = | |
62 | case eval env test of | |
63 | Boolean b -> if b then eval env texpr else eval env fexpr | |
64 | other -> errMsg "expected-boolean" other | |
65 | if_ env other = errMsg "illegal-arguments" other | |
72 | 66 | |
73 | 67 | eval_ :: Evaluable |
74 | eval_ env (List [envlist, form]) cc = | |
75 | eval env envlist (\newEnvVal -> | |
76 | eval env form (\body -> | |
77 | eval newEnvVal body cc)) | |
78 | eval_ env other cc = errMsg "illegal-arguments" other | |
68 | eval_ env (List [envlist, form]) = | |
69 | let | |
70 | newEnvVal = eval env envlist | |
71 | body = eval env form | |
72 | in | |
73 | eval newEnvVal body | |
74 | eval_ env other = errMsg "illegal-arguments" other | |
79 | 75 | |
80 | 76 | macro :: Evaluable |
81 | macro env (List [args@(List [(Symbol argsS), (Symbol envS)]), body]) cc = | |
82 | cc $ Operator "<operator>" $ makeMacro env args body | |
83 | macro env other cc = errMsg "illegal-arguments" other | |
77 | macro env (List [args@(List [(Symbol argsS), (Symbol envS)]), body]) = | |
78 | Operator "<operator>" $ makeMacro env args body | |
79 | macro env other = errMsg "illegal-arguments" other | |
84 | 80 | |
85 | 81 | abort :: Evaluable |
86 | abort env (List [expr]) cc = | |
87 | eval env expr (\v -> cc $ Abort v) | |
88 | abort env other cc = errMsg "illegal-arguments" other | |
82 | abort env (List [expr]) = | |
83 | Abort $ eval env expr | |
84 | abort env other = errMsg "illegal-arguments" other | |
89 | 85 | |
90 | 86 | recover :: Evaluable |
91 | recover env (List [expr, (Symbol okName), okExpr, (Symbol abortName), abortExpr]) cc = | |
92 | eval env expr (\result -> | |
93 | case result of | |
94 | e@(Abort contents) -> | |
95 | eval (insert abortName contents env) abortExpr cc | |
96 | other -> | |
97 | eval (insert okName other env) okExpr cc) | |
98 | recover env other cc = errMsg "illegal-arguments" other | |
87 | recover env (List [expr, (Symbol okName), okExpr, (Symbol abortName), abortExpr]) = | |
88 | case eval env expr of | |
89 | e@(Abort contents) -> eval (insert abortName contents env) abortExpr | |
90 | other -> eval (insert okName other env) okExpr | |
91 | recover env other = errMsg "illegal-arguments" other | |
99 | 92 | |
100 | 93 | robinIntrinsics :: Env |
101 | 94 | robinIntrinsics = fromList $ map (\(name,bif) -> (name, Operator name bif)) |
102 | 95 | [ |
103 | ("head", Language.Robin.Intrinsics.head), | |
104 | ("tail", Language.Robin.Intrinsics.tail), | |
96 | ("head", head_), | |
97 | ("tail", tail_), | |
105 | 98 | ("prepend", prepend), |
106 | 99 | ("list?", listP), |
107 | 100 | ("symbol?", symbolP), |
108 | 101 | ("operator?",operatorP), |
109 | 102 | ("number?", numberP), |
110 | 103 | ("equal?", equalP), |
111 | ("subtract", Language.Robin.Intrinsics.subtract), | |
104 | ("subtract", subtract_), | |
112 | 105 | ("sign", sign), |
113 | 106 | ("macro", macro), |
114 | 107 | ("eval", eval_), |
27 | 27 | applyStop (command:commands) = |
28 | 28 | (command:applyStop commands) |
29 | 29 | in |
30 | case eval env (List [body, event, state]) id of | |
30 | case eval env (List [body, event, state]) of | |
31 | 31 | (List (state':commands)) -> |
32 | 32 | (reactor{ state=state' }, applyStop commands) |
33 | 33 | expr -> |
30 | 30 | collect [] result = result |
31 | 31 | |
32 | 32 | collect ((List [Symbol "display", expr]):rest) world@World{ env=env, results=results } = |
33 | collect rest world{ results=((eval env expr id):results) } | |
33 | collect rest world{ results=((eval env expr):results) } | |
34 | 34 | |
35 | 35 | collect ((List [Symbol "assert", expr]):rest) world@World{ env=env, results=results } = |
36 | case eval env expr id of | |
36 | case eval env expr of | |
37 | 37 | Abort expr -> |
38 | 38 | world{ results=((Abort expr):results) } |
39 | 39 | Boolean False -> |
52 | 52 | case find s env of |
53 | 53 | Just _ -> |
54 | 54 | let |
55 | result = eval env expr id | |
55 | result = eval env expr | |
56 | 56 | in |
57 | 57 | collect rest world{ secondaryDefs=(insert s result secondaryDefs) } |
58 | 58 | Nothing -> |
59 | 59 | let |
60 | result = eval env expr id | |
60 | result = eval env expr | |
61 | 61 | in |
62 | 62 | collect rest world{ env=(insert s result env) } |
63 | 63 | |
64 | 64 | collect ((List [Symbol "reactor", facExpr, stateExpr, bodyExpr]):rest) world@World{ env=env, reactors=reactors } = |
65 | 65 | let |
66 | state = eval env stateExpr id | |
67 | body = eval env bodyExpr id | |
66 | state = eval env stateExpr | |
67 | body = eval env bodyExpr | |
68 | 68 | newReactor = Reactor.Reactor{ Reactor.rid=(fromIntegral $ length reactors), Reactor.env=env, Reactor.state=state, Reactor.body=body } |
69 | 69 | in |
70 | 70 | collect rest world{ reactors=(newReactor:reactors) } |