From 711226496cd61d371d21e74c9d0937ad9e42cd15 Mon Sep 17 00:00:00 2001 From: GrigoriyNovitskiy Date: Fri, 22 Nov 2024 18:07:30 +0300 Subject: [PATCH] Solve 2 task --- src/Expr.lama | 28 ++++++++++++++++++++++++++-- src/SM.lama | 42 +++++++++++++++++++++++++++++++++++++----- src/Stmt.lama | 18 ++++++++++++++++-- src/X86_64.lama | 45 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 9 deletions(-) diff --git a/src/Expr.lama b/src/Expr.lama index b758035636..ce46a47293 100644 --- a/src/Expr.lama +++ b/src/Expr.lama @@ -13,6 +13,30 @@ import State; -- Const (int) | -- Binop (string, expr, expr) -public fun evalExpr (st, expr) { - failure ("evalExpr not implemented\n") +public fun evalOp (op, x, y) { + 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 } + +public fun evalExpr (st, expr) { + -- fun (st) { + case expr of + Var (a) -> st (a) + | Const (c) -> c + | Binop (op, l, r) -> evalOp (op, evalExpr (st, l), evalExpr (st, r)) + esac + -- } +} \ No newline at end of file diff --git a/src/SM.lama b/src/SM.lama index 5e9e82bd9e..fd168d979f 100644 --- a/src/SM.lama +++ b/src/SM.lama @@ -26,8 +26,28 @@ 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 (c@[stack, st, w], insns) { + -- c.fst - stack, c.snd -> c + case insns of + {} -> c + | head:tail -> + -- printf(head.string, "\n"); + case head of + WRITE -> case stack of + h:t -> eval ([t, st, writeWorld(h, w)], tail) + esac + | READ -> var new_c = readWorld(w); + eval ([new_c.fst : stack, st, ((new_c).snd)], tail) + | BINOP (s) -> case stack of + y:x:t -> eval([evalOp(s, x, y): t, st, w] , tail) + esac + | LD (x) -> eval ([(st)(x) : stack, st, w], tail) + | ST (x) -> case stack of + h:t -> eval ([t, (st) <- [x, h], w], tail) + esac + | CONST (n) -> eval ([n : stack, st, w], tail) + esac + esac } -- Runs a stack machine for a given input and a given program, returns an output @@ -38,12 +58,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") + -- failure ("compileExpr not implemented\n") + case expr of + Var (x) -> {LD (x)} + | Const (n) -> {CONST (n)} + | Binop (op, x, y) -> compileExpr (x) +++ compileExpr (y) +++ { 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") -} + -- failure ("compileSM not implemented\n") + case stmt of + Assn (x, e) -> compileExpr(e) +++ { ST (x)} + | Seq (lhs, rhs) -> compileSM(lhs) +++ compileSM(rhs) + | Skip -> {} + | Read (x) -> { READ, ST (x)} + | Write (e) -> compileExpr(e) +++ { WRITE } + esac +} \ No newline at end of file diff --git a/src/Stmt.lama b/src/Stmt.lama index 67ec6db9e6..549b4b301e 100644 --- a/src/Stmt.lama +++ b/src/Stmt.lama @@ -17,10 +17,24 @@ import World; -- Write (expr) | fun eval (c, stmt) { - failure ("Stmt eval not implemented\n") + -- printf("bbbbbb\n"); + case stmt of + Assn (s, e) -> --printf("assn\n"); + [c.fst <- [s, evalExpr (c.fst, e)], c.snd] + | Seq (l, r) -> eval (eval (c, l), r) + | Skip -> --printf("skip\n"); + c + | Read (s) -> + var v = readWorld(c.snd); + -- printf("read\n"); + [c.fst <- [s, v.fst], v.snd] + | Write (e) -> + [c.fst, [(c.snd).fst, evalExpr(c.fst, e) : ((c.snd).snd)]] + esac + -- failure ("Stmt eval not implemented\n") } -- Evaluates a program with a given input and returns an output public fun evalStmt (input, stmt) { eval ([emptyState, createWorld (input)], stmt).snd.getOutput -} +} \ No newline at end of file diff --git a/src/X86_64.lama b/src/X86_64.lama index 9c03745cb8..f0ea840c6d 100644 --- a/src/X86_64.lama +++ b/src/X86_64.lama @@ -300,6 +300,51 @@ fun compile (env, code) { case env.pop of [s, env] -> [env, code <+ Mov (s, rdi) <+ Call ("Lwrite")] esac + | LD(x) -> + case env.addGlobal(x).allocate of + [s, env] -> [env, code <+> move(env.loc(x), s)] + esac + | ST(x) -> + case env.addGlobal(x).pop of + [s, env] -> [env, code <+> move(s, env.loc(x))] + esac + | BINOP (op) -> + case env.pop2 of + [x, y, env] -> + case env.allocate of + [s, env] -> + case op of + "+" -> + [env, code <+> (singletonBuffer(Mov(y, rax)) <+ Binop (op, x, rax) <+ Mov (rax, s))] + | "-" -> + [env, code <+> (singletonBuffer(Mov(y, rax)) <+ Binop (op, x, rax) <+ Mov (rax, s))] + | "*" -> + [env, code <+> (singletonBuffer(Mov(y, rax)) <+ Binop (op, x, rax) <+ Mov (rax, s))] + | "/" -> + [env, code <+> (singletonBuffer(Mov(y, rax)) <+ Cltd <+ IDiv (x) <+ Mov (rax, s))] + | "%" -> + [env, code <+> (singletonBuffer(Mov(y, rax)) <+ Cltd <+ IDiv (x) <+ Mov (rdx, s))] + | "<" -> + [env, code <+> (singletonBuffer(Mov(y, rax)) <+ Mov (L(0), rdx) <+ Binop ("cmp", x, rax) <+ Set ("l", "%dl") <+ Mov (rdx, s))] + | ">" -> + [env, code <+> (singletonBuffer(Mov(y, rax)) <+ Mov (L(0), rdx) <+ Binop ("cmp", x, rax) <+ Set ("g", "%dl") <+ Mov (rdx, s))] + | "==" -> + [env, code <+> (singletonBuffer(Mov(y, rax)) <+ Mov (L(0), rdx) <+ Binop ("cmp", x, rax) <+ Set ("e", "%dl") <+ Mov (rdx, s))] + | "<=" -> + [env, code <+> (singletonBuffer(Mov(y, rax)) <+ Mov (L(0), rdx) <+ Binop ("cmp", x, rax) <+ Set ("le", "%dl") <+ Mov (rdx, s))] + | ">=" -> + [env, code <+> (singletonBuffer(Mov(y, rax)) <+ Mov (L(0), rdx) <+ Binop ("cmp", x, rax) <+ Set ("ge", "%dl") <+ Mov (rdx, s))] + | "!=" -> + [env, code <+> (singletonBuffer(Mov(y, rax)) <+ Mov (L(0), rdx) <+ Binop ("cmp", x, rax) <+ Set ("ne", "%dl") <+ Mov (rdx, s))] + | "&&" -> [env, code <+> (singletonBuffer(Mov (L(1), s))) ] + esac + esac + esac + + | CONST (n) -> + case env.allocate of + [s, env] ->[env, code <+ Mov( L (n), s)] + esac | _ -> failure ("codegeneration for instruction %s is not yet implemented\n", i.string) esac }, [env, emptyBuffer ()], code)