diff --git a/src/lib.rs b/src/lib.rs index 7615628..0253397 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ pub mod ast; pub mod run; pub mod scope; +pub mod twopass; pub mod types; diff --git a/src/twopass.rs b/src/twopass.rs new file mode 100644 index 0000000..18f85ea --- /dev/null +++ b/src/twopass.rs @@ -0,0 +1,79 @@ +use std::collections::HashMap; + +use crate::ast; + +#[derive(Debug, Clone)] +pub struct Function { + name: Option, + args: Vec, + locals: Vec, + upvalues: Vec<(ast::Ident, Ident)>, + body: Vec, + ret: Box, +} + +#[derive(Debug, Clone, Copy)] +enum Ident { + Upvalue(usize), + Local(usize), + Argument(usize), +} + +#[derive(Debug, Clone)] +enum Statement { + Assign { + target: Location, + source: Box, + }, + Call(Call), +} + +#[derive(Debug, Clone)] +enum Location { + Variable { + name: Ident, + }, + Field { + table: Box, + index: Box, + }, +} + +#[derive(Debug, Clone)] +enum Expression { + Constant(ast::Constant), + Variable(Location), + Call(Call), + Function(Function), +} + +#[derive(Debug, Clone)] +struct Call { + callee: Location, + args: Vec, +} + +#[derive(Debug)] +struct BuildContext<'a> { + parent: Option<&'a mut BuildContext<'a>>, + upvalues: Vec<(ast::Ident, Ident)>, + scope: HashMap, +} + +impl BuildContext<'_> { + fn request(&mut self, name: &ast::Ident) -> Option { + if let Some(ident) = self.scope.get(name) { + return Some(*ident); + } + if let Some(ident) = self.parent.as_mut()?.request(name) { + let index = self.upvalues.len(); + self.upvalues.push((name.clone(), ident)); + return Some(Ident::Upvalue(index)); + } + None + } +} + +pub fn build(code: ast::Function) -> Function { + todo!() +}