Skip to content

Commit

Permalink
Fix G-Machine Part3, and Remove warnings (#341)
Browse files Browse the repository at this point in the history
* fix G-Machine Part1

* fix G-Machine Part2

* G-Machine Part3
  • Loading branch information
myfreess authored Dec 9, 2024
1 parent c436987 commit 2ae83af
Show file tree
Hide file tree
Showing 17 changed files with 1,307 additions and 228 deletions.
18 changes: 0 additions & 18 deletions next/sources/gmachine/src/part1/ast.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,6 @@ fn is_atom[T](self : RawExpr[T]) -> Bool {
}
}

fn binders_of[L, R](l : List[(L, R)]) -> List[L] {
fn fst(pair) {
let (l, _) = pair
return l
}

l.map(fst)
}

fn rhss_of[L, R](l : List[(L, R)]) -> List[R] {
fn snd(pair) {
let (_, r) = pair
return r
}

l.map(snd)
}

fn ScDef::new[T](
name : String,
args : List[T],
Expand Down
6 changes: 5 additions & 1 deletion next/sources/gmachine/src/part1/moon.pkg.json
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
{}
{

"warn-list": "-8-6"

}
2 changes: 2 additions & 0 deletions next/sources/gmachine/src/part1/top.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,6 @@ test "basic eval" {
inspect!(run(List::of([main])), content = "NNum(0)")
let main = "(defn main[] (K1 0 1))"
inspect!(run(List::of([main])), content = "NNum(1)")
let r = LazyRef::{ data : Waiting(fn (){ 3 + 4 })}
inspect!(square(r), content = "49")
}
2 changes: 0 additions & 2 deletions next/sources/gmachine/src/part1/vm.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,6 @@ fn unwind(self : GState) -> Unit {
self.put_stack(a)
self.put_code(Cons(Unwind, Nil))
}
otherwise =>
abort("unwind() : wrong kind of node \{otherwise}, address \{addr}")
}
}
// end unwind definition
Expand Down
18 changes: 0 additions & 18 deletions next/sources/gmachine/src/part2/ast.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,6 @@ fn is_atom[T](self : RawExpr[T]) -> Bool {
}
}

fn binders_of[L, R](l : List[(L, R)]) -> List[L] {
fn fst(pair) {
let (l, _) = pair
return l
}

l.map(fst)
}

fn rhss_of[L, R](l : List[(L, R)]) -> List[R] {
fn snd(pair) {
let (_, r) = pair
return r
}

l.map(snd)
}

fn ScDef::new[T](
name : String,
args : List[T],
Expand Down
4 changes: 3 additions & 1 deletion next/sources/gmachine/src/part2/moon.pkg.json
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
{}
{
"warn-list": "-8"
}
27 changes: 8 additions & 19 deletions next/sources/gmachine/src/part2/vm.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,10 @@ fn slide(self : GState, n : Int) -> Unit {
fn rearrange(self : GState, n : Int) -> Unit {
let appnodes = self.stack.take(n)
let args = appnodes.map(fn (addr) {
let NApp(_, arg) = self.heap[addr]
arg
guard let NApp(_, arg) = self.heap[addr] else {
_ => panic()
}
arg
})
self.stack = args + appnodes.drop(n - 1)
}
Expand Down Expand Up @@ -178,19 +180,8 @@ fn unwind(self : GState) -> Unit {
self.put_code(List::of([Unwind]))
}
NGlobal(_, n, c) => {
let k = self.stack.length()
if k < n {
match self.dump {
Nil => abort("Unwinding with too few arguments")
Cons((i, s), rest) => {
// a1 : ...... : ak
// ||
// ak : s
self.stack = self.stack.drop(k - 1) + s
self.dump = rest
self.code = i
}
}
if self.stack.length() < n {
abort("Unwinding with too few arguments")
} else {
if n != 0 {
self.rearrange(n)
Expand All @@ -204,8 +195,6 @@ fn unwind(self : GState) -> Unit {
self.put_stack(a)
self.put_code(List::of([Unwind]))
}
otherwise =>
abort("unwind() : wrong kind of node \{otherwise}, address \{addr}")
}
}
// end unwind definition
Expand Down Expand Up @@ -303,7 +292,7 @@ fn build_initial_heap(
}


// start step definition

fn step(self : GState) -> Bool {
match self.code {
Nil => return false
Expand Down Expand Up @@ -338,7 +327,7 @@ fn step(self : GState) -> Bool {
}
}
}
// end step definition



fn reify(self : GState) -> Node {
Expand Down
69 changes: 69 additions & 0 deletions next/sources/gmachine/src/part3/ast.mbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
typealias List[E] = @immut/list.T[E]


enum RawExpr[T] {
Var(T)
Num(Int)
Constructor(tag~:Int, arity~:Int) // tag, arity
App(RawExpr[T], RawExpr[T])
Let(Bool, List[(T, RawExpr[T])], RawExpr[T]) // isRec, Defs, Body
Case(RawExpr[T], List[(Int, List[T], RawExpr[T])])
} derive(Show)

struct ScDef[T] {
name : String
args : List[T]
body : RawExpr[T]
} derive(Show)

fn is_atom[T](self : RawExpr[T]) -> Bool {
match self {
Var(_) => true
Num(_) => true
_ => false
}
}

fn ScDef::new[T](
name : String,
args : List[T],
body : RawExpr[T]
) -> ScDef[T] {
{ name : name, args : args, body : body }
}

let prelude_defs : List[ScDef[String]] = {
let args : (FixedArray[String]) -> List[String] = List::of
let id = ScDef::new("I", args(["x"]), Var("x")) // id x = x
let k =
ScDef::new(
"K",
args(["x", "y"]),
Var("x")
) // K x y = x
let k1 =
ScDef::new(
"K1",
args(["x", "y"]),
Var("y")
) // K1 x y = y
let s =
ScDef::new(
"S",
args(["f", "g", "x"]),
App(App(Var("f"), Var("x")), App(Var("g"), Var("x")))
) // S f g x = f x (g x)
let compose =
ScDef::new(
"compose",
args(["f", "g", "x"]),
App(Var("f"), App(Var("g"), Var("x")))
) // compose f g x = f (g x)
let twice =
ScDef::new(
"twice",
args(["f"]),
App(App(Var("compose"), Var("f")), Var("f"))
) // twice f = compose f f
List::of([id, k, k1, s, compose, twice])
}
Loading

0 comments on commit 2ae83af

Please sign in to comment.