Skip to content

Commit

Permalink
Fix visit_cnts. Add factorial test case. Make parsing deterministic (…
Browse files Browse the repository at this point in the history
…use tree map for functions and continuations).
  • Loading branch information
gsps committed Jun 8, 2020
1 parent 8387fcb commit a0bfd2d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 10 deletions.
12 changes: 6 additions & 6 deletions src/l3/ast.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#![allow(non_snake_case, dead_code)]

use std::collections::{HashMap, HashSet};
use std::collections::{BTreeMap, HashSet};
use std::hash::Hash;
pub use std::rc::Rc;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Name<'a>(pub &'a str);

type BlockTag = u8;
Expand Down Expand Up @@ -101,15 +101,15 @@ pub enum Tree<'a> {

#[derive(Debug)]
pub struct Symbols<'a> {
cnts: HashMap<Name<'a>, Rc<Cnt<'a>>>,
funs: HashMap<Name<'a>, Rc<Fun<'a>>>,
cnts: BTreeMap<Name<'a>, Rc<Cnt<'a>>>,
funs: BTreeMap<Name<'a>, Rc<Fun<'a>>>,
}

impl<'a> Symbols<'a> {
fn new() -> Self {
Self {
cnts: HashMap::new(),
funs: HashMap::new(),
cnts: BTreeMap::new(),
funs: BTreeMap::new(),
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/l3/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,17 @@ impl<'a, 'ctx> Codegen<'a, 'ctx> {
let fun = fun.as_ref();

// Visit all continuations bound in `tree`
fn visit_cnts<'a, F: FnMut(Rc<Cnt<'a>>) -> ()>(tree: &Tree<'a>, mut f: F) -> () {
fn visit_cnts<'a, F: FnMut(Rc<Cnt<'a>>) -> ()>(tree: &Tree<'a>, f: &mut F) -> () {
match tree {
LetC { cnts, body } => {
for cnt in cnts {
f(cnt.clone());
visit_cnts(&cnt.body, f);
}
visit_cnts(body, f)
}
LetF { .. } => unreachable!(),
LetP { body, .. } => visit_cnts(body, f),
_ => (),
}
}
Expand Down Expand Up @@ -235,7 +237,7 @@ impl<'a, 'ctx> Codegen<'a, 'ctx> {
CPSId => next_arg(),
CPSByteRead => self.emit_call("rt_byteread", &[], "cpsbyteread"),
CPSByteWrite => self.emit_call("rt_bytewrite", &[next_arg().into()], "cpsbytewrite"),
_ => unreachable!(),
_ => unimplemented!(),
};
self.builder.build_store(*var, result);
},
Expand Down Expand Up @@ -339,7 +341,7 @@ impl<'a, 'ctx> Codegen<'a, 'ctx> {
state.add_vars_for_locals(&fun.body);

// Allocate continuation parameters and locals, register continuations
visit_cnts(&fun.body, |cnt| {
visit_cnts(&fun.body, &mut |cnt| {
for param_name in &cnt.params {
state.add_var(param_name);
}
Expand All @@ -358,7 +360,7 @@ impl<'a, 'ctx> Codegen<'a, 'ctx> {
state.emit_block(&fun.body);

// Emit one basic block per continuation
visit_cnts(&fun.body, |cnt| {
visit_cnts(&fun.body, &mut |cnt| {
let block = state.blocks.get(&cnt.name).unwrap();
state.builder.position_at_end(*block);
state.emit_block(&cnt.body);
Expand Down
40 changes: 40 additions & 0 deletions src/tests/run_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,43 @@ test_run!(
Some("+"),
43
);
test_run!(
test_fact_example,
"\
(let* ((fact_1
(fun (ret-fact x)
(let* ((then_1 (cnt () (ret-fact 3)))
(else_1
(cnt ()
(let* ((v_9 (@- x 2))
(rc_1
(cnt (r_2)
(let* ((x_2 (@xor x 1))
(r_3 (@shift-right r_2 1))
(x_1 (@* x_2 r_3))
(v_10 (@xor x_1 1)))
(ret-fact v_10)))))
(fact_1 rc_1 v_9)))))
(if (@= 1 x) then_1 else_1))))
(t_1 (@id 5))
(t (@shift-left t_1 1))
(v (@xor t 1))
(then (cnt () (let ((v_8 (@byte-write -54))) (halt 0))))
(else
(cnt ()
(let* ((v_1 (@- v 2))
(rc
(cnt (r)
(let* ((v_6 (@xor v 1))
(r_1 (@shift-right r 1))
(v_5 (@* v_6 r_1))
(v_4 (@xor v_5 1))
(v_3 (@- v_4 110))
(v_2 (@shift-right v_3 1))
(v_7 (@byte-write v_2)))
(halt 0)))))
(fact_1 rc v_1)))))
(if (@= 1 v) then else))",
Some("A"), // fact(5) - 55 = 65
0
);

0 comments on commit a0bfd2d

Please sign in to comment.