feat: builtins env (WIP)
This commit is contained in:
@@ -1,12 +1,7 @@
|
|||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
use crate::env::VmEnv;
|
|
||||||
use crate::ir::{DowngradeContext, Ir};
|
|
||||||
use crate::ty::common::Const;
|
use crate::ty::common::Const;
|
||||||
use crate::ty::internal::{PrimOp, Value};
|
use crate::ir::{DowngradeContext, Ir};
|
||||||
use crate::vm::VM;
|
|
||||||
|
|
||||||
pub fn ir_env(ctx: &mut DowngradeContext) -> HashMap<usize, Ir> {
|
pub fn ir_env(ctx: &mut DowngradeContext) -> HashMap<usize, Ir> {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
@@ -15,85 +10,3 @@ pub fn ir_env(ctx: &mut DowngradeContext) -> HashMap<usize, Ir> {
|
|||||||
|
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vm_env<'gc>(vm: &VM) -> Rc<VmEnv<'gc>> {
|
|
||||||
let primops = [
|
|
||||||
PrimOp::new("add", 2, |args, _| {
|
|
||||||
let Ok([mut first, second]): Result<[Value; 2], _> = args.try_into() else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
first.add(second);
|
|
||||||
first.ok()
|
|
||||||
}),
|
|
||||||
PrimOp::new("sub", 2, |args, _| {
|
|
||||||
let Ok([mut first, mut second]): Result<[Value; 2], _> = args.try_into() else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
second.neg();
|
|
||||||
first.add(second);
|
|
||||||
first.ok()
|
|
||||||
}),
|
|
||||||
PrimOp::new("mul", 2, |args, _| {
|
|
||||||
let Ok([mut first, second]): Result<[Value; 2], _> = args.try_into() else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
first.mul(second);
|
|
||||||
first.ok()
|
|
||||||
}),
|
|
||||||
PrimOp::new("div", 2, |args, _| {
|
|
||||||
let Ok([mut first, second]): Result<[Value; 2], _> = args.try_into() else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
first.div(second)?;
|
|
||||||
first.ok()
|
|
||||||
}),
|
|
||||||
PrimOp::new("lessThan", 2, |args, _| {
|
|
||||||
let Ok([mut first, second]): Result<[Value; 2], _> = args.try_into() else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
first.lt(second);
|
|
||||||
first.ok()
|
|
||||||
}),
|
|
||||||
/* PrimOp::new("seq", 2, |args, vm| {
|
|
||||||
let Ok([mut first, second]): Result<[_; 2]> = args.try_into() else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
first.force(vm).unwrap();
|
|
||||||
second.ok()
|
|
||||||
}),
|
|
||||||
PrimOp::new("deepSeq", 2, |args, vm| {
|
|
||||||
let Ok([mut first, second]): Result<[_; 2]> = args.try_into() else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
first.force_deep(vm).unwrap();
|
|
||||||
second.ok()
|
|
||||||
}), */
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut env_map = HashMap::new();
|
|
||||||
env_map.insert(vm.new_sym("true"), Value::Bool(true));
|
|
||||||
env_map.insert(vm.new_sym("false"), Value::Bool(false));
|
|
||||||
|
|
||||||
let mut map = HashMap::new();
|
|
||||||
for primop in primops {
|
|
||||||
let primop = Rc::new(primop);
|
|
||||||
env_map.insert(
|
|
||||||
vm.new_sym(format!("__{}", primop.name)),
|
|
||||||
Value::PrimOp(primop.clone()),
|
|
||||||
);
|
|
||||||
map.insert(vm.new_sym(primop.name), Value::PrimOp(primop));
|
|
||||||
}
|
|
||||||
let sym = vm.new_sym("builtins");
|
|
||||||
/* let mut attrs = CoW::new(AttrSet::new(map));
|
|
||||||
unsafe {
|
|
||||||
attrs.make_cyclic(|attrs, this| {
|
|
||||||
let _ = attrs.push_attr(sym, Value::AttrSet(this));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let builtins = Value::AttrSet(attrs);
|
|
||||||
|
|
||||||
env_map.insert(sym, builtins); */
|
|
||||||
// TODO:
|
|
||||||
// VmEnv::new(Gc::new(mc, env_map))
|
|
||||||
VmEnv::new(Vec::new())
|
|
||||||
}
|
|
||||||
|
|||||||
10
src/env.rs
10
src/env.rs
@@ -8,7 +8,7 @@ use crate::{ir::Ir, ty::internal::Value};
|
|||||||
pub struct Env<K: Hash + Eq, V> {
|
pub struct Env<K: Hash + Eq, V> {
|
||||||
let_: Rc<LetEnv<V>>,
|
let_: Rc<LetEnv<V>>,
|
||||||
with: Rc<With<K, V>>,
|
with: Rc<With<K, V>>,
|
||||||
args: Vec<V>,
|
args: Rc<Vec<V>>,
|
||||||
last: Option<Rc<Env<K, V>>>,
|
last: Option<Rc<Env<K, V>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,11 +42,11 @@ impl<K: Hash + Eq + Clone, V: Clone> Env<K, V> {
|
|||||||
pub fn new(map: Vec<V>) -> Rc<Self> {
|
pub fn new(map: Vec<V>) -> Rc<Self> {
|
||||||
Rc::new(Self {
|
Rc::new(Self {
|
||||||
let_: LetEnv::new(map),
|
let_: LetEnv::new(map),
|
||||||
with: Rc::new(With {
|
with: With {
|
||||||
map: None,
|
map: None,
|
||||||
last: None,
|
last: None,
|
||||||
}),
|
}.into(),
|
||||||
args: Vec::new(),
|
args: Vec::new().into(),
|
||||||
last: None,
|
last: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ impl<K: Hash + Eq + Clone, V: Clone> Env<K, V> {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn enter_arg(self: Rc<Self>, val: V) -> Rc<Self> {
|
pub fn enter_arg(self: Rc<Self>, val: V) -> Rc<Self> {
|
||||||
let mut args = self.args.clone();
|
let mut args = self.args.clone();
|
||||||
args.push(val);
|
Rc::make_mut(&mut args).push(val);
|
||||||
Rc::new(Self {
|
Rc::new(Self {
|
||||||
let_: self.let_.clone(),
|
let_: self.let_.clone(),
|
||||||
with: self.with.clone(),
|
with: self.with.clone(),
|
||||||
|
|||||||
@@ -2,14 +2,12 @@
|
|||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
use gc_arena::Arena;
|
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
|
|
||||||
use inkwell::context::Context;
|
use inkwell::context::Context;
|
||||||
|
|
||||||
use ecow::EcoString;
|
use ecow::EcoString;
|
||||||
|
|
||||||
use crate::builtins::vm_env;
|
|
||||||
use crate::compile::compile;
|
use crate::compile::compile;
|
||||||
use crate::ir::downgrade;
|
use crate::ir::downgrade;
|
||||||
use crate::jit::JITContext;
|
use crate::jit::JITContext;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ macro_rules! into {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Stack<T, const CAP: usize> {
|
pub struct Stack<T, const CAP: usize> {
|
||||||
items: Box<[MaybeUninit<T>; CAP]>,
|
items: [MaybeUninit<T>; CAP],
|
||||||
top: usize,
|
top: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,11 +28,7 @@ impl<T, const CAP: usize> Default for Stack<T, CAP> {
|
|||||||
impl<T, const CAP: usize> Stack<T, CAP> {
|
impl<T, const CAP: usize> Stack<T, CAP> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Stack {
|
Stack {
|
||||||
items: unsafe {
|
items: [const { MaybeUninit::uninit() }; CAP],
|
||||||
std::mem::transmute::<Box<MaybeUninit<[T; CAP]>>, Box<[MaybeUninit<T>; CAP]>>(
|
|
||||||
Box::new_uninit(),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
top: 0,
|
top: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ use std::rc::Rc;
|
|||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use inkwell::context::Context;
|
use inkwell::context::Context;
|
||||||
|
|
||||||
use crate::builtins::vm_env;
|
|
||||||
use crate::bytecode::{BinOp, Func as F, OpCode, OpCodes, Program, UnOp};
|
use crate::bytecode::{BinOp, Func as F, OpCode, OpCodes, Program, UnOp};
|
||||||
use crate::env::VmEnv;
|
use crate::env::VmEnv;
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
@@ -40,7 +39,7 @@ pub fn run(mut prog: Program) -> Result<p::Value> {
|
|||||||
jit: JITContext::new(&jit),
|
jit: JITContext::new(&jit),
|
||||||
};
|
};
|
||||||
prog.top_level.reverse();
|
prog.top_level.reverse();
|
||||||
Ok(eval(prog.top_level, &vm, vm_env(&vm))?.to_public(&vm, &mut HashSet::new()))
|
Ok(eval(prog.top_level, &vm, VmEnv::new(vec![]))?.to_public(&vm, &mut HashSet::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eval<'gc>(opcodes: Box<[OpCode]>, vm: &VM<'gc>, env: Rc<VmEnv<'gc>>) -> Result<Value<'gc>> {
|
pub fn eval<'gc>(opcodes: Box<[OpCode]>, vm: &VM<'gc>, env: Rc<VmEnv<'gc>>) -> Result<Value<'gc>> {
|
||||||
|
|||||||
Reference in New Issue
Block a user