diff --git a/src/Expr.lama b/src/Expr.lama index aac9294883..6e8f0c6c22 100644 --- a/src/Expr.lama +++ b/src/Expr.lama @@ -94,11 +94,36 @@ fun evalList (c, exprs) { esac } -(* Assignment *) fun eval (c@[s, w], expr) { - failure ("evalExpr not implemented\n") + case expr of + Var (varStr) -> [c, lookup(s, varStr)] + | Assn (x, a) -> case evalList (c, {x, a}) of [[s, w], {Ref (x), a}] -> [[s <- [x, a], w], a] esac + | Seq (q, t) -> case evalList (c, {q, t}) of [c, {q, t}] -> [c, t] esac + | Ref (e) -> [c, Ref(e)] + | Skip -> [c, None] + | Read (varStr) -> case readWorld (w) of [v, w] -> [[s <- [varStr, v], w], None] esac + | Write (expr) -> case eval (c, expr) of [[s, w], v] -> [[s, writeWorld (v, w)], None] esac + | If (iff, a, b) -> case eval(c, iff) of [c, out] -> if out then eval(c, a) else eval(c, b) fi esac + | While (iff, b) -> case eval(c, iff) of [c, out] -> if out then eval(c, Seq(b, While(iff, b))) else [c, {}] fi esac + | DoWhile (stmt, expr) -> eval (c, Seq (stmt, While (expr, stmt))) + | Const (n) -> [c, n] + | Binop (op, l, r) -> case evalList (c, {l, r}) of [c, {l, r}] -> [c, evalOp (op, l, r)] esac + | Scope (d, e) -> + case foldl (fun (s, t) { + case t of + Var (strs) -> addNames (s, strs) + | Fun (varStr, pars, body) -> addFunction (s, varStr, pars, body) + esac + }, + s.enterScope, d) of s -> case eval ([s, w], e) of [[s, w], v] -> [[s.leaveScope, w], v] esac + esac + | Call (f, pars) -> case evalList(c, pars) of [[st, w], vals] -> case lookup(st, f) of Fun(ns, body) -> + case foldl(fun(s, [n, v]){addName(s, n, v)}, enterFunction(st), zip(ns, vals)) of scp -> + case eval([scp, w], body) of [[scp, w], res] -> [[leaveFunction(st, getGlobal(scp)), w], res] + esac esac esac esac + | Ignore (e) -> case eval (c, e) of [c, em] -> [c, None] esac + esac } -(* End *) -- Evaluates a program with a given input and returns an output public fun evalExpr (input, expr) { diff --git a/src/Parser.lama b/src/Parser.lama index f90e423a7f..afd5cb5edd 100644 --- a/src/Parser.lama +++ b/src/Parser.lama @@ -105,24 +105,47 @@ fun distributeScope (expr, exprConstructor) { esac } -var primary = memo $ eta syntax ( - -- decimal constant - loc=pos x=decimal {fun (a) {assertValue (a, Const (stringInt (x)), loc)}} | - - -- identifier - x=lident args=inbr[s("("), list0(syntax(e=exp {e(Val)})), s(")")]? {fun (a) { - case args of - None -> case a of - Ref -> Ref (x) - | Void -> Ignore (Var (x)) - | _ -> Var (x) - esac - | Some (args) -> assertValue (a, Call (x, args)) - esac - }} | -(* Assignment *) - $(failure ("the rest of primary parsing in not implemented\n"))), -(* End *) +var primary = memo $ eta syntax ( + loc=pos x=decimal { fun (b) { + assertValue (b, Const (stringInt (x)), loc) + } + } + | loc=pos x=lident args=inbr[s("("), list0(syntax(e=exp {e(Val)})), s(")")]? { fun (b) { + case args of + None -> case b of + Ref -> Ref (x) + | Void -> Ignore (Var (x)) + | l -> Var (x) + esac + | Some (args) -> assertValue (b, Call (x, args), loc) + esac + } } + | inbr[s("("), scopeExpr, s(")")] + | loc=pos kRead x=inbr[s("("), lident, s(")")] { + fun (b) { + assertVoid (b, Read (x), loc) + } + } + | loc=pos kWrite e=inbr[s("("), exp, s(")")] { + fun (b) { + assertVoid (b, Write (e (Val)), loc) + } + } + | loc=pos kSkip { fun (b) { + assertVoid (b, Skip, loc)} + } + | loc=pos kIf c=exp kThen t=scopeExpr e=anSt { fun (b) { + If (c(Val), t (b), e (b)) } } + | loc=pos kWhile c=exp kDo b=scopeExpr kOd { fun (b) { + assertVoid (b, While (c (Val), b (Void)), loc)} } + | loc=pos kDo b=scopeExpr kWhile c=exp kOd { fun (b) { + assertVoid (b, distributeScope (b (Void), fun (b) { + DoWhile (b, c (Val)) }), loc) + } + } + | loc=pos kFor i=scopeExpr s[","] c=exp s[","] s=exp kDo b=scopeExpr kOd { fun (b) { + assertVoid (b, distributeScope(i (Void), fun (i) { + Seq (i, While (c (Val), Seq (b (Void), s (Void)))) }), loc) } }), basic = memo $ eta (expr ({[Right, {[s (":="), fun (l, loc, r) { fun (a) {assertValue (a, Assn (l (Ref), r (Val)), loc)} @@ -152,6 +175,17 @@ var primary = memo $ eta syntax ( } ), exp = memo $ eta syntax (basic | s1=basic s[";"] s2=exp {fun (a) {Seq (s1 (Void), s2 (a))}}); - +var anSt = memo $ eta syntax ( + kFi { fun (b) { + assertVoid (b, Skip, loc) + } + } + | kElse t=scopeExpr kFi { t } + | kElif c=exp kThen t=scopeExpr e=anSt { + fun (b) { + If (c (Val), t(b), e(b)) + } + } +); -- Public top-level parser public parse = syntax (s=scopeExpr {s (Void)});