implement Select and HasAttr
This commit is contained in:
+28
-7
@@ -74,6 +74,10 @@ pub trait VmContext {
|
||||
|
||||
pub(crate) trait VmContextExt: VmContext {
|
||||
fn get_string<'a, 'gc: 'a>(&'a self, val: StrictValue<'gc>) -> Option<&'a str>;
|
||||
fn get_string_id<'a, 'gc: 'a>(
|
||||
&'a mut self,
|
||||
val: StrictValue<'gc>,
|
||||
) -> std::result::Result<StringId, NixType>;
|
||||
fn convert_value(&self, val: Value) -> fix_common::Value;
|
||||
}
|
||||
|
||||
@@ -86,6 +90,19 @@ impl<T: VmContext> VmContextExt for T {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_string_id<'a, 'gc: 'a>(
|
||||
&'a mut self,
|
||||
val: StrictValue<'gc>,
|
||||
) -> std::result::Result<StringId, NixType> {
|
||||
if let Some(sid) = val.as_inline::<StringId>() {
|
||||
Ok(sid)
|
||||
} else if let Some(s) = val.as_gc::<NixString>().map(|ns| ns.as_ref().as_str()) {
|
||||
Ok(self.intern_string(s))
|
||||
} else {
|
||||
Err(val.ty())
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_value(&self, val: Value) -> fix_common::Value {
|
||||
use fix_common::Value;
|
||||
if let Some(i) = val.as_inline::<i32>() {
|
||||
@@ -288,7 +305,9 @@ impl<'gc> Vm<'gc> {
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn finish_type_err(&mut self, expected: NixType, got: NixType) -> Step {
|
||||
self.result = Some(Err(Error::eval_error(format!("expected {expected}, got {got}"))));
|
||||
self.result = Some(Err(Error::eval_error(format!(
|
||||
"expected {expected}, got {got}"
|
||||
))));
|
||||
Step::Break(Break::Done)
|
||||
}
|
||||
|
||||
@@ -320,8 +339,7 @@ impl<'gc> Vm<'gc> {
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub(crate) fn peek_forced(&mut self, depth: usize) -> StrictValue<'gc> {
|
||||
self
|
||||
.stack
|
||||
self.stack
|
||||
.get(self.stack.len() - depth - 1)
|
||||
.expect("stack underflow")
|
||||
.restrict()
|
||||
@@ -531,8 +549,13 @@ impl<'gc> Vm<'gc> {
|
||||
MakeEmptyAttrs => self.op_make_empty_attrs(),
|
||||
SelectStatic => self.op_select_static(ctx, &mut reader, mc),
|
||||
SelectDynamic => self.op_select_dynamic(ctx, &mut reader, mc),
|
||||
HasAttrPathStatic => self.op_has_attr_path_static(ctx, &mut reader, mc),
|
||||
HasAttrPathDynamic => self.op_has_attr_path_dynamic(ctx, &mut reader, mc),
|
||||
HasAttrStatic => self.op_has_attr_static(&mut reader, mc),
|
||||
HasAttrDynamic => self.op_has_attr_dynamic(ctx, &mut reader, mc),
|
||||
HasAttrResolve => self.op_has_attr_resolve(),
|
||||
JumpIfSelectFailed => self.op_jump_if_select_failed(&mut reader),
|
||||
JumpIfSelectSucceeded => self.op_jump_if_select_succeeded(&mut reader),
|
||||
HasAttr => self.op_has_attr(&mut reader),
|
||||
|
||||
MakeList => self.op_make_list(ctx, &mut reader, mc),
|
||||
MakeEmptyList => self.op_make_empty_list(),
|
||||
@@ -580,9 +603,7 @@ impl<'gc> Vm<'gc> {
|
||||
match result {
|
||||
Step::Continue(()) | Step::Break(Break::Force) => {}
|
||||
Step::Break(Break::Done) => {
|
||||
return Action::Done(
|
||||
self.result.take().expect("Break::Done without result"),
|
||||
);
|
||||
return Action::Done(self.result.take().expect("Break::Done without result"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user