Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
84b11fb
Assignment 3
danyaberezun Mar 7, 2025
ebcd603
Switched to portable regexps
dboulytchev Mar 9, 2025
95d67b3
Added missing origs
dboulytchev Mar 11, 2025
6c7c397
Assignment 4
danyaberezun Mar 15, 2025
4d19472
Merge branch 'T03' of github.com:danyaberezun/compilers-supplementary…
dboulytchev Mar 19, 2025
be32abc
Lexer switched to portable regexp
dboulytchev Mar 19, 2025
56fa4c6
Fixed stack in initEnv
dboulytchev Apr 10, 2025
ca9010c
Merge branch 'T04' of github.com:danyaberezun/compilers-supplementary…
dboulytchev Apr 10, 2025
44c5bdb
Fixed bug in initEnv
dboulytchev Apr 10, 2025
e18cd75
Fixed bug in initEnv
dboulytchev Apr 10, 2025
ecd6510
Fixed bug in initEnv
dboulytchev Apr 10, 2025
c431e23
T01 fin
SquareSweet Oct 26, 2025
c15357f
T02 fin
SquareSweet Nov 2, 2025
16b0a24
Merge branch 'T02' into T03
SquareSweet Nov 2, 2025
3e2e0bf
T03 fin
SquareSweet Nov 3, 2025
1b6cd41
Merge branch 'T03' into T04
SquareSweet Nov 16, 2025
0dc5722
reimplement eval
SquareSweet Nov 16, 2025
c08f919
T04 fin
SquareSweet Nov 16, 2025
1e15870
Merge branch 'T04' into T05
SquareSweet Nov 23, 2025
c16dc5a
T05 fin
SquareSweet Nov 24, 2025
b73196a
Delete debug print
SquareSweet Nov 24, 2025
3691427
Merge branch 'T05' into T06
SquareSweet Nov 24, 2025
575f31e
T06 fin
SquareSweet Nov 30, 2025
f72e20f
Merge branch 'T06' into T07
SquareSweet Nov 30, 2025
7a62ba8
T07 fin
SquareSweet Dec 14, 2025
64c3e56
Merge branch 'T07' into T08
SquareSweet Dec 14, 2025
46ce72e
T08 fin
SquareSweet Dec 14, 2025
a3c41be
Merge branch 'T08' into T09
SquareSweet Dec 21, 2025
e398562
T09 fin
SquareSweet Dec 21, 2025
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
94 changes: 91 additions & 3 deletions src/Expr.lama
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,104 @@ fun evalList (c, exprs) {
esac
}

fun eval (c@[s, w], expr) {
failure ("evalExpr not implemented\n")
fun evalDecls(c, exprs) {
fun evalDecl(c@[s, w], e) {
case e of
Var(x) -> let s = s.addNames(x) in [s, w]
| Fun(name, args, body) -> let s = s.addFunction(name, args, body) in [s, w]
esac
}

foldl(evalDecl, c, exprs)
}

fun evalArgs(s, args) {
fun evalArg(s, [name, value]) {
s.addName(name, value)
}

foldl(evalArg, s, args)
}

fun eval (c@[st, w], expr) {
case expr of
Assn (expr1, expr2) ->
let [c@[st, w], {ref, v}] = evalList(c, {expr1, expr2}) in
case ref of
Ref (x) -> [[st <- [x, v], w], v]
| ElemRef (arr, idx) -> arr[idx] := v; [c, v]
esac
| Seq (expr1, expr2) -> let [c1, v] = eval(c, expr1) in eval(c1, expr2)
| Skip -> [c, Void]
| If (cond, expr1, expr2) -> let [c, v] = eval(c, cond) in if v then eval(c, expr1) else eval(c, expr2) fi
| While (cond, body) ->
let [c1, n] = eval(c, cond) in
if n != 0
then
let [c2, _] = eval(c1, body) in
eval(c2, While(cond, body))
else
[c1, 0]
fi
| DoWhile (cond, body) -> evalList(c, {body, While (cond, body)})
| Var (x) -> [c, lookup(st, x)]
| Ref (x) -> [c, Ref (x)]
| Const (n) -> [c, n]
| Binop (op, expr1, expr2) ->
let [c, {l, r}] = evalList(c, {expr1, expr2}) in
[c, evalOp(op, l, r)]
| Ignore (expr1) -> let [c, v] = eval(c, expr1) in [c, Void]
| Scope (decl, stmt) ->
let st = st.enterScope in
let c@[st, w] = evalDecls([st, w], decl) in
let [[st, w], x] = eval(c, stmt) in
[[st.leaveScope, w], x]
| Call (name, args) ->
let Fun (argNames, body) = lookup(st, name) in
let [c@[st, w], vs] = c.evalList(args) in
let stIn = st.enterFunction in
let stIn = evalArgs(stIn, zip(argNames, vs)) in
let [[stIn, w], v] = eval([stIn, w], body) in
[[st.leaveFunction(stIn.getGlobal), w], v]
| Builtin (x, exprs) ->
let [c@[st, w], vals] = evalList (c, exprs) in
let [v, w] = evalBuiltin (x, vals, w) in
[[st, w], v]
| String (v) -> [c, v]
| Array (exprs) -> let [c, vals] = evalList (c, exprs) in [c, listArray (vals)]
| Elem (ea, ei) ->
let [c, arr] = eval (c, ea) in
let [c, idx] = eval (c, ei) in
let arr =
case arr of
Sexp (_, arr) -> arr
| arr -> arr
esac
in
[c, arr[idx]]
| ElemRef (ea, ei) ->
let [c, arr] = eval (c, ea) in
let [c, idx] = eval (c, ei) in
let arr =
case arr of
Sexp (_, arr) -> arr
| arr -> arr
esac
in
[c, ElemRef (arr, idx)]
| Sexp (tag, exprs) ->
let [c, args] = evalList (c, exprs) in
[c, Sexp (tag, listArray (args))]
esac
}


-- Evaluates a program with a given input and returns an output
public fun evalExpr (input, expr) {
case eval ([emptyState ().enterScope.addName ("read", Fun ({}, External))
.addName ("write", Fun ({"a"}, External))
.addName ("length", Fun ({"a"}, External)), createWorld (input)], expr) of
.addName ("length", Fun ({"a"}, External))
, createWorld (input)], expr) of
[c, _] -> c.snd.getOutput
esac
}
125 changes: 84 additions & 41 deletions src/Parser.lama
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ fun binop (op) {
]
}

--var elseStmt = memo $ eta syntax (
-- kElif e=exp kThen s1=exp s2=elseStmt {fun (a) {If(e(Val), s1(a), s2(a))}} |
-- kElse s2=exp kFi {fun (a) {s2(a)}} |
-- kFi {fun (a) {assertVoid(a, Skip, loc)}}
--);

-- Helper parser: parses a (possible empty) list of items separated by ","
fun list0 (item) {
list0By (item, s(","))
Expand All @@ -74,7 +80,7 @@ fun expandScope (defs, expr) {
foldr (fun ([defs, expr], def) {
case def of
[ident, None] -> [ident : defs, expr]
| [ident, Some (value)] -> [ident : defs, Seq (Ignore (Set (ident, value)), expr)]
| [ident, Some (value)] -> [ident : defs, Seq (Ignore (Assn (Ref(ident), value)), expr)]
esac
},
[{}, expr],
Expand All @@ -83,7 +89,7 @@ fun expandScope (defs, expr) {

fun expandValDefs (defs, expr) {
foldr (fun ([defs, expr], [ident, value]) {
[ident : defs, Seq (Ignore (Set (ident, value)), expr)]
[ident : defs, Seq (Ignore (Assn (Ref(ident), value)), expr)]
},
[{}, expr],
defs)
Expand Down Expand Up @@ -116,38 +122,76 @@ fun distributeScope (expr, exprConstructor) {
| _ -> exprConstructor (expr)
esac
}

fun isBuiltin(name) {
case name of
"write" -> true
| "read" -> true
| "length" -> true
| "stringval" -> true
| _ -> false
esac
}

var primary = memo $ eta syntax (
-- array constant
loc=pos x=inbr[s("["), list0(syntax (e=exp {e(Val)})), s("]")] {fun (a) {assertValue (a, Array (x), loc)}} |

-- string constant
loc=pos x=strlit {fun (a) {assertValue (a, String (x), loc)}} |

-- character literal
loc=pos x=chrlit {fun (a) {assertValue (a, Const (x), loc)}} |

-- 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
}} |

-- S-expression
loc=pos x=uident args=inbr[s("("), list0(syntax(e=exp {e(Val)})), s(")")]? {fun (a) {assertValue (a, Sexp (x, case args of
None -> {}
| Some (args) -> args
esac), loc)}} |
$(failure ("the rest of primary parsing in not implemented\n"))),
-- S-expression
loc=pos tag=uident args=(args=inbr[s("("), list(syntax (e=exp {e(Val)})), s(")")]? {
case args of
Some(args) -> args
| None -> {}
esac
}) {
fun (a) {assertValue(a, Sexp(tag, args), loc)}
} |

-- array constant
loc=pos x=inbr[s("["), list0(syntax (e=exp {e(Val)})), s("]")] {
fun (a) {assertValue(a, Array(x), loc)}
} |

-- string constant
loc=pos x=strlit {fun (a) {assertValue(a, String(x), loc)}} |

-- character literal
loc=pos x=chrlit {fun (a) {assertValue(a, Const(x), loc)}} |

-- 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,
if isBuiltin(x)
then Builtin (x, args)
else Call (x, args)
fi,
loc)
esac
}
} |
inbr[s("("), scopeExpr, s(")")] |
kSkip {fun (a) {assertVoid(a, Skip, loc)}} |
loc=pos kIf e=scopeExpr kThen s1=scopeExpr s2=elseStmt {fun (a) {If(e(Val), s1(a), s2(a))}} |
loc=pos kThen {fun (a) {assertVoid(a, Skip, loc)}} |
loc=pos kWhile e=scopeExpr kDo s=scopeExpr kOd {fun (a) {assertVoid(a, While (e(Val), s(Void)), loc)}} |
loc=pos kDo s=scopeExpr kWhile e=scopeExpr kOd {fun (a) {
distributeScope(s(Void), fun(s) {assertVoid(a, DoWhile(e(Val), s), loc)})
}} |
loc=pos kFor s1=scopeExpr s[","] e=scopeExpr s[","] s2=scopeExpr kDo s=scopeExpr kOd {fun (a) {
distributeScope(s1(Void), fun (s1) {assertVoid(a, Seq(s1, While (e(Val), Seq(s(Void), s2(Void)))), loc)})
}}
),
elseStmt = memo $ eta syntax (
kElif e=scopeExpr kThen s1=scopeExpr s2=elseStmt {fun (a) {If(e(Val), s1(a), s2(a))}} |
kElse s2=scopeExpr kFi {fun (a) {s2(a)}} |
kFi {fun (a) {assertVoid(a, Skip, loc)}}
),
basic = memo $ eta (expr ({[Right, {[s (":="),
fun (l, loc, r) {
fun (a) {assertValue (a, Assn (l (Ref), r (Val)), loc)}
Expand Down Expand Up @@ -181,15 +225,14 @@ var primary = memo $ eta syntax (
| _ -> Skip
esac)
}}),
definition = memo $ eta syntax (kVar ds=list[syntax (lident (s["="] e=basic {e (Val)})?)] s[";"] {Var (ds)} |
kVal ds=list[syntax (lident (s["="] e=basic {e (Val)}))] s[";"] {Val (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))}});
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