Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
c54b3db
????
ilyavoronin Sep 20, 2020
c689d08
done
ilyavoronin Sep 20, 2020
77e6725
extra file
Sep 21, 2020
b330af8
Add HW 2
Sep 21, 2020
1a45a02
extra file
Sep 21, 2020
3ce7f02
Add HW 2
Sep 21, 2020
96d29b2
rm extra
Sep 28, 2020
1f84c5d
hw3
Sep 28, 2020
4afa526
rm extra
Sep 28, 2020
6baedb2
rm extra
Sep 28, 2020
57d8d45
done2
ilyavoronin Sep 28, 2020
670756f
Merge branch 'A02-straight-line-x86' of https://github.com/danyaberez…
ilyavoronin Sep 28, 2020
babaf40
Fixed typo in X86 comment
dboulytchev Sep 29, 2020
8352586
hw4
Oct 1, 2020
e882db8
hw5
danyaberezun Oct 4, 2020
548dec5
add hw descr
Oct 5, 2020
bba45f2
add lecture notes pdf
Oct 5, 2020
ed83904
Merge branch 'A03-straight-line-parser' into A02-straight-line-x86
ilyavoronin Oct 6, 2020
82b93d8
done
ilyavoronin Oct 7, 2020
20d361a
HW6
Oct 12, 2020
49934f3
add lecture notes
Oct 12, 2020
acfc545
Compatibility with Ostap::expr
dboulytchev Oct 14, 2020
457df36
Fixed comment
dboulytchev Oct 14, 2020
0d4b304
Merge branch 'A02-straight-line-x86' into A04-control-flow-int
ilyavoronin Oct 14, 2020
e99ca50
done4
ilyavoronin Oct 15, 2020
136aae6
FIxed buffer initialization
dboulytchev Oct 24, 2020
d784de5
add hw7
Oct 26, 2020
779cd09
rm extra files
Oct 26, 2020
022dd8f
add lecture notes
Oct 26, 2020
849e91c
A08
danyaberezun Nov 9, 2020
bb82a7e
add travis.yml
danyaberezun Nov 9, 2020
ff6a36e
fix notes
danyaberezun Nov 9, 2020
412668f
Merge branch 'A04-control-flow-int' of https://github.com/danyaberezu…
ilyavoronin Nov 9, 2020
563bf78
Merge branch 'A04-control-flow-int' into A05-control-flow-sm-x86
ilyavoronin Nov 9, 2020
ba11f2b
Fixed locations
dboulytchev Nov 16, 2020
94b8c0d
Location table
dboulytchev Nov 16, 2020
f78efd2
hw9: arrays
danyaberezun Nov 17, 2020
9cb52b5
hw5 done
ilyavoronin Dec 17, 2020
9df35d6
Merge branch 'A05-control-flow-sm-x86' into A06-all-expressions
ilyavoronin Jan 13, 2021
4e9749c
fffff
ilyavoronin Jan 14, 2021
add93c2
hw6 done
ilyavoronin Jan 15, 2021
5e8523e
Merge branch 'A06-all-expressions' into A07-scopes-functions-int
ilyavoronin Jan 15, 2021
bf97c17
done7
ilyavoronin Jan 23, 2021
cea2c72
+merge
ilyavoronin Jan 23, 2021
25405f0
fix
ilyavoronin Jan 24, 2021
5ef2231
fix2
ilyavoronin Jan 24, 2021
96b8bff
Merge branch 'A07-scopes-functions-int' into A08-scopes-functions-sm-x86
ilyavoronin Jan 24, 2021
6636539
done8
ilyavoronin Jan 24, 2021
4b8359f
Merge branch 'A08-scopes-functions-sm-x86' into A09-arrays-builtins
ilyavoronin Jan 24, 2021
d7ac9db
done9
ilyavoronin Jan 25, 2021
5aecd31
Merge branch 'A09-arrays-builtins' into A10-fixed-num
ilyavoronin Jan 25, 2021
06896a4
done10
ilyavoronin Jan 25, 2021
b7fc507
disable compilation
ilyavoronin Jan 25, 2021
622f49d
fix x86
ilyavoronin Jan 25, 2021
1238fe5
Merge fix
ilyavoronin Jan 25, 2021
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.i
*.o
*.s
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
language: c
services:
- docker
before_install:
- docker pull berezun/cw-2020
- docker run -d -it --name cw-2020 -v $(pwd):/usr/share/compiler-2020 berezun/cw-2020
script:
docker exec -it cw-2020 sh test.sh
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
# compiler-2020
A supplementary repository for the course on compilers.
# HW 6
82 changes: 82 additions & 0 deletions regression/Embedding.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
-- A deep embedding of L0 into Lama
import List;
import Array;
import Fun;
import World;
import Stmt;
import State;
import SM;
import X86;

-- Embeds expression operands: strings are
-- embedded into identifiers, integer constants --- into
-- constants; non-operand expressions are left intact

# define HASH #

fun opnd (x) {
case x of
HASH string -> Var (x)
| HASH unboxed -> Const (x)
| _ -> x
esac
}

-- Redefinition of standard infix operators
infix + at + (l, r) {Binop ("+", opnd (l), opnd (r))}
infix - at - (l, r) {Binop ("-", opnd (l), opnd (r))}
infix * at * (l, r) {Binop ("*", opnd (l), opnd (r))}
infix / at / (l, r) {Binop ("/", opnd (l), opnd (r))}
infix % at % (l, r) {Binop ("%", opnd (l), opnd (r))}
infix == at == (l, r) {Binop ("==", opnd (l), opnd (r))}
infix != at != (l, r) {Binop ("!=", opnd (l), opnd (r))}
infix < at < (l, r) {Binop ("<", opnd (l), opnd (r))}
infix <= at <= (l, r) {Binop ("<=", opnd (l), opnd (r))}
infix > at > (l, r) {Binop (">", opnd (l), opnd (r))}
infix >= at >= (l, r) {Binop (">=", opnd (l), opnd (r))}
infix && at && (l, r) {Binop ("&&", opnd (l), opnd (r))}
infix !! at !! (l, r) {Binop ("!!", opnd (l), opnd (r))}

-- Embeds "read" construct; x is expected to be a string (not a "Var")
fun read (x) {
Read (x)
}

-- Embeds "write" construct; note, e is expression, thus it
-- is embedded using "opnd"
fun write (e) {
Write (opnd (e))
}

-- Embeds assignment operator; x is expected to be string, e is expression, this
-- it is embeeded using "opnd"
infix ::= before := (x, e) {
Assn (x, opnd (e))
}

-- Embeds sequential composition
infixr >> before ::= (s1, s2) {
Seq (s1, s2)
}

-- Returns embedded program (thus, the file has to be recompiled as the
-- program changes)
fun program () {
PROGRAM_BODY
}

fun state (x) {
Read (x)
}


local input = reverse (fix (fun (f) {fun (acc) {case readLine () of #unboxed -> acc | arg -> f (stringInt (arg) : acc) esac}}) ({}));

iter (fun (x) {printf ("%d\n", x)},
case sysargs[1] of
-- "-i" -> evalStmt (input, program ())
-- | "-s" -> evalSM (input, compileSM (program ()))
"-i" -> evalExpr (input, program ())
| _ -> failure ("Invalid compiler flag\n")
esac
)
6 changes: 3 additions & 3 deletions runtime/runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ void* Bsta (int i0, void *v, void *x) {
return v;
}

void Lwrite (int x) {
printf ("%d\n", UNBOX (x));
void Bwrite (int x) {
printf ("%d\n", UNBOX(x));
}

int Lread () {
int Bread () {
int result;

scanf ("%d", &result);
Expand Down
104 changes: 100 additions & 4 deletions src/Expr.lama
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,107 @@ fun evalList (c, exprs) {
esac
}

(* Assignment *)
fun eval (c@[s, w], expr) {
failure ("evalExpr not implemented\n")
fun dvar(v) {
case v of
Var(x) -> x
| _ -> failure("not a var")
esac
}

fun eval (c@[state, world], expr) {
case expr of
Read(x) -> case readWorld(world) of [val, nworld] ->
[[
state<-[x, Var(val)],
nworld
],
Void
]
esac
| Write(expr) ->
case eval(c, expr) of [[state, world], res] ->
[[
state,
writeWorld(res, world)
],
Void]
esac
| Assn(x, expr) -> case evalList(c, {x, expr}) of [[state, world], var:res:_] ->
[
[
case var of
Ref(x) -> state<-[x, Var(res)] |
ElemRef(arr, i) -> arr[i] := res; state
esac,
world
],
res
]
esac
| Seq(stmt1, stmt2) ->
eval(
eval(c, stmt1).fst,
stmt2
)
| If(cond, stmt, estmt) -> case eval(c, cond) of
[newConf, 0] -> case estmt of None -> [newConf, Void] | _ -> eval(newConf, estmt) esac |
[newConf, _] -> eval(newConf, stmt)
esac
| While(cond, stmt) -> case eval(c, cond) of
[newConf, 0] -> [newConf, Void] |
[newConf, _] -> eval(eval(newConf, stmt).fst, While(cond, stmt))
esac
| Rep(stmt, cond) ->
case eval(c, stmt).fst of newConf ->
case eval(newConf, cond) of
[newConf1, 0] -> eval(newConf1, Rep(stmt, cond)) |
[newConf1, _] -> [newConf1, Void]
esac
esac
| Skip -> [c, Void]
| Const(n) -> [c, n]
| Var(x) -> [c, state.lookup(x).dvar]
| Binop(op, lefto, righto) -> case evalList(c, {lefto, righto}) of [c, a:b:_] ->
[c, evalOp(op, a, b)]
esac
| Ref(x) -> [c, Ref(x)]
| Ignore(expr) -> [eval(c, expr).fst, Void]
| Scope(defs, expr) -> case evalList([state.enterScope, world], defs) of [c, _] ->
case eval(c, expr) of [[s, w], res] -> [[s.leaveScope, w], res] esac
esac
| Local(vars) -> [[state.addNames(vars), world], Void]
| Fun(name, args, body) -> [[state.addFunction(name, args, body), world], Void]
| Call(f, argExps) -> case c.evalList(argExps) of [[s, w], argVals] -> case state.lookup(f) of Fun(args, body) ->
case body of
External -> case evalBuiltin(f, argVals, w) of [res, w] -> [[s, w], res] esac|
_ -> local news = foldl(
fun (olds, [arg, val]) {olds.addName(arg, Var(val))},
s.enterFunction,
zip(args, argVals)
);
case eval([news, w],
body
) of [[sres, w], res] ->
[[s.leaveFunction(sres.getGlobal), w], res]
esac
esac
esac esac
| ElemRef(arr, i) -> case evalList(c, {arr, i}) of
[c, {arrRes, ires}] -> [c, ElemRef(arrRes, ires)]
esac
| Elem(arr, i) -> case evalList(c, {arr, i}) of
[c, {arrRes, ires}] -> [c, arrRes[ires]]
esac
| String(s) -> [c, s]
| Array(exps) -> case evalList(c, exps) of [c, ress] -> [c, listArray(ress)] esac
| Builtin(name, args) -> case evalList(c, args) of [[s, w], argRes] ->
case evalBuiltin(name, argRes, w) of [res, w] ->
[[s, w], res]
esac
esac
esac
}
(* End *)


-- Evaluates a program with a given input and returns an output
public fun evalExpr (input, expr) {
Expand Down
69 changes: 47 additions & 22 deletions src/Parser.lama
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,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 (Assn (Ref (ident), value)), expr)]
| [ident, Some (value)] -> [ident : defs, Seq (Ignore (Assn (Ref (ident), value(Val))), expr)]
esac
},
[{}, expr],
Expand Down Expand Up @@ -129,8 +129,44 @@ local primary = memo $ eta syntax (
| Some (args) -> assertValue (a, Call (x, args))
esac
}} |
(* Assignment *)
$(failure ("the rest of primary parsing in not implemented\n"))),
bexp=inbr[s("("), exp, s(")")] {fun(a) {bexp(a)} } |
loc=pos kSkip {fun(a) {assertVoid(a, Skip, loc)} } |

kIf c=exp kThen s=scopeExpr ot=elifStmt kFi {fun(a) {If(c(Val), s(a), ot(a))} } |
loc=pos kIf c=exp kThen s=scopeExpr kFi {fun(a) {assertVoid(a, If(c(Val), s(Void), None), loc)}} |
loc=pos kWhile c=exp kDo s=scopeExpr kOd {fun(a) { assertVoid(a, While(c(Val), s(Void)), loc)} }|
loc=pos kFor i=scopeExpr s[","] c=exp s[","] s=exp kDo ot=scopeExpr kOd
{ fun(a) {
distributeScope(i(Void),
fun(e) { assertVoid(
a,
Seq(e, While(c(Val), Seq(ot(Void), s(Void)))),
loc
)
}
)
}} |
loc=pos kRepeat b=scopeExpr kUntil c=inbr[s("("), exp, s(")")] {
fun(a) {
distributeScope(b(Void), fun(e) {assertVoid(a, Rep(e, c(Val)), loc) })
}
}|
se=inbr[s("{"), scopeExpr, s("}")] {fun(a) {se(a)}}
),
varDef = memo $ eta syntax (
x=lident v=(-s["="] basic)? {[x, v]}
),
funDef = memo $ eta syntax (
kFun name=lident args=inbr[s("("), list0(lident), s(")")] body=inbr[s("{"), scopeExpr, s("}")] {Fun(name, args, body(Weak))}
),
def = memo $ eta syntax (
kLocal l=list[varDef] s[";"] {Local(l)} |
funDef
),
scopeExpr = memo $ eta syntax (
defs=def+ e=exp? {fun(a) {expandScope(defs, case e of None -> Skip | Some(ee) -> ee(a) esac)}} |
e=exp {fun (a) {e(a)}}
),
(* End *)
basic = memo $ eta (expr ({[Right, singleton ([s (":="),
fun (l, loc, r) {
Expand All @@ -142,7 +178,7 @@ local primary = memo $ eta syntax (
[Left , map (binop, {"+", "-"})],
[Left , map (binop, {"*", "/", "%"})]
},
postfix)(id)),
postfix)),
postfix = memo $ eta syntax (loc=pos e=primary ps=(i=inbr[s("["), exp, s("]")] {Index (i (Val))} |
-s["."] kLength {Length}
)* {fun (a) {foldl (fun (e, p) {
Expand All @@ -158,25 +194,14 @@ local primary = memo $ eta syntax (
esac
}, e, ps) (a)
}}
),
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 (kLocal ds=list[syntax (lident (s["="] e=basic {e (Val)})?)] s[";"] {Local (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)});

local elifStmt = syntax (
kElif e=exp kThen s=scopeExpr ot=elifStmt {fun(a) { If(e(Val), s(a), ot(a))} } |
loc=pos kElif e=exp kThen s=scopeExpr {fun(a) { assertVoid(a, If(e(Val), s(Void), e(Void)), loc) }} |
kElse s=scopeExpr { fun(a) {s(a)} }
);
Loading