From b6ac5637fd44a1d5aae689d9cc270a647e52119d Mon Sep 17 00:00:00 2001 From: hlorenzi Date: Mon, 18 Jul 2022 20:11:36 -0300 Subject: [PATCH] add support for out-of-order constant declaration --- Cargo.toml | 2 +- src/asm/invocation.rs | 9 +++++++ src/asm/mod.rs | 1 + src/asm/parser/symbol.rs | 14 ++++++++++- src/asm/state.rs | 20 ++++++++++++++++ .../err1_unknown_y.asm | 3 +++ .../err2_unknown_z.asm | 5 ++++ .../err3_cyclical.asm | 6 +++++ .../err4_cascading_instr.asm | 20 ++++++++++++++++ .../err5_cascading_instr.asm | 20 ++++++++++++++++ tests/symbol_constant_outoforder/ok1_xy.asm | 5 ++++ tests/symbol_constant_outoforder/ok2_xyz.asm | 7 ++++++ .../ok3_cyclical_allzero.asm | 5 ++++ .../ok4_cascading_instr.asm | 24 +++++++++++++++++++ .../ok5_cascading_instr.asm | 20 ++++++++++++++++ .../1.asm | 0 .../2.asm | 0 .../3.asm | 0 .../err1_duplicate.asm} | 0 tests/symbol_variable_simple/4.asm | 10 -------- 20 files changed, 159 insertions(+), 12 deletions(-) create mode 100644 tests/symbol_constant_outoforder/err1_unknown_y.asm create mode 100644 tests/symbol_constant_outoforder/err2_unknown_z.asm create mode 100644 tests/symbol_constant_outoforder/err3_cyclical.asm create mode 100644 tests/symbol_constant_outoforder/err4_cascading_instr.asm create mode 100644 tests/symbol_constant_outoforder/err5_cascading_instr.asm create mode 100644 tests/symbol_constant_outoforder/ok1_xy.asm create mode 100644 tests/symbol_constant_outoforder/ok2_xyz.asm create mode 100644 tests/symbol_constant_outoforder/ok3_cyclical_allzero.asm create mode 100644 tests/symbol_constant_outoforder/ok4_cascading_instr.asm create mode 100644 tests/symbol_constant_outoforder/ok5_cascading_instr.asm rename tests/{symbol_variable_simple => symbol_constant_simple}/1.asm (100%) rename tests/{symbol_variable_simple => symbol_constant_simple}/2.asm (100%) rename tests/{symbol_variable_simple => symbol_constant_simple}/3.asm (100%) rename tests/{symbol_variable_simple/5.asm => symbol_constant_simple/err1_duplicate.asm} (100%) delete mode 100644 tests/symbol_variable_simple/4.asm diff --git a/Cargo.toml b/Cargo.toml index 3178106d..a3a21f6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "customasm" -version = "0.11.15" +version = "0.12.0" edition = "2021" authors = ["hlorenzi "] description = "An assembler for custom, user-defined instruction sets!" diff --git a/src/asm/invocation.rs b/src/asm/invocation.rs index 0fc002bb..9c12502e 100644 --- a/src/asm/invocation.rs +++ b/src/asm/invocation.rs @@ -17,6 +17,7 @@ pub enum InvocationKind Rule(RuleInvocation), Data(DataInvocation), Label(LabelInvocation), + Constant(ConstantInvocation), } @@ -57,6 +58,14 @@ pub struct DataInvocation pub struct LabelInvocation; +#[derive(Debug)] +pub struct ConstantInvocation +{ + pub expr: expr::Expr, + pub value_guess: expr::Value, +} + + impl Invocation { pub fn get_rule_invoc(&self) -> &RuleInvocation diff --git a/src/asm/mod.rs b/src/asm/mod.rs index fe058694..253333bc 100644 --- a/src/asm/mod.rs +++ b/src/asm/mod.rs @@ -28,6 +28,7 @@ pub use self::invocation::RuleInvocationCandidate; pub use self::invocation::RuleInvocationArgument; pub use self::invocation::DataInvocation; pub use self::invocation::LabelInvocation; +pub use self::invocation::ConstantInvocation; pub use self::bank::Bank; pub use self::bank::BankData; pub use self::symbol::SymbolManager; diff --git a/src/asm/parser/symbol.rs b/src/asm/parser/symbol.rs index 6700efaf..190a376b 100644 --- a/src/asm/parser/symbol.rs +++ b/src/asm/parser/symbol.rs @@ -32,7 +32,19 @@ pub fn parse_symbol( &ctx, &mut expr::EvalContext::new(), state.fileserver, - true)?; + false)?; + + let bankdata = state.asm_state.get_bankdata_mut(state.asm_state.cur_bank); + bankdata.push_invocation(asm::Invocation + { + ctx: ctx.clone(), + size_guess: 0, + span: span.clone(), + kind: asm::InvocationKind::Constant(asm::ConstantInvocation { + expr, + value_guess: value.clone(), + }), + }); state.parser.expect_linebreak()?; value diff --git a/src/asm/state.rs b/src/asm/state.rs index ba0de297..27376510 100644 --- a/src/asm/state.rs +++ b/src/asm/state.rs @@ -498,6 +498,26 @@ impl State continue; } + + asm::InvocationKind::Constant(ref constant_invoc) => + { + let final_value = self.eval_expr( + report.clone(), + &constant_invoc.expr, + &invoc.ctx, + &mut expr::EvalContext::new(), + fileserver, + true)?; + + if final_value != constant_invoc.value_guess + { + report.error_span( + "constant value did not converge after iterations", + &invoc.span); + } + + continue; + } }; let resolved = match maybe_resolved diff --git a/tests/symbol_constant_outoforder/err1_unknown_y.asm b/tests/symbol_constant_outoforder/err1_unknown_y.asm new file mode 100644 index 00000000..0a7c4043 --- /dev/null +++ b/tests/symbol_constant_outoforder/err1_unknown_y.asm @@ -0,0 +1,3 @@ +x = y + y ; error: unknown + +#d8 x \ No newline at end of file diff --git a/tests/symbol_constant_outoforder/err2_unknown_z.asm b/tests/symbol_constant_outoforder/err2_unknown_z.asm new file mode 100644 index 00000000..4ccdb539 --- /dev/null +++ b/tests/symbol_constant_outoforder/err2_unknown_z.asm @@ -0,0 +1,5 @@ +x = y + y +y = z + z ; error: unknown + +#d8 x +#d8 y \ No newline at end of file diff --git a/tests/symbol_constant_outoforder/err3_cyclical.asm b/tests/symbol_constant_outoforder/err3_cyclical.asm new file mode 100644 index 00000000..c294726e --- /dev/null +++ b/tests/symbol_constant_outoforder/err3_cyclical.asm @@ -0,0 +1,6 @@ +x = y + 1 ; error: converge +y = z + 1 ; error: converge +z = x + 1 + +#d8 x +#d8 y \ No newline at end of file diff --git a/tests/symbol_constant_outoforder/err4_cascading_instr.asm b/tests/symbol_constant_outoforder/err4_cascading_instr.asm new file mode 100644 index 00000000..bc0cea7c --- /dev/null +++ b/tests/symbol_constant_outoforder/err4_cascading_instr.asm @@ -0,0 +1,20 @@ +#ruledef test +{ + ld {x} => + { + assert(x <= 0x8) + 0x11 @ x`16 + } + + ld {x} => + { + assert(x > 0x8) + 0x22 @ x`8 + } +} + +x = y ; error: converge + ld x + ld x +label: +y = label + 3 \ No newline at end of file diff --git a/tests/symbol_constant_outoforder/err5_cascading_instr.asm b/tests/symbol_constant_outoforder/err5_cascading_instr.asm new file mode 100644 index 00000000..ef34fb21 --- /dev/null +++ b/tests/symbol_constant_outoforder/err5_cascading_instr.asm @@ -0,0 +1,20 @@ +#ruledef test +{ + ld {x} => + { + assert(x <= 0x8) + 0x11 @ x`16 + } + + ld {x} => + { + assert(x > 0x8) + 0x22 @ x`8 + } +} + + ld x ; error: converge + ld x ; error: converge +x = y +label: +y = label + 3 \ No newline at end of file diff --git a/tests/symbol_constant_outoforder/ok1_xy.asm b/tests/symbol_constant_outoforder/ok1_xy.asm new file mode 100644 index 00000000..bd215f23 --- /dev/null +++ b/tests/symbol_constant_outoforder/ok1_xy.asm @@ -0,0 +1,5 @@ +x = y + y +y = 1 + +#d8 x ; = 0x02 +#d8 y ; = 0x01 \ No newline at end of file diff --git a/tests/symbol_constant_outoforder/ok2_xyz.asm b/tests/symbol_constant_outoforder/ok2_xyz.asm new file mode 100644 index 00000000..cbb8076f --- /dev/null +++ b/tests/symbol_constant_outoforder/ok2_xyz.asm @@ -0,0 +1,7 @@ +x = y + y +y = z + z +z = 1 + +#d8 x ; = 0x04 +#d8 y ; = 0x02 +#d8 z ; = 0x01 \ No newline at end of file diff --git a/tests/symbol_constant_outoforder/ok3_cyclical_allzero.asm b/tests/symbol_constant_outoforder/ok3_cyclical_allzero.asm new file mode 100644 index 00000000..c9ed7393 --- /dev/null +++ b/tests/symbol_constant_outoforder/ok3_cyclical_allzero.asm @@ -0,0 +1,5 @@ +x = y +y = x + +#d8 x ; = 0x00 +#d8 y ; = 0x00 \ No newline at end of file diff --git a/tests/symbol_constant_outoforder/ok4_cascading_instr.asm b/tests/symbol_constant_outoforder/ok4_cascading_instr.asm new file mode 100644 index 00000000..dbc57ada --- /dev/null +++ b/tests/symbol_constant_outoforder/ok4_cascading_instr.asm @@ -0,0 +1,24 @@ +#ruledef test +{ + ld {x} => + { + assert(x <= 0x8) + 0x11 @ x`16 + } + + ld {x} => + { + assert(x > 0x8) + 0x22 @ x`8 + } +} + +x1 = y1 + y1 +ld x1 ; = 0x2210 +ld x1 ; = 0x2210 +y1 = 8 + +ld x2 ; = 0x110002 +ld x2 ; = 0x110002 +x2 = y2 + y2 +y2 = 1 \ No newline at end of file diff --git a/tests/symbol_constant_outoforder/ok5_cascading_instr.asm b/tests/symbol_constant_outoforder/ok5_cascading_instr.asm new file mode 100644 index 00000000..271cd7c5 --- /dev/null +++ b/tests/symbol_constant_outoforder/ok5_cascading_instr.asm @@ -0,0 +1,20 @@ +#ruledef test +{ + ld {x} => + { + assert(x <= 0x8) + 0x11 @ x`16 + } + + ld {x} => + { + assert(x > 0x8) + 0x22 @ x`8 + } +} + +x = y + ld x ; = 0x110006 + ld x ; = 0x110006 +y = label +label: \ No newline at end of file diff --git a/tests/symbol_variable_simple/1.asm b/tests/symbol_constant_simple/1.asm similarity index 100% rename from tests/symbol_variable_simple/1.asm rename to tests/symbol_constant_simple/1.asm diff --git a/tests/symbol_variable_simple/2.asm b/tests/symbol_constant_simple/2.asm similarity index 100% rename from tests/symbol_variable_simple/2.asm rename to tests/symbol_constant_simple/2.asm diff --git a/tests/symbol_variable_simple/3.asm b/tests/symbol_constant_simple/3.asm similarity index 100% rename from tests/symbol_variable_simple/3.asm rename to tests/symbol_constant_simple/3.asm diff --git a/tests/symbol_variable_simple/5.asm b/tests/symbol_constant_simple/err1_duplicate.asm similarity index 100% rename from tests/symbol_variable_simple/5.asm rename to tests/symbol_constant_simple/err1_duplicate.asm diff --git a/tests/symbol_variable_simple/4.asm b/tests/symbol_variable_simple/4.asm deleted file mode 100644 index 5a947b79..00000000 --- a/tests/symbol_variable_simple/4.asm +++ /dev/null @@ -1,10 +0,0 @@ -#ruledef test -{ - ld {x} => 0x55 @ x`8 -} - - -val2 = val1 + val1 ; error: unknown -val1 = 2 * 2 -ld val1 -ld val2 \ No newline at end of file