Skip to content

Commit

Permalink
feat: add a02 solution
Browse files Browse the repository at this point in the history
  • Loading branch information
m7kss1 committed Nov 23, 2024
1 parent 22794ac commit 43ee7fa
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 8 deletions.
Binary file added regression/test001-1.run
Binary file not shown.
Binary file added regression/test001.run
Binary file not shown.
Binary file added regression/test002.run
Binary file not shown.
Binary file added regression/test003.run
Binary file not shown.
Binary file added regression/test004.run
Binary file not shown.
Binary file added regression/test005.run
Binary file not shown.
Binary file added regression/test006.run
Binary file not shown.
Binary file added regression/test007.run
Binary file not shown.
Binary file added regression/test008.run
Binary file not shown.
25 changes: 24 additions & 1 deletion src/Expr.lama
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,29 @@ import State;
-- Const (int) |
-- Binop (string, expr, expr)

public fun evalBinop(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
| "!!" -> lhs !! rhs
esac
}

public fun evalExpr (st, expr) {
failure ("evalExpr not implemented\n")
case expr of
Var (x) -> st (x)
| Const (n) -> n
| Binop (op, x, y) -> evalBinop(op, evalExpr(st, x), evalExpr(st, y))
esac
}
49 changes: 44 additions & 5 deletions src/SM.lama
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,37 @@ 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, state, world], insns) {
fun evalIns(c@[stack, state, world], i) {
case i of
READ -> (
case readWorld(world) of
[value, new_world] -> [value: stack, state, new_world]
esac
)
| WRITE -> (
case stack of
top: new_stack -> [new_stack, state, writeWorld(top, world)]
esac
)
| BINOP (s) -> (
case stack of
y: x: new_stack -> [evalBinop(s, x, y): new_stack, state, world]
esac
)
| LD (x) -> [state (x) : stack, state, world]
| ST (x) -> (
case stack of
top: new_stack -> [new_stack, state <- [x, top], world]
esac
)
| CONST (n) -> [n : stack, state, world]
esac
}
case insns of
{} -> c
| i: rem -> eval(evalIns(c, i), rem)
esac
}

-- Runs a stack machine for a given input and a given program, returns an output
Expand All @@ -38,12 +67,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 (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")
}
case stmt of
Assn (x, expr) -> compileExpr (expr) +++ { ST (x) }
| Seq (st1, st2) -> compileSM(st1) +++ compileSM (st2)
| Skip -> {}
| Read (x) -> { READ, ST (x) }
| Write (expr) -> compileExpr (expr) +++ { WRITE }
esac
}
14 changes: 12 additions & 2 deletions src/Stmt.lama
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,18 @@ import World;
-- Read (string) |
-- Write (expr) |

fun eval (c, stmt) {
failure ("Stmt eval not implemented\n")
fun eval (c@[st, w], stmt) {
case stmt of
Assn (x, expr) -> [st <- [x,evalExpr(st, expr)], w]
| Seq (st1, st2) -> eval(eval(c, st1), st2)
| Skip -> c
| Read (x) -> (
case readWorld(w) of
[value, new_world] -> [st <- [x, value], new_world]
esac
)
| Write (expr) -> [st, writeWorld(evalExpr(st, expr), w)]
esac
}

-- Evaluates a program with a given input and returns an output
Expand Down
81 changes: 81 additions & 0 deletions src/X86_64.lama
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,68 @@ fun suffix (op) {
esac
}

fun compileBinop(op, x, y, out) {
var code = singletonBuffer(Mov(y, rax));
case op of
"+" -> code <+ Binop(op, x, rax)
| "-" -> code <+ Binop(op, x, rax)
| "*" -> code <+ Binop(op, x, rax)
| "/" -> code <+ Cltd <+ IDiv(x)
| "%" -> code <+ Cltd <+ IDiv(x) <+ Mov(rdx, rax)
| "<" ->
code <+ Mov(L(0), rdx)
<+ Binop("cmp", x, rax)
<+ Set(suffix(op), "%dl")
<+ Mov(rdx, rax)
| ">" ->
code <+ Mov(L(0), rdx)
<+ Binop("cmp", x, rax)
<+ Set(suffix(op), "%dl")
<+ Mov(rdx, rax)
| "<" ->
code <+ Mov(L(0), rdx)
<+ Binop("cmp", x, rax)
<+ Set(suffix(op), "%dl")
<+ Mov(rdx, rax)
| ">=" ->
code <+ Mov(L(0), rdx)
<+ Binop("cmp", x, rax)
<+ Set(suffix(op), "%dl")
<+ Mov(rdx, rax)
| "<=" ->
code <+ Mov(L(0), rdx)
<+ Binop("cmp", x, rax)
<+ Set(suffix(op), "%dl")
<+ Mov(rdx, rax)
| "==" ->
code <+ Mov(L(0), rdx)
<+ Binop("cmp", x, rax)
<+ Set(suffix(op), "%dl")
<+ Mov(rdx, rax)
| "!=" ->
code <+ Mov(L(0), rdx)
<+ Binop("cmp", x, rax)
<+ Set(suffix(op), "%dl")
<+ Mov(rdx, rax)
| "&&" ->
code <+ Mov(L(0), rax)
<+ Binop("cmp", L(0), y)
<+ Set(suffix("!="), "%al")
<+ Mov(L(0), rdx)
<+ Binop("cmp", L(0), x)
<+ Set(suffix("!="), "%dl")
<+ Binop(op, rdx, rax)
| "!!" ->
code <+ Mov(L(0), rax)
<+ Binop("cmp", L(0), y)
<+ Set(suffix("!="), "%al")
<+ Mov(L(0), rdx)
<+ Binop("cmp", L(0), x)
<+ Set(suffix("!="), "%dl")
<+ Binop(op, rdx, rax)
esac <+ Mov(rax, out)
}

-- Compiles stack machine code into a list of x86 instructions. Takes an environment
-- and stack machine code, returns an updated environment and x86 code.
fun compile (env, code) {
Expand All @@ -300,6 +362,25 @@ fun compile (env, code) {
case env.pop of
[s, env] -> [env, code <+ Mov (s, rdi) <+ Call ("Lwrite")]
esac
| BINOP (x) ->
case env.pop2 of
[lhs, rhs, env] ->
case env.allocate of
[out, env] -> [env, code <+> compileBinop(x, lhs, rhs, out)]
esac
esac
| CONST (n) ->
case env.allocate of
[s, env] -> [env, code <+ Mov (L (n), s)]
esac
| ST (x) ->
case env.pop of
[s, env] -> [env.addGlobal (x), code <+ Mov (s, env.loc(x))]
esac
| LD (x) ->
case env.allocate of
[s, env] -> [env, code <+ Mov (env.loc(x), s)]
esac
| _ -> failure ("codegeneration for instruction %s is not yet implemented\n", i.string)
esac
}, [env, emptyBuffer ()], code)
Expand Down

0 comments on commit 43ee7fa

Please sign in to comment.