Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HSE] A06 Maxim Ivanov #1599

Open
wants to merge 1 commit into
base: A06-scopes-functions
Choose a base branch
from
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
83 changes: 78 additions & 5 deletions src/Expr.lama
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,20 @@ fun addNames (state, names) {
fun addFunction (state, name, args, body) {
state.addName (name, Fun (args, body))
}


fun addNamesAndFunctions(state, defs) {
foldl(fun (state, def) {
case def of
Var(names) -> state.addNames(names)
| Fun(name, args, body) -> state.addFunction(name, args, body)
esac
}, state, defs)
}

fun addArgs(state, names, values) {
foldl (fun (s, [name, value]) { s.addName (name, value)}, state, zip (names, values))
}

-- Evaluates a list of expressions, properly threading a configurations.
-- Returns the final configuration and the list of values
fun evalList (c, exprs) {
Expand All @@ -101,15 +114,75 @@ fun evalList (c, exprs) {
esac
}

(* Assignment *)
fun eval (c@[s, w], expr) {
failure ("evalExpr not implemented\n")
case expr of
Assn(lhs, rhs) ->
case evalList(c, {lhs, rhs}) of
[[s, w], {Ref(x), Val(e)}] -> [[s <- [x, Val(e)], w], Val(e)]
esac
| Seq(e1, e2) ->
case eval(c, e1) of
[c, _] -> eval(c, e2)
esac
| Skip -> [c, Void]
| Read(x) ->
case readWorld(w) of
[z, w] -> [[s <- [x, Val(z)], w], Void]
esac
| Write(e) ->
case eval(c, e) of
[[s, w], Val(value)] -> [[s, writeWorld(value, w)], Void]
esac
| If(e, st1, st2) ->
case eval(c, e) of
[c, Val(0)] -> eval(c, st2)
| [c, Val(_)] -> eval(c, st1)
esac
| While(e, st) ->
case eval(c, e) of
[c, Val(0)] -> [c, Void]
| [c, Val(_)] -> case eval(c, st) of
[c, Void] -> eval(c, expr)
esac
esac
| DoWhile(st, e) ->
case eval(c, st) of
[c, Void] -> case eval(c, e) of
[c, Val(0)] -> [c, Void]
| [c, Val(_)] -> eval(c, expr)
esac
esac
| Var(x) -> [c, s.lookup(x)]
| Ref(x) -> [c, Ref(x)]
| Const(n) -> [c, Val(n)]
| Binop(op, e1, e2) ->
case evalList(c, {e1, e2}) of
[c, {Val(lhs), Val(rhs)}] -> [c, Val(evalOp(op, lhs, rhs))]
esac
| Ignore(e) ->
case eval(c, e) of
[c, _] -> [c, Void]
esac
| Scope(defs, e) ->
case eval([s.enterScope.addNamesAndFunctions(defs), w], e) of
[[s, w], v] -> [[s.leaveScope, w], v]
esac
| Call(x, args) ->
case evalList(c, args) of
[[s1, w], values] ->
case s1.lookup(x) of
Fun(args, body) ->
case eval([s1.enterFunction.addArgs(args, values), w], body) of
[[s2, w], v] -> [[s1.leaveFunction(s2.getGlobal), w], v]
esac
esac
esac
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
}
}
125 changes: 78 additions & 47 deletions src/Parser.lama
Original file line number Diff line number Diff line change
Expand Up @@ -105,53 +105,84 @@ 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 *)
basic = memo $ eta (expr ({[Right, {[s (":="),
fun (l, loc, r) {
fun (a) {assertValue (a, Assn (l (Ref), r (Val)), loc)}
}]}],
[Left , map (binop, {"!!"})],
[Left , map (binop, {"&&"})],
[Nona , map (binop, {"==", "!=", "<", ">", "<=", ">="})],
[Left , map (binop, {"+", "-"})],
[Left , map (binop, {"*", "/", "%"})]
},
primary)),
scopeExpr = memo $ eta syntax (ds=definition* e=exp? {fun (a) {fun (e) {
case ds of
{} -> e
| _ -> expandScope (ds, e)
esac
} (case e of
Some (e) -> e (a)
| _ -> Skip
esac)
}}),
definition = memo $ eta syntax (kVar ds=list[syntax (lident (s["="] e=basic {e (Val)})?)] s[";"] {Var (ds)} |
kFun name=lident
args=inbr[s("("), list0 (lident), s(")")]
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))}});
var primary = memo $ eta syntax (
-- decimal constant
loc=pos x=decimal {fun (a) {assertValue (a, Const (stringInt (x)), loc)}} |
-- identifier
loc=pos 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), loc)
esac
}
} |
e=inbr[s("("), scopeExpr, s(")")] { e } |
loc=pos kSkip { fun (a) { assertVoid(a, Skip, loc) } } |
loc=pos kRead x=inbr[s("("), lident, s(")")] { fun (a) { assertVoid(a, Read(x), loc) } } |
loc=pos kWrite e=inbr[s("("), exp, s(")")] { fun (a) { assertVoid(a, Write(e(Val)), loc) } } |
loc=pos kWhile e=exp kDo st=scopeExpr kOd { fun (a) { assertVoid(a, While(e(Val), st(Void)), loc) } } |
loc=pos kDo st=scopeExpr kWhile e=exp kOd {
fun (a) { assertVoid(a, distributeScope(st(Void), fun (ec) { DoWhile(ec, e(Val)) }), loc) }
} |
loc=pos kFor s1=scopeExpr s[","] e=exp s[","] s2=exp kDo body=exp kOd {
fun (a) {
assertVoid(a, distributeScope(
s1(Void), fun (ce) { Seq(ce, While(e(Val), Seq(body(Void), s2(Void)))) }
), loc)
}
} |
loc=pos kIf e=exp kThen st=scopeExpr els=elseSyntax { fun (a) { If(e(Val), st(a), els(a)) } }),

elseSyntax = memo $ eta syntax(
loc=pos kFi { fun (a) { assertVoid(a, Skip, loc) } } |
kElse st=scopeExpr kFi { st } |
kElif e=exp kThen st=scopeExpr els=elseSyntax { fun(a) { If(e(Val), st(a), els(a)) } }
),

basic = memo $ eta (expr ({
[Right, {
[s (":="),
fun (l, loc, r) {
fun (a) {assertValue (a, Assn (l (Ref), r (Val)), loc)}
}]
}],
[Left , map (binop, {"!!"})],
[Left , map (binop, {"&&"})],
[Nona , map (binop, {"==", "!=", "<", ">", "<=", ">="})],
[Left , map (binop, {"+", "-"})],
[Left , map (binop, {"*", "/", "%"})]
}, primary)),

scopeExpr = memo $ eta syntax (
ds=definition* e=exp? {
fun (a) {
fun (e) {
case ds of
{} -> e
| _ -> expandScope (ds, e)
esac
} (case e of
Some (e) -> e (a)
| _ -> Skip
esac)
}
}
),

definition = memo $ eta syntax (
kVar ds=list[syntax (lident (s["="] e=basic {e (Val)})?)] s[";"] {Var (ds)} |
kFun name=lident
args=inbr[s("("), list0 (lident), s(")")]
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
public parse = syntax (s=scopeExpr {s (Void)});
Loading
Loading