Skip to content

Commit

Permalink
add inspect instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
tiye committed Jan 16, 2024
1 parent 8274366 commit 48c23d9
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 6 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ Calx Binary Edition `0.1`:
| `return` | | TODO |
| `fn $types $body` | | Global definition |
| `assert` | `quit(1)` if not `true` | for testing |
| `inspect | println inspection information | |

For `$types`, it can be `($t1 $t2 -> $t3 $t4)`, where supported types are:

Expand All @@ -146,6 +147,17 @@ For `$types`, it can be `($t1 $t2 -> $t3 $t4)`, where supported types are:
- list _TODO_
- link _TODO_

### Preprocess

Before Calx running the instructions, Calx performs preprocessing to them. There are several tasks:

- `block` and `loop` are expanded since there are `block-end` instructions
- `br` and `br-if` also expanded to `jmp` and `jmp-if` instructions, internally
- stack size is checked to ensure it's consistent among branches, and tidied up at function end
- local variables are renamed to indexes

these steps simplies debugging, although it's sure that's good features.

### License

MIT
3 changes: 3 additions & 0 deletions demos/named.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ fn f-add (($a i64) ($b i64) -> i64)
local.get $b
local.get $c
dup

inspect

echo
return

Expand Down
5 changes: 3 additions & 2 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ pub fn parse_function(nodes: &[Cirru]) -> Result<CalxFunc, String> {
}

Ok(CalxFunc {
name: name.to_string(),
params_types,
name: Rc::new(name.to_string()),
params_types: params_types.into(),
ret_types: Rc::new(ret_types),
local_names: Rc::new(locals_collector.locals),
instrs: Rc::new(body),
Expand Down Expand Up @@ -259,6 +259,7 @@ pub fn parse_instr(ptr_base: usize, node: &Cirru, collector: &mut LocalsCollecto

Ok(vec![CalxInstr::Assert((*message).to_owned())])
}
"inspect" => Ok(vec![CalxInstr::Inspect]),
_ => Err(format!("unknown instruction: {}", name)),
},
}
Expand Down
12 changes: 9 additions & 3 deletions src/primes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ impl fmt::Display for Calx {

#[derive(Debug, Clone, PartialEq, PartialOrd, Encode, Decode)]
pub struct CalxFunc {
pub name: String,
pub params_types: Vec<CalxType>,
pub name: Rc<String>,
pub params_types: Rc<Vec<CalxType>>,
pub ret_types: Rc<Vec<CalxType>>,
pub instrs: Rc<Vec<CalxInstr>>,
pub local_names: Rc<Vec<String>>,
Expand All @@ -83,7 +83,7 @@ pub struct CalxFunc {
impl fmt::Display for CalxFunc {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "CalxFunc {} (", self.name)?;
for p in &self.params_types {
for p in &*self.params_types {
write!(f, "{:?} ", p)?;
}
f.write_str("-> ")?;
Expand Down Expand Up @@ -182,6 +182,8 @@ pub enum CalxInstr {
Return,
/// TODO might also be a foreign function instead
Assert(String),
/// inspecting stack
Inspect,
}

impl CalxInstr {
Expand Down Expand Up @@ -242,6 +244,8 @@ impl CalxInstr {
CalxInstr::Quit(_) => (0, 0),
CalxInstr::Return => (0, 0), // TODO
CalxInstr::Assert(_) => (1, 0),
// debug
CalxInstr::Inspect => (0, 0),
}
}
}
Expand Down Expand Up @@ -292,6 +296,7 @@ impl BlockData {

#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct CalxFrame {
pub name: Rc<String>,
pub locals: Vec<Calx>, // params + added locals
/** store return values */
pub instrs: Rc<Vec<CalxInstr>>,
Expand All @@ -304,6 +309,7 @@ pub struct CalxFrame {
impl Default for CalxFrame {
fn default() -> Self {
CalxFrame {
name: String::from("<zero>").into(),
locals: vec![],
instrs: Rc::new(vec![]),
pointer: 0,
Expand Down
25 changes: 24 additions & 1 deletion src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ impl CalxVM {
pub fn new(fns: Vec<CalxFunc>, globals: Vec<Calx>, imports: CalxImportsDict) -> Self {
let main_func = find_func(&fns, "main").expect("main function is required");
let main_frame = CalxFrame {
name: main_func.name.to_owned(),
initial_stack_size: 0,
blocks_track: vec![],
instrs: main_func.instrs.clone(),
Expand Down Expand Up @@ -399,13 +400,15 @@ impl CalxVM {
Some(f) => {
let instrs = f.instrs.to_owned();
let ret_types = f.ret_types.to_owned();
let f_name = f.name.to_owned();
let mut locals: Vec<Calx> = vec![];
for _ in 0..f.params_types.len() {
let v = self.stack_pop()?;
locals.insert(0, v);
}
self.frames.push(self.top_frame.to_owned());
self.top_frame = CalxFrame {
name: f_name,
blocks_track: vec![],
initial_stack_size: self.stack.len(),
locals,
Expand All @@ -427,6 +430,7 @@ impl CalxVM {
// println!("examine stack: {:?}", self.stack);
let instrs = f.instrs.to_owned();
let ret_types = f.ret_types.to_owned();
let f_name = f.name.to_owned();
let mut locals: Vec<Calx> = vec![];
for _ in 0..f.params_types.len() {
let v = self.stack_pop()?;
Expand All @@ -441,6 +445,7 @@ impl CalxVM {
)));
}
self.top_frame = CalxFrame {
name: f_name,
blocks_track: vec![],
initial_stack_size: self.stack.len(),
locals,
Expand Down Expand Up @@ -494,6 +499,24 @@ impl CalxVM {
return Err(self.gen_err(format!("Failed assertion: {}", message)));
}
}
CalxInstr::Inspect => {
println!("[ ----------------");
println!(
" Internal frames: {:?}",
self.frames.iter().map(|x| x.name.to_owned()).collect::<Vec<_>>()
);
println!(" Top frame: {}", self.top_frame.name);
println!(" Locals: {:?}", self.top_frame.locals);
println!(" Blocks: {:?}", self.top_frame.blocks_track);
println!(" Stack({}): {:?}", self.stack.len(), self.stack);
println!(
" Sizes: {} + {}",
self.top_frame.initial_stack_size,
self.top_frame.ret_types.len()
);
println!(" Pointer: {}", self.top_frame.pointer);
println!(" -------------- ]");
}
}

self.top_frame.pointer += 1;
Expand Down Expand Up @@ -747,5 +770,5 @@ impl CalxVM {
}

pub fn find_func<'a>(funcs: &'a [CalxFunc], name: &str) -> Option<&'a CalxFunc> {
funcs.iter().find(|x| &*x.name == name)
funcs.iter().find(|x| *x.name == name)
}

0 comments on commit 48c23d9

Please sign in to comment.