Skip to content

Commit

Permalink
Solve 2 task
Browse files Browse the repository at this point in the history
  • Loading branch information
GrigoriyNovitskiy committed Nov 22, 2024
1 parent 22794ac commit 7112264
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 9 deletions.
28 changes: 26 additions & 2 deletions src/Expr.lama
Original file line number Diff line number Diff line change
Expand Up @@ -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
-- }
}
42 changes: 37 additions & 5 deletions src/SM.lama
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}
18 changes: 16 additions & 2 deletions src/Stmt.lama
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
45 changes: 45 additions & 0 deletions src/X86_64.lama
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 7112264

Please sign in to comment.