diff --git a/src/bytecode.rs b/src/bytecode.rs index 80d37b0..73ec019 100644 --- a/src/bytecode.rs +++ b/src/bytecode.rs @@ -49,8 +49,6 @@ pub enum OpCode { /// push an empty attribute set onto stack AttrSet, - /// push an empty recursive attribute set onto stack - RecAttrSet, /// [ .. set value ] consume 1 element, push a static kv pair (`name`, `value`) into `set` PushStaticAttr { name: EcoString }, /// [ .. set name value ] consume 2 elements, push a dynamic kv pair (`name`, `value`) in to `set` diff --git a/src/ty/internal/func.rs b/src/ty/internal/func.rs index d87e5a2..6e904f1 100644 --- a/src/ty/internal/func.rs +++ b/src/ty/internal/func.rs @@ -1,5 +1,6 @@ use ecow::EcoString; +use crate::ty::internal::Value; use crate::bytecode::{OpCodes, ThunkIdx}; #[derive(Debug, Clone)] @@ -18,6 +19,12 @@ pub struct Func { pub opcodes: OpCodes } +impl Func { + pub fn call(self, _arg: Value) -> Value { + todo!() + } +} + impl PartialEq for Func { fn eq(&self, _: &Self) -> bool { false diff --git a/src/ty/internal/mod.rs b/src/ty/internal/mod.rs index b27c181..fa2ec2f 100644 --- a/src/ty/internal/mod.rs +++ b/src/ty/internal/mod.rs @@ -43,10 +43,31 @@ pub enum Value { use Value::Const as VmConst; impl Value { - pub fn call(self, args: Vec) -> Value { + pub fn callable(&self) -> bool { match self { - Value::PrimOp(func) => func.call(args), - Value::PartialPrimOp(func) => func.call(args), + Value::PrimOp(_) | Value::PartialPrimOp(_) | Value::Const(Const::Func(_)) => true, + Value::AttrSet(_) => todo!(), + _ => false, + } + } + + pub fn call(self, args: Vec) -> Value { + use Value as V; + match self { + V::PrimOp(func) => func.call(args), + V::PartialPrimOp(func) => func.call(args), + mut func @ Value::Const(Const::Func(_)) => { + let mut iter = args.into_iter(); + while let Some(arg) = iter.next() { + func = match func { + V::PrimOp(func) => return func.call([arg].into_iter().chain(iter).collect()), + V::PartialPrimOp(func) => return func.call([arg].into_iter().chain(iter).collect()), + V::Const(Const::Func(func)) => func.call(arg), + _ => todo!() + } + } + func + } _ => todo!(), } } diff --git a/src/vm/vm.rs b/src/vm/vm.rs index eccef44..fb4c34c 100644 --- a/src/vm/vm.rs +++ b/src/vm/vm.rs @@ -81,6 +81,12 @@ impl VM { let func = stack.pop()?; stack.push(func.call(args))?; } + OpCode::Func { param, length } => { + todo!() + } + OpCode::Ret => { + todo!() + } OpCode::UnOp { op } => { use UnOp::*; let value = stack.pop()?; @@ -105,6 +111,9 @@ impl VM { let rhs = stack.pop()?; stack.tos_mut()?.concat_string(rhs); } + OpCode::Path => { + todo!() + } OpCode::List => { stack.push(Value::List(List::empty()))?; } @@ -166,7 +175,11 @@ impl VM { OpCode::LeaveEnv => { env.leave(); } - _ => todo!(), + OpCode::Assert => { + if !stack.pop()?.unwrap_const().unwrap_bool() { + todo!() + } + } } Ok(0) }