Add function compilation

Functions are compiled in the most naiive way right now. I want to fix
up how scope lookups are done before it becomes too much to update.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-09-26 18:31:23 -07:00
parent 3976b2135a
commit 4848a342f0
7 changed files with 53 additions and 21 deletions

View File

@@ -4,13 +4,13 @@ mod locals;
pub mod thunk;
use crate::{syn::ast::Body, obj::prelude::*, vm::{consts::*, package::Package}};
use std::collections::{BTreeMap, HashMap};
use std::collections::HashMap;
#[derive(Default)]
pub struct Compile {
const_data: ConstData,
globals: BTreeMap<Sym, Name>,
scope: Vec<BTreeMap<Sym, Name>>,
globals: Locals,
scope: Vec<Locals>,
names: Vec<Sym>,
next_local: Name,
}
@@ -50,10 +50,12 @@ impl Compile {
self.const_data_mut().const_str(s)
}
/// Inserts a constant object without deduplication.
pub fn push_const(&mut self, obj: ObjRef) -> (ConstHandle, ObjRef) {
self.const_data_mut().push(obj)
}
/// Looks up a variable name.
///
/// This will search up the locals stack until the given name is found, ultimately ending with
/// a global name lookup.
pub fn lookup_scope(&mut self, sym: Sym) -> Option<Name> {
self.scope
.iter()
@@ -109,7 +111,7 @@ impl Compile {
}
/// Pops a scope layer of local variables, if any are available.
pub(crate) fn pop_scope_layer(&mut self) -> Option<BTreeMap<Sym, Name>> {
pub(crate) fn pop_scope_layer(&mut self) -> Option<Locals> {
self.scope.pop()
}
@@ -136,7 +138,7 @@ impl ConstData {
pair.clone()
} else {
let obj = Int::new_obj(int);
let hdl = self.const_pool.push(obj.clone());
let (hdl, _) = self.push(obj.clone());
self.ints.insert(int, (hdl, obj.clone()));
(hdl, obj)
}
@@ -149,9 +151,18 @@ impl ConstData {
pair.clone()
} else {
let obj = Str::new_obj(s.to_string());
let hdl = self.const_pool.push(obj.clone());
let (hdl, _) = self.push(obj.clone());
self.strs.insert(s.to_string(), (hdl, obj.clone()));
(hdl, obj)
}
}
/// Inserts a user-defined function constant object.
///
/// This function provides no de-duplication. Use `const_str` or `const_int` for objects that
/// may be repeated.
pub fn push(&mut self, obj: ObjRef) -> (ConstHandle, ObjRef) {
let hdl = self.const_pool.push(obj.clone());
(hdl, obj)
}
}