This commit is contained in:
2025-08-05 21:51:03 +08:00
parent 7afb2a7b1c
commit 64f650b695
12 changed files with 288 additions and 86 deletions

View File

@@ -24,7 +24,9 @@ pub trait EvalContext: Sized {
f: impl FnOnce(&mut Self) -> T,
) -> (Vec<Value<Self>>, T);
fn lookup_with<'a>(&'a self, ident: &str) -> Option<&'a Value<Self>>;
fn lookup_arg<'a>(&'a self, offset: usize) -> Option<&'a Value<Self>>;
fn pop_frame(&mut self) -> Vec<Value<Self>>;
fn consume_arg(&mut self, func: ExprId) -> Result<bool>;
}
pub trait Evaluate<Ctx: EvalContext> {
@@ -39,7 +41,38 @@ impl<Ctx: EvalContext> Evaluate<Ctx> for ExprId {
impl<Ctx: EvalContext> Evaluate<Ctx> for lir::Lir {
fn eval(&self, ctx: &mut Ctx) -> Result<Value<Ctx>> {
todo!()
use lir::Lir::*;
match self {
AttrSet(x) => x.eval(ctx),
List(x) => x.eval(ctx),
HasAttr(x) => x.eval(ctx),
BinOp(x) => x.eval(ctx),
UnOp(x) => x.eval(ctx),
Select(x) => x.eval(ctx),
If(x) => x.eval(ctx),
Call(x) => x.eval(ctx),
With(x) => x.eval(ctx),
Assert(x) => x.eval(ctx),
ConcatStrings(x) => x.eval(ctx),
Const(x) => x.eval(ctx),
Str(x) => x.eval(ctx),
Var(x) => x.eval(ctx),
Path(x) => x.eval(ctx),
ExprRef(expr) => expr.eval(ctx),
&FuncRef(func) => {
if ctx.consume_arg(func)? {
ctx.eval(func)
} else {
Ok(Value::Func(func))
}
},
&ArgRef(arg) => {
let idx: usize = unsafe { core::mem::transmute(arg) };
ctx.lookup_arg(idx)
.cloned()
.ok_or_else(|| Error::EvalError("argument not found".to_string()))
}
}
}
}
@@ -243,7 +276,15 @@ impl<Ctx: EvalContext> Evaluate<Ctx> for ir::With {
impl<Ctx: EvalContext> Evaluate<Ctx> for ir::Assert {
fn eval(&self, ctx: &mut Ctx) -> Result<Value<Ctx>> {
todo!()
let cond = self.assertion.eval(ctx)?;
let cond = cond
.try_unwrap_bool()
.map_err(|_| Error::EvalError(format!("expected a boolean but found ...")))?;
if cond {
self.expr.eval(ctx)
} else {
Err(Error::EvalError("assertion failed".to_string()))
}
}
}

View File

@@ -142,7 +142,7 @@ impl<Ctx: EvalContext> PartialEq for Value<Ctx> {
impl<Ctx: EvalContext> Eq for Value<Ctx> {}
#[derive(IsVariant, Unwrap, Clone)]
#[derive(IsVariant, TryUnwrap, Unwrap, Clone)]
pub enum ValueAsRef<'v, Ctx: EvalContext> {
Int(i64),
Float(f64),