Skip to content

Commit

Permalink
first try
Browse files Browse the repository at this point in the history
  • Loading branch information
Arishkamu committed Nov 17, 2024
1 parent 22794ac commit 553854c
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 23 deletions.
27 changes: 25 additions & 2 deletions 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 evalExpr (st, expr) {
failure ("evalExpr not implemented\n")
public fun evalOp (op, l, r) {
case op of
"+" -> l + r
| "-" -> l - r
| "*" -> l * r
| "/" -> l / r
| "%" -> l % r
| ">" -> l > r
| "<" -> l < r
| ">=" -> l >= r
| "<=" -> l <= r
| "==" -> l == r
| "!=" -> l != r
| "&&" -> l && r
| "!!" -> l !! r
| op -> failure ("undefined operation ""%s""\n", op)
esac
}

public fun evalExpr (st, expr) {
case expr of
Var (strr) -> st (strr)
| Const (n) -> n
| Binop (op, exprL, exprR) -> evalOp(op, evalExpr(st, exprL), evalExpr(st, exprR))
esac
}
44 changes: 34 additions & 10 deletions src/SM.lama
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import Fun;
-- string representation.
public fun showSMInsn (i) {
case i of
READ -> sprintf ("READ")
| WRITE -> sprintf ("WRITE")
| BINOP (s) -> sprintf ("BINOP %s", s)
| LD (x) -> sprintf ("LD %s", x)
| ST (x) -> sprintf ("ST %s", x)
| CONST (n) -> sprintf ("CONST %d", n)
READ -> sprintf ("READ")
| WRITE -> sprintf ("WRITE")
| BINOP (s) -> sprintf ("BINOP %s", s)
| LD (x) -> sprintf ("LD %s", x)
| ST (x) -> sprintf ("ST %s", x)
| CONST (n) -> sprintf ("CONST %d", n)
esac
}

Expand All @@ -27,7 +27,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")
case insns of
{} -> c
| i:ns ->
case c of
[stack, s, w] -> case i of
READ -> case readWorld(w) of [z, w1] -> eval ([z:stack, s, w1], ns) esac
| WRITE -> case stack of z:stack1 -> eval ([stack1, s, writeWorld(z, w)], ns) esac
| BINOP (op) -> case stack of y:x:stack1 -> eval ([(evalOp(op, x, y)):stack1, s, w], ns) esac
| LD (x) -> eval([s(x):stack, s, w], ns)
| ST (strr) -> case stack of z:stack1 -> eval ([stack1, s <- [strr, z], w], ns) esac
| CONST (n) -> eval ([n:stack, s, w], ns)
esac
| _ -> failure ("no SM-comfiguration")
esac
esac
}

-- Runs a stack machine for a given input and a given program, returns an output
Expand All @@ -38,12 +52,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, exprL, exprR) -> compileExpr(exprL) +++ compileExpr(exprR) +++ {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 (strr, expr) -> compileExpr(expr) +++ {ST (strr)}
| Seq (stmt1, stmt2) -> compileSM(stmt1) +++ compileSM(stmt2)
| Read (strr) -> {READ, ST (strr)}
| Write (expr) -> compileExpr(expr) +++ {WRITE}
| Skip -> {}
esac
}
17 changes: 15 additions & 2 deletions src/Stmt.lama
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,23 @@ import World;
-- Write (expr) |

fun eval (c, stmt) {
failure ("Stmt eval not implemented\n")
case c of [s, w] ->
case stmt of
Assn (strr, expr) -> [s <- [strr, evalExpr (s, expr)], w]
| Seq (stmt1, stmt2) -> eval(eval(c, stmt1), stmt2)
| Skip -> c
| Read (strr) ->
case readWorld (w) of
[z, w1] -> [s <- [strr, z], w1]
| _ -> failure ("no world")
esac
| Write (expr) -> [s, writeWorld(evalExpr(s, expr), w)]
esac
| _ -> failure ("no configuration")
esac
}

-- Evaluates a program with a given input and returns an output
public fun evalStmt (input, stmt) {
eval ([emptyState, createWorld (input)], stmt).snd.getOutput
}
}
67 changes: 58 additions & 9 deletions src/X86_64.lama
Original file line number Diff line number Diff line change
Expand Up @@ -292,19 +292,68 @@ fun compile (env, code) {
fun ([env, scode], i) {
var code = scode <+ Meta ("# " ++ showSMInsn (i) ++ "\n");
case i of
READ ->
case env.allocate of
[s, env] -> [env, code <+ Call ("Lread") <+ Mov (rax, s)]
esac
| WRITE ->
case env.pop of
[s, env] -> [env, code <+ Mov (s, rdi) <+ Call ("Lwrite")]
esac
| _ -> failure ("codegeneration for instruction %s is not yet implemented\n", i.string)
READ ->
case env.allocate of
[s, env] -> [env, code <+ Call ("Lread") <+ Mov (rax, s)]
esac
| WRITE ->
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 <+ Mov (env.loc(x), s)]
esac
| ST(x) ->
case env.addGlobal (x).pop of
[s, env] -> [env, code <+ Mov (s, env.loc (x))]
esac
| CONST(x) ->
case env.allocate of
[s, env] -> [env, code <+ Mov (L (x), s)]
esac
| BINOP (op) ->
case env.pop2 of
[x, y, env] ->
case env.allocate of
[s, env] -> [env, myBinop(code, x, y, op, s)]
esac
esac
| _ -> failure ("codegeneration for instruction %s is not yet implemented\n", i.string)
esac
}, [env, emptyBuffer ()], code)
}


fun myBinop(code, x, y, op, s) {
case op of
"+" -> code <+ Binop (op, x, y)
| "-" -> code <+ Binop (op, x, y)
| "*" -> code <+ Binop (op, x, y)
| "/" -> code <+ Mov (y, rax) <+ IDiv (x) <+ Mov (rax, y)
| "%" -> code <+ Mov (y, rax) <+ IDiv (x) <+ Mov (rdx, y)

| ">" -> code <+ Binop("^", rdx, rdx) <+ Binop("cmp", x, y) <+ Set(suffix(op), "%dl") <+ Mov (rdx, s)
| "<" -> code <+ Binop("^", rdx, rdx) <+ Binop("cmp", x, y) <+ Set(suffix(op), "%dl") <+ Mov (rdx, s)
| ">=" -> code <+ Binop("^", rdx, rdx) <+ Binop("cmp", x, y) <+ Set(suffix(op), "%dl") <+ Mov (rdx, s)
| "<=" -> code <+ Binop("^", rdx, rdx) <+ Binop("cmp", x, y) <+ Set(suffix(op), "%dl") <+ Mov (rdx, s)
| "==" -> code <+ Binop("^", rdx, rdx) <+ Binop("cmp", x, y) <+ Set(suffix(op), "%dl") <+ Mov (rdx, s)
| "!=" -> code <+ Binop("^", rdx, rdx) <+ Binop("cmp", x, y) <+ Set(suffix(op), "%dl") <+ Mov (rdx, s)

| "&&" -> code
<+ Binop("^", rdx, rdx) <+ Binop("cmp", rdx, x) <+ Set(suffix("!="), "%dl")
<+ Binop("^", rax, rax) <+ Binop("cmp", rax, y) <+ Set(suffix("!="), "%al")
<+ Binop(op, rdx, rax)
<+ Mov (rax, s)
| "||" -> code
<+ Binop("^", rdx, rdx) <+ Binop("cmp", rdx, x) <+ Set(suffix("!="), "%dl")
<+ Binop("^", rax, rax) <+ Binop("cmp", rax, y) <+ Set(suffix("!="), "%al")
<+ Binop(op, rdx, rax)
<+ Mov (rax, s)
esac
}


-- A top-level codegeneration function. Takes a stack machine program
-- and returns x86 listing as a string
public fun compileX86 (code) {
Expand Down

0 comments on commit 553854c

Please sign in to comment.