diff --git a/src/Expr.lama b/src/Expr.lama index aac9294883..b03a65fd1f 100644 --- a/src/Expr.lama +++ b/src/Expr.lama @@ -95,8 +95,70 @@ fun evalList (c, exprs) { } (* Assignment *) + +fun addNamesToState (st, names, vals) { + foldl(fun(s, [name, v]) {addName(s, name, v)}, st, zip(names, vals)) +} + + +fun addDefs (st, defs) { + foldl(fun(s, def) { + case def of + Fun(name, arg, body) -> addFunction(s, name, arg, body) + | Var(names) -> addNames(s, names) + esac + }, + st, defs) +} + fun eval (c@[s, w], expr) { - failure ("evalExpr not implemented\n") + case expr of + Assn(e1, e2) -> case evalList(c, {e1, e2}) of + [c@[s, w], {l, r}] -> [[s <- [l, r], w], r] + esac + | Seq(e1, e2) -> case evalList(c, {e1, e2}) of + [c, {_, r}] -> [c, r] + esac + | Skip -> [c, None] + | Read(x) -> case w.readWorld of + [rd, w] -> [[s <- [x, rd], w], None] + esac + | Write(e) -> case eval(c, e) of + [c@[s, w], x] -> [[s, writeWorld(x, w)], None] + esac + | If (cond, e1, e2) -> case eval(c, cond) of + [c, cond] -> eval(c, if cond then e1 else e2 fi) + esac + | wExpr@While(cond, e) -> case eval(c, cond) of + [c, 0] -> [c, None] + | _ -> eval(c, Seq(e, wExpr)) + esac + | DoWhile(e, cond) -> case eval(c, e) of + [c, _] -> eval(c, While(cond, e)) + esac + | Var(x) -> [c, lookup(s, x)] + | Ref(x) -> [c, x] + | Const(x) -> [c, x] + | Binop(x, e1, e2) -> case evalList(c, {e1, e2}) of + [c, {l, r}] -> [c, evalOp(x, l, r)] + esac + | Ignore(e) -> case eval(c, e) of + [c, _] -> [c, None] + esac + | Call(f, arg) -> case evalList(c, arg) of + [c@[arg_s, w], x] -> case lookup(arg_s, f) of + Fun(arg, body) -> case addNamesToState(enterFunction(arg_s), arg, x) of + cur_s -> case eval([cur_s, w], body) of + [c2@[s2, w2], res] -> [[leaveFunction(arg_s, getGlobal(s2)), w2], res] + esac + esac + esac + esac + | Scope(defs, body) -> case eval([addDefs(enterScope(s), defs), w], body) of + [c@[s, w], x] -> [[leaveScope(s), w], x] + esac + + esac } (* End *) @@ -105,4 +167,4 @@ public fun evalExpr (input, expr) { case eval ([emptyState (), createWorld (input)], expr) of [c, _] -> c.snd.getOutput esac -} \ No newline at end of file +} diff --git a/src/Parser.lama b/src/Parser.lama index f90e423a7f..bbbe7fdfeb 100644 --- a/src/Parser.lama +++ b/src/Parser.lama @@ -105,6 +105,12 @@ fun distributeScope (expr, exprConstructor) { esac } +var ifExp = memo $ eta syntax ( + e=scopeExpr kThen stmt1=scopeExpr kElse stmt2=scopeExpr kFi { fun(a) { If (e (Val), stmt1(a), stmt2(a)) }} | + e=scopeExpr kThen stmt1=scopeExpr kElif stmt2=ifExp { fun(a) { If (e (Val), stmt1(a), stmt2(a)) }} | + e=scopeExpr kThen stmt1=scopeExpr kFi loc=pos { fun(a) { If (e (Val), stmt1(a), assertVoid(a, Skip, loc)) }} +); + var primary = memo $ eta syntax ( -- decimal constant loc=pos x=decimal {fun (a) {assertValue (a, Const (stringInt (x)), loc)}} | @@ -120,8 +126,24 @@ var primary = memo $ eta syntax ( | Some (args) -> assertValue (a, Call (x, args)) esac }} | +loc=pos kRead x=inbr[s("("), lident, s(")")] { fun(a) { assertVoid(a, Read (x), loc) }} | + +loc=pos kSkip{ fun(a) { assertVoid(a, Skip, loc) } } | + +loc=pos kWrite x=inbr[s("("), exp, s(")")] { fun(a) { assertVoid(a, Write (x (Val)), loc) }} | + +inbr [s ("("), scopeExpr, s (")")] | + +loc=pos kIf e=ifExp { fun(a) { e(a) } } | + +loc=pos kWhile e=scopeExpr kDo body=scopeExpr kOd { fun(a) { assertVoid(a, While(e(Val), body(Void)), loc)} } | + +loc=pos kDo body=scopeExpr kWhile e=scopeExpr kOd { fun(a) { assertVoid(a, distributeScope(body(Void), fun(a2) {DoWhile(a2, e(Val))}), loc)}} | + +loc=pos kFor e=scopeExpr s[","] cond=scopeExpr s[","] e2=scopeExpr kDo body=scopeExpr kOd { fun(a) {assertVoid(a, distributeScope(e(Void), fun(a2) { Seq(a2, While (cond(Val), Seq(body(Void), e2(Void))))}), loc)}} +), (* Assignment *) - $(failure ("the rest of primary parsing in not implemented\n"))), + -- $(failure ("the rest of primary parsing in not implemented\n"))), (* End *) basic = memo $ eta (expr ({[Right, {[s (":="), fun (l, loc, r) {