-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLangDef.hs
95 lines (73 loc) · 2.85 KB
/
LangDef.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
{- Internal Definition of the Language. This serves as the interface between syntax and runtime of the language. -}
module LangDef where
import qualified Data.Map
data Statement = Noop
| Assignment VarId Expression
| Sequence [Statement]
| Alternative Expression Statement Statement
| Option Expression Statement
| Loop Expression Statement
| Return Expression
| ObjAssignment Expression ObjKey Expression
| Let [(VarId, Lambda)]
deriving (Show)
data Expression = Concrete Integer
| OneOp (Value -> Value) Expression
| TwoOpInf
Expression
(Value -> Value -> Value)
Expression
| Ref VarId
| LambdaExpr Lambda
| Call Expression [Expression]
| New
| AccessObj Expression ObjKey
data Value = MyInteger Integer
| Function [VarId] Statement Stack
| ObjRef ObjId
deriving (Show)
data State = State Stack Heap
deriving (Show)
data Stack = Top Vartable
| Sub Stack Vartable
deriving (Show)
type Heap = Data.Map.Map ObjId Object
type Vartable = Data.Map.Map VarId Value
type VarId = String
type ObjId = Integer
type Object = Data.Map.Map ObjKey Value
type ObjKey = String
type Lambda = ([VarId], Statement)
newState = State (Top Data.Map.empty) Data.Map.empty
instance Show Expression where
show (Concrete a) = show a
show (OneOp f expr) = "f("++(show expr)++")"
show (TwoOpInf left f right) = "|"++(show left) ++ " x " ++ (show right) ++ "|"
show (Ref varid) = "Var#"++(show varid)
show (Call foo params) = "Call"++(show foo)++" With "++ (show params)
show (LambdaExpr (vars, body)) = (show vars) ++ "->" ++ (show body)
show New = "New"
show (AccessObj expr key) = show expr ++ "." ++ key
---- Wraps around haskell functions
intWrap :: (Integer -> Integer -> Integer)
-> Expression -> Expression -> Expression
intWrap f a b = TwoOpInf a wrap b
where wrap (MyInteger a) (MyInteger b) = MyInteger (f a b)
wrap x y = error (show x ++ " or " ++ show y ++" are no numbers")
mult = intWrap (*)
plus = intWrap (+)
minus = intWrap (-)
equal = intWrap (\x y -> if x == y then 0 else 1)
singleIntWrap :: (Integer -> Integer) -> Expression -> Expression
singleIntWrap f o = OneOp wrap o
where wrap (MyInteger x) = MyInteger (f x)
--TODO: rewrite using singleIntWrap
negate :: Expression -> Expression
negate a = OneOp f a
where f (MyInteger i) = MyInteger (-i)
square :: Expression -> Expression
square a = OneOp f a
where f (MyInteger i) = MyInteger (i*i)
notop = singleIntWrap f
where f 0 = 1
f x = 0