diff --git a/src/Expr.lama b/src/Expr.lama index b75803563..b651a39ec 100644 --- a/src/Expr.lama +++ b/src/Expr.lama @@ -14,5 +14,26 @@ import State; -- Binop (string, expr, expr) public fun evalExpr (st, expr) { - failure ("evalExpr not implemented\n") + case expr of + Var (name) -> st (name) + | Const (x) -> x + | Binop (op, ex, ey) -> + var x = evalExpr (st, ex); + var y = evalExpr (st, ey); + case op of + "+" -> x + y + | "-" -> x - y + | "*" -> x * y + | "/" -> x / y + | "%" -> x % y + | "<" -> x < y + | ">" -> x > y + | "<=" -> x <= y + | ">=" -> x >= y + | "==" -> x == y + | "!=" -> x != y + | "&&" -> x && y + | "!!" -> x !! y + esac + esac } diff --git a/src/SM.lama b/src/SM.lama index 5e9e82bd9..f0deec027 100644 --- a/src/SM.lama +++ b/src/SM.lama @@ -26,8 +26,37 @@ public fun showSM (prg) { -- Stack machine interpreter. Takes an SM-configuration and a program, -- returns a final configuration -fun eval (c, insns) { - failure ("SM eval not implemented\n") +fun eval (conf@[stack, state, world], prog) { + case prog of + {} -> conf + | ins:prog -> + case ins of + READ -> case readWorld (world) of [x, world] -> eval ([x : stack, state, world], prog) esac + | WRITE -> case stack of x : stack -> eval ([stack, state, writeWorld (x, world)], prog) esac + | CONST (x) -> eval ([x : stack, state, world], prog) + | LD (name) -> eval ([state (name) : stack, state, world], prog) + | ST (name) -> case stack of x : stack -> eval ([stack, state <- [name, x], world], prog) esac + | BINOP (op) -> + case stack of y : x : stack -> + var z = case op of + "+" -> x + y + | "-" -> x - y + | "*" -> x * y + | "/" -> x / y + | "%" -> x % y + | "<" -> x < y + | ">" -> x > y + | "<=" -> x <= y + | ">=" -> x >= y + | "==" -> x == y + | "!=" -> x != y + | "&&" -> x && y + | "!!" -> x !! y + esac; + eval ([z : stack, state, world], prog) + esac + esac + esac } -- Runs a stack machine for a given input and a given program, returns an output @@ -38,12 +67,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 (name) -> {LD (name)} + | Const (x) -> {CONST (x)} + | Binop (op, ex, ey) -> compileExpr (ex) +++ compileExpr (ey) +++ {BINOP (op)} + esac +} + +fun compileStmt (stmt) { + case stmt of + Skip -> {} + | Assn (name, expr) -> compileExpr (expr) +++ {ST (name)} + | Seq (stmt1, stmt2) -> compileSM (stmt1) +++ compileSM (stmt2) + | Read (name) -> {READ, ST (name)} + | Write (expr) -> compileExpr (expr) +++ {WRITE} + 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") + compileStmt (stmt) } diff --git a/src/Stmt.lama b/src/Stmt.lama index 67ec6db9e..f2607cf90 100644 --- a/src/Stmt.lama +++ b/src/Stmt.lama @@ -16,8 +16,14 @@ import World; -- Read (string) | -- Write (expr) | -fun eval (c, stmt) { - failure ("Stmt eval not implemented\n") +fun eval (conf@[state, world], stmt) { + case stmt of + Skip -> conf + | Assn (name, expr) -> [state <- [name, evalExpr (state, expr)], world] + | Seq (stmt1, stmt2) -> eval (eval (conf, stmt1), stmt2) + | Read (name) -> case readWorld (world) of [x, world] -> [state <- [name, x], world] esac + | Write (expr) -> [state, writeWorld (evalExpr (state, expr), world)] + esac } -- Evaluates a program with a given input and returns an output