Add instruction dumper
A vector of instructions and constants can now be decompiled as text on the terminal to give an idea of what the VM is doing. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -11,6 +11,7 @@ pub struct Compile {
|
||||
const_data: ConstData,
|
||||
globals: BTreeMap<Sym, Local>,
|
||||
locals: Vec<BTreeMap<Sym, Local>>,
|
||||
names: Vec<Sym>,
|
||||
next_local: Local,
|
||||
}
|
||||
|
||||
@@ -63,6 +64,15 @@ impl Compile {
|
||||
.copied()
|
||||
}
|
||||
|
||||
/// Looks up a variable name, or creates a global name if it doesn't exist.
|
||||
pub fn lookup_scope_or_create_global(&mut self, sym: Sym) -> Local {
|
||||
if let Some(local) = self.lookup_scope(sym) {
|
||||
local
|
||||
} else {
|
||||
self.create_global(sym)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new local variable if it does not exist in the current local scope.
|
||||
pub(crate) fn create_local(&mut self, sym: Sym) -> Local {
|
||||
let locals = self.locals.last_mut().expect("scope");
|
||||
@@ -73,6 +83,8 @@ impl Compile {
|
||||
let local = self.next_local;
|
||||
self.next_local = self.next_local.next();
|
||||
locals.insert(sym, local);
|
||||
self.names.push(sym);
|
||||
assert_eq!(self.names.len(), self.next_local.index());
|
||||
local
|
||||
}
|
||||
}
|
||||
@@ -85,6 +97,8 @@ impl Compile {
|
||||
let global = self.next_local;
|
||||
self.next_local = self.next_local.next();
|
||||
self.globals.insert(sym, global);
|
||||
self.names.push(sym);
|
||||
assert_eq!(self.names.len(), self.next_local.index());
|
||||
global
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user