prepare types for two-pass implementation

This commit is contained in:
numzero 2025-04-19 11:36:14 +03:00
parent 4ab81edda1
commit c42a7b2251
2 changed files with 80 additions and 0 deletions

View File

@ -1,4 +1,5 @@
pub mod ast; pub mod ast;
pub mod run; pub mod run;
pub mod scope; pub mod scope;
pub mod twopass;
pub mod types; pub mod types;

79
src/twopass.rs Normal file
View File

@ -0,0 +1,79 @@
use std::collections::HashMap;
use crate::ast;
#[derive(Debug, Clone)]
pub struct Function {
name: Option<ast::Ident>,
args: Vec<ast::Ident>,
locals: Vec<ast::Ident>,
upvalues: Vec<(ast::Ident, Ident)>,
body: Vec<Statement>,
ret: Box<Expression>,
}
#[derive(Debug, Clone, Copy)]
enum Ident {
Upvalue(usize),
Local(usize),
Argument(usize),
}
#[derive(Debug, Clone)]
enum Statement {
Assign {
target: Location,
source: Box<Expression>,
},
Call(Call),
}
#[derive(Debug, Clone)]
enum Location {
Variable {
name: Ident,
},
Field {
table: Box<Location>,
index: Box<Expression>,
},
}
#[derive(Debug, Clone)]
enum Expression {
Constant(ast::Constant),
Variable(Location),
Call(Call),
Function(Function),
}
#[derive(Debug, Clone)]
struct Call {
callee: Location,
args: Vec<Expression>,
}
#[derive(Debug)]
struct BuildContext<'a> {
parent: Option<&'a mut BuildContext<'a>>,
upvalues: Vec<(ast::Ident, Ident)>,
scope: HashMap<ast::Ident, Ident>,
}
impl BuildContext<'_> {
fn request(&mut self, name: &ast::Ident) -> Option<Ident> {
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!()
}