fix: PartialFunc
This commit is contained in:
148
src/eval/mod.rs
148
src/eval/mod.rs
@@ -19,27 +19,35 @@ impl Evaluate for ir::Attrs {
|
||||
let mut attrs = AttrSet::new(
|
||||
self.stcs
|
||||
.iter()
|
||||
.map(|(k, v)| Ok((k.clone(), v.eval(engine, env)?)))
|
||||
.map(|(k, v)| {
|
||||
let eval_result = v.eval(engine, env);
|
||||
Ok((k.clone(), eval_result?))
|
||||
})
|
||||
.collect::<Result<_>>()?,
|
||||
);
|
||||
for DynAttr(k, v) in self.dyns.iter() {
|
||||
let mut k = k.eval(engine, env)?;
|
||||
k.coerce_to_string();
|
||||
attrs.push_attr(k.unwrap_string(), v.eval(engine, env)?);
|
||||
k.force(engine, env)?.coerce_to_string();
|
||||
let v_eval_result = v.eval(engine, env)?;
|
||||
attrs.push_attr(k.unwrap_string(), v_eval_result);
|
||||
}
|
||||
Value::AttrSet(attrs.into()).ok()
|
||||
let result = Value::AttrSet(attrs.into()).ok();
|
||||
Ok(result.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for ir::List {
|
||||
fn eval(&self, engine: &mut Engine, env: &mut Env) -> Result<Value> {
|
||||
Value::List(List::from(
|
||||
self.items
|
||||
.iter()
|
||||
.map(|val| val.eval(engine, env))
|
||||
.collect::<Result<EcoVec<_>>>()?,
|
||||
))
|
||||
.ok()
|
||||
let items = self
|
||||
.items
|
||||
.iter()
|
||||
.map(|val| {
|
||||
let eval_result = val.eval(engine, env);
|
||||
eval_result
|
||||
})
|
||||
.collect::<Result<EcoVec<_>>>()?;
|
||||
let result = Value::List(List::from(items)).ok();
|
||||
Ok(result.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,18 +55,20 @@ impl Evaluate for ir::HasAttr {
|
||||
fn eval(&self, engine: &mut Engine, env: &mut Env) -> Result<Value> {
|
||||
use ir::Attr::*;
|
||||
let mut val = self.lhs.eval(engine, env)?;
|
||||
val.has_attr(self.rhs.iter().map(|attr| {
|
||||
Ok(match attr {
|
||||
Str(ident) => ident.clone(),
|
||||
Strs(expr) => expr.eval(engine, env)?.unwrap_string(),
|
||||
Dynamic(expr) => {
|
||||
let mut val = expr.eval(engine, env)?;
|
||||
val.coerce_to_string();
|
||||
val.unwrap_string()
|
||||
}
|
||||
})
|
||||
}))?;
|
||||
val.ok()
|
||||
val.force(engine, env)?
|
||||
.has_attr(self.rhs.iter().map(|attr| {
|
||||
Ok(match attr {
|
||||
Str(ident) => ident.clone(),
|
||||
Strs(expr) => expr.eval(engine, env)?.unwrap_string(),
|
||||
Dynamic(expr) => {
|
||||
let mut val = expr.eval(engine, env)?;
|
||||
val.force(engine, env)?.coerce_to_string();
|
||||
val.unwrap_string()
|
||||
}
|
||||
})
|
||||
}))?;
|
||||
let result = val.ok();
|
||||
Ok(result.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +77,8 @@ impl Evaluate for ir::BinOp {
|
||||
use ir::BinOpKind::*;
|
||||
let mut lhs = self.lhs.eval(engine, env)?;
|
||||
let mut rhs = self.rhs.eval(engine, env)?;
|
||||
lhs.force(engine, env)?;
|
||||
rhs.force(engine, env)?;
|
||||
match self.kind {
|
||||
Add => lhs.add(rhs),
|
||||
Sub => {
|
||||
@@ -116,10 +128,15 @@ impl Evaluate for ir::UnOp {
|
||||
fn eval(&self, engine: &mut Engine, env: &mut Env) -> Result<Value> {
|
||||
use ir::UnOpKind::*;
|
||||
let mut rhs = self.rhs.eval(engine, env)?;
|
||||
rhs.force(engine, env)?;
|
||||
match self.kind {
|
||||
Neg => rhs.neg(),
|
||||
Not => rhs.not(),
|
||||
}
|
||||
Neg => {
|
||||
rhs.neg();
|
||||
}
|
||||
Not => {
|
||||
rhs.not();
|
||||
}
|
||||
};
|
||||
Ok(rhs)
|
||||
}
|
||||
}
|
||||
@@ -130,14 +147,14 @@ impl Evaluate for ir::Select {
|
||||
let mut val = self.expr.eval(engine, env)?;
|
||||
if let Some(default) = &self.default {
|
||||
let default = default.eval(engine, env)?;
|
||||
val.select_with_default(
|
||||
val.force(engine, env)?.select_with_default(
|
||||
self.attrpath.iter().map(|attr| {
|
||||
Ok(match attr {
|
||||
Str(ident) => ident.clone(),
|
||||
Strs(expr) => expr.eval(engine, env)?.unwrap_string(),
|
||||
Dynamic(expr) => {
|
||||
let mut val = expr.eval(engine, env)?;
|
||||
val.coerce_to_string();
|
||||
val.force(engine, env)?.coerce_to_string();
|
||||
val.unwrap_string()
|
||||
}
|
||||
})
|
||||
@@ -145,58 +162,60 @@ impl Evaluate for ir::Select {
|
||||
default,
|
||||
)?;
|
||||
} else {
|
||||
val
|
||||
val.force(engine, env)?
|
||||
.select(self.attrpath.iter().map(|attr| {
|
||||
Ok(match attr {
|
||||
Str(ident) => ident.clone(),
|
||||
Strs(expr) => expr.eval(engine, env)?.unwrap_string(),
|
||||
Dynamic(expr) => {
|
||||
let mut val = expr.eval(engine, env)?;
|
||||
val.coerce_to_string();
|
||||
val.force(engine, env)?.coerce_to_string();
|
||||
val.unwrap_string()
|
||||
}
|
||||
})
|
||||
}))?;
|
||||
}
|
||||
val.ok()
|
||||
let result = val.ok();
|
||||
Ok(result.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for ir::If {
|
||||
fn eval(&self, engine: &mut Engine, env: &mut Env) -> Result<Value> {
|
||||
// TODO: Error Handling
|
||||
let cond = self.cond.eval(engine, env)?.unwrap_bool();
|
||||
if cond {
|
||||
let mut cond = self.cond.eval(engine, env)?;
|
||||
cond.force(engine, env)?;
|
||||
let cond = cond.unwrap_bool();
|
||||
let result = if cond {
|
||||
self.consq.eval(engine, env)
|
||||
} else {
|
||||
self.alter.eval(engine, env)
|
||||
}
|
||||
};
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for ir::LoadFunc {
|
||||
fn eval(&self, engine: &mut Engine, env: &mut Env) -> Result<Value> {
|
||||
let idx = engine.func_offset + self.idx;
|
||||
Value::Func(idx).ok()
|
||||
let result = Value::Func(idx).ok();
|
||||
Ok(result.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for ir::Call {
|
||||
fn eval(&self, engine: &mut Engine, env: &mut Env) -> Result<Value> {
|
||||
let mut func = self.func.eval(engine, env)?;
|
||||
func.call(
|
||||
func.force(engine, env)?;
|
||||
let result = func.call(
|
||||
self.args
|
||||
.iter()
|
||||
.map(|arg| arg.eval(engine, env))
|
||||
.collect::<Result<_>>()?,
|
||||
engine,
|
||||
env,
|
||||
)?;
|
||||
// FIXME: Modify Value::call
|
||||
// for arg in self.args {
|
||||
// func.call(arg.eval(engine, env)?, engine, env)?;
|
||||
// }
|
||||
func.ok()
|
||||
);
|
||||
Ok(func.ok().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +227,8 @@ impl Evaluate for ir::Let {
|
||||
|
||||
impl Evaluate for ir::With {
|
||||
fn eval(&self, engine: &mut Engine, env: &mut Env) -> Result<Value> {
|
||||
let namespace = self.namespace.eval(engine, env)?;
|
||||
let mut namespace = self.namespace.eval(engine, env)?;
|
||||
namespace.force(engine, env)?;
|
||||
// TODO: Error Handling
|
||||
env.enter_with(namespace.unwrap_attr_set().into_inner());
|
||||
let ret = self.expr.eval(engine, env);
|
||||
@@ -230,50 +250,56 @@ impl Evaluate for ir::ConcatStrings {
|
||||
.iter()
|
||||
.map(|part| {
|
||||
let mut part = part.eval(engine, env)?;
|
||||
part.coerce_to_string();
|
||||
part.force(engine, env)?.coerce_to_string();
|
||||
part.ok()
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?
|
||||
.into_iter();
|
||||
let init = parts.next().unwrap();
|
||||
parts
|
||||
.fold(init, |mut a, b| {
|
||||
a.concat_string(b);
|
||||
a
|
||||
})
|
||||
.ok()
|
||||
let result = parts.fold(init, |mut a, b| {
|
||||
a.concat_string(b);
|
||||
a
|
||||
});
|
||||
Ok(result.ok().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for ir::String {
|
||||
fn eval(&self, _: &mut Engine, _: &mut Env) -> Result<Value> {
|
||||
Value::String(self.val.clone()).ok()
|
||||
let result = Value::String(self.val.clone()).ok();
|
||||
Ok(result.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for ir::Const {
|
||||
fn eval(&self, _: &mut Engine, _: &mut Env) -> Result<Value> {
|
||||
match self.val {
|
||||
let result = match self.val {
|
||||
Const::Null => Value::Null,
|
||||
Const::Int(x) => Value::Int(x),
|
||||
Const::Float(x) => Value::Float(x),
|
||||
Const::Bool(x) => Value::Bool(x),
|
||||
}
|
||||
.ok()
|
||||
.ok();
|
||||
Ok(result.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for ir::Var {
|
||||
fn eval(&self, _: &mut Engine, env: &mut Env) -> Result<Value> {
|
||||
env.lookup_with(&self.sym).ok_or_else(|| {
|
||||
Error::EvalError(format!("variable {} not found", Symbol::from(self.sym.clone())))
|
||||
})
|
||||
let result = env.lookup_with(&self.sym).ok_or_else(|| {
|
||||
Error::EvalError(format!(
|
||||
"variable {} not found",
|
||||
Symbol::from(self.sym.clone())
|
||||
))
|
||||
});
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for ir::Arg {
|
||||
fn eval(&self, _: &mut Engine, env: &mut Env) -> Result<Value> {
|
||||
env.lookup_arg(self.level).clone().ok()
|
||||
let result = env.lookup_arg(self.level).clone().ok();
|
||||
Ok(result.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,18 +311,18 @@ impl Evaluate for ir::LetVar {
|
||||
|
||||
impl Evaluate for ir::Thunk {
|
||||
fn eval(&self, engine: &mut Engine, env: &mut Env) -> Result<Value> {
|
||||
env.lookup_cache(self.idx, |env| engine.eval_thunk(self.idx, env))
|
||||
// Value::Thunk(self.idx).ok()
|
||||
Value::Thunk(self.idx).ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluate for ir::MaybeThunk {
|
||||
fn eval(&self, engine: &mut Engine, env: &mut Env) -> Result<Value> {
|
||||
match self {
|
||||
let result = match self {
|
||||
ir::MaybeThunk::Const(cnst) => cnst.eval(engine, env),
|
||||
ir::MaybeThunk::String(string) => string.eval(engine, env),
|
||||
ir::MaybeThunk::Thunk(thunk) => thunk.eval(engine, env),
|
||||
}
|
||||
};
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user