WIP trait Eval
This commit is contained in:
parent
f3ae2b8461
commit
ad2044b81d
|
|
@ -1,4 +1,4 @@
|
|||
use std::cell::RefCell;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use crate::{ast, types};
|
||||
|
||||
|
|
@ -241,6 +241,92 @@ pub fn build(code: &ast::Function) -> OpenFunction {
|
|||
OpenFunction(build_function(&BuildContext::new_toplevel(), &code))
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Variable(RefCell<types::Value>);
|
||||
|
||||
impl Variable {
|
||||
fn get(&self) -> types::Value {
|
||||
self.0.borrow().clone()
|
||||
}
|
||||
|
||||
fn set(&self, value: types::Value) {
|
||||
*self.0.borrow_mut() = value
|
||||
}
|
||||
}
|
||||
|
||||
type VariableRef = Rc<Variable>;
|
||||
|
||||
struct RunContext {
|
||||
args: Vec<VariableRef>,
|
||||
locals: Vec<VariableRef>,
|
||||
upvalues: Vec<VariableRef>,
|
||||
}
|
||||
|
||||
impl RunContext {
|
||||
fn var(&self, id: Ident) -> VariableRef {
|
||||
Rc::clone(match id {
|
||||
Ident::Upvalue(index) => self
|
||||
.upvalues
|
||||
.get(index)
|
||||
.expect("upvalue index out of bounds"),
|
||||
Ident::Local(index) => self.locals.get(index).expect("local index out of bounds"),
|
||||
Ident::Argument(index) => self.args.get(index).expect("argument index out of bounds"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
trait Eval {
|
||||
fn eval(&self, ctx: &RunContext) -> types::Value;
|
||||
}
|
||||
|
||||
impl Eval for ast::Constant {
|
||||
fn eval(&self, _ctx: &RunContext) -> types::Value {
|
||||
match self {
|
||||
ast::Constant::Nil => None,
|
||||
ast::Constant::Boolean(value) => Some(types::ValueInner::Boolean(*value)),
|
||||
ast::Constant::Number(value) => Some(types::ValueInner::Number(*value)),
|
||||
ast::Constant::String(value) => Some(types::ValueInner::String(value.clone())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eval for Location {
|
||||
fn eval(&self, ctx: &RunContext) -> types::Value {
|
||||
match self {
|
||||
Location::Variable { id } => todo!(),
|
||||
Location::Field { table, index } => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eval for Call {
|
||||
fn eval(&self, ctx: &RunContext) -> types::Value {
|
||||
let callee = self.callee.eval(ctx);
|
||||
let args: Vec<_> = self.args.iter().map(|arg| arg.eval(ctx)).collect();
|
||||
let Some(types::ValueInner::Function(f)) = callee else {
|
||||
panic!("attempt to call a non-function");
|
||||
};
|
||||
f.call(&args)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eval for Function {
|
||||
fn eval(&self, ctx: &RunContext) -> types::Value {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Eval for Expression {
|
||||
fn eval(&self, ctx: &RunContext) -> types::Value {
|
||||
match self {
|
||||
Expression::Constant(inner) => inner.eval(ctx),
|
||||
Expression::Variable(inner) => inner.eval(ctx),
|
||||
Expression::Call(inner) => inner.eval(ctx),
|
||||
Expression::Function(inner) => inner.eval(ctx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Function {
|
||||
fn call(&self, upvalues: &[types::Value], args: &[types::Value]) -> types::Value {
|
||||
assert_eq!(upvalues.len(), self.upvalues.len());
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user