├── README.md
├── ex1
├── Implementation.scala
└── README.md
├── ex2
├── Implementation.scala
└── README.md
├── ex3
├── Implementation.scala
└── README.md
├── ex4
├── README.md
└── solution.md
├── ex5
├── Implementation.scala
└── README.md
├── ex6
├── Implementation.scala
└── README.md
├── ex7
├── README.md
└── solution.pdf
├── ex8
├── README.md
└── solution.md
├── hw1
├── 1.jpg
├── 2.jpg
├── 3.jpg
├── 4.jpg
└── README.md
├── proj1
└── README.md
├── proj2
└── README.md
└── proj3
└── README.md
/README.md:
--------------------------------------------------------------------------------
1 | # KAIST CS320 Assignment Instructions
2 |
3 | The course has 5 coding exercises (no submission required) and 3 projects
4 | (submission required).
5 |
6 | * [Exercise #1: Scala Tutorial](/ex1)
7 | * [Exercise #2: Identifiers](/ex2)
8 | * [Exercise #3: MVAE](/ex3)
9 | * [Exercise #5: MRFVAE](/ex5)
10 | * [Exercise #6: SRBFAE](/ex6)
11 | * [Project #1: FIBER](/proj1)
12 | * [Project #2: X-FIBER](/proj2)
13 | * [Project #3: FABRIC](/proj3)
14 |
15 | ## Prerequisites
16 |
17 | * JDK >= 8 ()
18 | * sbt ()
19 |
20 | ## Download
21 |
22 | Run `sbt new kaist-plrg-cs320/[assignment name].g8` in your terminal.
23 | The project directory whose name is the same as the assignment will be created
24 | under the current directory.
25 |
26 | Below is an example.
27 |
28 | ```
29 | $ sbt new kaist-plrg-cs320/scala-tutorial.g8
30 | ...
31 | name [Scala Tutorial]:
32 | Template applied in ./scala-tutorial
33 | ```
34 |
35 | See the instructions for each assignment to find the exact assignment name.
36 |
37 | ## Directory Structure
38 |
39 | You can find the following directories and files in the project directory:
40 |
41 | ```
42 | core/src
43 | - main/scala
44 | - cs320
45 | - Implementation.scala
46 | - Template.scala
47 | - package.scala
48 | - test/scala
49 | - cs320
50 | - Spec.scala
51 | ```
52 |
53 | **DO NOT** edit files other than
54 | `core/src/main/scala/cs320/Implementation.scala` and
55 | `core/src/test/scala/cs320/Spec.scala`.
56 |
57 | * `core/src/main/scala/cs320/Implementation.scala`:
58 | You must fill this file to implement the required function(s).
59 | It is enough to edit only this file to finish the assignment.
60 |
61 | * `core/src/main/scala/cs320/Template.scala`:
62 | This file contains the definitions of functions that you must implement to
63 | complete the assignment.
64 |
65 | * `core/src/main/scala/package.scala`:
66 | This file defines `error` functions. You can throw an exception with an error
67 | message `s` by calling `error(s)`. To omit the message, you can use `error()`,
68 | instead of `error("")`.
69 |
70 | * `core/src/test/scala/cs320/Spec.scala`
71 | This file contains test cases.
72 | Passing all the provided tests does not guarantee that your implementation is correct.
73 | We highly recommend adding your own tests.
74 |
75 | ## Restrictions
76 |
77 | You must not use any of the following features in your implementation:
78 |
79 | * `asInstanceOf`
80 | * `isInstanceOf`
81 | * `null`
82 | * `return`
83 | * `throw`
84 | * `var`
85 | * `while`
86 | * `try-catch`
87 | * mutable data structures
88 |
89 | You can use any other features that are not explicitly forbidden. For example,
90 |
91 | * You can define helper functions and additional types.
92 | * You can use immutable data structures.
93 | * You can use `for`.
94 | * You can mutate mutable variables/fields already defined in the provided code.
95 |
96 | The use of the prohibited features will make your code not compile. If your code
97 | compiles successfully, you are not using any prohibited features.
98 |
99 | ## Testing Your Implementation
100 |
101 | Under the project directory, execute `sbt` to start an sbt console.
102 |
103 | ```
104 | $ sbt
105 | [info] welcome to sbt
106 | ...
107 | sbt:...>
108 | ```
109 |
110 | To run the test cases in `Spec.scala`, execute the `test` command.
111 | Every test case will fail at the beginning.
112 |
113 | ```
114 | sbt:...> test
115 | ...
116 | [error] Failed tests:
117 | [error] cs320.Spec
118 | ```
119 |
120 | After implementing every function correctly, every test will succeed.
121 |
122 | ```
123 | sbt:...> test
124 | ...
125 | [info] All tests passed.
126 | ```
127 |
128 | (If you are working on Exercise #1, stop reading here. The remaining parts are
129 | for the other assignments.)
130 |
131 | ### REPL
132 |
133 | Any assignments other than Exercise #1 provide REPL.
134 | REPL allows you to input an arbitrary expression into your implementation and see the result.
135 | Using REPL, you can quickly test your implementation without changing `Spec.scala`.
136 |
137 | Execute the `run` command to start REPL.
138 | Below is REPL of Exercise #3.
139 |
140 | ```
141 | sbt:mvae > run
142 | [info] running cs320.Main
143 | Welcome to the MVAE REPL.
144 | Type in :q, :quit, or the EOF character to terminate the REPL.
145 |
146 | MVAE>
147 | ```
148 |
149 | REPL will not work properly at the beginning.
150 |
151 | ```
152 | MVAE> { val x = (1, 2); (x + x) }
153 | Parsed: Val(x,Num(List(1, 2)),Add(Id(x),Id(x)))
154 | scala.NotImplementedError: an implementation is missing
155 | at scala.Predef$.$qmark$qmark$qmark(Predef.scala:347)
156 | at cs320.Implementation$.interp(Implementation.scala:18)
157 | ```
158 |
159 | After finishing the implementation, REPL will behave correctly.
160 |
161 | ```
162 | MVAE> { val x = (1, 2); (x + x) }
163 | Parsed: Val(x,Num(List(1, 2)),Add(Id(x),Id(x)))
164 | Result: (2, 3, 3, 4)
165 | ```
166 |
167 | (If you are working on an exercise, stop reading here. The remaining parts are
168 | for the projects.)
169 |
170 | ### Fuzzing
171 |
172 | Each project (but no exercise) provides a fuzzer. A fuzzer randomly generates
173 | expressions to test your interpreter. You need to install
174 | [Node.js](https://nodejs.org/en/download/) on your machine to use the fuzzer.
175 |
176 | Execute the `run fuzzer` command to use the fuzzer.
177 |
178 | ```
179 | sbt:... > run fuzzer
180 | [info] running cs320.Main fuzzer
181 | 10000
182 | ```
183 |
184 | The number shown on the screen is the number of expressions your interpreter
185 | correctly interpreted so far. The fuzzer runs forever until it finds a wrong
186 | behavior. Press `ctrl+c` to stop fuzzing.
187 |
188 | When the fuzzer finds a wrong behavior, it prints detailed information and
189 | terminates.
190 |
191 | ```
192 | Incorrect behavior detected
193 | Expr: (1 + 2)
194 | Correct result: 3
195 | Your result: Unexpected Error
196 | an implementation is missing
197 | scala.Predef$.$qmark$qmark$qmark(Predef.scala:344)
198 | cs320.Implementation$.interp(Implementation.scala:7)
199 | cs320.Template.run(Template.scala:5)
200 | cs320.Template.run$(Template.scala:5)
201 | cs320.Implementation$.run(Implementation.scala:5)
202 | ```
203 |
204 | If the fuzzer reports a failed case after you press `ctrl+c`, it is due to the
205 | abrupt termination, not a defect in your implementation, so you can ignore it.
206 |
207 | If your implementation correctly interprets a huge number of expressions, your
208 | implementation is highly likely to be correct.
209 |
210 | ## Grading
211 |
212 | You must submit your `Implementation.scala` of each project.
213 | See the instructions for each project to find the submission link.
214 |
215 | Violation of the honor code will give you F.
216 | You must work on each project by yourself without getting any help.
217 | You can refer to the lecture materials, including
218 | the lecture slides, the textbook, and the sample solutions to the exercises.
219 |
220 | We disallow late submissions. If you submit multiple times, only the last
221 | submission will be graded.
222 |
223 | You can get maximum 100 points. If your code uses a disallow feature or does not
224 | compile, you will get 0 points.
225 |
226 | * Test cases: 80 points (1 point per case)
227 | * Fuzzing: 20 points
228 |
229 | The test cases for the grading are similar to, but not the same as, those
230 | provided in `Spec.scala`. You get more points as you pass more test cases. The
231 | execution of each test case does not affect the others, e.g., the other test
232 | cases will be graded properly even when your implementation runs forever for a
233 | certain test case.
234 |
235 | If your implementation passes all the test cases,
236 | we test the implementation with the same fuzzer as the one you have.
237 | We use 10,000 expressions for each student.
238 | The expressions are the same for every student.
239 | If your implementation behaves correctly for every expression, you will get 20
240 | points for the Fuzzing part. Otherwise, you will get 0 points.
241 |
242 | ## FAQ
243 |
244 | ### My code does not terminate or emits stack overflow error
245 |
246 | Though not the only cause, this usually happens in student's implementation when student tries to call `error()` function with some string interpolation, for example
247 |
248 | ```scala
249 | error(s"not both number: $x, $y")
250 | ```
251 |
252 | Maybe changing the code to use plain string might solve the issue, like
253 |
254 | ```scala
255 | error(s"not both number")
256 | ```
257 |
--------------------------------------------------------------------------------
/ex1/Implementation.scala:
--------------------------------------------------------------------------------
1 | package cs320
2 |
3 | object Implementation extends Template {
4 |
5 | def volumeOfCuboid(a: Int, b: Int, c: Int): Int = a * b * c
6 |
7 | def concat(x: String, y: String): String = x + y
8 |
9 | def addN(n: Int): Int => Int = _ + n
10 |
11 | def twice(f: Int => Int): Int => Int = x => f(f(x))
12 |
13 | def compose(f: Int => Int, g: Int => Int): Int => Int = x => f(g(x))
14 |
15 | def double(l: List[Int]): List[Int] = l.map(_ * 2)
16 |
17 | def sum(l: List[Int]): Int = l.foldLeft(0)(_ + _)
18 |
19 | def getKey(m: Map[String, Int], s: String): Int = m.getOrElse(s, error(s))
20 |
21 | def countLeaves(t: Tree): Int = t match {
22 | case Branch(l, _, r) => countLeaves(l) + countLeaves(r)
23 | case _ => 1
24 | }
25 |
26 | def flatten(t: Tree): List[Int] = t match {
27 | case Branch(l, v, r) => flatten(l) ++ (v :: flatten(r))
28 | case Leaf(v) => List(v)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/ex1/README.md:
--------------------------------------------------------------------------------
1 | # Exercise #1: Scala Tutorial
2 |
3 | **Read the [common instructions](https://github.com/kaist-plrg-cs320/assignment-docs) first if you have not read them.**
4 |
5 | ## Download
6 |
7 | ```bash
8 | sbt new kaist-plrg-cs320/scala-tutorial.g8
9 | ```
10 |
11 | ## Descriptions
12 |
13 | ### Primitives
14 |
15 | * `volumeOfCuboid` takes three non-negative integers `a`, `b`, and `c`
16 | denoting the lengths of three sides and returns the volume of the cuboid.
17 | ```scala
18 | test(volumeOfCuboid(1, 3, 5), 15)
19 | test(volumeOfCuboid(2, 3, 4), 24)
20 | ```
21 |
22 | * `concat` takes two strings `x` and `y`
23 | and returns their concatenation.
24 | ```scala
25 | test(concat("x", "y"), "xy")
26 | test(concat("abc", "def"), "abcdef")
27 | ```
28 |
29 | ### Functions
30 |
31 | * `addN` takes an integer `n`
32 | and returns a function that adds `n` to a given integer.
33 | ```scala
34 | test(addN(5)(3), 8)
35 | test(addN(5)(42), 47)
36 | ```
37 |
38 | * `twice` takes a function `f` whose type is `Int => Int`
39 | and returns a function that applies `f` twice.
40 | ```scala
41 | test(twice(addN(3))(2), 8)
42 | test(twice(addN(3))(7), 13)
43 | ```
44 |
45 | * `compose` takes two `Int => Int` functions `f` and `g`
46 | and returns their composition `f ∘ g`.
47 | ```scala
48 | test(compose(addN(3), addN(4))(5), 12)
49 | test(compose(addN(3), addN(4))(11), 18)
50 | ```
51 |
52 | ### Lists
53 |
54 | * `double` takes an interger list `l`
55 | and returns a list whose elements are the doubles of the elements of `l`.
56 | ```scala
57 | test(double(List(1, 2, 3)), List(2, 4, 6))
58 | test(double(double(List(1, 2, 3, 4, 5))), List(4, 8, 12, 16, 20))
59 | ```
60 |
61 | * `sum` takes an integer list `l`
62 | and returns the sum of the elements of `l`.
63 | ```scala
64 | test(sum(List(1, 2, 3)), 6)
65 | test(sum(List(4, 2, 3, 7, 5)), 21)
66 | ```
67 |
68 | ### Maps
69 |
70 | * `getKey` takes a map `m` from strings to integers and a string `s`
71 | and returns the integer corresponding to `s` if `m` has such mapping
72 | and throws an exception with a message containing `s` otherwise.
73 | ```scala
74 | val m: Map[String, Int] = Map("Ryu" -> 42, "PL" -> 37)
75 | test(getKey(m, "Ryu"), 42)
76 | testExc(getKey(m, "CS320"), "CS320")
77 | ```
78 |
79 | ### Algebraic Data Types
80 |
81 | The `Tree` type represents binary trees.
82 | A `Tree` is either `Branch` (a non-leaf node) or `Leaf` (a leaf node).
83 | A `Branch` consists of three fields: `left` and `right` denoting
84 | the left and right subtrees and `value` denoting its value.
85 | A `Leaf` has one field: `value` denoting its value.
86 |
87 | ```scala
88 | sealed trait Tree
89 | case class Branch(left: Tree, value: Int, right: Tree) extends Tree
90 | case class Leaf(value: Int) extends Tree
91 | ```
92 |
93 | The `Tree` type is already defined in `Template.scala`.
94 | **DO NOT** define it again in `Implementation.scala`.
95 |
96 | * `countLeaves` takes a tree `t` and
97 | and returns the number of its leaf nodes.
98 | ```scala
99 | val t1: Tree = Branch(Leaf(1), 2, Leaf(3))
100 | val t2: Tree = Branch(Leaf(1), 2, Branch(Leaf(3), 4, Leaf(5)))
101 | test(countLeaves(t1), 2)
102 | test(countLeaves(t2), 3)
103 | ```
104 |
105 | * `flatten` takes a tree `t`
106 | and returns a list containing the value of each node in `t` with in-order traversal.
107 | ```scala
108 | val t1: Tree = Branch(Leaf(1), 2, Leaf(3))
109 | val t2: Tree = Branch(Leaf(1), 2, Branch(Leaf(3), 4, Leaf(5)))
110 | test(flatten(t1), List(1, 2, 3))
111 | test(flatten(t2), List(1, 2, 3, 4, 5))
112 | ```
113 |
114 | ## Sample Solution
115 |
116 | [`Implementation.scala`](./Implementation.scala)
117 |
--------------------------------------------------------------------------------
/ex2/Implementation.scala:
--------------------------------------------------------------------------------
1 | package cs320
2 |
3 | object Implementation extends Template {
4 |
5 | def freeIds(expr: Expr): Set[String] = {
6 | def frees(e: Expr, ids: Set[String]): Set[String] = e match {
7 | case Num(n) => Set()
8 | case Add(left, right) => frees(left, ids) ++ frees(right, ids)
9 | case Sub(left, right) => frees(left, ids) ++ frees(right, ids)
10 | case Val(name, expr, body) => frees(expr, ids) ++ frees(body, ids + name)
11 | case Id(id) => if (ids contains id) Set() else Set(id)
12 | }
13 | frees(expr, Set())
14 | }
15 |
16 | def bindingIds(expr: Expr): Set[String] = expr match {
17 | case Num(n) => Set()
18 | case Add(left, right) => bindingIds(left) ++ bindingIds(right)
19 | case Sub(left, right) => bindingIds(left) ++ bindingIds(right)
20 | case Val(name, expr, body) => bindingIds(expr) ++ bindingIds(body) + name
21 | case Id(id) => Set()
22 | }
23 |
24 | def boundIds(expr: Expr): Set[String] = {
25 | def bounds(e: Expr, ids: Set[String]): Set[String] = e match {
26 | case Num(n) => Set()
27 | case Add(left, right) => bounds(left, ids) ++ bounds(right, ids)
28 | case Sub(left, right) => bounds(left, ids) ++ bounds(right, ids)
29 | case Val(name, expr, body) => bounds(expr, ids) ++ bounds(body, ids + name)
30 | case Id(id) => if (ids contains id) Set(id) else Set()
31 | }
32 | bounds(expr, Set())
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/ex2/README.md:
--------------------------------------------------------------------------------
1 | # Exercise #2: Identifiers
2 |
3 | **Read the [common instructions](https://github.com/kaist-plrg-cs320/assignment-docs) first if you have not read them.**
4 | **Don't forget to read the [REPL](https://github.com/kaist-plrg-cs320/assignment-docs#repl) section.**
5 |
6 | ## Download
7 |
8 | ```bash
9 | sbt new kaist-plrg-cs320/identifiers.g8
10 | ```
11 |
12 | ## Descriptions
13 |
14 | Expressions are defined in `core/src/main/scala/cs320/Expr.scala`:
15 | ```
16 | e ::= n
17 | | e + e
18 | | e - e
19 | | val x = e; e
20 | | x
21 | ```
22 |
23 | * `freeIds` takes an expression
24 | and returns the set of every free identifier in the expression.
25 | ```scala
26 | test(freeIds(Expr("{ val x = 1; (x + y) }")), Set("y"))
27 | test(freeIds(Expr("{ val z = 2; 1 }")), Set())
28 | ```
29 |
30 | * `bindingIds` takes an expression
31 | and returns the set of every binding identifier in the expression
32 | (whether or not the binding identifier is ever referenced by a bound identifier).
33 | ```scala
34 | test(bindingIds(Expr("{ val x = 1; (x + y) }")), Set("x"))
35 | test(bindingIds(Expr("{ val z = 2; 1 }")), Set("z"))
36 | ```
37 |
38 | * `boundIds` takes an expression
39 | and returns the set of every bound identifier in the expression.
40 | ```scala
41 | test(boundIds(Expr("{ val x = 1; (x + y) }")), Set("x"))
42 | test(boundIds(Expr("{ val z = 2; 1 }")), Set())
43 | ```
44 |
45 | ## Sample Solution
46 |
47 | [`Implementation.scala`](./Implementation.scala)
48 |
--------------------------------------------------------------------------------
/ex3/Implementation.scala:
--------------------------------------------------------------------------------
1 | package cs320
2 |
3 | object Implementation extends Template {
4 |
5 | def binOp(
6 | op: (Int, Int) => Int,
7 | ls: List[Int],
8 | rs: List[Int]
9 | ): List[Int] = ls match {
10 | case Nil => Nil
11 | case l :: rest =>
12 | def f(r: Int): Int = op(l, r)
13 | rs.map(f) ++ binOp(op, rest, rs)
14 | }
15 |
16 | type Env = Map[String, List[Int]]
17 |
18 | def interp(expr: Expr, env: Env): List[Int] = expr match {
19 | case Num(ns) => ns
20 | case Add(l, r) => binOp(_ + _, interp(l, env), interp(r, env))
21 | case Sub(l, r) => binOp(_ - _, interp(l, env), interp(r, env))
22 | case Val(x, e, b) => interp(b, env + (x -> interp(e, env)))
23 | case Id(x) => env.getOrElse(x, error(s"free identifier: $x"))
24 | case Min(l, m, r) =>
25 | val v = binOp(_ min _, interp(l, env), interp(m, env))
26 | binOp(_ min _, v, interp(r, env))
27 | case Max(l, m, r) =>
28 | val v = binOp(_ max _, interp(l, env), interp(m, env))
29 | binOp(_ max _, v, interp(r, env))
30 | }
31 |
32 | def interp(expr: Expr): List[Int] = interp(expr, Map())
33 | }
34 |
--------------------------------------------------------------------------------
/ex3/README.md:
--------------------------------------------------------------------------------
1 | # Exercise #3: MVAE
2 |
3 | **Read the [common instructions](https://github.com/kaist-plrg-cs320/assignment-docs) first if you have not read them.**
4 | **Don't forget to read the [REPL](https://github.com/kaist-plrg-cs320/assignment-docs#repl) section.**
5 |
6 | ## Download
7 |
8 | ```bash
9 | sbt new kaist-plrg-cs320/mvae.g8
10 | ```
11 |
12 | ## Descriptions
13 |
14 | MVAE extends VAE with multi-integers. Implement an interpreter for MVAE.
15 |
16 | ### Overview
17 |
18 | A multi-integer is a value consisting of zero or more integers. For example,
19 | `()`, `(2)`, `(1, 42)`, and `(3, 4, 5)` are multi-integers. A multi-integer
20 | expression is defined as follows:
21 |
22 | ```scala
23 | case class Num(values: List[Int]) extends Expr
24 | ```
25 |
26 | Addition and subtraction on multi-integers produce multi-integers by considering
27 | every possible combination.
28 |
29 | ```scala
30 | test(run("(3 + 7)"), List(10))
31 | test(run("(10 - (3, 5))"), List(7, 5))
32 | test(run("((1, 2) + (3, 4))"), List(4, 5, 5, 6))
33 | ```
34 |
35 | `((3) + (7))` is `(10)` because `3 + 7` is the only possible combination.
36 | `((10) - (3, 5))` is `(7, 5)` because both `10 - 3` and `10 - 5` are possible.
37 | `((1, 2) + (3, 4))` is `(4, 5, 5, 6)` because `1 + 3`, `1 + 4`, `2 + 3`, and `2 + 4` are possible.
38 |
39 | MVAE additionally supports two more arithmetic operators: `min` and `max`.
40 | Each of them takes three expressions and returns the minimum/maximum.
41 |
42 | ```scala
43 | test(run("min(3, 4, 5)"), List(3))
44 | test(run("min((1, 4), (2, 9), 3)"), List(1, 1, 2, 3))
45 | ```
46 |
47 | `min((3), (4), (5))` is `(3)` because `min(3, 4, 5)` is the only possible combination.
48 | `min((1, 4), (2, 9), 3)` is `(1, 1, 2, 3)` because `min(1, 2, 3)`, `min(1, 9,
49 | 3)`, `min(4, 2, 3)`, and `min(4, 9 ,3)` are possible.
50 |
51 | ### Concrete Syntax
52 |
53 | We use the [extended Backus-Naur form](https://en.wikipedia.org/wiki/Extended_Backus\%E2\%80\%93Naur_form).
54 | Note that `{ }` denotes a repetition of zero or more times.
55 |
56 | ```
57 | expr ::= ...
58 | | "(" ")"
59 | | "(" num {"," num} ")"
60 | | "min" "(" expr "," expr "," expr ")"
61 | | "max" "(" expr "," expr "," expr ")"
62 | ```
63 |
64 | ### Abstract Syntax
65 |
66 | $e::=\cdots\ |\ (n,\cdots, n)\ |\ \min(e,e,e)\ |\ \max(e,e,e)$
67 |
68 | Expressions are defined in `core/src/main/scala/cs320/Expr.scala`.
69 |
70 | ### Operational Semantics
71 |
72 | $\sigma\vdash (n_1,\cdots,n_i) \Rightarrow (n_1,\cdots,n_i)$
73 |
74 | $\Large\frac{\sigma\vdash e_1\Rightarrow(n_1,\cdots,n_i)\quad\sigma\vdash e_2\Rightarrow(m_1,\cdots,m_j)}{\sigma\vdash e_1+e_2\Rightarrow(n_1+m_1,n_1+m_2,\cdots,n_i+m_{j-1},n_i+m_j)}$
75 |
76 | $\Large\frac{\sigma\vdash e_1\Rightarrow(n_1,\cdots,n_i)\quad\sigma\vdash e_2\Rightarrow(m_1,\cdots,m_j)}{\sigma\vdash e_1-e_2\Rightarrow(n_1-m_1,n_1-m_2,\cdots,n_i-m_{j-1},n_i-m_j)}$
77 |
78 | $\Large\frac{\sigma\vdash e_1\Rightarrow(n_1,\cdots,n_i)\quad\sigma\vdash e_2\Rightarrow(m_1,\cdots,m_j)\quad\sigma\vdash e_3\Rightarrow(l_1,\cdots,l_k)}{\sigma\vdash\min(e_1,e_2,e_3)\Rightarrow(\min(n_1,m_1,l_1),\min(n_1,m_1,l_2),\cdots,\min(n_i,m_j,l_k))}$
79 |
80 | $\Large\frac{\sigma\vdash e_1\Rightarrow(n_1,\cdots,n_i)\quad\sigma\vdash e_2\Rightarrow(m_1,\cdots,m_j)\quad\sigma\vdash e_3\Rightarrow(l_1,\cdots,l_k)}{\sigma\vdash\max(e_1,e_2,e_3)\Rightarrow(\max(n_1,m_1,l_1),\max(n_1,m_1,l_2),\cdots,\max(n_i,m_j,l_k))}$
81 |
82 | ## Sample Solution
83 |
84 | [`Implementation.scala`](./Implementation.scala)
85 |
--------------------------------------------------------------------------------
/ex4/README.md:
--------------------------------------------------------------------------------
1 | # Exercise #4: F1VAE
2 |
3 | Consider the following syntax of F1VAE:
4 |
5 | $d::={\sf def}\ x(x)=e$
6 |
7 | $e::=n\ |\ e+e\ |\ {\sf val}\ x=e;e\ |\ x\ |\ x(e)$
8 |
9 | $d\in{\it FunDef},\ x\in{\it Id},\ \sigma\in{\it Id}\rightarrow\mathbb{Z},\ \Lambda\in{\it Id}\rightarrow{\it FunDef}$
10 |
11 | Write the operational semantics of the form $\sigma,\Lambda\vdash e\Rightarrow n$.
12 |
13 | ## Sample Solution
14 |
15 | [sample solution](./solution.md)
16 |
--------------------------------------------------------------------------------
/ex4/solution.md:
--------------------------------------------------------------------------------
1 | $\sigma,\Lambda\vdash n\Rightarrow n$
2 |
3 | $\Large\frac{\sigma,\Lambda\vdash e_1\Rightarrow n_1\quad\sigma,\Lambda\vdash e_2\Rightarrow n_2}{\sigma,\Lambda\vdash e_1+e_2\Rightarrow n_1+n_2}$
4 |
5 | $\Large\frac{\sigma,\Lambda\vdash e_1\Rightarrow n_1\quad\sigma[x\mapsto n_1],\Lambda\vdash e_2\Rightarrow n_2}{\sigma,\Lambda\vdash {\sf val}\ x=e_1;e_2\Rightarrow n_2}$
6 |
7 | $\Large\frac{x\in\mathit{Domain}(\sigma)}{\sigma,\Lambda\vdash x\Rightarrow\sigma(x)}$
8 |
9 | $\Large\frac{\sigma,\Lambda\vdash e\Rightarrow n\quad x\in\mathit{Domain}(\Lambda)\quad\Lambda(x)=({\sf def}\ x(x_1)=e_1)\quad[x_1\mapsto n],\Lambda\vdash e_1\Rightarrow n_1}{\sigma,\Lambda\vdash x(e)\Rightarrow n_1}$
10 |
--------------------------------------------------------------------------------
/ex5/Implementation.scala:
--------------------------------------------------------------------------------
1 | package cs320
2 |
3 | import Value._
4 |
5 | object Implementation extends Template {
6 |
7 | def numVop(op: (Int, Int) => Int): (Value, Value) => NumV = (_, _) match {
8 | case (NumV(x), NumV(y)) => NumV(op(x, y))
9 | case (x, y) => error(s"not both numbers: $x, $y")
10 | }
11 |
12 | val numVAdd = numVop(_ + _)
13 | val numVSub = numVop(_ - _)
14 |
15 | def interp(expr: Expr, env: Env): Value = expr match {
16 | case Num(n) => NumV(n)
17 | case Add(l, r) => numVAdd(interp(l, env), interp(r, env))
18 | case Sub(l, r) => numVSub(interp(l, env), interp(r, env))
19 | case Val(x, e, b) => interp(b, env + (x -> interp(e, env)))
20 | case Id(x) => env.getOrElse(x, error(s"free identifier: $x"))
21 | case Fun(ps, b) => CloV(ps, b, env)
22 | case App(f, args) => interp(f, env) match {
23 | case CloV(params, b, fenv) => {
24 | val avals = args.map(interp(_, env))
25 | if (args.length != params.length) error(s"wrong arity: $params, $args")
26 | interp(b, fenv ++ (params zip avals))
27 | }
28 | case v => error(s"not a closure: $v")
29 | }
30 | case Rec(m) => RecV(m.map { case (f, e) => (f, interp(e, env)) })
31 | case Acc(r, x) => interp(r, env) match {
32 | case RecV(m) => m.getOrElse(x, error(s"no such field: $x"))
33 | case v => error(s"not a record: $v")
34 | }
35 | }
36 |
37 | def interp(expr: Expr): Value = interp(expr, Map())
38 | }
39 |
--------------------------------------------------------------------------------
/ex5/README.md:
--------------------------------------------------------------------------------
1 | # Exercise #5: MRFVAE
2 |
3 | **Read the [common instructions](https://github.com/kaist-plrg-cs320/assignment-docs) first if you have not read them.**
4 | **Don't forget to read the [REPL](https://github.com/kaist-plrg-cs320/assignment-docs#repl) section.**
5 |
6 | ## Download
7 |
8 | ```bash
9 | sbt new kaist-plrg-cs320/mrfvae.g8
10 | ```
11 |
12 | ## Descriptions
13 |
14 | MRFVAE extends FVAE with multi-parameter functions and records.
15 | Implement an interpreter for MRFVAE.
16 |
17 | ### Overview
18 |
19 | #### Multi-Parameter Functions
20 |
21 | Functions have any number (including zero) of parameters.
22 |
23 | ```scala
24 | test(run("{ (x, y) => (x + y) }(1, 2)"), "3")
25 | test(run("{ () => (3 + 4) }()"), "7")
26 | ```
27 |
28 | Function applications can cause two kinds of error: applying a non-function
29 | value to arguments and applying a function to a wrong number of arguments. In
30 | the first case, the interpreter must throw an exception whose message includes
31 | `"not a closure"`. In the second case, the interpreter must throw an exception
32 | whose message includes `"wrong arity"`.
33 |
34 | ```scala
35 | testExc(run("2((3 + 4))"), "not a closure")
36 | testExc(run("{ (x, y) => (x + y) }(1)"), "wrong arity")
37 | ```
38 |
39 | #### Records
40 |
41 | A record is a value mapping fields to values. One can access a field of a record
42 | to obtain the value of the field.
43 |
44 | ```scala
45 | test(run("{ a = 10, b = (1 + 2) }"), "{ a = 10, b = 3 }")
46 | test(run("{ a = 10, b = (1 + 2) }.b"), "3")
47 | ```
48 |
49 | Accessing the fields of records can cause two kinds of error: accessing a field
50 | of a non-record value and accessing a field not in a given record value. In the
51 | first case, the interpreter must throw an exception whose message includes `"not
52 | a record"`. In the second case, the interpreter must throw an exception whose
53 | message includes `"no such field"`.
54 |
55 | ```scala
56 | testExc(run("(1 + 2).a"), "not a record")
57 | testExc(run("{ z = { z = 0 }.y }"), "no such field")
58 | ```
59 |
60 | ### Concrete Syntax
61 |
62 | We use the [extended Backus-Naur form](https://en.wikipedia.org/wiki/Extended_Backus\%E2\%80\%93Naur_form).
63 | Note that `{ }` denotes a repetition of zero or more times.
64 |
65 | ```
66 | expr ::= ...
67 | | "{" "(" ")" "=>" expr "}"
68 | | "{" id "=>" expr "}"
69 | | "{" "(" id {"," id} ")" "=>" expr "}"
70 | | expr "(" ")"
71 | | expr "(" expr {"," expr} ")"
72 | | "{" "}"
73 | | "{" field "=" expr {"," field "=" expr} "}"
74 | | expr "." field
75 | ```
76 |
77 | ### Abstract Syntax
78 |
79 | $e::=\cdots\ |\ \lambda x\cdots x.e\ |\ e(e,\cdots,e)\ |\ \lbrace f=e,\cdots,f=e\rbrace\ |\ e.f$
80 |
81 | $v::=\cdots\ |\ \langle\lambda x\cdots x.e,\sigma\rangle\ |\ \lbrace f=v,\cdots,f=v\rbrace$
82 |
83 | Expressions are defined in `core/src/main/scala/cs320/Expr.scala`, and values
84 | are defined in `core/src/main/scala/cs320/Value.scala`.
85 |
86 | ### Operational Semantics
87 |
88 | $\sigma\vdash\lambda x_1\cdots x_n.e\Rightarrow\langle\lambda x_1\cdots x_n.e,\sigma\rangle$
89 |
90 | $\Large\frac{\sigma\vdash e\Rightarrow\langle\lambda x_1\cdots x_n.e',\sigma'\rangle\quad\sigma\vdash e_1\Rightarrow v_1\quad\cdots\quad\sigma\vdash e_n\Rightarrow v_n\quad\sigma'[x_1\mapsto v_1,\cdots,x_n\mapsto v_n]\vdash e'\Rightarrow v'}{\sigma\vdash e(e_1,\cdots,e_n)\Rightarrow v'}$
91 |
92 | $\Large\frac{\sigma\vdash e_1\Rightarrow v_1\quad\cdots\quad\sigma\vdash e_n\Rightarrow v_n}{\sigma\vdash\lbrace f_1=e_1,\cdots,f_n=e_n\rbrace\Rightarrow\lbrace f_1=v_1,\cdots,f_n=v_n\rbrace}$
93 |
94 | $\Large\frac{\sigma\vdash e\Rightarrow\lbrace\cdots,f=v,\cdots\rbrace}{\sigma\vdash e.f\Rightarrow v}$
95 |
96 | ## Sample Solution
97 |
98 | [`Implementation.scala`](./Implementation.scala)
99 |
--------------------------------------------------------------------------------
/ex6/Implementation.scala:
--------------------------------------------------------------------------------
1 | package cs320
2 |
3 | import Value._
4 |
5 | object Implementation extends Template {
6 |
7 | type Sto = Map[Addr, Value]
8 |
9 | def interp(expr: Expr): Value = interp(expr, Map(), Map())._1
10 |
11 | private def interp(e: Expr, env: Env, sto: Sto): (Value, Sto) = e match {
12 | case Num(n) => (NumV(n), sto)
13 | case Add(l, r) =>
14 | val (lv, ls) = interp(l, env, sto)
15 | val (rv, rs) = interp(r, env, ls)
16 | (numVAdd(lv, rv), rs)
17 | case Sub(l, r) =>
18 | val (lv, ls) = interp(l, env, sto)
19 | val (rv, rs) = interp(r, env, ls)
20 | (numVSub(lv, rv), rs)
21 | case Id(x) =>
22 | val v = env.getOrElse(x, error(s"free identifier: $x"))
23 | (v, sto)
24 | case Fun(p, b) =>
25 | val cloV = CloV(p, b, env)
26 | (cloV, sto)
27 | case App(f, arg) =>
28 | val (fv, fs) = interp(f, env, sto)
29 | fv match {
30 | case CloV(param, b, fenv) =>
31 | val (av, as) = interp(arg, env, fs)
32 | interp(b, fenv + (param -> av), as)
33 | case v => error(s"not a closure: $v")
34 | }
35 | case NewBox(e) =>
36 | val (v, s) = interp(e, env, sto)
37 | val addr = malloc(s)
38 | (BoxV(addr), s + (addr -> v))
39 | case SetBox(b, e) =>
40 | val (bv, bs) = interp(b, env, sto)
41 | bv match {
42 | case BoxV(addr) =>
43 | val (v, s) = interp(e, env, bs)
44 | (v, s + (addr -> v))
45 | case v => error(s"not a box: $v")
46 | }
47 | case OpenBox(b) =>
48 | val (bv, bs) = interp(b, env, sto)
49 | bv match {
50 | case BoxV(addr) =>
51 | val v = bs.getOrElse(addr, error(s"unallocated address: $addr"))
52 | (v, bs)
53 | case v => error(s"not a box: $v")
54 | }
55 | case Seqn(l, rs) =>
56 | val initial = interp(l, env, sto)
57 | rs.foldLeft(initial) {
58 | case ((v, s), r) => interp(r, env, s)
59 | }
60 | case Rec(fs) =>
61 | val (fields, s) = fs.foldLeft(Map[String, Addr](), sto) {
62 | case ((m0, s0), (f, e)) =>
63 | val (v, s1) = interp(e, env, s0)
64 | val addr = malloc(s1)
65 | val s2 = s1 + (addr -> v)
66 | val m1 = m0 + (f -> addr)
67 | (m1, s2)
68 | }
69 | (RecV(fields), s)
70 | case Get(r, f) =>
71 | val (rv, rs) = interp(r, env, sto)
72 | rv match {
73 | case RecV(fields) =>
74 | val addr = fields.getOrElse(f, error(s"no such field: $f"))
75 | val v = rs.getOrElse(addr, error(s"unallocated address: $addr"))
76 | (v, rs)
77 | case v => error(s"not a record: $v")
78 | }
79 | case Set(r, f, e) =>
80 | val (rv, rs) = interp(r, env, sto)
81 | rv match {
82 | case RecV(fields) =>
83 | val addr = fields.getOrElse(f, error(s"no such field: $f"))
84 | val (v, s) = interp(e, env, rs)
85 | (v, s + (addr -> v))
86 | case v => error(s"not a record: $v")
87 | }
88 | }
89 |
90 | private def numVop(op: (Int, Int) => Int): (Value, Value) => NumV = {
91 | case (NumV(x), NumV(y)) => NumV(op(x, y))
92 | case (x, y) => error(s"not both numbers: $x, $y")
93 | }
94 | private val numVAdd = numVop(_ + _)
95 | private val numVSub = numVop(_ - _)
96 |
97 | private def malloc(sto: Sto): Addr = sto.keys.maxOption.map(_ + 1).getOrElse(0)
98 | }
99 |
--------------------------------------------------------------------------------
/ex6/README.md:
--------------------------------------------------------------------------------
1 | # Exercise #6: SRBFAE
2 |
3 | **Read the [common instructions](https://github.com/kaist-plrg-cs320/assignment-docs) first if you have not read them.**
4 | **Don't forget to read the [REPL](https://github.com/kaist-plrg-cs320/assignment-docs#repl) section.**
5 |
6 | ## Download
7 |
8 | ```bash
9 | sbt new kaist-plrg-cs320/srbfae.g8
10 | ```
11 |
12 | ## Descriptions
13 |
14 | SRBFAE extends BFAE with generalized sequencing and mutable records.
15 | Implement an interpreter for SRBFAE.
16 |
17 | ### Overview
18 |
19 | #### Generalized Sequencing
20 |
21 | Generalized sequencing allows one or more subexpressions,
22 | instead of exactly two subexpressions.
23 |
24 | ```scala
25 | test(run("""{
26 | b => {
27 | b.set((2 + b.get));
28 | b.set((3 + b.get));
29 | b.set((4 + b.get));
30 | b.get
31 | }
32 | }(Box(1))"""), "10")
33 | ```
34 |
35 | #### Mutable Records
36 |
37 | Unlike records in MRFVAE, records in SRBFAE are mutable. `{ e1.f = e2 }`
38 | changes the value of a field `f` in the record produced by `e1`. The value of
39 | `e2` determines the field's new value, and that value is also the result of the
40 | expression.
41 |
42 | ```scala
43 | test(run("""{
44 | r => {
45 | { r.x = 5 };
46 | r.x
47 | }
48 | }({ x = 1 })"""), "5")
49 | ```
50 |
51 | As in MRFVAE, the interpreter must throw an exception whose message
52 | includes `"not a record"` when updating a field of a non-record value and `"no
53 | such field"` when updating a field not in a given record value.
54 |
55 | ### Concrete Syntax
56 |
57 | We use the [extended Backus-Naur form](https://en.wikipedia.org/wiki/Extended_Backus\%E2\%80\%93Naur_form).
58 | Note that `{ }` denotes a repetition of zero or more times.
59 |
60 | ```
61 | expr ::= ...
62 | | "{" expr {";" expr} "}"
63 | | "{" "}"
64 | | "{" field "=" expr {"," field "=" expr} "}"
65 | | expr "." field
66 | | "{" expr "." field "=" expr "}"
67 | ```
68 |
69 | ### Abstract Syntax
70 |
71 | $e::=\cdots\ |\ e;\cdots;e\ |\ \lbrace f=e,\cdots,f=e\rbrace\ |\ e.f\ |\ e.f:=e$
72 |
73 | $v::=\cdots\ \| \lbrace f=a,\cdots,f=a\rbrace$
74 |
75 | Expressions are defined in `core/src/main/scala/cs320/Expr.scala`, and values
76 | are defined in `core/src/main/scala/cs320/Value.scala`.
77 |
78 | ### Operational Semantics
79 |
80 | $\Large\frac{\sigma,M_0\vdash e_1\Rightarrow v_1,M_1\quad\cdots\quad\sigma,M_{n-1}\vdash e_n\Rightarrow v_n,M_n}{ \sigma,M_0\vdash e_1;\cdots;e_n\Rightarrow v_n,M_n}$
81 |
82 | $\Large\frac{\sigma,M_0\vdash e_1\Rightarrow v_1,M_1'\quad\cdots\quad \sigma,M_{n-1}\vdash e_n\Rightarrow v_n,M_n'\quad a_1\not\in\mathit{Domain}(M_1')\quad\cdots\quad a_n\not\in\mathit{Domain}(M_n')\quad M_1=M_1'[a_1\mapsto v_1]\quad\cdots\quad M_n=M_n'[a_n\mapsto v_n]}{\sigma,M_0\vdash\lbrace f_1=e_1,\cdots,f_n=e_n\rbrace\Rightarrow\lbrace f_1=a_1,\cdots,f_n=a_n\rbrace,M_n}$
83 |
84 | $\Large\frac{\sigma,M\vdash e\Rightarrow\lbrace\cdots,f=a,\cdots\rbrace,M_1\quad a\in\mathit{Domain}(M_1)}{\sigma,M\vdash e.f\Rightarrow M_1(a),M_1}$
85 |
86 | $\Large\frac{\sigma,M\vdash e_1\Rightarrow\lbrace\cdots,f=a,\cdots\rbrace,M_1\quad\sigma,M_1\vdash e_2\Rightarrow v,M_2}{\sigma,M\vdash e_1.f:=e_2\Rightarrow v,M_2[a\mapsto v]}$
87 |
88 | ## Sample Solution
89 |
90 | [`Implementation.scala`](./Implementation.scala)
91 |
--------------------------------------------------------------------------------
/ex7/README.md:
--------------------------------------------------------------------------------
1 | # Exercise #7: TFAE
2 |
3 | Draw type derivations of the following expressions:
4 |
5 | 1. $(\lambda({\tt x}{:}{\sf num},{\tt y}{:}{\sf num}).{\tt x}+{\tt y})(8)$
6 | 2. $({\sf if}\ {\sf false}\ (\lambda({\tt x}{:}{\sf num}).{\tt x})\ (\lambda({\tt y}{:}{\sf num}).2))(57)$
7 | 3. $(\lambda({\tt x}{:}{\sf num},{\tt y}{:}{\sf num}\rightarrow{\sf bool}).{\tt y}({\tt x}+17))(42,\lambda({\tt x}{:}{\sf num}).{\tt x}>72)$
8 |
9 | where the type of $e_1>e_2$ is $\sf bool$ if the types of $e_1$ and $e_2$ are $\sf num$.
10 |
11 | ## Sample Solution
12 |
13 | [sample solution](./solution.pdf)
14 |
--------------------------------------------------------------------------------
/ex7/solution.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaist-plrg-cs320/assignment-docs/f4e963185b395e8050eb7f1970b74d4419e96d18/ex7/solution.pdf
--------------------------------------------------------------------------------
/ex8/README.md:
--------------------------------------------------------------------------------
1 | # Exercise 8: TpolyFAE
2 |
3 | Consider TpolyFAE.
4 |
5 | $\Large\frac{\alpha\not\in{\it Domain}(\Gamma)\quad\Gamma[\alpha]\vdash e:\tau}{\Gamma\vdash\Lambda\alpha.e:\forall\alpha.\tau}$
6 |
7 | $\Large\frac{\Gamma\vdash\tau_0\quad\Gamma\vdash e:\forall\alpha.\tau_1}{\Gamma\vdash e[\tau_0]:\tau_1[\alpha\leftarrow\tau_0]}$
8 |
9 | $\Large\frac{\alpha\in{\it Domain}(\Gamma)}{\Gamma\vdash\alpha}$
10 |
11 | $\Large\frac{\Gamma[\alpha]\vdash\tau}{\Gamma\vdash\forall\alpha.\tau}$
12 |
13 | Rewrite the following expression using explicit annotations of polymorphic types
14 | with $\Lambda\alpha.$ and $[\tau]$
15 | to replace all the occurrences of $?$ with types
16 | and to make function calls to take explicit type arguments.
17 | For example, if a given expression is $(\lambda {\tt x}{:}?.{\tt x})\ 1$, then the answer is
18 | $(\Lambda\alpha.\lambda {\tt x}{:}\alpha.{\tt x})[{\sf num}]\ 1$.
19 |
20 | ${\sf val}\ {\tt f}{:}?=(\lambda{\tt g}{:}?.\lambda{\tt v}{:}?.{\tt g}\ {\tt v});\ {\sf val}\ {\tt g}{:}?=(\lambda {\tt x}{:}?.{\tt x});\ {\tt f}\ {\tt g}\ 10$
21 |
22 | ## Sample Solution
23 |
24 | [sample solution](./solution.md)
25 |
--------------------------------------------------------------------------------
/ex8/solution.md:
--------------------------------------------------------------------------------
1 | ${\sf val}\ {\tt f}{:}\forall\alpha.\forall\beta.(\alpha\rightarrow\beta)\rightarrow(\alpha\rightarrow\beta)=(\Lambda\alpha.\Lambda\beta.\lambda{\tt g}{:}\alpha\rightarrow\beta.\lambda{\tt v}{:}\alpha.{\tt g}\ {\tt v});\ {\sf val}\ {\tt g}{:}\forall\gamma.\gamma\rightarrow\gamma=(\Lambda\gamma.\lambda{\tt x}{:}\gamma.{\tt x});\ ({\tt f}[{\sf num}][{\sf num}])\ ({\tt g}[{\sf num}])\ 10$
2 |
--------------------------------------------------------------------------------
/hw1/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaist-plrg-cs320/assignment-docs/f4e963185b395e8050eb7f1970b74d4419e96d18/hw1/1.jpg
--------------------------------------------------------------------------------
/hw1/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaist-plrg-cs320/assignment-docs/f4e963185b395e8050eb7f1970b74d4419e96d18/hw1/2.jpg
--------------------------------------------------------------------------------
/hw1/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaist-plrg-cs320/assignment-docs/f4e963185b395e8050eb7f1970b74d4419e96d18/hw1/3.jpg
--------------------------------------------------------------------------------
/hw1/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaist-plrg-cs320/assignment-docs/f4e963185b395e8050eb7f1970b74d4419e96d18/hw1/4.jpg
--------------------------------------------------------------------------------
/hw1/README.md:
--------------------------------------------------------------------------------
1 | # Homework #1: Growing a Language
2 |
3 | ## Descriptions
4 |
5 | Watch the [Growing a Language](https://youtu.be/_ahvzDzKdB0) video by Guy L. Steele Jr.
6 | The script of the video is available [online](https://link.springer.com/content/pdf/10.1023\%2FA\%3A1010085415024.pdf).
7 | If you are outside the campus,
8 | refer to the [Downloading the script outside the campus](#Downloading-the-script-outside-the-campus) section to access the script.
9 |
10 | Write an essay after watching the video. You must summarize the content of the
11 | video in your own words. In addition, you must include your own opinions on the
12 | video in the essay. You can write the essay both in Korean and English. There is
13 | no restriction on the format and length of the essay.
14 |
15 | ## Submission
16 |
17 | Submit your essay file at
18 | .
19 |
20 | Only `pdf` files are allowed to submit. You can freely choose the file name.
21 |
22 | ## Downloading the script outside the campus
23 |
24 | * Go to the [KAIST Library](https://library.kaist.ac.kr/main.do) website
25 | and sign in.
26 | * Click the "Remote Access (전자정보 교외접속)" button.
27 | 
28 | * Click the "Direct Link (바로가기)" button.
29 | 
30 | * Paste the link ()
31 | in the box of the "Direct URL (직접 입력)" section at "Method 2 (방법 2)."
32 | 
33 | * Click the "GO" button.
34 | 
35 | * The script file will be downloaded.
36 |
--------------------------------------------------------------------------------
/proj1/README.md:
--------------------------------------------------------------------------------
1 | # Project #1: FIBER
2 |
3 | **Read the [common instructions](https://github.com/kaist-plrg-cs320/assignment-docs) first if you have not read them.**
4 | **Don't forget to read the
5 | [REPL](https://github.com/kaist-plrg-cs320/assignment-docs#repl),
6 | [Fuzzing](https://github.com/kaist-plrg-cs320/assignment-docs#fuzzing), and
7 | [Grading](https://github.com/kaist-plrg-cs320/assignment-docs#grading)
8 | sections.**
9 |
10 | ## Download
11 |
12 | ```bash
13 | sbt new kaist-plrg-cs320/fiber.g8
14 | ```
15 |
16 | ## Descriptions
17 |
18 | Read the FIBER language specification (`fiber-spec.pdf`) in the project directory,
19 | and then implement an interpreter for FIBER.
20 | Expressions are defined in `core/src/main/scala/cs320/Expr.scala`,
21 | and values are defined in `core/src/main/scala/cs320/Value.scala`.
22 |
23 | ### Reference Interpreter
24 |
25 | The reference interpreter of FIBER is available at .
26 | Use the reference interpreter to find the correct result of a certain expression.
27 |
28 | ## Submission
29 |
30 | Submit your `Implementation.scala` at
31 | .
32 |
--------------------------------------------------------------------------------
/proj2/README.md:
--------------------------------------------------------------------------------
1 | # Project #2: X-FIBER
2 |
3 | **Read the [common instructions](https://github.com/kaist-plrg-cs320/assignment-docs) first if you have not read them.**
4 | **Don't forget to read the
5 | [REPL](https://github.com/kaist-plrg-cs320/assignment-docs#repl),
6 | [Fuzzing](https://github.com/kaist-plrg-cs320/assignment-docs#fuzzing), and
7 | [Grading](https://github.com/kaist-plrg-cs320/assignment-docs#grading)
8 | sections.**
9 |
10 | ## Download
11 |
12 | ```bash
13 | sbt new kaist-plrg-cs320/x-fiber.g8
14 | ```
15 |
16 | ## Descriptions
17 |
18 | Read the X-FIBER language specification (`x-fiber-spec.pdf`) in the project directory,
19 | and then implement an interpreter for X-FIBER.
20 | Expressions are defined in `core/src/main/scala/cs320/Expr.scala`,
21 | and values are defined in `core/src/main/scala/cs320/Value.scala`.
22 |
23 | ### Reference Interpreter
24 |
25 | The reference interpreter of X-FIBER is available at .
26 | Use the reference interpreter to find the correct result of a certain expression.
27 |
28 | ## Submission
29 |
30 | Submit your `Implementation.scala` at
31 | .
32 |
--------------------------------------------------------------------------------
/proj3/README.md:
--------------------------------------------------------------------------------
1 | # Project #3: FABRIC
2 |
3 | **Read the [common instructions](https://github.com/kaist-plrg-cs320/assignment-docs) first if you have not read them.**
4 | **Don't forget to read the
5 | [REPL](https://github.com/kaist-plrg-cs320/assignment-docs#repl),
6 | [Fuzzing](https://github.com/kaist-plrg-cs320/assignment-docs#fuzzing), and
7 | [Grading](https://github.com/kaist-plrg-cs320/assignment-docs#grading)
8 | sections.**
9 |
10 | ## Download
11 |
12 | ```bash
13 | sbt new kaist-plrg-cs320/fabric.g8
14 | ```
15 |
16 | ## Descriptions
17 |
18 | Read the FABRIC language specification (`fabric.pdf`) in the project directory,
19 | and then implement a type checker and an interpreter for FABRIC.
20 |
21 | ### Important Files
22 |
23 | * `core/src/main/scala/cs320/Implementation.scala`
24 |
25 | You must fill this file to implement the type checker and the interpreter.
26 | More precisely, you must complete the `typeCheck` and `interp` functions.
27 | You will see the following code in the file:
28 | ```scala
29 | def typeCheck(e: Typed.Expr): Typed.Type = T.typeCheck(e)
30 |
31 | def interp(e: Untyped.Expr): Untyped.Value = U.interp(e)
32 |
33 | object T {
34 | import Typed._
35 |
36 | def typeCheck(expr: Expr): Type = ???
37 | }
38 |
39 | object U {
40 | import Untyped._
41 |
42 | def interp(expr: Expr): Value = ???
43 | }
44 | ```
45 | We recommend you to implement everything related to type checking inside the
46 | object `T` and to implement everything related to interpretation inside the
47 | object `U`.
48 |
49 | * `core/src/main/scala/cs320/Template.scala`
50 |
51 | This file contains the
52 | definition of two functions that you must implement to complete the project.
53 | ```scala
54 | def typeCheck(expr: Typed.Expr): Typed.Type
55 | def interp(expr: Untyped.Expr): Untyped.Value
56 | ```
57 | In addition, it defines two other functions:
58 | ```scala
59 | def run(str: String): String = {
60 | val expr = Typed.Expr(str)
61 | typeCheck(expr)
62 | val erased = Typed.erase(expr)
63 | Untyped.showValue(interp(erased))
64 | }
65 | def runWithStdLib(str: String): String =
66 | run(StdLib.code + str)
67 | ```
68 | The `run` function parses a given string to get a typed expression. It
69 | type-checks the expression with the `typeCheck` function.
70 | If the type checking succeeds, it erases types from
71 | the expression with the `erase` function to obtain an untyped expression.
72 | It evaluates the untyped expression with the `interp` function and returns
73 | the result after converting it to a string.
74 |
75 | The `runWithStdLib` function does a similar thing with `run`, but it
76 | prepends the source code of the standard library in front of a given string
77 | before running it.
78 |
79 | * `core/src/main/scala/cs320/Typed.scala`
80 |
81 | This file defines typed expressions, the parser, the desugarer, and the type
82 | erasure of the language.
83 |
84 | * `core/src/main/scala/cs320/Untyped.scala`
85 |
86 | This file defines untyped expression and values of the language.
87 |
88 | ### REPL
89 |
90 | If you give the `--lib` flag to the REPL, it will run a given expression with
91 | the standard library. In this case, it does not show the results of
92 | parsing and erasing.
93 |
94 | ```
95 | sbt:fabric> run --lib
96 | [info] running cs320.Main
97 | Welcome to the FABRIC REPL.
98 | Type in :q, :quit, or the EOF character to terminate the REPL.
99 |
100 | FABRIC> listLength[Int](List5[Int](1, 2, 3, 4, 5))
101 | Type: Int
102 | Result: 5
103 | ```
104 |
105 | ### Fuzzing
106 |
107 | Note that fuzzing may take some time. It may not print anything for a minute
108 | after start-up.
109 |
110 | ### Reference Interpreter
111 |
112 | The reference interpreter of FABRIC is available at .
113 | Use the reference interpreter to find the correct result of a certain expression.
114 |
115 | ## Submission
116 |
117 | Submit your `Implementation.scala` at
118 | .
119 |
--------------------------------------------------------------------------------