refactor: builtins, value
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
use derive_more::Constructor;
|
||||
|
||||
use super::vm::Env;
|
||||
use super::vm::Symbol;
|
||||
use super::vm::Value;
|
||||
use crate::vm::{Env, Symbol, Value, AttrSet};
|
||||
use crate::value::Const;
|
||||
|
||||
pub fn env() -> Env {
|
||||
@@ -10,42 +8,39 @@ pub fn env() -> Env {
|
||||
env.insert(Symbol::from("true"), Value::Const(Const::Bool(true)));
|
||||
env.insert(Symbol::from("false"), Value::Const(Const::Bool(false)));
|
||||
|
||||
env.insert(
|
||||
Symbol::from("__add"),
|
||||
Value::PrimOp(PrimOp::new("add", 2, |args| {
|
||||
let primops = [
|
||||
PrimOp::new("add", 2, |args| {
|
||||
let [first, second]: [Value; 2] = args.try_into().unwrap();
|
||||
first.add(second)
|
||||
})),
|
||||
);
|
||||
env.insert(
|
||||
Symbol::from("__sub"),
|
||||
Value::PrimOp(PrimOp::new("sub", 2, |args| {
|
||||
}),
|
||||
PrimOp::new("sub", 2, |args| {
|
||||
let [first, second]: [Value; 2] = args.try_into().unwrap();
|
||||
first.add(second.neg())
|
||||
})),
|
||||
);
|
||||
env.insert(
|
||||
Symbol::from("__mul"),
|
||||
Value::PrimOp(PrimOp::new("mul", 2, |args| {
|
||||
}),
|
||||
PrimOp::new("mul", 2, |args| {
|
||||
let [first, second]: [Value; 2] = args.try_into().unwrap();
|
||||
first.mul(second)
|
||||
})),
|
||||
);
|
||||
env.insert(
|
||||
Symbol::from("__div"),
|
||||
Value::PrimOp(PrimOp::new("div", 2, |args| {
|
||||
}),
|
||||
PrimOp::new("div", 2, |args| {
|
||||
let [first, second]: [Value; 2] = args.try_into().unwrap();
|
||||
first.div(second)
|
||||
})),
|
||||
);
|
||||
env.insert(
|
||||
Symbol::from("__lessThan"),
|
||||
Value::PrimOp(PrimOp::new("lessThan", 2, |args| {
|
||||
}),
|
||||
PrimOp::new("lessThan", 2, |args| {
|
||||
let [first, second]: [Value; 2] = args.try_into().unwrap();
|
||||
first.lt(second)
|
||||
})),
|
||||
);
|
||||
})
|
||||
];
|
||||
|
||||
let mut builtins = AttrSet::empty();
|
||||
for primop in primops {
|
||||
env.insert(
|
||||
Symbol::from(format!("__{}", primop.name)),
|
||||
Value::PrimOp(primop.clone()),
|
||||
);
|
||||
builtins.push_attr(Symbol::from(primop.name), Value::PrimOp(primop));
|
||||
}
|
||||
|
||||
env.insert(Symbol::from("builtins"), Value::AttrSet(builtins));
|
||||
env
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use rpds::HashTrieMapSync;
|
||||
|
||||
use super::value::{Symbol, VmValue};
|
||||
use super::value::{Symbol, Value};
|
||||
|
||||
pub struct Env {
|
||||
last: Option<Box<Env>>,
|
||||
map: HashTrieMapSync<Symbol, VmValue>,
|
||||
map: HashTrieMapSync<Symbol, Value>,
|
||||
}
|
||||
|
||||
impl Env {
|
||||
@@ -15,7 +15,7 @@ impl Env {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup(&self, symbol: Symbol) -> VmValue {
|
||||
pub fn lookup(&self, symbol: Symbol) -> Value {
|
||||
if let Some(value) = self.map.get(&symbol) {
|
||||
value.clone()
|
||||
} else {
|
||||
@@ -24,11 +24,11 @@ impl Env {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, symbol: Symbol, value: VmValue) {
|
||||
pub fn insert(&mut self, symbol: Symbol, value: Value) {
|
||||
self.map.insert_mut(symbol, value);
|
||||
}
|
||||
|
||||
pub fn enter(&mut self, map: HashTrieMapSync<Symbol, VmValue>) {
|
||||
pub fn enter(&mut self, map: HashTrieMapSync<Symbol, Value>) {
|
||||
let last = std::mem::replace(self, Env { last: None, map });
|
||||
self.last = Some(Box::new(last));
|
||||
}
|
||||
|
||||
@@ -9,4 +9,4 @@ mod test;
|
||||
|
||||
pub use env::Env;
|
||||
pub use value::Symbol;
|
||||
pub use value::VmValue as Value;
|
||||
pub use value::*;
|
||||
|
||||
@@ -3,12 +3,12 @@ use std::ops::Deref;
|
||||
|
||||
use anyhow::{Result, anyhow};
|
||||
|
||||
use super::value::VmValue;
|
||||
use super::value::Value;
|
||||
|
||||
pub const STACK_SIZE: usize = 8 * 1024 / size_of::<VmValue>();
|
||||
pub const STACK_SIZE: usize = 8 * 1024 / size_of::<Value>();
|
||||
|
||||
pub struct Stack<const CAP: usize> {
|
||||
items: Box<[MaybeUninit<VmValue>; CAP]>,
|
||||
items: Box<[MaybeUninit<Value>; CAP]>,
|
||||
top: usize,
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ impl<const CAP: usize> Stack<CAP> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push(&mut self, item: VmValue) -> Result<()> {
|
||||
pub fn push(&mut self, item: Value) -> Result<()> {
|
||||
self.items
|
||||
.get_mut(self.top)
|
||||
.map_or(Err(anyhow!("stack overflow")), |ok| Ok(ok))?
|
||||
@@ -33,7 +33,7 @@ impl<const CAP: usize> Stack<CAP> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn pop(&mut self) -> Result<VmValue> {
|
||||
pub fn pop(&mut self) -> Result<Value> {
|
||||
self.top -= 1;
|
||||
let item = self
|
||||
.items
|
||||
@@ -42,7 +42,7 @@ impl<const CAP: usize> Stack<CAP> {
|
||||
unsafe { Ok(std::mem::replace(item, MaybeUninit::uninit()).assume_init()) }
|
||||
}
|
||||
|
||||
pub fn tos(&self) -> Result<&VmValue> {
|
||||
pub fn tos(&self) -> Result<&Value> {
|
||||
if self.top == 0 {
|
||||
Err(anyhow!(""))
|
||||
} else {
|
||||
@@ -50,7 +50,7 @@ impl<const CAP: usize> Stack<CAP> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tos_mut(&mut self) -> Result<&mut VmValue> {
|
||||
pub fn tos_mut(&mut self) -> Result<&mut Value> {
|
||||
if self.top == 0 {
|
||||
Err(anyhow!(""))
|
||||
} else {
|
||||
@@ -58,7 +58,7 @@ impl<const CAP: usize> Stack<CAP> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_tos(&self, func: impl Fn(&VmValue)) -> Result<()> {
|
||||
pub fn with_tos(&self, func: impl Fn(&Value)) -> Result<()> {
|
||||
if self.top != 0 {
|
||||
Err(anyhow!(""))
|
||||
} else {
|
||||
@@ -66,7 +66,7 @@ impl<const CAP: usize> Stack<CAP> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub fn with_tos_mut(&mut self, func: impl Fn(&mut VmValue)) -> Result<()> {
|
||||
pub fn with_tos_mut(&mut self, func: impl Fn(&mut Value)) -> Result<()> {
|
||||
if self.top != 0 {
|
||||
Err(anyhow!(""))
|
||||
} else {
|
||||
@@ -77,7 +77,7 @@ impl<const CAP: usize> Stack<CAP> {
|
||||
}
|
||||
|
||||
impl<const CAP: usize> Deref for Stack<CAP> {
|
||||
type Target = [VmValue];
|
||||
type Target = [Value];
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { transmute(&self.items[0..self.top]) }
|
||||
}
|
||||
|
||||
@@ -1,29 +1,33 @@
|
||||
use derive_more::Constructor;
|
||||
use rpds::HashTrieMapSync;
|
||||
|
||||
use crate::value::{self, Value};
|
||||
use crate::value::{self, Value as Value_};
|
||||
|
||||
use super::super::vm::VM;
|
||||
use super::{Symbol, ToValue, VmValue};
|
||||
use super::{Symbol, ToValue, Value};
|
||||
|
||||
#[derive(Debug, Constructor, Clone, PartialEq)]
|
||||
pub struct AttrSet {
|
||||
data: HashTrieMapSync<Symbol, VmValue>,
|
||||
data: HashTrieMapSync<Symbol, Value>,
|
||||
}
|
||||
|
||||
impl AttrSet {
|
||||
pub fn push_attr_force(&mut self, sym: Symbol, val: VmValue) {
|
||||
pub fn empty() -> AttrSet {
|
||||
AttrSet { data: HashTrieMapSync::new_sync() }
|
||||
}
|
||||
|
||||
pub fn push_attr_force(&mut self, sym: Symbol, val: Value) {
|
||||
self.data.insert_mut(sym, val);
|
||||
}
|
||||
|
||||
pub fn push_attr(&mut self, sym: Symbol, val: VmValue) {
|
||||
pub fn push_attr(&mut self, sym: Symbol, val: Value) {
|
||||
if self.data.get(&sym).is_some() {
|
||||
todo!()
|
||||
}
|
||||
self.data.insert_mut(sym, val);
|
||||
}
|
||||
|
||||
pub fn select(&self, sym: Symbol) -> Option<VmValue> {
|
||||
pub fn select(&self, sym: Symbol) -> Option<Value> {
|
||||
self.data.get(&sym).cloned()
|
||||
}
|
||||
|
||||
@@ -38,14 +42,14 @@ impl AttrSet {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn to_data(self) -> HashTrieMapSync<Symbol, VmValue> {
|
||||
pub fn to_data(self) -> HashTrieMapSync<Symbol, Value> {
|
||||
self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for AttrSet {
|
||||
fn to_value(self, vm: &VM) -> Value {
|
||||
Value::AttrSet(value::AttrSet::new(
|
||||
fn to_value(self, vm: &VM) -> Value_ {
|
||||
Value_::AttrSet(value::AttrSet::new(
|
||||
self.data
|
||||
.iter()
|
||||
.map(|(sym, value)| {
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
use derive_more::Constructor;
|
||||
use rpds::VectorSync;
|
||||
|
||||
use crate::value::{self, Value};
|
||||
use crate::value::{self, Value as Value_};
|
||||
|
||||
use super::super::vm::VM;
|
||||
use super::{ToValue, VmValue};
|
||||
use super::{ToValue, Value};
|
||||
|
||||
#[derive(Debug, Constructor, Clone, PartialEq)]
|
||||
pub struct List {
|
||||
data: VectorSync<VmValue>,
|
||||
data: VectorSync<Value>,
|
||||
}
|
||||
|
||||
impl List {
|
||||
pub fn push(&mut self, elem: VmValue) {
|
||||
pub fn empty() -> List {
|
||||
List {
|
||||
data: VectorSync::new_sync()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push(&mut self, elem: Value) {
|
||||
self.data.push_back_mut(elem);
|
||||
}
|
||||
|
||||
@@ -25,8 +31,8 @@ impl List {
|
||||
}
|
||||
|
||||
impl ToValue for List {
|
||||
fn to_value(self, vm: &VM) -> Value {
|
||||
Value::List(value::List::new(
|
||||
fn to_value(self, vm: &VM) -> Value_ {
|
||||
Value_::List(value::List::new(
|
||||
self.data
|
||||
.iter()
|
||||
.map(|value| value.clone().to_value(vm))
|
||||
|
||||
@@ -2,7 +2,7 @@ use anyhow::Result;
|
||||
use derive_more::{Constructor, IsVariant, Unwrap};
|
||||
use ecow::EcoString;
|
||||
|
||||
use crate::value::*;
|
||||
use crate::value::{Value as Value_, Const, Catchable};
|
||||
|
||||
use super::env::Env;
|
||||
use super::vm::VM;
|
||||
@@ -16,7 +16,7 @@ pub use list::List;
|
||||
pub use string::ContextfulString;
|
||||
|
||||
pub trait ToValue {
|
||||
fn to_value(self, vm: &VM) -> Value;
|
||||
fn to_value(self, vm: &VM) -> Value_;
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Constructor)]
|
||||
@@ -32,7 +32,7 @@ impl<T: Into<EcoString>> From<T> for Symbol {
|
||||
pub struct Thunk(usize);
|
||||
|
||||
#[derive(Debug, IsVariant, Unwrap, Clone, PartialEq)]
|
||||
pub enum VmValue {
|
||||
pub enum Value {
|
||||
Const(Const),
|
||||
Thunk(Thunk),
|
||||
AttrSet(AttrSet),
|
||||
@@ -42,17 +42,17 @@ pub enum VmValue {
|
||||
PartialPrimOp(crate::builtins::PartialPrimOp),
|
||||
}
|
||||
|
||||
use VmValue::Const as VmConst;
|
||||
impl VmValue {
|
||||
pub fn call(self, args: Vec<VmValue>) -> VmValue {
|
||||
use Value::Const as VmConst;
|
||||
impl Value {
|
||||
pub fn call(self, args: Vec<Value>) -> Value {
|
||||
match self {
|
||||
VmValue::PrimOp(func) => func.call(args),
|
||||
VmValue::PartialPrimOp(func) => func.call(args),
|
||||
Value::PrimOp(func) => func.call(args),
|
||||
Value::PartialPrimOp(func) => func.call(args),
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn not(self) -> VmValue {
|
||||
pub fn not(self) -> Value {
|
||||
use Const::*;
|
||||
match self {
|
||||
VmConst(Bool(bool)) => VmConst(Bool(!bool)),
|
||||
@@ -60,7 +60,7 @@ impl VmValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn and(self, other: VmValue) -> VmValue {
|
||||
pub fn and(self, other: Value) -> Value {
|
||||
use Const::*;
|
||||
match (self, other) {
|
||||
(VmConst(Bool(a)), VmConst(Bool(b))) => VmConst(Bool(a && b)),
|
||||
@@ -68,7 +68,7 @@ impl VmValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn or(self, other: VmValue) -> VmValue {
|
||||
pub fn or(self, other: Value) -> Value {
|
||||
use Const::*;
|
||||
match (self, other) {
|
||||
(VmConst(Bool(a)), VmConst(Bool(b))) => VmConst(Bool(a || b)),
|
||||
@@ -76,12 +76,12 @@ impl VmValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eq(self, other: VmValue) -> VmValue {
|
||||
pub fn eq(self, other: Value) -> Value {
|
||||
use Const::Bool;
|
||||
VmConst(Bool(self == other))
|
||||
}
|
||||
|
||||
pub fn lt(self, other: VmValue) -> VmValue {
|
||||
pub fn lt(self, other: Value) -> Value {
|
||||
use Const::*;
|
||||
VmConst(Bool(match (self, other) {
|
||||
(VmConst(Int(a)), VmConst(Int(b))) => a < b,
|
||||
@@ -93,7 +93,7 @@ impl VmValue {
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn neg(self) -> VmValue {
|
||||
pub fn neg(self) -> Value {
|
||||
use Const::*;
|
||||
match self {
|
||||
VmConst(Int(int)) => VmConst(Int(-int)),
|
||||
@@ -102,7 +102,7 @@ impl VmValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(self, other: VmValue) -> VmValue {
|
||||
pub fn add(self, other: Value) -> Value {
|
||||
use Const::*;
|
||||
match (self, other) {
|
||||
(VmConst(Int(a)), VmConst(Int(b))) => VmConst(Int(a + b)),
|
||||
@@ -118,7 +118,7 @@ impl VmValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mul(self, other: VmValue) -> VmValue {
|
||||
pub fn mul(self, other: Value) -> Value {
|
||||
use Const::*;
|
||||
match (self, other) {
|
||||
(VmConst(Int(a)), VmConst(Int(b))) => VmConst(Int(a * b)),
|
||||
@@ -129,7 +129,7 @@ impl VmValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn div(self, other: VmValue) -> VmValue {
|
||||
pub fn div(self, other: Value) -> Value {
|
||||
use Const::*;
|
||||
match (self, other) {
|
||||
(_, VmConst(Int(0))) => todo!(),
|
||||
@@ -142,7 +142,7 @@ impl VmValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn concat_string(&mut self, mut other: VmValue) -> &mut Self {
|
||||
pub fn concat_string(&mut self, mut other: Value) -> &mut Self {
|
||||
if let (VmConst(Const::String(a)), VmConst(Const::String(b))) =
|
||||
(self.coerce_to_string(), other.coerce_to_string())
|
||||
{
|
||||
@@ -153,8 +153,8 @@ impl VmValue {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn push(&mut self, elem: VmValue) -> &mut Self {
|
||||
if let VmValue::List(list) = self {
|
||||
pub fn push(&mut self, elem: Value) -> &mut Self {
|
||||
if let Value::List(list) = self {
|
||||
list.push(elem);
|
||||
} else {
|
||||
todo!()
|
||||
@@ -162,16 +162,16 @@ impl VmValue {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn concat(self, other: VmValue) -> VmValue {
|
||||
if let (VmValue::List(a), VmValue::List(b)) = (self, other) {
|
||||
VmValue::List(a.concat(b))
|
||||
pub fn concat(self, other: Value) -> Value {
|
||||
if let (Value::List(a), Value::List(b)) = (self, other) {
|
||||
Value::List(a.concat(b))
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_attr(&mut self, sym: Symbol, val: VmValue) -> &mut Self {
|
||||
if let VmValue::AttrSet(attrs) = self {
|
||||
pub fn push_attr(&mut self, sym: Symbol, val: Value) -> &mut Self {
|
||||
if let Value::AttrSet(attrs) = self {
|
||||
attrs.push_attr(sym, val)
|
||||
} else {
|
||||
todo!()
|
||||
@@ -179,19 +179,19 @@ impl VmValue {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn update(self, other: VmValue) -> VmValue {
|
||||
if let (VmValue::AttrSet(a), VmValue::AttrSet(b)) = (self, other) {
|
||||
VmValue::AttrSet(a.update(b))
|
||||
pub fn update(self, other: Value) -> Value {
|
||||
if let (Value::AttrSet(a), Value::AttrSet(b)) = (self, other) {
|
||||
Value::AttrSet(a.update(b))
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select(&mut self, sym: Symbol) -> &mut Self {
|
||||
if let VmValue::AttrSet(attrs) = self {
|
||||
if let Value::AttrSet(attrs) = self {
|
||||
let val = attrs
|
||||
.select(sym.clone())
|
||||
.unwrap_or(VmValue::Catchable(Catchable::new(Some(format!(
|
||||
.unwrap_or(Value::Catchable(Catchable::new(Some(format!(
|
||||
"{sym:?} not found"
|
||||
)))));
|
||||
*self = val;
|
||||
@@ -201,8 +201,8 @@ impl VmValue {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn select_with_default(&mut self, sym: Symbol, default: VmValue) -> &mut Self {
|
||||
if let VmValue::AttrSet(attrs) = self {
|
||||
pub fn select_with_default(&mut self, sym: Symbol, default: Value) -> &mut Self {
|
||||
if let Value::AttrSet(attrs) = self {
|
||||
let val = attrs.select(sym).unwrap_or(default);
|
||||
*self = val;
|
||||
} else {
|
||||
@@ -212,7 +212,7 @@ impl VmValue {
|
||||
}
|
||||
|
||||
pub fn has_attr(&mut self, sym: Symbol) -> &mut Self {
|
||||
if let VmValue::AttrSet(attrs) = self {
|
||||
if let Value::AttrSet(attrs) = self {
|
||||
let val = VmConst(Const::Bool(attrs.has_attr(sym)));
|
||||
*self = val;
|
||||
} else {
|
||||
@@ -231,7 +231,7 @@ impl VmValue {
|
||||
}
|
||||
|
||||
pub fn force(&mut self, vm: &VM, env: &mut Env) -> Result<&mut Self> {
|
||||
if let VmValue::Thunk(thunk) = self {
|
||||
if let Value::Thunk(thunk) = self {
|
||||
let value = vm.get_thunk_value(thunk.0, env)?;
|
||||
*self = value
|
||||
}
|
||||
@@ -239,16 +239,16 @@ impl VmValue {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for VmValue {
|
||||
fn to_value(self, vm: &VM) -> Value {
|
||||
impl ToValue for Value {
|
||||
fn to_value(self, vm: &VM) -> Value_ {
|
||||
match self {
|
||||
VmValue::AttrSet(attrs) => attrs.to_value(vm),
|
||||
VmValue::List(list) => list.to_value(vm),
|
||||
VmValue::Catchable(catchable) => Value::Catchable(catchable),
|
||||
VmValue::Const(cnst) => Value::Const(cnst),
|
||||
VmValue::Thunk(_) => Value::Thunk,
|
||||
VmValue::PrimOp(_) => Value::PrimOp,
|
||||
VmValue::PartialPrimOp(_) => Value::PartialPrimOp,
|
||||
Value::AttrSet(attrs) => attrs.to_value(vm),
|
||||
Value::List(list) => list.to_value(vm),
|
||||
Value::Catchable(catchable) => Value_::Catchable(catchable),
|
||||
Value::Const(cnst) => Value_::Const(cnst),
|
||||
Value::Thunk(_) => Value_::Thunk,
|
||||
Value::PrimOp(_) => Value_::PrimOp,
|
||||
Value::PartialPrimOp(_) => Value_::PartialPrimOp,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
25
src/vm/vm.rs
25
src/vm/vm.rs
@@ -1,16 +1,15 @@
|
||||
use anyhow::Result;
|
||||
use rpds::{HashTrieMap, HashTrieMapSync, Vector};
|
||||
|
||||
use crate::builtins::env;
|
||||
use crate::bytecode::{self, *};
|
||||
use crate::value::{Const, Value};
|
||||
use crate::value::{Const, Value as Value_};
|
||||
|
||||
use super::env::Env;
|
||||
use super::stack::{STACK_SIZE, Stack};
|
||||
use super::value::{self as vmValue, *};
|
||||
use super::vmthunk::*;
|
||||
|
||||
pub fn run(prog: Program) -> Result<Value> {
|
||||
pub fn run(prog: Program) -> Result<Value_> {
|
||||
let vm = VM::new(prog.thunks);
|
||||
Ok(vm.eval(prog.top_level, &mut env())?.to_value(&vm))
|
||||
}
|
||||
@@ -28,11 +27,11 @@ impl VM {
|
||||
VM { thunks }
|
||||
}
|
||||
|
||||
pub fn get_thunk_value(&self, idx: usize, env: &mut Env) -> Result<VmValue> {
|
||||
pub fn get_thunk_value(&self, idx: usize, env: &mut Env) -> Result<Value> {
|
||||
self.thunks.get(idx).unwrap().force(self, env)
|
||||
}
|
||||
|
||||
pub fn eval(&self, opcodes: OpCodes, env: &mut Env) -> Result<VmValue> {
|
||||
pub fn eval(&self, opcodes: OpCodes, env: &mut Env) -> Result<Value> {
|
||||
let mut stack = Stack::<STACK_SIZE>::new();
|
||||
let mut iter = opcodes.into_iter();
|
||||
while let Some(opcode) = iter.next() {
|
||||
@@ -54,8 +53,8 @@ impl VM {
|
||||
) -> Result<usize> {
|
||||
match opcode {
|
||||
OpCode::NoOp => (),
|
||||
OpCode::Const { value } => stack.push(VmValue::Const(value))?,
|
||||
OpCode::LoadThunk { idx } => stack.push(VmValue::Thunk(vmValue::Thunk::new(idx)))?,
|
||||
OpCode::Const { value } => stack.push(Value::Const(value))?,
|
||||
OpCode::LoadThunk { idx } => stack.push(Value::Thunk(vmValue::Thunk::new(idx)))?,
|
||||
OpCode::LoadValue { idx } => {
|
||||
stack.push(self.get_thunk_value(idx, env)?)?;
|
||||
}
|
||||
@@ -64,12 +63,12 @@ impl VM {
|
||||
}
|
||||
OpCode::Jmp { step } => return Ok(step),
|
||||
OpCode::JmpIfTrue { step } => {
|
||||
if let VmValue::Const(Const::Bool(true)) = stack.pop()? {
|
||||
if let Value::Const(Const::Bool(true)) = stack.pop()? {
|
||||
return Ok(step);
|
||||
}
|
||||
}
|
||||
OpCode::JmpIfFalse { step } => {
|
||||
if let VmValue::Const(Const::Bool(false)) = stack.pop()? {
|
||||
if let Value::Const(Const::Bool(false)) = stack.pop()? {
|
||||
return Ok(step);
|
||||
}
|
||||
}
|
||||
@@ -106,14 +105,14 @@ impl VM {
|
||||
stack.tos_mut()?.concat_string(rhs);
|
||||
}
|
||||
OpCode::List => {
|
||||
stack.push(VmValue::List(List::new(Vector::new_sync())))?;
|
||||
stack.push(Value::List(List::empty()))?;
|
||||
}
|
||||
OpCode::PushElem => {
|
||||
let elem = stack.pop()?;
|
||||
stack.tos_mut()?.push(elem);
|
||||
}
|
||||
OpCode::AttrSet => {
|
||||
stack.push(VmValue::AttrSet(AttrSet::new(HashTrieMap::new_sync())))?;
|
||||
stack.push(Value::AttrSet(AttrSet::empty()))?;
|
||||
}
|
||||
OpCode::PushStaticAttr { name } => {
|
||||
let val = stack.pop()?;
|
||||
@@ -138,7 +137,7 @@ impl VM {
|
||||
OpCode::SelectOrEmpty { sym } => {
|
||||
stack.tos_mut()?.select_with_default(
|
||||
Symbol::new(sym),
|
||||
VmValue::AttrSet(AttrSet::new(HashTrieMapSync::new_sync())),
|
||||
Value::AttrSet(AttrSet::empty()),
|
||||
);
|
||||
}
|
||||
OpCode::SelectDynamic => {
|
||||
@@ -160,7 +159,7 @@ impl VM {
|
||||
let sym = val.unwrap_const().unwrap_string().into();
|
||||
stack.tos_mut()?.select_with_default(
|
||||
sym,
|
||||
VmValue::AttrSet(AttrSet::new(HashTrieMapSync::new_sync())),
|
||||
Value::AttrSet(AttrSet::empty()),
|
||||
);
|
||||
}
|
||||
OpCode::HasAttr { sym } => {
|
||||
|
||||
@@ -7,7 +7,7 @@ use derive_more::{IsVariant, Unwrap};
|
||||
use crate::bytecode::OpCodes;
|
||||
|
||||
use super::env::Env;
|
||||
use super::value::VmValue;
|
||||
use super::value::Value;
|
||||
use super::vm::VM;
|
||||
|
||||
pub struct VmThunk {
|
||||
@@ -19,7 +19,7 @@ pub struct VmThunk {
|
||||
enum _VmThunk {
|
||||
Code(OpCodes),
|
||||
SuspendedFrom(*const VmThunk),
|
||||
Value(VmValue),
|
||||
Value(Value),
|
||||
}
|
||||
|
||||
impl VmThunk {
|
||||
@@ -30,7 +30,7 @@ impl VmThunk {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn force(&self, vm: &VM, env: &mut Env) -> Result<VmValue> {
|
||||
pub fn force(&self, vm: &VM, env: &mut Env) -> Result<Value> {
|
||||
{
|
||||
let _guard = self.lock.read().unwrap();
|
||||
match &*self.thunk.borrow() {
|
||||
@@ -59,7 +59,7 @@ impl VmThunk {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn value(&self) -> Option<VmValue> {
|
||||
pub fn value(&self) -> Option<Value> {
|
||||
let _guard = self.lock.read();
|
||||
match &*self.thunk.borrow() {
|
||||
_VmThunk::Value(value) => Some(value.clone()),
|
||||
|
||||
Reference in New Issue
Block a user