git @ Cat's Eye Technologies Robin / 17388cc
Use evalToBoolean, evalToNumber. Chris Pressey 4 years ago
3 changed file(s) with 27 addition(s) and 35 deletion(s). Raw diff Collapse all Expand all
00 module Language.Robin.Builtins where
1
2 import Data.Int
31
42 import Language.Robin.Expr
53 import Language.Robin.Env (Env, fromList, mergeEnvs, empty, insert)
3432 cc $ insert formal value nenv))
3533 evalArgs ecc _ _ origActuals env _ =
3634 errMsg ecc "illegal-arguments" $ List origActuals
37
38
39 evalTwoNumbers :: (Int32 -> Int32 -> (Expr -> Expr) -> Expr) -> Evaluable
40 evalTwoNumbers fn env (List [xexpr, yexpr]) cc =
41 evalB cc env xexpr (\x ->
42 assertNumber cc env x (\(Number xv) ->
43 evalB cc env yexpr (\y ->
44 assertNumber cc env y (\(Number yv) ->
45 (fn xv yv cc)))))
46 evalTwoNumbers fn env other cc = errMsg cc "illegal-arguments" other
4735
4836 --
4937 -- `Small`
137125
138126 abs_ :: Evaluable
139127 abs_ env (List [expr]) cc =
140 eval env expr (\x -> assertNumber (cc) env x (\(Number xv) -> cc (Number $ abs xv)))
128 evalToNumber cc env expr (\(Number xv) -> cc $ Number $ abs xv)
141129 abs_ env other cc = errMsg cc "illegal-arguments" other
142130
143131 add :: Evaluable
00 module Language.Robin.Eval where
1
2 import Data.Int
13
24 import Language.Robin.Expr
35 import Language.Robin.Env (Env, find, insert)
99101 True -> cc expr
100102 False -> errMsg ecc msg expr
101103
102 assertSymbol ecc env expr = assert ecc env (isSymbol) "expected-symbol" expr
103 assertBoolean ecc env expr = assert ecc env (isBoolean) "expected-boolean" expr
104104 assertList ecc env expr = assert ecc env (isList) "expected-list" expr
105 assertNumber ecc env expr = assert ecc env (isNumber) "expected-number" expr
106 assertOperator ecc env expr = assert ecc env (isOperator) "expected-operator" expr
105
106 evalExpect pred msg ecc env expr cc =
107 eval env expr (\value ->
108 case pred value of
109 True -> cc value
110 False -> errMsg ecc msg value)
111
112 evalToBoolean = evalExpect (isBoolean) "expected-boolean"
113 evalToList = evalExpect (isList) "expected-list"
114 evalToNumber = evalExpect (isNumber) "expected-number"
115
116 evalTwoNumbers :: (Int32 -> Int32 -> (Expr -> Expr) -> Expr) -> Evaluable
117 evalTwoNumbers fn env (List [xexpr, yexpr]) cc =
118 evalToNumber cc env xexpr (\(Number xv) ->
119 evalToNumber cc env yexpr (\(Number yv) ->
120 (fn xv yv cc)))
121 evalTwoNumbers fn env other cc = errMsg cc "illegal-arguments" other
2525 prepend :: Evaluable
2626 prepend env (List [e1, e2]) cc =
2727 evalB cc env e1 (\x1 ->
28 evalB cc env e2 (\val ->
29 case val of
30 List x2 -> cc $ List (x1:x2)
31 other -> errMsg cc "expected-list" other))
28 evalToList cc env e2 (\(List x2) -> cc $ List (x1:x2)))
3229 prepend env other cc = errMsg cc "illegal-arguments" other
3330
3431 equalP :: Evaluable
4643 numberP = predP isNumber
4744
4845 subtract_ :: Evaluable
49 subtract_ env (List [xexpr, yexpr]) cc =
50 eval env xexpr (\x ->
51 assertNumber cc env x (\(Number xv) ->
52 eval env yexpr (\y ->
53 assertNumber cc env y (\(Number yv) ->
54 cc (Number (xv - yv))))))
55 subtract_ env other cc = errMsg cc "illegal-arguments" other
46 subtract_ = evalTwoNumbers (\x y cc -> cc $ Number (x - y))
5647
5748 sign :: Evaluable
5849 sign env (List [expr]) cc =
5950 let
6051 sgn x = if x == 0 then 0 else if x < 0 then -1 else 1
6152 in
62 evalB cc env expr (\x ->
63 assertNumber cc env x (\(Number xv) ->
64 cc $ Number $ sgn xv))
53 evalToNumber cc env expr (\(Number xv) ->
54 cc $ Number $ sgn xv)
6555 sign env other cc = errMsg cc "illegal-arguments" other
6656
6757 if_ :: Evaluable
68 if_ env (List [test, texpr, fexpr]) cc =
69 evalB cc env test (\x ->
70 assertBoolean cc env x (\(Boolean b) ->
71 if b then eval env texpr cc else eval env fexpr cc))
58 if_ env (List [testExpr, trueExpr, falseExpr]) cc =
59 evalToBoolean cc env testExpr (\(Boolean b) ->
60 if b then eval env trueExpr cc else eval env falseExpr cc)
7261 if_ env other cc = errMsg cc "illegal-arguments" other
7362
7463 eval_ :: Evaluable