feat: function (WIP)
This commit is contained in:
64
Cargo.lock
generated
64
Cargo.lock
generated
@@ -80,9 +80,12 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "convert_case"
|
name = "convert_case"
|
||||||
version = "0.4.0"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "countme"
|
name = "countme"
|
||||||
@@ -126,15 +129,24 @@ checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
version = "0.99.17"
|
version = "2.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678"
|
||||||
|
dependencies = [
|
||||||
|
"derive_more-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_more-impl"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"convert_case",
|
"convert_case",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustc_version",
|
"syn",
|
||||||
"syn 1.0.109",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -387,27 +399,12 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc_version"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
|
||||||
dependencies = [
|
|
||||||
"semver",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "semver"
|
|
||||||
version = "1.0.23"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.4.2"
|
version = "1.4.2"
|
||||||
@@ -439,17 +436,6 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "1.0.109"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.58"
|
version = "2.0.58"
|
||||||
@@ -494,7 +480,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.58",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -509,6 +495,18 @@ version = "1.0.12"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ itertools = "0.12"
|
|||||||
rayon = "1.10"
|
rayon = "1.10"
|
||||||
tokio = { version = "1.38", features = [ "full" ] }
|
tokio = { version = "1.38", features = [ "full" ] }
|
||||||
rpds = "1.1"
|
rpds = "1.1"
|
||||||
derive_more = "0.99"
|
derive_more = { version = "2.0", features = [ "full" ] }
|
||||||
crossbeam-channel = "0.5"
|
crossbeam-channel = "0.5"
|
||||||
ecow = "0.2"
|
ecow = "0.2"
|
||||||
once_cell = "1.19"
|
once_cell = "1.19"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use ecow::EcoString;
|
use ecow::EcoString;
|
||||||
|
|
||||||
use crate::ty::internal::{Const, Param};
|
use crate::ty::internal::Const;
|
||||||
|
|
||||||
type Slice<T> = Box<[T]>;
|
type Slice<T> = Box<[T]>;
|
||||||
|
|
||||||
@@ -35,7 +35,17 @@ pub enum OpCode {
|
|||||||
/// return a value
|
/// return a value
|
||||||
Ret,
|
Ret,
|
||||||
/// make a function
|
/// make a function
|
||||||
Func { param: Param, length: usize },
|
Func { idx: ThunkIdx },
|
||||||
|
/// push param `sym` into TOS
|
||||||
|
PushIdentParam { sym: EcoString },
|
||||||
|
/// push formal param `sym` into TOS
|
||||||
|
PushFormalParam { sym: EcoString },
|
||||||
|
/// push default formal param with thunkidx `idx` into TOS
|
||||||
|
PushDefaultParam { idx: ThunkIdx },
|
||||||
|
/// TODO:
|
||||||
|
SetEllipsis,
|
||||||
|
/// TODO:
|
||||||
|
SetAlias { sym: EcoString },
|
||||||
|
|
||||||
/// consume 1 element, assert TOS is true
|
/// consume 1 element, assert TOS is true
|
||||||
Assert,
|
Assert,
|
||||||
|
|||||||
@@ -406,10 +406,25 @@ impl Compile for ir::Assert {
|
|||||||
|
|
||||||
impl Compile for ir::Func {
|
impl Compile for ir::Func {
|
||||||
fn compile(self, comp: &mut Compiler) {
|
fn compile(self, comp: &mut Compiler) {
|
||||||
let idx = comp.idx();
|
comp.push(OpCode::Func { idx: self.body.idx });
|
||||||
comp.push(OpCode::NoOp);
|
use ir::Param::*;
|
||||||
let length = self.body.compile_with_length(comp);
|
match self.param {
|
||||||
comp.modify(idx, OpCode::Func { param: self.param.into(), length });
|
Ident(sym) => comp.push(OpCode::PushIdentParam { sym }),
|
||||||
|
Formals { formals, ellipsis, alias } => {
|
||||||
|
for (sym, default) in formals {
|
||||||
|
comp.push(OpCode::PushFormalParam { sym });
|
||||||
|
if let Some(ir::Thunk { idx }) = default {
|
||||||
|
comp.push(OpCode::PushDefaultParam { idx });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ellipsis {
|
||||||
|
comp.push(OpCode::SetEllipsis);
|
||||||
|
}
|
||||||
|
if let Some(sym) = alias {
|
||||||
|
comp.push(OpCode::SetAlias { sym });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ ir! {
|
|||||||
UnOp => { rhs: Box<Ir>, kind: UnOpKind },
|
UnOp => { rhs: Box<Ir>, kind: UnOpKind },
|
||||||
Select => { expr: Box<Ir>, attrpath: Vec<Attr>, default: Option<Box<Ir>> },
|
Select => { expr: Box<Ir>, attrpath: Vec<Attr>, default: Option<Box<Ir>> },
|
||||||
If => { cond: Box<Ir>, consq: Box<Ir>, alter: Box<Ir> },
|
If => { cond: Box<Ir>, consq: Box<Ir>, alter: Box<Ir> },
|
||||||
Func => { param: Param, body: Box<Ir> },
|
Func => { param: Param, body: Thunk },
|
||||||
Call => { func: Box<Ir>, args: Vec<Ir> },
|
Call => { func: Box<Ir>, args: Vec<Ir> },
|
||||||
|
|
||||||
Let => { attrs: Attrs, expr: Box<Ir> },
|
Let => { attrs: Attrs, expr: Box<Ir> },
|
||||||
@@ -630,7 +630,8 @@ impl Downgrade for ast::Lambda {
|
|||||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||||
let body = self.body().unwrap();
|
let body = self.body().unwrap();
|
||||||
let param = downgrade_param(self.param().unwrap(), state)?;
|
let param = downgrade_param(self.param().unwrap(), state)?;
|
||||||
let body = body.downgrade(state)?.boxed();
|
let body = body.downgrade(state)?;
|
||||||
|
let body = state.new_thunk(body);
|
||||||
Func { param, body }.ir().ok()
|
Func { param, body }.ir().ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,12 @@ use derive_more::{IsVariant, Unwrap};
|
|||||||
|
|
||||||
use ecow::EcoString;
|
use ecow::EcoString;
|
||||||
|
|
||||||
use super::Func;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, IsVariant, Unwrap)]
|
#[derive(Debug, Clone, IsVariant, Unwrap)]
|
||||||
pub enum Const {
|
pub enum Const {
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
Int(i64),
|
Int(i64),
|
||||||
Float(f64),
|
Float(f64),
|
||||||
String(EcoString),
|
String(EcoString),
|
||||||
Func(Func),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<bool> for Const {
|
impl From<bool> for Const {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use ecow::EcoString;
|
use ecow::EcoString;
|
||||||
|
|
||||||
use crate::ty::internal::Value;
|
|
||||||
use crate::bytecode::{OpCodes, ThunkIdx};
|
use crate::bytecode::{OpCodes, ThunkIdx};
|
||||||
|
use crate::ty::internal::Value;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Param {
|
pub enum Param {
|
||||||
@@ -15,14 +15,65 @@ pub enum Param {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Func {
|
pub struct Func {
|
||||||
pub param: Param,
|
pub param: Option<Param>,
|
||||||
pub opcodes: OpCodes
|
pub opcodes: OpCodes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Func {
|
impl Func {
|
||||||
|
pub fn new(opcodes: OpCodes) -> Func {
|
||||||
|
Func {
|
||||||
|
param: None,
|
||||||
|
opcodes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn call(self, _arg: Value) -> Value {
|
pub fn call(self, _arg: Value) -> Value {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn push_ident_param(&mut self, param: EcoString) {
|
||||||
|
self.param = Some(Param::Ident(param))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_formal_param(&mut self, param: EcoString) {
|
||||||
|
let Param::Formals { formals, .. } = self.param.get_or_insert_with(|| Param::Formals {
|
||||||
|
formals: Vec::with_capacity(1),
|
||||||
|
ellipsis: false,
|
||||||
|
alias: None,
|
||||||
|
}) else {
|
||||||
|
panic!()
|
||||||
|
};
|
||||||
|
formals.push((param, None));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_default_param(&mut self, default: ThunkIdx) {
|
||||||
|
let Param::Formals { formals, .. } = self.param.as_mut().unwrap() else {
|
||||||
|
panic!()
|
||||||
|
};
|
||||||
|
formals.last_mut().unwrap().1 = Some(default)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_ellipsis(&mut self) {
|
||||||
|
let Param::Formals { ellipsis, .. } = self.param.get_or_insert_with(|| Param::Formals {
|
||||||
|
formals: Vec::new(),
|
||||||
|
ellipsis: false,
|
||||||
|
alias: None,
|
||||||
|
}) else {
|
||||||
|
panic!()
|
||||||
|
};
|
||||||
|
*ellipsis = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_alias(&mut self, sym: EcoString) {
|
||||||
|
let Param::Formals { alias, .. } = self.param.get_or_insert_with(|| Param::Formals {
|
||||||
|
formals: Vec::new(),
|
||||||
|
ellipsis: false,
|
||||||
|
alias: None,
|
||||||
|
}) else {
|
||||||
|
panic!()
|
||||||
|
};
|
||||||
|
*alias = Some(sym);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Func {
|
impl PartialEq for Func {
|
||||||
|
|||||||
@@ -39,30 +39,88 @@ pub enum Value {
|
|||||||
Catchable(c::Catchable),
|
Catchable(c::Catchable),
|
||||||
PrimOp(PrimOp),
|
PrimOp(PrimOp),
|
||||||
PartialPrimOp(PartialPrimOp),
|
PartialPrimOp(PartialPrimOp),
|
||||||
|
Func(Func),
|
||||||
|
// FuncWithEnv(Func)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, IsVariant, Unwrap, Clone, PartialEq)]
|
||||||
|
pub enum ValueAsRef<'a> {
|
||||||
|
Const(&'a Const),
|
||||||
|
Thunk(&'a Thunk),
|
||||||
|
AttrSet(&'a AttrSet),
|
||||||
|
List(&'a List),
|
||||||
|
Catchable(&'a c::Catchable),
|
||||||
|
PrimOp(&'a PrimOp),
|
||||||
|
PartialPrimOp(&'a PartialPrimOp),
|
||||||
|
Func(&'a Func),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, IsVariant, Unwrap, PartialEq)]
|
||||||
|
pub enum ValueAsMut<'a> {
|
||||||
|
Const(&'a mut Const),
|
||||||
|
Thunk(&'a mut Thunk),
|
||||||
|
AttrSet(&'a mut AttrSet),
|
||||||
|
List(&'a mut List),
|
||||||
|
Catchable(&'a mut c::Catchable),
|
||||||
|
PrimOp(&'a mut PrimOp),
|
||||||
|
PartialPrimOp(&'a mut PartialPrimOp),
|
||||||
|
Func(&'a mut Func),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Value {
|
||||||
|
pub fn as_ref(&self) -> ValueAsRef<'_> {
|
||||||
|
use Value::*;
|
||||||
|
use ValueAsRef as R;
|
||||||
|
match self {
|
||||||
|
Const(x) => R::Const(x),
|
||||||
|
Thunk(x) => R::Thunk(x),
|
||||||
|
AttrSet(x) => R::AttrSet(x),
|
||||||
|
List(x) => R::List(x),
|
||||||
|
Catchable(x) => R::Catchable(x),
|
||||||
|
PrimOp(x) => R::PrimOp(x),
|
||||||
|
PartialPrimOp(x) => R::PartialPrimOp(x),
|
||||||
|
Func(x) => R::Func(x),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_mut(&mut self) -> ValueAsMut<'_> {
|
||||||
|
use Value::*;
|
||||||
|
use ValueAsMut as M;
|
||||||
|
match self {
|
||||||
|
Const(x) => M::Const(x),
|
||||||
|
Thunk(x) => M::Thunk(x),
|
||||||
|
AttrSet(x) => M::AttrSet(x),
|
||||||
|
List(x) => M::List(x),
|
||||||
|
Catchable(x) => M::Catchable(x),
|
||||||
|
PrimOp(x) => M::PrimOp(x),
|
||||||
|
PartialPrimOp(x) => M::PartialPrimOp(x),
|
||||||
|
Func(x) => M::Func(x),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use Value::Const as VmConst;
|
use Value::Const as VmConst;
|
||||||
impl Value {
|
impl Value {
|
||||||
pub fn callable(&self) -> bool {
|
pub fn callable(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Value::PrimOp(_) | Value::PartialPrimOp(_) | Value::Const(Const::Func(_)) => true,
|
Value::PrimOp(_) | Value::PartialPrimOp(_) | Value::Func(_) => true,
|
||||||
Value::AttrSet(_) => todo!(),
|
Value::AttrSet(_) => todo!(),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call(self, args: Vec<Value>) -> Value {
|
pub fn call(self, args: Vec<Value>) -> Value {
|
||||||
use Value as V;
|
use Value::*;
|
||||||
match self {
|
match self {
|
||||||
V::PrimOp(func) => func.call(args),
|
PrimOp(func) => func.call(args),
|
||||||
V::PartialPrimOp(func) => func.call(args),
|
PartialPrimOp(func) => func.call(args),
|
||||||
mut func @ Value::Const(Const::Func(_)) => {
|
mut func @ Value::Func(_) => {
|
||||||
let mut iter = args.into_iter();
|
let mut iter = args.into_iter();
|
||||||
while let Some(arg) = iter.next() {
|
while let Some(arg) = iter.next() {
|
||||||
func = match func {
|
func = match func {
|
||||||
V::PrimOp(func) => return func.call([arg].into_iter().chain(iter).collect()),
|
PrimOp(func) => return func.call([arg].into_iter().chain(iter).collect()),
|
||||||
V::PartialPrimOp(func) => return func.call([arg].into_iter().chain(iter).collect()),
|
PartialPrimOp(func) => return func.call([arg].into_iter().chain(iter).collect()),
|
||||||
V::Const(Const::Func(func)) => func.call(arg),
|
Func(func) => func.call(arg),
|
||||||
_ => todo!()
|
_ => todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,8 +325,9 @@ impl ToPublic for Value {
|
|||||||
Value::Catchable(catchable) => p::Value::Catchable(catchable),
|
Value::Catchable(catchable) => p::Value::Catchable(catchable),
|
||||||
Value::Const(cnst) => p::Value::Const(cnst.into()),
|
Value::Const(cnst) => p::Value::Const(cnst.into()),
|
||||||
Value::Thunk(_) => p::Value::Thunk,
|
Value::Thunk(_) => p::Value::Thunk,
|
||||||
Value::PrimOp(_) => p::Value::PrimOp,
|
Value::PrimOp(primop) => p::Value::PrimOp(primop.name),
|
||||||
Value::PartialPrimOp(_) => p::Value::PartialPrimOp,
|
Value::PartialPrimOp(primop) => p::Value::PartialPrimOp(primop.name),
|
||||||
|
Value::Func(_) => p::Value::Func,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ pub enum Const {
|
|||||||
Int(i64),
|
Int(i64),
|
||||||
Float(f64),
|
Float(f64),
|
||||||
String(EcoString),
|
String(EcoString),
|
||||||
Func
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<i::Const> for Const {
|
impl From<i::Const> for Const {
|
||||||
@@ -21,7 +20,6 @@ impl From<i::Const> for Const {
|
|||||||
Int(int) => Const::Int(int),
|
Int(int) => Const::Int(int),
|
||||||
Float(float) => Const::Float(float),
|
Float(float) => Const::Float(float),
|
||||||
String(string) => Const::String(string),
|
String(string) => Const::String(string),
|
||||||
Func(_) => Const::Func
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,6 @@ pub enum Value {
|
|||||||
Catchable(Catchable),
|
Catchable(Catchable),
|
||||||
Thunk,
|
Thunk,
|
||||||
Func,
|
Func,
|
||||||
PrimOp,
|
PrimOp(&'static str),
|
||||||
PartialPrimOp,
|
PartialPrimOp(&'static str),
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/vm/vm.rs
21
src/vm/vm.rs
@@ -1,3 +1,5 @@
|
|||||||
|
use std::ops::Index;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use crate::builtins::env;
|
use crate::builtins::env;
|
||||||
@@ -81,8 +83,23 @@ impl VM {
|
|||||||
let func = stack.pop()?;
|
let func = stack.pop()?;
|
||||||
stack.push(func.call(args))?;
|
stack.push(func.call(args))?;
|
||||||
}
|
}
|
||||||
OpCode::Func { param, length } => {
|
OpCode::Func { idx } => {
|
||||||
todo!()
|
stack.push(Value::Func(Func::new(self.thunks[idx].unwrap_code())))?;
|
||||||
|
}
|
||||||
|
OpCode::PushIdentParam { sym } => {
|
||||||
|
stack.tos_mut()?.as_mut().unwrap_func().push_ident_param(sym);
|
||||||
|
}
|
||||||
|
OpCode::PushFormalParam { sym } => {
|
||||||
|
stack.tos_mut()?.as_mut().unwrap_func().push_formal_param(sym);
|
||||||
|
}
|
||||||
|
OpCode::PushDefaultParam { idx } => {
|
||||||
|
stack.tos_mut()?.as_mut().unwrap_func().push_default_param(idx);
|
||||||
|
}
|
||||||
|
OpCode::SetEllipsis => {
|
||||||
|
stack.tos_mut()?.as_mut().unwrap_func().set_ellipsis();
|
||||||
|
}
|
||||||
|
OpCode::SetAlias { sym } => {
|
||||||
|
stack.tos_mut()?.as_mut().unwrap_func().set_alias(sym);
|
||||||
}
|
}
|
||||||
OpCode::Ret => {
|
OpCode::Ret => {
|
||||||
todo!()
|
todo!()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub struct VmThunk {
|
|||||||
lock: RwLock<()>,
|
lock: RwLock<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(IsVariant, Unwrap)]
|
#[derive(IsVariant, Unwrap, Clone)]
|
||||||
enum _VmThunk {
|
enum _VmThunk {
|
||||||
Code(OpCodes),
|
Code(OpCodes),
|
||||||
SuspendedFrom(*const VmThunk),
|
SuspendedFrom(*const VmThunk),
|
||||||
@@ -30,6 +30,11 @@ impl VmThunk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unwrap_code(&self) -> OpCodes {
|
||||||
|
let _guard = self.lock.read().unwrap();
|
||||||
|
self.thunk.borrow().clone().unwrap_code()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn force(&self, vm: &VM, env: &mut Env) -> Result<Value> {
|
pub fn force(&self, vm: &VM, env: &mut Env) -> Result<Value> {
|
||||||
{
|
{
|
||||||
let _guard = self.lock.read().unwrap();
|
let _guard = self.lock.read().unwrap();
|
||||||
@@ -43,7 +48,6 @@ impl VmThunk {
|
|||||||
_VmThunk::Code(_) => (),
|
_VmThunk::Code(_) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
|
||||||
let _guard = self.lock.write().unwrap();
|
let _guard = self.lock.write().unwrap();
|
||||||
let opcodes = std::mem::replace(
|
let opcodes = std::mem::replace(
|
||||||
&mut *self.thunk.borrow_mut(),
|
&mut *self.thunk.borrow_mut(),
|
||||||
@@ -57,7 +61,6 @@ impl VmThunk {
|
|||||||
);
|
);
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn value(&self) -> Option<Value> {
|
pub fn value(&self) -> Option<Value> {
|
||||||
let _guard = self.lock.read();
|
let _guard = self.lock.read();
|
||||||
|
|||||||
Reference in New Issue
Block a user