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
42 changes: 40 additions & 2 deletions src/Expr.lama
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fun addNames (state, names) {
fun addFunction (state, name, args, body) {
state.addName (name, Fun (args, body))
}

-- Evaluates a list of expressions, properly threading a configurations.
-- Returns the final configuration and the list of values
fun evalList (c, exprs) {
Expand All @@ -102,8 +102,46 @@ fun evalList (c, exprs) {
}

(* Assignment *)
fun scopeHelper(s, expr) {
case expr of
Var (x) -> s.addNames(x)
| Fun (name, args, body) -> s.addFunction(name, args, body)
esac
}

fun callHelper(s, [name, Val (value)]) { s.addName(name, value) }

-- Invariant: ALWAYS REAL VALUE IN STATE, YOU STUPID BASTARD
fun eval (c@[s, w], expr) {
failure ("evalExpr not implemented\n")
case expr of
Const (n) -> [c, Val (n)]
| Var (x) -> [c, Val (s.lookup(x))]
| Ref (x) -> [c, Ref (x)]
| Binop (op, e1, e2) -> let [c, {Val (l), Val (r)}] = evalList(c, {e1, e2}) in [c, Val (evalOp(op, l, r))]
| Skip -> [c, Void]
| Assn (e1, e2) -> let [[s, w], Ref (x)] = eval ([s, w], e1) in
let [[s, w], Val (v)] = eval ([s, w], e2) in
[[s <- [x, v], w], Val (v)]
| Read (x) -> let [z, w1] = readWorld(w) in [[s <- [x, z], w1], Void]
| Write (e) -> let [c@[s1, w1], Val (v)] = eval(c, e) in [[s1, writeWorld(v, w1)], Void]
| Seq (e1, e2) -> let [c1, _] = eval(c, e1) in eval(c1, e2)
| If (e, s1, s2) -> let [c1, Val (n)] = eval(c, e) in if (n != 0) then eval(c1, s1) else eval(c1, s2) fi
| While (e, s) -> let [c1, Val (n)] = eval(c, e) in if (n == 0) then [c1, Void] else
let [c2, _] = eval(c1, s) in eval(c2, While (e, s))
fi
| DoWhile (s, e) -> evalList(c, {s, While (e, s)})
| Ignore (e) -> let [c, _] = eval(c, e) in [c, Void]
| Scope (ds, ss) -> let s = s.enterScope in
let s = (foldl(scopeHelper, s, ds)) in
let [[s, w], v] = eval ([s, w], ss) in
[[s.leaveScope, w], v]
| Call (name, args) -> let Fun (argsNames, body) = s.lookup(name) in
let [c@[s, w], vs] = c.evalList(args) in
let s_inner = s.enterFunction in
let s_inner = foldl(callHelper, s_inner, zip(argsNames, vs)) in
let [[s_inner, w], v] = eval([s_inner, w], body) in
[[s.leaveFunction(s_inner.getGlobal), w], v]
esac
}
(* End *)

Expand Down
50 changes: 42 additions & 8 deletions src/Parser.lama
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ fun list (item) {
-- initializers into assignments
fun expandScope (defs, expr) {
fun expandDefs (defs, expr) {
foldr (fun ([defs, expr], def) {
foldr (fun ([defs, expr], def) {
case def of
[ident, None] -> [ident : defs, expr]
| [ident, Some (value)] -> [ident : defs, Seq (Ignore (Assn (Ref (ident), value)), expr)]
Expand All @@ -81,7 +81,7 @@ fun expandScope (defs, expr) {
defs)
}

case
case
foldr (fun ([defs, expr], def) {
case def of
f@Fun (_, _, _) -> [f : defs, expr]
Expand All @@ -94,7 +94,7 @@ fun expandScope (defs, expr) {
[{}, expr],
defs) of
[defs, expr] -> Scope (defs, expr)
esac
esac
}

-- Helper AST function: distributes a scope through an expression
Expand All @@ -117,11 +117,45 @@ var primary = memo $ eta syntax (
| Void -> Ignore (Var (x))
| _ -> Var (x)
esac
| Some (args) -> assertValue (a, Call (x, args))
| Some (args) -> assertValue (a, Call (x, args), loc)
esac
}} |
(* Assignment *)
$(failure ("the rest of primary parsing in not implemented\n"))),
-- brackets
inbr[s("("), scopeExpr, s(")")] |
-- read
loc=pos kRead x=inbr[s("("), lident, s(")")] {fun(a) { assertVoid(a, Read(x), loc) }} |
-- write
loc=pos kWrite e=inbr[s("("), scopeExpr, s(")")] {fun(a) { assertVoid(a, Write(e(Val)), loc)}} |
-- skip
loc=pos kSkip {fun(a) { assertVoid(a, Skip, loc) }} |
-- if elif else fi
loc=pos kIf e=scopeExpr kThen s1=scopeExpr elf=(-kElif scopeExpr -kThen scopeExpr)* s2=(-kElse scopeExpr)? kFi {
fun helper (final, elf, type) {
case elf of
{} -> final
| [e, s]:elf -> If (e(Val), s(type), helper(final, elf, type))
esac
}
fun (a) {
distributeScope(e(Val), fun (expr) { If(expr, s1(a), helper (
case s2 of
None -> assertVoid(a, Skip, loc)
| Some (s) -> s(a)
esac,
elf, a)) })
}
} |
-- while do od
loc=pos kWhile e=scopeExpr kDo s=scopeExpr kOd {fun(a) { assertVoid(a, While(e(Val), s(Void)), loc) }} |
-- do while od
loc=pos kDo s=scopeExpr kWhile e=scopeExpr kOd {fun(a) {
distributeScope(s(Void), fun (expr) { assertVoid(a, DoWhile(expr, e(Val)), loc) })
}} |
-- for do od
kFor s1=scopeExpr s[","] cond=scopeExpr s[","] s2=scopeExpr kDo s=scopeExpr kOd {
fun(a) { distributeScope(s1(Void), fun (expr) { Seq(expr, While (cond(Val), Seq(s(Void), s2(Void)))) })}
}),
(* End *)
basic = memo $ eta (expr ({[Right, {[s (":="),
fun (l, loc, r) {
Expand All @@ -137,9 +171,9 @@ var primary = memo $ eta syntax (
scopeExpr = memo $ eta syntax (ds=definition* e=exp? {fun (a) {fun (e) {
case ds of
{} -> e
| _ -> expandScope (ds, e)
| _ -> expandScope (ds, e)
esac
} (case e of
} (case e of
Some (e) -> e (a)
| _ -> Skip
esac)
Expand All @@ -150,7 +184,7 @@ var primary = memo $ eta syntax (
body=inbr[s("{"), scopeExpr, s("}")] {
Fun (name, args, body (Weak))
}
),
),
exp = memo $ eta syntax (basic | s1=basic s[";"] s2=exp {fun (a) {Seq (s1 (Void), s2 (a))}});

-- Public top-level parser
Expand Down
Loading