Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions runtime64/runtime.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# include <stdio.h>

void Lwrite (long x) {
# define ALIGN_STACK asm ("andq $0xFFFFFFFFFFFFFFF0,%rsp")

void Lwrite (long x) {
ALIGN_STACK;
printf ("%ld\n", x);
}

long Lread () {
long result;


ALIGN_STACK;
scanf ("%ld", &result);

return result;
Expand Down
124 changes: 71 additions & 53 deletions src/Expr.lama
Original file line number Diff line number Diff line change
@@ -1,36 +1,31 @@
-- Expression evaluator

import List;
import State;
import World;
import Lexer;
import Parser;

-- As association map which maps "\otimes" into "\oplus"
var ops = {
["+" , infix + ],
["-" , infix - ],
["*" , infix * ],
["/" , infix / ],
["%" , infix % ],
["==", infix ==],
["!=", infix !=],
["<" , infix < ],
["<=", infix <=],
[">" , infix > ],
[">=", infix >=],
["&&", infix &&],
["!!", infix !!]
};

var ops = {["+", infix +],
["-", infix -],
["*", infix *],
["/", infix /],
["%", infix %],
["==", infix ==],
["!=", infix !=],
["<", infix <],
["<=", infix <=],
[">", infix >],
[">=", infix >=],
["&&", infix &&],
["!!", infix !!]};
-- The evaluator for infix operators: takes an operator as a string
-- and two operand values, and returns the result
public fun evalOp (op, l, r) {
case assoc (ops, op) of
Some (f) -> f (l, r)
esac
case assoc(ops, op) of
Some(f) -> f(l, r)
esac
}

-- Evaluates an expression "expr" in a configuration "c".
-- A configuration is a pair of a state "s" and a world "w".
-- Returns a final configuration (if any)
Expand All @@ -51,58 +46,81 @@ public fun evalOp (op, l, r) {
-- Binop (string, expr, expr) |
-- Call (string, expr list) |
-- Ignore (expr)

-- Helper function: checks that given name designates a regular variable in
-- a given state
fun checkVar (state, name) {
case state.lookup (name) of
Var (_) -> skip
| _ -> error (sprintf ("the name ""%s"" does not designate a variable", name), getLoc (name))
esac
case state.lookup(name) of
Var(_) -> skip
| _ -> error(sprintf("the name ""%s"" does not designate a variable", name), getLoc(name))
esac
}

-- Helper function: checks that given name designates a function in
-- a given state
fun checkFun (state, name) {
case state.lookup (name) of
Fun (_, _) -> skip
| _ -> error (sprintf ("the name ""%s"" does not designate a function", name), getLoc (name))
esac
case state.lookup(name) of
Fun(_, _) -> skip
| _ -> error(sprintf("the name ""%s"" does not designate a function", name), getLoc(name))
esac
}

-- Helper function: adds a bunch of regular variables current scope
fun addNames (state, names) {
foldl (fun (s, name) {s.addName (name, Var (0))}, state, names)
foldl(fun (s, name) {s.addName(name, Var(0))}, state, names)
}

-- Helper function: adds a function in current scope
fun addFunction (state, name, args, body) {
state.addName (name, Fun (args, body))
state.addName(name, Fun(args, body))
}
fun addDecs (state, decs) {
foldl(fun (s, dec) {
case dec of
Var(names) -> s.addNames(names)
| Fun(name, args, body) -> s.addFunction(name, args, body)
esac
}, state, decs)
}
fun addArgs (state, args, vals) {
foldl(fun (s, [arg, value]) {s.addName(arg, value)}, state, zip(args, vals))
}

-- Evaluates a list of expressions, properly threading a configurations.
-- Returns the final configuration and the list of values
fun evalList (c, exprs) {
case foldl (fun ([c, vals], e) {
case eval (c, e) of
[c, v] -> [c, v : vals]
esac
},
[c, {}],
exprs) of
[c, vals] -> [c, reverse (vals)]
esac
case foldl(fun ([c, vals], e) {
case eval(c, e) of
[c, v] -> [c, v : vals]
esac
}, [c, {}], exprs) of
[c, vals] -> [c, reverse(vals)]
esac
}

(* Assignment *)
fun eval (c@[s, w], expr) {
failure ("evalExpr not implemented\n")
case expr of
Var(v) -> [c, s.lookup(v)]
| Ref(r) -> [c, r]
| Const(i) -> [c, i]
| Skip -> [c, None]
| Binop(op, expr1, expr2) -> let [c, {l, r}] = evalList(c, {expr1, expr2}) in [c, evalOp(op, l, r)]
| Assn(expr1, expr2) -> let [c@[s, w], {l, r}] = evalList(c, {expr1, expr2}) in [[s <- [l, r], w], r]
| Seq(expr1, expr2) -> let [c, v] = eval(c, expr1) in eval(c, expr2)
| Read(varname) -> let [r, w] = readWorld(w) in [[s <- [varname, r], w], None]
| Write(expr1) -> let [c@[s, w], ref] = eval(c, expr1) in [[s, writeWorld(ref, w)], None]
| If(cond, expr1, expr2) -> let [c, v] = eval(c, cond) in if v then eval(c, expr1) else eval(c, expr2) fi
| While(cond, expr) -> case eval(c, cond) of
[c, 0] -> [c, None]
| [c, _] -> let [c, _] = eval(c, expr) in eval(c, While(cond, expr))
esac
| DoWhile(cond, expr) -> eval(c, Seq(expr, While(cond, expr)))
| Ignore(expr) -> [eval(c, expr)[0], None]
| Scope(d, e) -> let [[s, w], v] = eval([s.enterScope.addDecs(d), w], e) in [[s.leaveScope, w], v]
| Call(f, expr) -> let [[s, w], vals] = evalList(c, expr) in
let Fun(args, body) = s.lookup(f) in
let [[ss, w], v] = eval([s.enterFunction.addArgs(args, vals), w], body) in
[[s.leaveFunction(ss.getGlobal), w], v]
| _ -> [c, None]
esac
}
(* End *)

-- Evaluates a program with a given input and returns an output
public fun evalExpr (input, expr) {
case eval ([emptyState (), createWorld (input)], expr) of
[c, _] -> c.snd.getOutput
esac
case eval([emptyState(), createWorld(input)], expr) of
[c, _] -> c.snd.getOutput
esac
}
Loading