Skip to content

Commit

Permalink
implement closureps interpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
glyh committed Oct 7, 2024
1 parent 5807a5c commit 9db18fc
Show file tree
Hide file tree
Showing 16 changed files with 471 additions and 255 deletions.
11 changes: 11 additions & 0 deletions notes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## Call Convention
1. We use `ra` to store the continuation address, as it's otherwise unused in our language. We do need to push it onto stack to preserve it's value when doing a native call, though.
2. We store `closure` pointer after any arguments, so we should be able to work with native functions just fine. This differs from what is being done in the book "Compiling with Continuations".

## TODO
1. fix call convention for external functions. For example:
```
:print_int([?26, kont_main.4.22])
```
Inside print_int, we should do something like this:
```
fn_ptr.99 = kont_main.4.22.0
fn_ptr.99([result, kont_main.4.22])
```
135 changes: 25 additions & 110 deletions src/bin/externals.mbt
Original file line number Diff line number Diff line change
@@ -1,185 +1,100 @@
fn add_interpreter_fns(interpreter : @knf_eval.KnfInterpreter) -> Unit {
fn add_clops_interp_fns(interpreter : @closureps_eval.CloPSInterpreter) -> Unit {
interpreter.add_extern_fn(
"minimbt_print_int",
"print_int",
fn(args) {
match args[0] {
Int(i) => @io.print(i)
_ => @util.die("print_int expects Int")
}
Unit
},
1,
)
interpreter.add_extern_fn(
"minimbt_print_endline",
"print_endline",
fn(_args) {
@io.print("\n")
Unit
},
0,
)
let create_array = fn(args : Array[@knf_eval.Value]) {
let create_array = fn(args : Array[@closureps_eval.Value]) {
match args[0] {
Int(n) => @knf_eval.Value::Array(Array::make(n, args[1]))
Int(n) => @closureps_eval.Value::Array(Array::make(n, args[1]))
_ => @util.die("create_array expects Int")
}
}
interpreter.add_extern_fn("minimbt_create_array", create_array)
interpreter.add_extern_fn("minimbt_create_float_array", create_array)
interpreter.add_extern_fn("minimbt_create_ptr_array", create_array)
interpreter.add_extern_fn("create_array", create_array, 2)
interpreter.add_extern_fn("create_float_array", create_array, 2)
interpreter.add_extern_fn("create_ptr_array", create_array, 2)
interpreter.add_extern_fn(
"minimbt_truncate",
"truncate",
fn(args) {
match args[0] {
Double(d) => Int(d.to_int())
_ => @util.die("truncate expects Double")
_ => @util.die("expects Double")
}
},
1,
)
interpreter.add_extern_fn(
"minimbt_sin",
"sin",
fn(args) {
match args[0] {
Double(d) => Double(@math.sin(d))
_ => @util.die("sin expects Double")
}
},
1,
)
interpreter.add_extern_fn(
"minimbt_cos",
"cos",
fn(args) {
match args[0] {
Double(d) => Double(@math.cos(d))
_ => @util.die("cos expects Double")
}
},
1,
)
interpreter.add_extern_fn(
"minimbt_sqrt",
"sqrt",
fn(args) {
match args[0] {
Double(d) => Double(d.sqrt())
_ => @util.die("sqrt expects Double")
}
},
1,
)
interpreter.add_extern_fn(
"minimbt_abs_float",
"abs_float",
fn(args) {
match args[0] {
Double(d) => Double(@double.abs(d))
_ => @util.die("abs_float expects Double")
}
},
1,
)
interpreter.add_extern_fn(
"minimbt_int_of_float",
"int_of_float",
fn(args) {
match args[0] {
Double(d) => Int(d.to_int())
_ => @util.die("int_of_float expects Double")
}
},
1,
)
interpreter.add_extern_fn(
"minimbt_float_of_int",
fn(args) {
match args[0] {
Int(i) => Double(i.to_double())
_ => @util.die("float_of_int expects Int")
}
},
)
}

fn add_closure_interpreter_fns(
interpreter : @closure_eval.ClosureInterpreter
) -> Unit {
interpreter.add_extern_fn(
"minimbt_print_int",
fn(args) {
match args[0] {
Int(i) => @io.print(i)
_ => @util.die("print_int expects Int")
}
Unit
},
)
interpreter.add_extern_fn(
"minimbt_print_endline",
fn(_args) {
@io.print("\n")
Unit
},
)
let create_array = fn(args : Array[@closure_eval.Value]) {
match args[0] {
Int(n) => @closure_eval.Value::Array(Array::make(n, args[1]))
_ => @util.die("create_array expects Int")
}
}
interpreter.add_extern_fn("minimbt_create_array", create_array)
interpreter.add_extern_fn("minimbt_create_float_array", create_array)
interpreter.add_extern_fn("minimbt_create_ptr_array", create_array)
interpreter.add_extern_fn(
"minimbt_truncate",
fn(args) {
match args[0] {
Double(d) => Int(d.to_int())
_ => @util.die("truncate expects Double")
}
},
)
interpreter.add_extern_fn(
"minimbt_sin",
fn(args) {
match args[0] {
Double(d) => Double(@math.sin(d))
_ => @util.die("sin expects Double")
}
},
)
interpreter.add_extern_fn(
"minimbt_cos",
fn(args) {
match args[0] {
Double(d) => Double(@math.cos(d))
_ => @util.die("cos expects Double")
}
},
)
interpreter.add_extern_fn(
"minimbt_sqrt",
fn(args) {
match args[0] {
Double(d) => Double(d.sqrt())
_ => @util.die("sqrt expects Double")
}
},
)
interpreter.add_extern_fn(
"minimbt_abs_float",
fn(args) {
match args[0] {
Double(d) => Double(@double.abs(d))
_ => @util.die("abs_float expects Double")
}
},
)
interpreter.add_extern_fn(
"minimbt_int_of_float",
fn(args) {
match args[0] {
Double(d) => Int(d.to_int())
_ => @util.die("int_of_float expects Double")
}
},
)
interpreter.add_extern_fn(
"minimbt_float_of_int",
"float_of_int",
fn(args) {
match args[0] {
Int(i) => Double(i.to_double())
_ => @util.die("float_of_int expects Int")
}
},
1,
)
}
96 changes: 22 additions & 74 deletions src/bin/main.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ fn CompileStatus::step(self : CompileStatus) -> Bool {
}
Cps => {
let cpsenv = @cps.CpsEnv::new(self.counter)
let mut cps = cpsenv.precps2cps(self.precps.unwrap(), @cps.Cps::Just)
let mut cps = cpsenv.precps2cps(self.precps.unwrap(), fn { _ => Exit })
cps = @cps.alias_analysis(cps)
self.cps = Some(cps)
self.counter = cpsenv.counter.val
Expand Down Expand Up @@ -152,15 +152,12 @@ fn CompileStatus::output(self : CompileStatus, json : Bool) -> String {
fn main {
let argv = @env.get_args()
let mut file = None
let knf_opt_iters = Ref::new(10)
let knf_opt_inline_threshold = Ref::new(10)

// Testing directives
let json = Ref::new(false)
let start_stage = Ref::new(Stages::Parse)
let end_stage = Ref::new(Stages::Finished)
let knf_interpreter = Ref::new(false)
let closure_interpreter = Ref::new(false)
let closureps_interpreter = Ref::new(false)
let out_file = Ref::new("-")
let print = Ref::new([])

Expand Down Expand Up @@ -194,16 +191,10 @@ fn main {
"End stage",
),
(
"--knf-interpreter",
"--clops-interp",
"",
@ArgParser.Set(knf_interpreter),
"Run with KNF interpreter",
),
(
"--closure-interpreter",
"",
@ArgParser.Set(closure_interpreter),
"Run with closure interpreter",
@ArgParser.Set(closureps_interpreter),
"Run with closure passing style interpreter",
),
(
"--out-file",
Expand All @@ -220,34 +211,6 @@ fn main {
@ArgParser.String(fn(s) { print.val = s.split(",").collect() }),
"",
),
(
"--knf-opt-iters",
"N",
@ArgParser.String(
fn(s) {
let i = @strconv.parse_int?(s)
match i {
Ok(i) => knf_opt_iters.val = i
Err(_) => @util.die("Invalid number")
}
},
),
"Number of optimization iterations",
),
(
"--knf-opt-inline-threshold",
"N",
@ArgParser.String(
fn(s) {
let i = @strconv.parse_int?(s)
match i {
Ok(i) => knf_opt_inline_threshold.val = i
Err(_) => @util.die("Invalid number")
}
},
),
"Inline threshold for KNF optimization",
),
],
fn(s) {
if file.is_empty().not() {
Expand All @@ -260,12 +223,6 @@ fn main {
)

// Configure pipeline
//if knf_interpreter.val {
// end_stage.val = Stages::Knf
//}
//if closure_interpreter.val {
// end_stage.val = Stages::Closure
//}
let stages_to_print = print.val.map(
fn(s) {
match Stages::from_string(s) {
Expand Down Expand Up @@ -308,32 +265,23 @@ fn main {
}

// Output
//if knf_interpreter.val {
// let knfi = @knf_eval.KnfInterpreter::new()
// add_interpreter_fns(knfi)
// match knfi.eval_full?(status.knf.unwrap()) {
// Ok(_) => ()
// Err(Failure(e)) => {
// println(e)
// @util.die("KNF interpreter error")
// }
// }
//} else if closure_interpreter.val {
// let clsi = @closure_eval.ClosureInterpreter::new()
// add_closure_interpreter_fns(clsi)
// match clsi.eval_full?(status.closure_ir.unwrap()) {
// Ok(_) => ()
// Err(Failure(e)) => {
// println(e)
// @util.die("Closure interpreter error")
// }
// }
//} else {
let out_string = status.output(json.val)
if out_file.val == "-" {
println(out_string)
if closureps_interpreter.val {
let clops = status.clops.unwrap()
let interpreter = @closureps_eval.CloPSInterpreter::new(clops)
add_clops_interp_fns(interpreter)
try {
interpreter.eval!(clops.root)
} catch {
VariableNotFind(v) => println("Undefined variable: \{v}")
} else {
v => ignore(v)
}
} else {
@fs.write_to_string(out_file.val, out_string)
let out_string = status.output(json.val)
if out_file.val == "-" {
println(out_string)
} else {
@fs.write_to_string(out_file.val, out_string)
}
}
//}
}
1 change: 1 addition & 0 deletions src/bin/moon.pkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"moonbitlang/minimbt/knf",
"moonbitlang/minimbt/typing",
"moonbitlang/minimbt/knf_eval",
"moonbitlang/minimbt/closureps_eval",
"lijunchen/unstable_io/io",
"moonbitlang/minimbt/closure",
"moonbitlang/minimbt/riscv",
Expand Down
Loading

0 comments on commit 9db18fc

Please sign in to comment.