65 lines
2.2 KiB
Rust
65 lines
2.2 KiB
Rust
use hashbrown::HashMap;
|
|
use std::rc::Rc;
|
|
|
|
use crate::ty::common::Const;
|
|
use crate::ty::internal::{AttrSet, PrimOp, Value};
|
|
use crate::vm::{VM, VmEnv};
|
|
|
|
pub fn env<'jit, 'vm>(vm: &'vm VM<'jit>) -> VmEnv<'jit, 'vm> {
|
|
let mut env_map = HashMap::new();
|
|
env_map.insert(vm.new_sym("true"), Value::Const(Const::Bool(true)));
|
|
env_map.insert(vm.new_sym("false"), Value::Const(Const::Bool(false)));
|
|
|
|
let primops = [
|
|
PrimOp::new("add", 2, |_, args| {
|
|
let [first, second]: [Value; 2] = args.try_into().unwrap();
|
|
first.add(second).ok()
|
|
}),
|
|
PrimOp::new("sub", 2, |_, args| {
|
|
let [first, second]: [Value; 2] = args.try_into().unwrap();
|
|
first.add(second.neg()).ok()
|
|
}),
|
|
PrimOp::new("mul", 2, |_, args| {
|
|
let [first, second]: [Value; 2] = args.try_into().unwrap();
|
|
first.mul(second).ok()
|
|
}),
|
|
PrimOp::new("div", 2, |_, args| {
|
|
let [first, second]: [Value; 2] = args.try_into().unwrap();
|
|
first.div(second)
|
|
}),
|
|
PrimOp::new("lessThan", 2, |_, args| {
|
|
let [first, second]: [Value; 2] = args.try_into().unwrap();
|
|
first.lt(second).ok()
|
|
}),
|
|
PrimOp::new("seq", 2, |vm, args| {
|
|
let [mut first, second]: [Value; 2] = args.try_into().unwrap();
|
|
first.force(vm).unwrap();
|
|
second.ok()
|
|
}),
|
|
PrimOp::new("deepSeq", 2, |vm, args| {
|
|
let [mut first, second]: [Value; 2] = args.try_into().unwrap();
|
|
first.force_deep(vm).unwrap();
|
|
second.ok()
|
|
}),
|
|
];
|
|
|
|
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 attrs = Rc::new_cyclic(|weak| {
|
|
map.insert(sym, Value::Builtins(weak.clone()));
|
|
AttrSet::from_inner(map)
|
|
});
|
|
let builtins = Value::AttrSet(attrs);
|
|
|
|
env_map.insert(sym, builtins);
|
|
VmEnv::new(env_map.into())
|
|
}
|