From 381c192399926a76535ff9a561455a1dbaee315d Mon Sep 17 00:00:00 2001 From: Emmett Brown Date: Tue, 19 Oct 2021 01:08:37 +0200 Subject: [PATCH] Partial fix for issue #115: Initial support for local labels inside asm{} --- src/asm/state.rs | 110 ++++++++++++++++++++++++------------------- tests/issue115/3.asm | 29 ++++++++++++ 2 files changed, 91 insertions(+), 48 deletions(-) create mode 100644 tests/issue115/3.asm diff --git a/src/asm/state.rs b/src/asm/state.rs index 8373dd5d..32aba2a7 100644 --- a/src/asm/state.rs +++ b/src/asm/state.rs @@ -1386,68 +1386,82 @@ impl State subparser.suppress_reports(); //println!("> after subs `{:?}`", subs_tokens); - - let matches = asm::parser::match_rule_invocation( - &self, - subparser, - inner_ctx.clone(), - fileserver, - info.report.clone())?; - - let value = self.resolve_rule_invocation( - info.report.clone(), - &matches, - fileserver, - true, - info.args)?; - //println!(" value = {:?}", value); - - let (bigint, size) = match value.get_bigint() + if subparser.next_is(0, syntax::TokenKind::Identifier) && + subparser.next_is(1, syntax::TokenKind::Colon) { - Some(bigint) => + let label_tk = subparser.expect(syntax::TokenKind::Identifier)?; + let label_name = label_tk.excerpt.as_ref().unwrap(); + info.args.set_local( + label_name, + expr::Value::make_integer( + self.get_addr(info.report.clone(), &inner_ctx, &subparser_span)?) + ); + subparser.expect(syntax::TokenKind::Colon)?; + } + else + { + let matches = asm::parser::match_rule_invocation( + &self, + subparser, + inner_ctx.clone(), + fileserver, + info.report.clone())?; + + let value = self.resolve_rule_invocation( + info.report.clone(), + &matches, + fileserver, + true, + info.args)?; + + //println!(" value = {:?}", value); + + let (bigint, size) = match value.get_bigint() { - match bigint.size + Some(bigint) => { - Some(size) => (bigint, size), - None => + match bigint.size { - info.report.error_span( - "cannot infer size of instruction", - &subparser_span); + Some(size) => (bigint, size), + None => + { + info.report.error_span( + "cannot infer size of instruction", + &subparser_span); - return Err(()); + return Err(()); + } } } - } - _ => - { - info.report.error_span( - "wrong type returned from instruction", - &subparser_span); + _ => + { + info.report.error_span( + "wrong type returned from instruction", + &subparser_span); - return Err(()); - } - }; + return Err(()); + } + }; - if size > 0 - { - if result.size.unwrap() == 0 - { - result = bigint; - } - else + if size > 0 { - result = result.concat( - (result.size.unwrap(), 0), - &bigint, - (size, 0)); + if result.size.unwrap() == 0 + { + result = bigint; + } + else + { + result = result.concat( + (result.size.unwrap(), 0), + &bigint, + (size, 0)); + } + + inner_ctx.bit_offset += size; } - - inner_ctx.bit_offset += size; } - parser.expect_linebreak()?; } diff --git a/tests/issue115/3.asm b/tests/issue115/3.asm new file mode 100644 index 00000000..53c337ea --- /dev/null +++ b/tests/issue115/3.asm @@ -0,0 +1,29 @@ +#ruledef { + emit {x:u8} => x + + nested_test => asm + { + label: + emit $ + label2: + emit $ + emit label + emit label2 + emit $ + test + } + + test => asm + { + label: + emit $ + label2: + emit $ + emit label + emit label2 + emit $ + } +} + +test ; = 0x00_01_00_01_04 +nested_test ; = 0x05_06_05_06_09_0a_0b_0a_0b_0e \ No newline at end of file