Add deep access
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
parent
4f770c1f24
commit
ffd9baf90f
9 changed files with 669 additions and 5 deletions
|
|
@ -108,6 +108,20 @@ pub enum Instruction {
|
|||
args: Vec<VariableSlot>,
|
||||
slot: VariableSlot,
|
||||
},
|
||||
LoadFromSlotToSlot {
|
||||
from_slot: VariableSlot,
|
||||
to_slot: VariableSlot,
|
||||
},
|
||||
JumpIfUndefined {
|
||||
slot: VariableSlot,
|
||||
jump: LabelSlot,
|
||||
},
|
||||
IndexSlotToSlot {
|
||||
name: NomoInput,
|
||||
from_slot: VariableSlot,
|
||||
to_slot: VariableSlot,
|
||||
fail_on_not_found: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -452,6 +466,63 @@ fn emit_expr_load(
|
|||
fail_on_not_found: false,
|
||||
});
|
||||
}
|
||||
TemplateAstExpr::AccessOperation { op, lhs, rhs } => {
|
||||
assert_eq!(
|
||||
op,
|
||||
&TokenOperator::Dot,
|
||||
"Only dot can be used to access variables, this is a bug"
|
||||
);
|
||||
fn inner_access_op(
|
||||
eval: &mut Vec<Instruction>,
|
||||
end_label: LabelSlot,
|
||||
current_slot: VariableSlot,
|
||||
next: &TemplateAstExpr<'_>,
|
||||
) {
|
||||
match next {
|
||||
TemplateAstExpr::ConditionalAccess(template_token)
|
||||
| TemplateAstExpr::VariableAccess(template_token) => {
|
||||
eval.push(Instruction::IndexSlotToSlot {
|
||||
name: template_token.source().clone(),
|
||||
from_slot: current_slot,
|
||||
to_slot: current_slot,
|
||||
fail_on_not_found: matches!(
|
||||
next,
|
||||
TemplateAstExpr::VariableAccess { .. }
|
||||
),
|
||||
});
|
||||
eval.push(Instruction::JumpIfUndefined {
|
||||
slot: current_slot,
|
||||
jump: end_label,
|
||||
});
|
||||
}
|
||||
TemplateAstExpr::AccessOperation { op, lhs, rhs } => {
|
||||
assert_eq!(
|
||||
op,
|
||||
&TokenOperator::Dot,
|
||||
"Only dot can be used to access variables, this is a bug"
|
||||
);
|
||||
|
||||
inner_access_op(eval, end_label, current_slot, lhs);
|
||||
inner_access_op(eval, end_label, current_slot, rhs);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
let end_label = machine.reserve_label();
|
||||
let start_slot = machine.reserve_slot();
|
||||
emit_expr_load(machine, eval, start_slot, lhs);
|
||||
eval.push(Instruction::JumpIfUndefined {
|
||||
slot: start_slot,
|
||||
jump: end_label,
|
||||
});
|
||||
inner_access_op(eval, end_label, start_slot, rhs);
|
||||
machine.assign_label(end_label, eval.len());
|
||||
eval.push(Instruction::LoadFromSlotToSlot {
|
||||
from_slot: start_slot,
|
||||
to_slot: emit_slot,
|
||||
});
|
||||
}
|
||||
TemplateAstExpr::Literal { source, value } => {
|
||||
eval.push(Instruction::LoadLiteralToSlot {
|
||||
source: source.clone(),
|
||||
|
|
@ -492,7 +563,6 @@ fn emit_expr_load(
|
|||
}
|
||||
TemplateAstExpr::ConditionalChain { .. } => todo!(),
|
||||
TemplateAstExpr::ElseConditional { .. } => todo!(),
|
||||
TemplateAstExpr::AccessOperation { .. } => todo!(),
|
||||
TemplateAstExpr::EndBlock => todo!(),
|
||||
TemplateAstExpr::Block { .. } => todo!(),
|
||||
TemplateAstExpr::ForChain { .. } => todo!(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue