From 3fc6d221471a7a008fc0398da5be2861e9613fd7 Mon Sep 17 00:00:00 2001 From: Jegor Popow Date: Sat, 7 Oct 2023 22:07:53 +0300 Subject: [PATCH] first iteration --- src/Expr.lama | 27 +++++++++++++++++-- src/SM.lama | 75 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/Stmt.lama | 29 +++++++++++++++++++- 3 files changed, 125 insertions(+), 6 deletions(-) diff --git a/src/Expr.lama b/src/Expr.lama index b75803563..79e4ea1cb 100644 --- a/src/Expr.lama +++ b/src/Expr.lama @@ -3,7 +3,6 @@ import List; import State; - -- The evaluator itself: takes a state and an expression, -- returns integer value -- @@ -14,5 +13,29 @@ import State; -- Binop (string, expr, expr) public fun evalExpr (st, expr) { - failure ("evalExpr not implemented\n") + + fun applyOperator(op, lhs, rhs) { + -- printf("Opearator `%s` called on operands %d, %d\n", op, lhs, rhs); + case op of + "+" -> lhs + rhs + | "-" -> lhs - rhs + | "*" -> lhs * rhs + | "/" -> lhs / rhs + | "%" -> lhs % rhs + | "==" -> lhs == rhs + | "!=" -> lhs != rhs + | "<" -> lhs < rhs + | "<=" -> lhs <= rhs + | ">" -> lhs > rhs + | ">=" -> lhs >= rhs + | "&&" -> lhs && rhs + | "!!" -> lhs !! rhs + esac + } + + case expr of + Var (name) -> st(name) + | Const (value) -> value + | Binop (op, lhs, rhs) -> applyOperator(op, evalExpr(st, lhs), evalExpr(st, rhs)) + esac } diff --git a/src/SM.lama b/src/SM.lama index 5e9e82bd9..5ee96d122 100644 --- a/src/SM.lama +++ b/src/SM.lama @@ -27,7 +27,66 @@ 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 applyOperator(op, lhs, rhs) { + -- printf("Opearator `%s` called on operands %d, %d\n", op, lhs, rhs); + case op of + "+" -> lhs + rhs + | "-" -> lhs - rhs + | "*" -> lhs * rhs + | "/" -> lhs / rhs + | "%" -> lhs % rhs + | "==" -> lhs == rhs + | "!=" -> lhs != rhs + | "<" -> lhs < rhs + | "<=" -> lhs <= rhs + | ">" -> lhs > rhs + | ">=" -> lhs >= rhs + | "&&" -> lhs && rhs + | "!!" -> lhs !! rhs + esac + } + + + fun store([value:tail, state, world], name) { + [tail, state <- [name, value], world] + } + + fun load([stack, state, world], name) { + [state(name):stack, state, world] + } + + fun read([stack, state, world]) { + case readWorld(world) of + [value, newWorld] -> [value : stack, state, newWorld] + esac + } + + fun write([value:tail, state, world]) { + [tail, state, writeWorld(value, world)] + } + + fun binop([rhs:lhs:tail, state, world], op) { + [applyOperator(op, lhs, rhs):tail, state, world] + } + + fun push([stack, state, world], value) { + [value : stack, state, world] + } + + fun step(c@[stack, state, world], insn) { + case insn of + READ -> read(c) + | WRITE -> write(c) + | BINOP (op) -> binop(c, op) + | LD (name) -> load(c, name) + | ST (name) -> store(c, name) + | CONST (value) -> push(c, value) + esac + } + + foldl (step, c, insns) } -- Runs a stack machine for a given input and a given program, returns an output @@ -38,12 +97,22 @@ 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 (value) -> {CONST(value)} + | Binop (op, lhs, rhs) -> compileExpr(lhs) +++ compileExpr(rhs) +++ {BINOP(op)} + 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 (name, expr) -> compileExpr(expr) +++ {ST(name)} + | Seq (first, second) -> compileSM(first) +++ compileSM(second) + | Skip -> {} + | Read (name) -> {READ, ST(name)} + | Write (expr) -> compileExpr(expr) +++ {WRITE} + esac } diff --git a/src/Stmt.lama b/src/Stmt.lama index 67ec6db9e..34047d0c7 100644 --- a/src/Stmt.lama +++ b/src/Stmt.lama @@ -17,9 +17,36 @@ import World; -- Write (expr) | fun eval (c, stmt) { - failure ("Stmt eval not implemented\n") + + fun applyAssn([st, world], name, expr) { + [st <- [name, evalExpr(st, expr)], world] + } + + fun applySeq(c, first, second) { + var intermediate = eval(c, first); + eval (intermediate, second) + } + + fun applyRead([st, world], name) { + case readWorld(world) of + [value, newWorld] -> [st <- [name, value], newWorld] + esac + } + + fun applyWrite([st, world], expr) { + [st, writeWorld(evalExpr(st, expr), world)] + } + + case stmt of + Assn (name, expr) -> applyAssn(c, name, expr) + | Seq (first, second) -> applySeq(c, first, second) + | Skip -> c + | Read (name) -> applyRead(c, name) + | Write (expr) -> applyWrite(c, expr) + esac } + -- Evaluates a program with a given input and returns an output public fun evalStmt (input, stmt) { eval ([emptyState, createWorld (input)], stmt).snd.getOutput