small changes

This commit is contained in:
2026-04-03 23:56:23 +08:00
parent dc96e63b7c
commit e78e62795b
2 changed files with 21 additions and 97 deletions
+12 -14
View File
@@ -195,23 +195,21 @@ impl<'id: 'ir, 'ir, Ctx: DowngradeContext<'id, 'ir>> Downgrade<'id, 'ir, Ctx> fo
&& matches!(normalized.first(), Some(ast::InterpolPart::Literal(_))); && matches!(normalized.first(), Some(ast::InterpolPart::Literal(_)));
let bump = ctx.bump(); let bump = ctx.bump();
let parts = normalized let mut parts = normalized.into_iter().map(|part| match part {
.into_iter() ast::InterpolPart::Literal(lit) => Ok(ctx.new_expr(Ir::Str(lit.box_in(bump)))),
.map(|part| match part { ast::InterpolPart::Interpolation(interpol) => {
ast::InterpolPart::Literal(lit) => Ok(ctx.new_expr(Ir::Str(lit.box_in(bump)))), let inner = interpol
ast::InterpolPart::Interpolation(interpol) => { .expr()
let inner = interpol .require(ctx, interpol.syntax().text_range())?
.expr() .downgrade(ctx)?;
.require(ctx, interpol.syntax().text_range())? Ok(ctx.maybe_thunk(inner))
.downgrade(ctx)?; }
Ok(ctx.maybe_thunk(inner)) });
}
})
.collect_in::<Result<Vec<'ir, _>>>(bump)?;
Ok(if is_single_literal { Ok(if is_single_literal {
parts.into_iter().next().expect("is_single_literal checked") parts.next().expect("is_single_literal checked")?
} else { } else {
let parts = parts.collect_in::<Result<_>>(bump)?;
ctx.new_expr(Ir::ConcatStrings { ctx.new_expr(Ir::ConcatStrings {
parts, parts,
force_string: true, force_string: true,
+9 -83
View File
@@ -8,7 +8,7 @@ use smallvec::SmallVec;
use string_interner::{DefaultStringInterner, Symbol as _}; use string_interner::{DefaultStringInterner, Symbol as _};
use super::Runtime; use super::Runtime;
use super::builtins::{BUILTINS, BuiltinId, PrimOpArgs, PrimOpStrictArgs}; use super::builtins::{BUILTINS, BuiltinId};
use super::stack::Stack; use super::stack::Stack;
use super::value::*; use super::value::*;
use crate::codegen::{ use crate::codegen::{
@@ -78,79 +78,6 @@ pub(super) fn new_gc_root<'gc>(
} }
impl<'gc> GcRoot<'gc> { impl<'gc> GcRoot<'gc> {
fn init_builtins(
mc: &Mutation<'gc>,
strings: &mut DefaultStringInterner,
) -> (Value<'gc>, HashMap<StringId, PrimOp>) {
let mut builtin_lookup = HashMap::new();
let mut entries = SmallVec::new();
for (id, &(name, arity)) in BUILTINS.iter().enumerate() {
let Some(sym) = strings.get(name) else {
continue;
};
let sid = StringId(sym);
let primop = PrimOp {
id: BuiltinId::try_from_primitive(id as u8).expect("invalid BuiltinId??"),
arity,
};
builtin_lookup.insert(sid, primop);
// Regular primop
if arity != 0 {
entries.push((sid, Value::new_inline(primop)));
}
}
// Add constant entries
macro_rules! add_const {
($name:expr, $val:expr) => {{
let sym = strings.get_or_intern($name);
entries.push((StringId(sym), $val));
}};
}
add_const!(
"currentSystem",
Value::new_gc(Gc::new(mc, NixString::new("x86_64-linux")))
);
add_const!("langVersion", Value::new_inline(6i32));
add_const!(
"nixVersion",
Value::new_gc(Gc::new(mc, NixString::new("2.24.0")))
);
add_const!(
"storeDir",
Value::new_gc(Gc::new(mc, NixString::new("/nix/store")))
);
add_const!(
"nixPath",
Value::new_gc(Gc::new(
mc,
List {
inner: SmallVec::new()
}
))
);
add_const!("null", Value::new_inline(Null));
add_const!("true", Value::new_inline(true));
add_const!("false", Value::new_inline(false));
// Self-reference thunk for builtins.builtins
let self_ref_thunk: Gc<'gc, Thunk<'gc>> = Gc::new(mc, RefLock::new(ThunkState::Blackhole));
let sym = strings.get_or_intern("builtins");
entries.push((StringId(sym), Value::new_gc(self_ref_thunk)));
entries.sort_by_key(|(k, _)| *k);
let builtins_set = Gc::new(mc, unsafe { AttrSet::from_sorted_unchecked(entries) });
let builtins_val = Value::new_gc(builtins_set);
// Populate the self-reference
*self_ref_thunk.borrow_mut(mc) = ThunkState::Evaluated(builtins_val);
(builtins_val, builtin_lookup)
}
#[inline(always)] #[inline(always)]
fn env(&self) -> Gc<'gc, RefLock<Env<'gc>>> { fn env(&self) -> Gc<'gc, RefLock<Env<'gc>>> {
self.current_env.expect("no current env") self.current_env.expect("no current env")
@@ -396,12 +323,12 @@ impl Runtime {
LoadLocal => { LoadLocal => {
let idx = self.read_u32() as usize; let idx = self.read_u32() as usize;
self.arena self.arena
.mutate_root(|mc, root| root.push_stack(root.env().borrow().locals[idx])) .mutate_root(|_, root| root.push_stack(root.env().borrow().locals[idx]))
} }
LoadOuter => { LoadOuter => {
let layer = self.read_u8(); let layer = self.read_u8();
let idx = self.read_u32() as usize; let idx = self.read_u32() as usize;
self.arena.mutate_root(|mc, root| { self.arena.mutate_root(|_, root| {
let mut cur = root.env(); let mut cur = root.env();
for _ in 0..layer { for _ in 0..layer {
let prev = cur.borrow().prev.expect("LoadOuter: env chain too short"); let prev = cur.borrow().prev.expect("LoadOuter: env chain too short");
@@ -724,12 +651,11 @@ impl Runtime {
let found = self.arena.mutate_root(|_, root| { let found = self.arena.mutate_root(|_, root| {
let val = root.pop_stack(); let val = root.pop_stack();
if let Some(attrset) = val.as_gc::<AttrSet<'_>>() { if let Some(attrset) = val.as_gc::<AttrSet<'_>>()
if let Some(v) = attrset.lookup(key_sid) { && let Some(v) = attrset.lookup(key_sid) {
root.push_stack(v); root.push_stack(v);
return true; return true;
} }
}
// Not a set or key missing → use default // Not a set or key missing → use default
false false
}); });
@@ -757,7 +683,7 @@ impl Runtime {
} }
HasAttr => { HasAttr => {
let n = self.read_u16() as usize; let n = self.read_u16() as usize;
let keys = self.read_attr_keys(n); let _keys = self.read_attr_keys(n);
todo!("implement HasAttr (force + check)"); todo!("implement HasAttr (force + check)");
} }
@@ -846,8 +772,8 @@ impl Runtime {
} }
Assert => { Assert => {
let raw_idx = self.read_u32(); let _raw_idx = self.read_u32();
let span_id = self.read_u32(); let _span_id = self.read_u32();
todo!("implement Assert (force TOS)"); todo!("implement Assert (force TOS)");
} }
@@ -871,7 +797,7 @@ impl Runtime {
root.with_scope = scope.prev; root.with_scope = scope.prev;
}), }),
WithLookup => { WithLookup => {
let name = self.read_string_id(); let _name = self.read_string_id();
todo!("implement WithLookup (force with_scope)"); todo!("implement WithLookup (force with_scope)");
} }