diff --git a/src/Expr.lama b/src/Expr.lama index b758035636..9c1155570d 100644 --- a/src/Expr.lama +++ b/src/Expr.lama @@ -14,5 +14,31 @@ import State; -- Binop (string, expr, expr) public fun evalExpr (st, expr) { - failure ("evalExpr not implemented\n") + case expr of + Var (vName) -> st (vName) + | Const (value) -> value + | Binop (op, left, right) -> case evalExpr(st, left) of + leftValue -> case evalExpr(st, right) of + rightValue -> evalBinop(op, leftValue, rightValue) + esac + esac + esac } + +public fun evalBinop (op, l, r) { + case op of + "+" -> l + r + | "-" -> l - r + | "*" -> l * r + | "/" -> l / r + | "%" -> l % r + | "==" -> l == r + | "!=" -> l != r + | "<" -> l < r + | "<=" -> l <= r + | ">" -> l > r + | ">=" -> l >= r + | "&&" -> l && r + | "!!" -> l !! r + esac +} \ No newline at end of file diff --git a/src/SM.lama b/src/SM.lama index 5e9e82bd9e..973c77d26c 100644 --- a/src/SM.lama +++ b/src/SM.lama @@ -24,10 +24,34 @@ public fun showSM (prg) { map (fun (i) {showSMInsn (i) ++ "\n"}, prg).stringcat } +fun evalStep (c, inst) { + case c of + [stack, state, world] -> case inst of + READ -> case readWorld (world) of + [value, nextWorld] -> [value : stack, state, nextWorld] + esac + | WRITE -> case stack of + value : newStack -> [newStack, state, writeWorld (value, world)] + esac + | BINOP (op) -> case stack of + right : left : newStack -> [evalBinop (op, left, right) : newStack, state, world] + esac + | LD (varName) -> [state (varName) : stack, state, world] + | ST (varName) -> case stack of + value : newStack -> [newStack, state <- [varName, value], world] + esac + | CONST (value) -> [value : stack, state, world] + esac + esac +} + -- Stack machine interpreter. Takes an SM-configuration and a program, -- returns a final configuration fun eval (c, insns) { - failure ("SM eval not implemented\n") + case insns of + {} -> c + | inst : rest -> eval (evalStep (c, inst), rest) + esac } -- Runs a stack machine for a given input and a given program, returns an output @@ -38,12 +62,26 @@ public fun evalSM (input, insns) { -- Compiles an expression into a stack machine code. -- Takes an expression, returns a list of stack machine instructions fun compileExpr (expr) { - failure ("compileExpr not implemented\n") + case expr of + Var (varName) -> LD (varName) : {} + | Const (value) -> CONST (value) : {} + | Binop (op, left, right) -> case compileExpr (left) of + leftInsns -> case compileExpr (right) of + rightInsns -> leftInsns +++ rightInsns +++ (BINOP (op) : {}) + esac + esac + esac } -- Compiles a statement into a stack machine code. -- Takes a statement, returns a list of stack machine -- instructions. public fun compileSM (stmt) { - failure ("compileSM not implemented\n") + case stmt of + Assn (varName, expr) -> compileExpr (expr) +++ (ST (varName) : {}) + | Seq (first, second) -> compileSM (first) +++ compileSM (second) + | Skip -> {} + | Read (varName) -> READ : ST (varName) : {} + | Write (expr) -> compileExpr (expr) +++ (WRITE : {}) + esac } diff --git a/src/Stmt.lama b/src/Stmt.lama index 67ec6db9e6..1a8ff66b44 100644 --- a/src/Stmt.lama +++ b/src/Stmt.lama @@ -17,7 +17,21 @@ import World; -- Write (expr) | fun eval (c, stmt) { - failure ("Stmt eval not implemented\n") + case c of + [state, world] -> case stmt of + Assn (varName, expr) -> [state <- [varName, evalExpr (state, expr)], world] + | Seq (first, second) -> case eval (c, first) of + nextC -> eval(nextC, second) + esac + | Skip -> c + | Read (varName) -> case readWorld (world) of + [value, nextWorld] -> [state <- [varName, value], nextWorld] + esac + | Write (expr) -> case evalExpr (state, expr) of + value -> [state, writeWorld (value, world)] + esac + esac + esac } -- Evaluates a program with a given input and returns an output