mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-04 23:03:08 +00:00
Merge pull request #727 from mir-protocol/fix_macro_vars_in_stack
Fix macro vars in `%stack` directives
This commit is contained in:
commit
a84d3f5d44
@ -195,12 +195,12 @@ fn expand_macro_call(
|
||||
Item::StackManipulation(before, after) => {
|
||||
let after = after
|
||||
.iter()
|
||||
.map(|replacement| {
|
||||
if let StackReplacement::MacroLabel(label) = replacement {
|
||||
.map(|replacement| match replacement {
|
||||
StackReplacement::MacroLabel(label) => {
|
||||
StackReplacement::Identifier(get_actual_label(label))
|
||||
} else {
|
||||
replacement.clone()
|
||||
}
|
||||
StackReplacement::MacroVar(var) => get_arg(var).into(),
|
||||
_ => replacement.clone(),
|
||||
})
|
||||
.collect();
|
||||
Item::StackManipulation(before.clone(), after)
|
||||
@ -508,8 +508,8 @@ mod tests {
|
||||
"%macro bar(y) PUSH $y %endmacro",
|
||||
"%foo(42)",
|
||||
]);
|
||||
let push = get_push_opcode(1);
|
||||
assert_eq!(kernel.code, vec![push, 42, push, 42]);
|
||||
let push1 = get_push_opcode(1);
|
||||
assert_eq!(kernel.code, vec![push1, 42, push1, 42]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -587,6 +587,34 @@ mod tests {
|
||||
assert_eq!(kernel.code, vec![dup1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stack_manipulation_in_macro() {
|
||||
let pop = get_opcode("POP");
|
||||
let push1 = get_push_opcode(1);
|
||||
|
||||
let kernel = parse_and_assemble(&[
|
||||
"%macro set_top(x) %stack (a) -> ($x) %endmacro",
|
||||
"%set_top(42)",
|
||||
]);
|
||||
assert_eq!(kernel.code, vec![pop, push1, 42]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stack_manipulation_in_macro_with_name_collision() {
|
||||
let pop = get_opcode("POP");
|
||||
let push_label = get_push_opcode(BYTES_PER_OFFSET);
|
||||
|
||||
// In the stack directive, there's a named item `foo`.
|
||||
// But when we invoke `%foo(foo)`, the argument refers to the `foo` label.
|
||||
// Thus the expanded macro is `%stack (foo) -> (label foo)` (not real syntax).
|
||||
let kernel = parse_and_assemble(&[
|
||||
"global foo:",
|
||||
"%macro foo(x) %stack (foo) -> ($x) %endmacro",
|
||||
"%foo(foo)",
|
||||
]);
|
||||
assert_eq!(kernel.code, vec![pop, push_label, 0, 0, 0]);
|
||||
}
|
||||
|
||||
fn parse_and_assemble(files: &[&str]) -> Kernel {
|
||||
parse_and_assemble_ext(files, HashMap::new(), true)
|
||||
}
|
||||
|
||||
@ -46,14 +46,27 @@ pub(crate) enum StackPlaceholder {
|
||||
/// The right hand side of a %stack stack-manipulation macro.
|
||||
#[derive(Eq, PartialEq, Clone, Debug)]
|
||||
pub(crate) enum StackReplacement {
|
||||
Literal(U256),
|
||||
/// Can be either a named item or a label.
|
||||
Identifier(String),
|
||||
Literal(U256),
|
||||
Label(String),
|
||||
MacroLabel(String),
|
||||
MacroVar(String),
|
||||
Constant(String),
|
||||
}
|
||||
|
||||
impl From<PushTarget> for StackReplacement {
|
||||
fn from(target: PushTarget) -> Self {
|
||||
match target {
|
||||
PushTarget::Literal(x) => Self::Literal(x),
|
||||
PushTarget::Label(l) => Self::Label(l),
|
||||
PushTarget::MacroLabel(l) => Self::MacroLabel(l),
|
||||
PushTarget::MacroVar(v) => Self::MacroVar(v),
|
||||
PushTarget::Constant(c) => Self::Constant(c),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The target of a `PUSH` operation.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub(crate) enum PushTarget {
|
||||
|
||||
@ -52,6 +52,7 @@ fn expand(names: Vec<StackPlaceholder>, replacements: Vec<StackReplacement>) ->
|
||||
let mut dst = replacements
|
||||
.into_iter()
|
||||
.flat_map(|item| match item {
|
||||
StackReplacement::Literal(n) => vec![StackItem::PushTarget(PushTarget::Literal(n))],
|
||||
StackReplacement::Identifier(name) => {
|
||||
// May be either a named item or a label. Named items have precedence.
|
||||
if stack_blocks.contains_key(&name) {
|
||||
@ -68,7 +69,7 @@ fn expand(names: Vec<StackPlaceholder>, replacements: Vec<StackReplacement>) ->
|
||||
vec![StackItem::PushTarget(PushTarget::Label(name))]
|
||||
}
|
||||
}
|
||||
StackReplacement::Literal(n) => vec![StackItem::PushTarget(PushTarget::Literal(n))],
|
||||
StackReplacement::Label(name) => vec![StackItem::PushTarget(PushTarget::Label(name))],
|
||||
StackReplacement::MacroLabel(_)
|
||||
| StackReplacement::MacroVar(_)
|
||||
| StackReplacement::Constant(_) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user