From 3b6180f7ee3255a6343b997664e39719b415c411 Mon Sep 17 00:00:00 2001 From: Denis Porsev Date: Sun, 27 Oct 2024 22:47:43 +0300 Subject: [PATCH] [AO1][PORSEV] Implemented base expr and stmt evaluation, SM interpreret and compiler to SM --- src/Expr.lama | 25 ++++++++++++++++++++++++- src/SM.lama | 34 ++++++++++++++++++++++++++++++---- src/Stmt.lama | 10 ++++++++-- 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src/Expr.lama b/src/Expr.lama index b758035636..1e5e55c003 100644 --- a/src/Expr.lama +++ b/src/Expr.lama @@ -4,6 +4,25 @@ import List; import State; +-- Evaluate the binary operation +public fun evalBinop(op) { + case op of + "+" -> infix + + | "-" -> infix - + | "*" -> infix * + | "/" -> infix / + | "%" -> infix % + | "&&" -> infix && + | "==" -> infix == + | "!=" -> infix != + | "<=" -> infix <= + | "<" -> infix < + | ">=" -> infix >= + | ">" -> infix > + | "!!" -> infix !! + esac +} + -- The evaluator itself: takes a state and an expression, -- returns integer value -- @@ -14,5 +33,9 @@ import State; -- Binop (string, expr, expr) public fun evalExpr (st, expr) { - failure ("evalExpr not implemented\n") + case expr of + Const (n) -> n + | Var (x) -> st (x) + | Binop (op, x, y) -> evalBinop (op) (evalExpr (st, x), evalExpr (st, y)) + esac } diff --git a/src/SM.lama b/src/SM.lama index 5e9e82bd9e..579a14cfe8 100644 --- a/src/SM.lama +++ b/src/SM.lama @@ -26,8 +26,21 @@ 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 ([stack, st, w], insns) { + case insns of + {} -> [stack, st, w] + | ins : insns -> eval ( + case ins of + LD (x) -> [st (x) : stack, st, w] + | CONST (n) -> [n : stack, st, w] + | BINOP (op) -> case stack of h : m : stack -> [evalBinop (op) (m, h) : stack, st, w] esac + | ST (x) -> case stack of h : stack -> [stack, st <- [x, h], w] esac + | READ -> case readWorld (w) of [n, w] -> [n : stack, st, w] esac + | WRITE -> case stack of h : stack -> [stack, st, writeWorld (h, w)] esac + esac, + insns + ) + esac } -- Runs a stack machine for a given input and a given program, returns an output @@ -38,12 +51,25 @@ 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 (x) -> singletonBuffer (LD (x)) + | Const (n) -> singletonBuffer (CONST (n)) + | Binop (op, l, r) -> compileExpr (l) <+> compileExpr (r) <+ 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") + fun compile (stmt) { + case stmt of + Assn (x, expr) -> compileExpr (expr) <+ ST (x) + | Seq (stmt1, stmt2) -> compile (stmt1) <+> compile (stmt2) + | Skip -> emptyBuffer () + | Read (x) -> singletonBuffer (READ) <+ ST (x) + | Write (expr) -> compileExpr (expr) <+ WRITE + esac + } + getBuffer $ compile (stmt) } diff --git a/src/Stmt.lama b/src/Stmt.lama index 67ec6db9e6..c49b422309 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 ([st, w], stmt) { + case stmt of + Assn (x, expr) -> [st <- [x, evalExpr (st, expr)], w] + | Seq (stmt1, stmt2) -> eval (eval ([st, w], stmt1), stmt2) + | Skip -> [st, w] + | Read (x) -> case readWorld (w) of [new_x, new_w] -> [st <- [x, new_x], new_w] esac + | Write (expr) -> [st, writeWorld (evalExpr (st, expr), w)] + esac } -- Evaluates a program with a given input and returns an output