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};
|
use crate::{ast, types};
|
||||||
|
|
||||||
|
|
@ -241,6 +241,92 @@ pub fn build(code: &ast::Function) -> OpenFunction {
|
||||||
OpenFunction(build_function(&BuildContext::new_toplevel(), &code))
|
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 {
|
impl Function {
|
||||||
fn call(&self, upvalues: &[types::Value], args: &[types::Value]) -> types::Value {
|
fn call(&self, upvalues: &[types::Value], args: &[types::Value]) -> types::Value {
|
||||||
assert_eq!(upvalues.len(), self.upvalues.len());
|
assert_eq!(upvalues.len(), self.upvalues.len());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user