-
Notifications
You must be signed in to change notification settings - Fork 1
/
Core.hs
executable file
·79 lines (65 loc) · 2.54 KB
/
Core.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
module Core where
import Types
import Eval
import qualified Data.Map as Map
import Control.Monad.State
import qualified Data.Vector as V
import Control.Monad.Error (throwError)
math :: (Integer -> Integer -> Integer) -> Result
math f = do (List args) <- getSymbol "..."
binOp f args
binOp :: (Integer -> Integer -> Integer) -> [Expr] -> Result
binOp op args = do return $ foldl1 (binOp' op) args
where binOp' op (Integer i) (Integer j) = Integer (i `op` j)
eq :: Result
eq = do (List args) <- getSymbol "..."
return $ foldl1 (\(Integer a) (Integer b) -> Integer(if a == b then 1 else 0)) args
defArgs = ["symbol", "value"]
def :: Result
def = do [(Symbol s), e] <- getSymbols defArgs
evalE <- eval e
updateSymbolInParent s evalE
return evalE
ifArgs = ["condition", "expr1", "expr2"]
arrowIf :: Result
arrowIf = do [condExpr, expr1, expr2] <- getSymbols ifArgs
evalCond <- eval condExpr
if (0 `notEqual` evalCond)
then eval expr1
else eval expr2
where notEqual val1 (Integer val2) = val1 /= val2
firstArgs = ["coll"]
first :: Result
first = do [List (x:_)] <- getSymbols firstArgs
return x
restArgs = ["coll"]
rest :: Result
rest = do [List (_:xs)] <- getSymbols restArgs
return $ List xs
consArgs = ["x", "xs"]
cons :: Result
cons = do [x, (List xs)] <- getSymbols consArgs
return $ List (x:xs)
fnArgs = ["args", "..."]
fn :: Result
fn = do [(Vector args), (List body)] <- getSymbols fnArgs
let newFn = do evalBody <- mapM eval body
return $ last evalBody
return $ Fn newFn (map (\(Symbol arg) -> arg) (V.toList args))
stdEnv :: Env
stdEnv = Env (Map.fromList [ ("+", Fn (math (+)) ["..."])
, ("-", Fn (math (-)) ["..."])
, ("*", Fn (math (*)) ["..."])
, ("/", Fn (math div) ["..."])
, ("eq", Fn eq ["..."])
, ("first", Fn first firstArgs)
, ("rest", Fn rest restArgs)
, ("cons", Fn cons consArgs)
, ("def", Special def defArgs)
, ("if", Special arrowIf ifArgs)
, ("fn", Special fn fnArgs )
]) Nothing
getSymbol :: String -> Result
getSymbol sym = eval $ (Symbol sym)
getSymbols :: [String] -> ListResult
getSymbols syms = mapM getSymbol syms