Christian Collberg
Department of Computer Science
University of Arizona






These are the abstract syntactic domains of Wren:





type Num = Rational
data SV = IVal Num | BVal Bool | Undefined
type Identifier = String
data Operator = Add | Sub | Mul | Minus | Div | Not |
Or | And | Lt | Gt | Eq | Ne | Le | Ge
data Expression = Id String |
LitInt Num |
TrueVal |
FalseVal |
Unary Operator Expression |
Binary Expression Operator Expression
data Program = Prog [Declaration] Command
data Declaration = Var [Identifier] Type
data Type = IntType | BoolType
data Command = Skip |
Assign String Expression |
Read String |
Write Expression |
IfThen Expression Command |
IfThenElse Expression Command Command |
While Expression Command |
Seq Command Command
bcompute :: SV -> Operator -> SV -> SV
bcompute (IVal a) Add (IVal b) = (IVal (a + b))
bcompute (IVal a) Mul (IVal b) = (IVal (a * b))
bcompute (IVal a) Div (IVal b) =
if b==0 then error "Division by 0"
else (IVal (toRational(a / b)))
bcompute (IVal a) Sub (IVal b) = (IVal (a - b))
bcompute (BVal a) And (BVal b) = (BVal (a && b))
bcompute (BVal a) Or (BVal b) = (BVal (a || b))
bcompute (IVal a) Lt (IVal b) = (BVal (a < b))
bcompute (IVal a) Gt (IVal b) = (BVal (a > b))
bcompute (IVal a) Le (IVal b) = (BVal (a <= b))
bcompute (IVal a) Ge (IVal b) = (BVal (a >= b))
bcompute (IVal a) Eq (IVal b) = (BVal (a == b))
bcompute (IVal a) Ne (IVal b) = (BVal (not (a == b)))
ucompute :: Operator -> SV -> SV ucompute Minus (IVal b) = (IVal (- b)) ucompute Not (BVal b) = (BVal (not b))
evaluate :: Expression -> Store -> SV
evaluate (Id id) sto =
if val == Undefined then val else val
where val = applySto sto id
evaluate (LitInt n) sto = (IVal n)
evaluate (TrueVal) sto = (BVal True)
evaluate (FalseVal) sto = (BVal False)
evaluate (Unary op r) sto = ucompute op n
where n = evaluate r sto
evaluate (Binary l op r) sto = bcompute m op n
where m = evaluate l sto
n = evaluate r sto
> s1
[("b",True),("a",5 % 1)]
> evaluate (Binary (LitInt 5) Add (LitInt 6)) s1
11 % 1
> evaluate (Binary (LitInt 5) Add (Id "a")) s1
10 % 1
> evaluate (Binary (Binary (LitInt 6) Mul (LitInt 2)) Add (Id "a")) s1
17 % 1
execute :: Command -> Store -> Store
execute (Skip) sto = sto
execute (Assign id e) sto = updateSto sto id (evaluate e sto)
execute (Seq c1 c2) sto = execute c2 (execute c1 sto)
execute (IfThen b c) sto =
if (evaluate b sto) == (BVal True) then
execute c sto
else sto
execute (IfThenElse b c1 c2) sto =
if (evaluate b sto) == (BVal True) then
execute c1 sto
else execute c2 sto
execute (While b c) sto = loop sto
where loop sto = if (evaluate b sto) == (BVal True) then
(loop (execute c sto)) else sto
> s1
[("b",True),("a",5 % 1)]
> execute (Assign "a" (LitInt 9)) s1
[("a",9 % 1),("b",True)]
> execute (IfThen (Unary Not (Id "b")) (Assign "a" (LitInt 9))) s1
[("b",True),("a",5 % 1)]
> execute (While (Binary (Id "a") Lt (LitInt 10)) (Assign "a" (Binary (Id "a") Add (LitInt 1)))) s1
[("a",10 % 1),("b",True)]
type Store = [(Identifier,SV)]
emptySto:: Store
emptySto = []
updateSto:: Store -> Identifier -> SV -> Store
updateSto env id val =
(id,val) : (filter (\ (x,_) -> not(id==x)) env)
applySto:: Store -> Identifier -> SV
applySto env id =
snd (foldl (\ r c -> if id==(fst r) then r else c) ("",Undefined) env)
s1 = updateSto (updateSto emptySto "a" (IVal 5)) "b" (BVal True)
> s1
[("b",True),("a",5 % 1)]
> applySto s1 "a"
5 % 1
> applySto s1 "b"
True
> applySto emptySto "a"
Undefined