mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-08 00:33:06 +00:00
Fix macro vars in %stack directive
This commit is contained in:
parent
ee575f7c33
commit
f876a8ab02
@ -195,12 +195,12 @@ fn expand_macro_call(
|
|||||||
Item::StackManipulation(before, after) => {
|
Item::StackManipulation(before, after) => {
|
||||||
let after = after
|
let after = after
|
||||||
.iter()
|
.iter()
|
||||||
.map(|replacement| {
|
.map(|replacement| match replacement {
|
||||||
if let StackReplacement::MacroLabel(label) = replacement {
|
StackReplacement::MacroLabel(label) => {
|
||||||
StackReplacement::Identifier(get_actual_label(label))
|
StackReplacement::Identifier(get_actual_label(label))
|
||||||
} else {
|
|
||||||
replacement.clone()
|
|
||||||
}
|
}
|
||||||
|
StackReplacement::MacroVar(var) => get_arg(var).into(),
|
||||||
|
_ => replacement.clone(),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
Item::StackManipulation(before.clone(), after)
|
Item::StackManipulation(before.clone(), after)
|
||||||
@ -508,8 +508,8 @@ mod tests {
|
|||||||
"%macro bar(y) PUSH $y %endmacro",
|
"%macro bar(y) PUSH $y %endmacro",
|
||||||
"%foo(42)",
|
"%foo(42)",
|
||||||
]);
|
]);
|
||||||
let push = get_push_opcode(1);
|
let push1 = get_push_opcode(1);
|
||||||
assert_eq!(kernel.code, vec![push, 42, push, 42]);
|
assert_eq!(kernel.code, vec![push1, 42, push1, 42]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -587,6 +587,34 @@ mod tests {
|
|||||||
assert_eq!(kernel.code, vec![dup1]);
|
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 {
|
fn parse_and_assemble(files: &[&str]) -> Kernel {
|
||||||
parse_and_assemble_ext(files, HashMap::new(), true)
|
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.
|
/// The right hand side of a %stack stack-manipulation macro.
|
||||||
#[derive(Eq, PartialEq, Clone, Debug)]
|
#[derive(Eq, PartialEq, Clone, Debug)]
|
||||||
pub(crate) enum StackReplacement {
|
pub(crate) enum StackReplacement {
|
||||||
|
Literal(U256),
|
||||||
/// Can be either a named item or a label.
|
/// Can be either a named item or a label.
|
||||||
Identifier(String),
|
Identifier(String),
|
||||||
Literal(U256),
|
Label(String),
|
||||||
MacroLabel(String),
|
MacroLabel(String),
|
||||||
MacroVar(String),
|
MacroVar(String),
|
||||||
Constant(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.
|
/// The target of a `PUSH` operation.
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub(crate) enum PushTarget {
|
pub(crate) enum PushTarget {
|
||||||
|
|||||||
@ -52,6 +52,7 @@ fn expand(names: Vec<StackPlaceholder>, replacements: Vec<StackReplacement>) ->
|
|||||||
let mut dst = replacements
|
let mut dst = replacements
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|item| match item {
|
.flat_map(|item| match item {
|
||||||
|
StackReplacement::Literal(n) => vec![StackItem::PushTarget(PushTarget::Literal(n))],
|
||||||
StackReplacement::Identifier(name) => {
|
StackReplacement::Identifier(name) => {
|
||||||
// May be either a named item or a label. Named items have precedence.
|
// May be either a named item or a label. Named items have precedence.
|
||||||
if stack_blocks.contains_key(&name) {
|
if stack_blocks.contains_key(&name) {
|
||||||
@ -68,7 +69,7 @@ fn expand(names: Vec<StackPlaceholder>, replacements: Vec<StackReplacement>) ->
|
|||||||
vec![StackItem::PushTarget(PushTarget::Label(name))]
|
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::MacroLabel(_)
|
||||||
| StackReplacement::MacroVar(_)
|
| StackReplacement::MacroVar(_)
|
||||||
| StackReplacement::Constant(_) => {
|
| StackReplacement::Constant(_) => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user