diff --git a/src/Expr.lama b/src/Expr.lama index b758035636..8fc8ea1fd2 100644 --- a/src/Expr.lama +++ b/src/Expr.lama @@ -14,5 +14,25 @@ import State; -- Binop (string, expr, expr) public fun evalExpr (st, expr) { - failure ("evalExpr not implemented\n") + case expr of + Var (name) -> st(name) + | Const (value) -> value + | Binop (op, l, r) -> + case op of + "+" -> evalExpr(st, l) + evalExpr(st, r) + | "-" -> evalExpr(st, l) - evalExpr(st, r) + | "*" -> evalExpr(st, l) * evalExpr(st, r) + | "/" -> evalExpr(st, l) / evalExpr(st, r) + | "%" -> evalExpr(st, l) % evalExpr(st, r) + | "<" -> evalExpr(st, l) < evalExpr(st, r) + | "<=" -> evalExpr(st, l) <= evalExpr(st, r) + | ">" -> evalExpr(st, l) > evalExpr(st, r) + | ">=" -> evalExpr(st, l) >= evalExpr(st, r) + | "==" -> evalExpr(st, l) == evalExpr(st, r) + | "!=" -> evalExpr(st, l) != evalExpr(st, r) + | "&&" -> evalExpr(st, l) && evalExpr(st, r) + | "!!" -> evalExpr(st, l) !! evalExpr(st, r) + esac + esac + -- failure ("evalExpr not implemented\n") } diff --git a/src/SM.lama b/src/SM.lama index 5e9e82bd9e..9ed54b4179 100644 --- a/src/SM.lama +++ b/src/SM.lama @@ -20,6 +20,7 @@ public fun showSMInsn (i) { esac } + public fun showSM (prg) { map (fun (i) {showSMInsn (i) ++ "\n"}, prg).stringcat } @@ -27,7 +28,46 @@ 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") + case c of [stack, st, rw] -> + case insns of + {} -> c + | ins:inss -> case ins of + READ -> case readWorld (rw) of + [res, rrw] -> eval ([res : c, st, rrw], inss) + esac + | WRITE -> case stack of + {} -> failure ("can't write from empty stack") + | x:xs -> eval ([xs, st, writeWorld(x, rw)], inss) + esac + | BINOP (s) -> case stack of + y:(x:xs) -> case s of + "+" -> eval ([(x + y) : xs, st, rw], inss) + | "-" -> eval ([(x - y) : xs, st, rw], inss) + | "*" -> eval ([(x * y) : xs, st, rw], inss) + | "/" -> eval ([(x / y) : xs, st, rw], inss) + | "%" -> eval ([(x % y) : xs, st, rw], inss) + | "<" -> eval ([(x < y) : xs, st, rw], inss) + | "<=" -> eval ([(x <= y) : xs, st, rw], inss) + | ">" -> eval ([(x > y) : xs, st, rw], inss) + | ">=" -> eval ([(x >= y) : xs, st, rw], inss) + | "==" -> eval ([(x == y) : xs, st, rw], inss) + | "!=" -> eval ([(x != y) : xs, st, rw], inss) + | "&&" -> eval ([(x && y) : xs, st, rw], inss) + | "!!" -> eval ([(x !! y) : xs, st, rw], inss) + esac + | _ -> failure ("can't take enough arguments from stack") + esac + | LD (x) -> eval ([(st (x)) : stack, st,rw], inss) + | ST (x) -> + case stack of + {} -> failure ("can't read from empty stack") + | y:xs -> eval ([xs, st <- [x, y], rw], inss) + esac + | CONST (n) -> eval ([n:stack, st, rw], inss) + esac + esac + esac + -- failure ("SM eval not implemented\n") } -- Runs a stack machine for a given input and a given program, returns an output @@ -38,12 +78,24 @@ 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 (v) -> {LD (v)} + | Const (v) -> {CONST (v)} + | Binop (op, lhs, rhs) -> compileExpr (lhs) +++ compileExpr (rhs) +++ {BINOP (op)} + esac + -- failure ("compileExpr not implemented\n") } -- 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 + Skip -> {} + | Assn (v, expr) -> compileExpr(expr) +++ {ST (v)} + | Write (expr) -> compileExpr(expr) +++ {WRITE} + | Read (v) -> {READ, ST (v)} + | Seq (l, r) -> compileSM(l) +++ compileSM(r) + esac + -- failure ("compileSM not implemented\n") } diff --git a/src/Stmt.lama b/src/Stmt.lama index 67ec6db9e6..2dbe3756e3 100644 --- a/src/Stmt.lama +++ b/src/Stmt.lama @@ -17,7 +17,24 @@ import World; -- Write (expr) | fun eval (c, stmt) { - failure ("Stmt eval not implemented\n") + case stmt of + Skip -> c + | Assn (v, expr) -> [c.fst <- [v, evalExpr(c.fst, expr)], c.snd] + | Write (expr) -> case c of [st, rw] -> [st, writeWorld(evalExpr(st, expr), rw)] esac + | Read (v) -> + case c of [st, rw] -> + case readWorld(rw) of [va, nrw] -> + [st <- [v, va], nrw] + esac + esac + | Seq (l, r) -> + ( + var c1; + c1 := eval (c, l); + eval (c1, r) + ) + esac + -- failure ("Stmt eval not implemented\n") } -- Evaluates a program with a given input and returns an output