ugh, variance...
This commit is contained in:
parent
c42a7b2251
commit
6c1e6d6bfa
|
|
@ -1,4 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
use std::{cell::RefCell, collections::HashMap};
|
||||
|
||||
use crate::ast;
|
||||
|
||||
|
|
@ -53,27 +53,62 @@ struct Call {
|
|||
args: Vec<Expression>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct BuildContext<'a> {
|
||||
parent: Option<&'a mut BuildContext<'a>>,
|
||||
#[derive(Debug, Clone, Default)]
|
||||
struct Scope {
|
||||
upvalues: Vec<(ast::Ident, Ident)>,
|
||||
scope: HashMap<ast::Ident, Ident>,
|
||||
}
|
||||
|
||||
impl Scope {
|
||||
fn new_toplevel() -> Self {
|
||||
Self {
|
||||
upvalues: vec![("_ENV".to_string(), Ident::Local(0))],
|
||||
scope: [("_ENV".to_string(), Ident::Upvalue(0))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct BuildContext<'a> {
|
||||
parent: Option<&'a BuildContext<'a>>, // mustn't be &mut because of variance
|
||||
scope: RefCell<Scope>,
|
||||
}
|
||||
|
||||
impl BuildContext<'_> {
|
||||
fn request(&mut self, name: &ast::Ident) -> Option<Ident> {
|
||||
if let Some(ident) = self.scope.get(name) {
|
||||
fn request(&self, name: &ast::Ident) -> Option<Ident> {
|
||||
let mut scope = self.scope.borrow_mut();
|
||||
if let Some(ident) = scope.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));
|
||||
if let Some(ident) = self.parent.as_ref()?.request(name) {
|
||||
let index = scope.upvalues.len();
|
||||
scope.upvalues.push((name.clone(), ident));
|
||||
let ident = Ident::Upvalue(index);
|
||||
scope.scope.insert(name.clone(), ident);
|
||||
return Some(ident);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build(code: ast::Function) -> Function {
|
||||
fn build_in_scope(parent: &BuildContext<'_>, code: ast::Function) -> Function {
|
||||
let scope = BuildContext {
|
||||
parent: Some(parent),
|
||||
scope: Default::default(),
|
||||
};
|
||||
if false {
|
||||
build_in_scope(&scope, code.clone());
|
||||
build_in_scope(&scope, code.clone());
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn build(code: ast::Function) -> Function {
|
||||
let mut root = BuildContext {
|
||||
parent: None,
|
||||
scope: RefCell::new(Scope::new_toplevel()),
|
||||
};
|
||||
build_in_scope(&mut root, code)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user