diff --git a/src/asm/matcher/mod.rs b/src/asm/matcher/mod.rs index f0b8b4aa..71aa11a4 100644 --- a/src/asm/matcher/mod.rs +++ b/src/asm/matcher/mod.rs @@ -596,53 +596,40 @@ fn match_with_expr<'tokens>( match_so_far: &mut InstructionMatch) -> WorkingMatches<'tokens> { - if walker.is_at_partial() - { - match walker.maybe_expect_partial_usize() - { - None => - { - return vec![]; - } - Some(value) => - { - let expr = expr::Value::make_integer(value) - .make_literal(); + walker.reinterpret_next_tokens(&mut diagn::Report::new()).unwrap(); - match_so_far.args.push(InstructionArgument { - kind: InstructionArgumentKind::Expr(expr), - tokens: Vec::new(), - }); - } + let token_start = walker.get_current_token_index(); + + let maybe_expr = parse_with_lookahead( + &rule.pattern, + at_pattern_part, + walker, + |walker| expr::parse_optional(walker)); + + dbg!(&maybe_expr); + + let token_end = walker.get_current_token_index(); + + let expr = { + match maybe_expr + { + Some(expr) => expr, + None => return vec![], } - } - else - { - let token_start = walker.get_current_token_index(); + }; - let maybe_expr = parse_with_lookahead( - &rule.pattern, - at_pattern_part, - walker, - |walker| expr::parse_optional(walker)); + let tokens = walker.get_cloned_tokens_by_index( + token_start, + token_end); - let token_end = walker.get_current_token_index(); + dbg!(&tokens); - let expr = { - match maybe_expr - { - Some(expr) => expr, - None => return vec![], - } - }; + match_so_far.args.push(InstructionArgument { + kind: InstructionArgumentKind::Expr(expr), + tokens, + }); - match_so_far.args.push(InstructionArgument { - kind: InstructionArgumentKind::Expr(expr), - tokens: walker.get_cloned_tokens_by_index( - token_start, - token_end), - }); - } + dbg!(&match_so_far.args); match_with_rule( defs, @@ -664,6 +651,8 @@ fn match_with_nested_ruledef<'tokens>( match_so_far: &mut InstructionMatch) -> WorkingMatches<'tokens> { + walker.reinterpret_next_tokens(&mut diagn::Report::new()).unwrap(); + let token_start = walker.get_current_token_index(); let nested_matches = parse_with_lookahead( @@ -687,11 +676,15 @@ fn match_with_nested_ruledef<'tokens>( let mut match_so_far = match_so_far.clone(); + let tokens = walker.get_cloned_tokens_by_index( + token_start, + walker.get_current_token_index()); + + dbg!(&tokens); + match_so_far.args.push(InstructionArgument { kind: InstructionArgumentKind::Nested(nested_match.0), - tokens: walker.get_cloned_tokens_by_index( - token_start, - walker.get_current_token_index()), + tokens, }); diff --git a/src/asm/parser/directive_ruledef.rs b/src/asm/parser/directive_ruledef.rs index 069daee6..d72b3474 100644 --- a/src/asm/parser/directive_ruledef.rs +++ b/src/asm/parser/directive_ruledef.rs @@ -61,7 +61,7 @@ pub fn parse( -> Result { let tk_name = walker.maybe_expect(syntax::TokenKind::Identifier); - let name = tk_name.map(|tk| tk.excerpt.clone().unwrap()); + let name = tk_name.clone().map(|tk| tk.excerpt.clone().unwrap()); let name_span = tk_name .map(|tk| tk.span) .unwrap_or_else(|| header_span); diff --git a/src/asm/parser/mod.rs b/src/asm/parser/mod.rs index 65285f46..034ebc5a 100644 --- a/src/asm/parser/mod.rs +++ b/src/asm/parser/mod.rs @@ -4,36 +4,24 @@ use crate::*; mod directive; mod directive_addr; -pub use directive_addr::{ - AstDirectiveAddr, -}; +pub use directive_addr::AstDirectiveAddr; mod directive_align; -pub use directive_align::{ - AstDirectiveAlign, -}; +pub use directive_align::AstDirectiveAlign; mod directive_bank; -pub use directive_bank::{ - AstDirectiveBank, -}; +pub use directive_bank::AstDirectiveBank; mod directive_bankdef; -pub use directive_bankdef::{ - AstDirectiveBankdef, -}; +pub use directive_bankdef::AstDirectiveBankdef; mod directive_bits; -pub use directive_bits::{ - AstDirectiveBits, -}; +pub use directive_bits::AstDirectiveBits; mod directive_const; mod directive_data; -pub use directive_data::{ - AstDirectiveData, -}; +pub use directive_data::AstDirectiveData; mod directive_fn; pub use directive_fn::{ @@ -42,34 +30,22 @@ pub use directive_fn::{ }; mod directive_if; -pub use directive_if::{ - AstDirectiveIf, -}; +pub use directive_if::AstDirectiveIf; mod directive_include; -pub use directive_include::{ - AstDirectiveInclude, -}; +pub use directive_include::AstDirectiveInclude; mod directive_labelalign; -pub use directive_labelalign::{ - AstDirectiveLabelAlign, -}; +pub use directive_labelalign::AstDirectiveLabelAlign; mod directive_noemit; -pub use directive_noemit::{ - AstDirectiveNoEmit, -}; +pub use directive_noemit::AstDirectiveNoEmit; mod directive_once; -pub use directive_once::{ - AstDirectiveOnce, -}; +pub use directive_once::AstDirectiveOnce; mod directive_res; -pub use directive_res::{ - AstDirectiveRes, -}; +pub use directive_res::AstDirectiveRes; mod directive_ruledef; pub use directive_ruledef::{ @@ -87,9 +63,7 @@ pub use fields::{ }; mod instruction; -pub use instruction::{ - AstInstruction, -}; +pub use instruction::AstInstruction; mod symbol; pub use symbol::{ diff --git a/src/asm/resolver/eval_asm.rs b/src/asm/resolver/eval_asm.rs index db5fe739..5fabfc08 100644 --- a/src/asm/resolver/eval_asm.rs +++ b/src/asm/resolver/eval_asm.rs @@ -152,11 +152,11 @@ pub fn eval_asm( } -struct AsmSubstitution<'a> +struct AsmSubstitution { pub start: usize, pub end: usize, - pub name: &'a str, + pub name: String, pub span: diagn::Span, } @@ -164,7 +164,7 @@ struct AsmSubstitution<'a> fn parse_substitutions<'tokens>( report: &mut diagn::Report, tokens: &'tokens [syntax::Token]) - -> Result>, ()> + -> Result, ()> { let mut substs = Vec::new(); @@ -180,7 +180,7 @@ fn parse_substitutions<'tokens>( report, syntax::TokenKind::Identifier)?; - let name = tk_name.excerpt.as_ref().unwrap(); + let name = tk_name.clone().excerpt.unwrap(); let span = tk_name.span; walker.expect( @@ -208,7 +208,7 @@ fn parse_substitutions<'tokens>( fn perform_substitutions<'tokens>( tokens: &'tokens [syntax::Token], - substs: &Vec>, + substs: &Vec, info: &mut expr::EvalAsmBlockQuery) -> Result, ()> { @@ -225,7 +225,7 @@ fn perform_substitutions<'tokens>( } let token_subst = { - match info.eval_ctx.get_token_subst(subst.name) + match info.eval_ctx.get_token_subst(&subst.name) { Some(t) => t, None => diff --git a/src/diagn/span.rs b/src/diagn/span.rs index 387cbc7f..c24f5c70 100644 --- a/src/diagn/span.rs +++ b/src/diagn/span.rs @@ -8,6 +8,8 @@ pub type SpanIndex = u32; pub struct Span { pub file_handle: util::FileServerHandle, + + /// Represents byte indices (not UTF-8 char indices) location: (SpanIndex, SpanIndex), } @@ -45,6 +47,17 @@ impl Span Some(self.location) } + + + pub fn length(&self) -> usize + { + if self.location.0 == SpanIndex::MAX + { + return 0; + } + + (self.location.1 - self.location.0) as usize + } pub fn before(&self) -> Span diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index a5063f86..562fa639 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -3,13 +3,15 @@ pub use self::token::{ Token, TokenKind, tokenize, + decide_next_token, is_whitespace, }; mod token_walker; -pub use self::token_walker::{ - TokenWalker, -}; +pub use self::token_walker::TokenWalker; + +mod walker; +pub use self::walker::Walker; mod excerpt; pub use self::excerpt::{ diff --git a/src/syntax/token.rs b/src/syntax/token.rs index 0a815747..836ea7ba 100644 --- a/src/syntax/token.rs +++ b/src/syntax/token.rs @@ -263,14 +263,7 @@ pub fn tokenize( let remaining = &src.get(index..).unwrap(); // Decide what the next token's kind and length are. - let (kind, length) = - check_for_whitespace(remaining).unwrap_or_else(|| - check_for_comment (remaining).unwrap_or_else(|| - check_for_number (remaining).unwrap_or_else(|| - check_for_identifier(remaining).unwrap_or_else(|| - check_for_special (remaining).unwrap_or_else(|| - check_for_string (remaining).unwrap_or_else(|| - (TokenKind::Error, 1))))))); + let (kind, length) = decide_next_token(&remaining); let span = diagn::Span::new( src_file_handle, @@ -315,6 +308,20 @@ pub fn tokenize( } +pub fn decide_next_token( + src: &str) + -> (TokenKind, usize) +{ + check_for_whitespace(src).unwrap_or_else(|| + check_for_comment (src).unwrap_or_else(|| + check_for_number (src).unwrap_or_else(|| + check_for_identifier(src).unwrap_or_else(|| + check_for_special (src).unwrap_or_else(|| + check_for_string (src).unwrap_or_else(|| + (TokenKind::Error, 1))))))) +} + + #[derive(Clone)] struct CharWalker<'a> { diff --git a/src/syntax/token_walker.rs b/src/syntax/token_walker.rs index 84d3fed8..80d3b733 100644 --- a/src/syntax/token_walker.rs +++ b/src/syntax/token_walker.rs @@ -5,6 +5,7 @@ use crate::*; pub struct TokenWalker<'tokens> { tokens: &'tokens [syntax::Token], + reinterpreted_token: Option, index: usize, index_prev: usize, read_linebreak: bool, @@ -36,9 +37,9 @@ impl<'tokens> TokenWalker<'tokens> excerpt: None, }; - let mut parser = TokenWalker - { + let mut parser = TokenWalker { tokens: tokens, + reinterpreted_token: None, index: 0, index_prev: 0, read_linebreak: false, @@ -53,6 +54,27 @@ impl<'tokens> TokenWalker<'tokens> } + pub fn get_token(&self, index: usize) -> &syntax::Token + { + if let Some(ref tk) = self.reinterpreted_token + { + if index == 0 + { tk } + else if self.index >= self.tokens.len() + { &self.dummy_token } + else + { &self.tokens[index - 1] } + } + else + { + if self.index >= self.tokens.len() + { &self.dummy_token } + else + { &self.tokens[index] } + } + } + + pub fn get_current_token_index(&self) -> usize { self.index @@ -156,7 +178,7 @@ impl<'tokens> TokenWalker<'tokens> } - pub fn clone_slice<'b>( + pub fn clone_with_token_range<'b>( &'b self, start: usize, end: usize) @@ -201,11 +223,11 @@ impl<'tokens> TokenWalker<'tokens> if self.get_current_token_index() == start { - self.clone_slice(start, start) + self.clone_with_token_range(start, start) } else { - self.clone_slice(start, self.get_previous_token_index() + 1) + self.clone_with_token_range(start, self.get_previous_token_index() + 1) } } @@ -246,11 +268,11 @@ impl<'tokens> TokenWalker<'tokens> if self.get_current_token_index() == start { - self.clone_slice(start, start) + self.clone_with_token_range(start, start) } else { - self.clone_slice(start, self.get_previous_token_index() + 1) + self.clone_with_token_range(start, self.get_previous_token_index() + 1) } } @@ -326,6 +348,7 @@ impl<'tokens> TokenWalker<'tokens> self.read_whitespace_index = other.read_whitespace_index; self.read_whitespace_acknowledged = other.read_whitespace_acknowledged; self.partial_index = other.partial_index; + self.reinterpreted_token = other.reinterpreted_token.clone(); self.skip_ignorable(); } @@ -338,6 +361,9 @@ impl<'tokens> TokenWalker<'tokens> pub fn skip_ignorable(&mut self) { + if self.reinterpreted_token.is_some() + { return; } + while self.index < self.tokens.len() && self.tokens[self.index].kind.is_ignorable() { @@ -355,20 +381,26 @@ impl<'tokens> TokenWalker<'tokens> } - pub fn advance(&mut self) -> &'tokens syntax::Token + pub fn advance(&mut self) -> syntax::Token { if self.is_at_partial() { panic!("trying to advance TokenWalker at partial token"); } self.index_prev = self.index; - let token = &self.tokens[self.index]; + let token = { + if self.reinterpreted_token.is_some() + { self.reinterpreted_token.take().unwrap() } + else + { self.tokens[self.index].clone() } + }; if self.index < self.tokens.len() { self.index += 1; } self.read_linebreak = false; - + self.reinterpreted_token = None; + self.skip_ignorable(); token } @@ -376,10 +408,21 @@ impl<'tokens> TokenWalker<'tokens> pub fn advance_partial(&mut self) -> char { - if self.index >= self.tokens.len() - { return '\0'; } + let token = { + if let Some(ref reinterp_token) = self.reinterpreted_token + { + &reinterp_token + } + else + { + if self.index >= self.tokens.len() + { return '\0'; } - let sliced = self.tokens[self.index] + &self.tokens[self.index] + } + }; + + let sliced = token .text() .get(self.partial_index..) .unwrap(); @@ -408,14 +451,29 @@ impl<'tokens> TokenWalker<'tokens> } - pub fn next(&self) -> &'tokens syntax::Token + pub fn next(&self) -> &syntax::Token { + if let Some(ref reinterp_token) = self.reinterpreted_token + { + return &reinterp_token; + } + + if self.index >= self.tokens.len() + { + return &self.dummy_token; + } + &self.tokens[self.index] } pub fn next_nth(&self, nth: usize) -> &syntax::Token { + if nth == 0 + { + return self.next(); + } + if self.index + nth >= self.tokens.len() { return &self.dummy_token; @@ -427,13 +485,24 @@ impl<'tokens> TokenWalker<'tokens> pub fn next_partial(&mut self) -> char { - if self.index >= self.tokens.len() - { return '\0'; } + let token = { + if let Some(ref reinterp_token) = self.reinterpreted_token + { + &reinterp_token + } + else + { + if self.index >= self.tokens.len() + { return '\0'; } - if self.tokens[self.index].kind == syntax::TokenKind::Whitespace - { return ' '; } + if self.tokens[self.index].kind == syntax::TokenKind::Whitespace + { return ' '; } - let sliced = self.tokens[self.index] + &self.tokens[self.index] + } + }; + + let sliced = token .text() .get(self.partial_index..) .unwrap(); @@ -457,8 +526,13 @@ impl<'tokens> TokenWalker<'tokens> pub fn next_is(&self, mut nth: usize, kind: syntax::TokenKind) -> bool { - let mut index = self.index; + if let Some(ref reinterp_token) = self.reinterpreted_token + { + return reinterp_token.kind == kind; + } + let mut index = self.index; + while nth > 0 && index < self.tokens.len() { nth -= 1; @@ -479,7 +553,7 @@ impl<'tokens> TokenWalker<'tokens> pub fn maybe_expect( &mut self, kind: syntax::TokenKind) - -> Option<&'tokens syntax::Token> + -> Option { if self.next_is(0, kind) { @@ -495,11 +569,11 @@ impl<'tokens> TokenWalker<'tokens> &mut self, report: &mut diagn::Report, kind: syntax::TokenKind) - -> Result<&'tokens syntax::Token, ()> + -> Result { match self.maybe_expect(kind) { - Some(token) => Ok(&token), + Some(token) => Ok(token), None => { let descr = format!("expected {}", kind.printable()); @@ -516,11 +590,11 @@ impl<'tokens> TokenWalker<'tokens> report: &mut diagn::Report, kind: syntax::TokenKind, descr: S) - -> Result<&'tokens syntax::Token, ()> + -> Result { match self.maybe_expect(kind) { - Some(token) => Ok(&token), + Some(token) => Ok(token), None => { report.error_span( @@ -676,7 +750,7 @@ impl<'tokens> TokenWalker<'tokens> pub fn expect_usize( &mut self, report: &mut diagn::Report) - -> Result<(&'tokens syntax::Token, usize), ()> + -> Result<(syntax::Token, usize), ()> { let tk = self.expect(report, syntax::TokenKind::Number)?; @@ -725,4 +799,65 @@ impl<'tokens> TokenWalker<'tokens> Some(value) } + + + pub fn reinterpret_next_tokens( + &mut self, + report: &mut diagn::Report) + -> Result<(), ()> + { + if self.index >= self.tokens.len() + { return Ok(()); } + + if !self.is_at_partial() + { return Ok(()); } + + let token = &self.tokens[self.index]; + + let span_start = token.span.location().unwrap().0; + + let remaining_text = token + .text() + .get(self.partial_index..) + .unwrap(); + + dbg!(token.text(), remaining_text); + + let (kind, length) = syntax::decide_next_token(&remaining_text); + dbg!((kind, length)); + + if kind == syntax::TokenKind::Error || + length != remaining_text.len() + { + report.error_span( + "invalid token split", + diagn::Span::new( + token.span.file_handle, + span_start + self.partial_index as diagn::SpanIndex, + span_start + (self.partial_index + length) as diagn::SpanIndex),); + + return Err(()); + } + + let excerpt = { + match kind.needs_excerpt() + { + false => None, + true => Some(remaining_text.to_string()), + } + }; + + let new_token = syntax::Token { + kind, + excerpt, + span: diagn::Span::new( + token.span.file_handle, + span_start + self.partial_index as diagn::SpanIndex, + span_start + (self.partial_index + length) as diagn::SpanIndex), + }; + + self.reinterpreted_token = Some(new_token); + self.partial_index = 0; + Ok(()) + } } \ No newline at end of file diff --git a/src/syntax/walker.rs b/src/syntax/walker.rs new file mode 100644 index 00000000..f6a1c6b5 --- /dev/null +++ b/src/syntax/walker.rs @@ -0,0 +1,214 @@ +use crate::*; + + +pub struct Walker<'src> +{ + src: &'src str, + src_file_handle: util::FileServerHandle, + src_byte_index: usize, + + cached_next_useful_token: Option, +} + + +impl<'src> Walker<'src> +{ + pub fn new( + src: &'src str, + src_file_handle: util::FileServerHandle) + -> Walker<'src> + { + let walker = Walker { + src, + src_file_handle, + src_byte_index: 0, + cached_next_useful_token: None, + }; + + walker + } + + + fn next_useful_token( + &mut self) + -> &syntax::Token + { + let mut byte_index = self.src_byte_index; + + /*if let Some(ref cached) = self.cached_next_useful_token + { + if byte_index == cached.span.location().unwrap().0 as usize + { + return cached; + } + }*/ + + loop + { + let token = self.token_at(byte_index); + + if !token.kind.is_ignorable() || + byte_index >= self.src.len() + { + self.cached_next_useful_token = Some(token); + return self.cached_next_useful_token.as_ref().unwrap(); + } + + byte_index += token.span.length(); + } + } + + + fn advance( + &mut self, + bytes: usize) + { + self.src_byte_index += bytes; + } + + + fn skip_to( + &mut self, + byte_index: usize) + { + self.src_byte_index = byte_index; + } + + + fn char_at( + &self, + byte_index: usize) + -> char + { + if byte_index >= self.src.len() + { + '\0' + } + else + { + self.src[byte_index..].chars().next().unwrap_or('\0') + } + } + + + pub fn next_char( + &self) + -> char + { + self.char_at(self.src_byte_index) + } + + + fn token_at( + &self, + byte_index: usize) + -> syntax::Token + { + if byte_index >= self.src.len() + { + let span = diagn::Span::new( + self.src_file_handle, + self.src.len() as diagn::SpanIndex, + self.src.len() as diagn::SpanIndex); + + return syntax::Token { + kind: syntax::TokenKind::LineBreak, + span, + excerpt: None, + }; + } + + let src_next = &self.src[byte_index..]; + let (kind, length) = syntax::decide_next_token(src_next); + + let end = byte_index + length; + + let span = diagn::Span::new( + self.src_file_handle, + byte_index as diagn::SpanIndex, + end as diagn::SpanIndex); + + let excerpt = { + match kind.needs_excerpt() { + true => Some(self.src[byte_index..end].to_string()), + false => None, + } + }; + + syntax::Token { + kind, + span, + excerpt, + } + } + + + pub fn next_token( + &mut self) + -> &syntax::Token + { + self.next_useful_token() + } + + + pub fn next_nth_token( + &mut self, + nth: usize) + -> syntax::Token + { + let mut byte_index = self.next_useful_token().span.location().unwrap().0 as usize; + + let mut step = 0; + + while step < nth + { + let token = self.token_at(byte_index); + byte_index += token.span.length(); + + if !token.kind.is_ignorable() + { + step += 1; + } + } + + self.token_at(byte_index) + } + + + pub fn maybe_expect( + &mut self, + kind: syntax::TokenKind) + -> Option + { + let token = self.next_token(); + if token.kind == kind + { + let token = token.clone(); + //self.acknowledge_whitespace(); + self.skip_to(token.span.location().unwrap().1 as usize); + Some(token) + } + else + { + None + } + } + + + pub fn maybe_expect_char( + &mut self, + wanted_char: char) + -> bool + { + let c = self.next_char(); + if c == wanted_char + { + self.advance(c.len_utf8()); + true + } + else + { + false + } + } +} \ No newline at end of file diff --git a/tests/issue193/ok.asm b/tests/issue193/ok.asm new file mode 100644 index 00000000..c89fbb94 --- /dev/null +++ b/tests/issue193/ok.asm @@ -0,0 +1,12 @@ +#ruledef mode +{ + eq => 0xff +} + +#ruledef +{ + b{m: mode} => mode + j{m: mode} => asm { b{m} } +} + +jeq ; = 0xff \ No newline at end of file diff --git a/tests/rule_arg_glued/err_one_param.asm b/tests/rule_arg_glued/err_one_param.asm index d7d5bb46..92ae4337 100644 --- a/tests/rule_arg_glued/err_one_param.asm +++ b/tests/rule_arg_glued/err_one_param.asm @@ -3,6 +3,4 @@ ld r{x} => 0x55 @ x`8 } -ld r0xff ; error: no match -ld r0x123 ; error: no match ld 0 ; error: no match \ No newline at end of file diff --git a/tests/rule_arg_glued/err_one_param_symbol.asm b/tests/rule_arg_glued/err_one_param_symbol.asm deleted file mode 100644 index a397b655..00000000 --- a/tests/rule_arg_glued/err_one_param_symbol.asm +++ /dev/null @@ -1,7 +0,0 @@ -#ruledef test -{ - ld r{x} => 0x55 @ x`8 -} - -x = 0 -ld rx ; error: no match \ No newline at end of file diff --git a/tests/rule_arg_glued/err_symbol_unknown.asm b/tests/rule_arg_glued/err_symbol_unknown.asm new file mode 100644 index 00000000..eba7c920 --- /dev/null +++ b/tests/rule_arg_glued/err_symbol_unknown.asm @@ -0,0 +1,7 @@ +#ruledef test +{ + ld r{x} => 0x55 @ x`8 +} + +x = 0x12 +ld ry ; error: failed / note:_:3: within / error: unknown \ No newline at end of file diff --git a/tests/rule_arg_glued/err_two_params.asm b/tests/rule_arg_glued/err_two_params.asm index 41cc895f..ceacc5c4 100644 --- a/tests/rule_arg_glued/err_two_params.asm +++ b/tests/rule_arg_glued/err_two_params.asm @@ -3,6 +3,4 @@ ld r{x}, {y} => 0x55 @ x`8 @ y`8 } -ld r0xff, 0x12 ; error: no match -ld r0x123, 0x12 ; error: no match ld 0, 0x12 ; error: no match \ No newline at end of file diff --git a/tests/rule_arg_glued/err_two_params_symbol.asm b/tests/rule_arg_glued/err_two_params_symbol.asm deleted file mode 100644 index 60cb6751..00000000 --- a/tests/rule_arg_glued/err_two_params_symbol.asm +++ /dev/null @@ -1,7 +0,0 @@ -#ruledef test -{ - ld r{x}, {y} => 0x55 @ x`8 @ y`8 -} - -x = 0 -ld rx, x ; error: no match \ No newline at end of file diff --git a/tests/rule_arg_glued/ok_one_param.asm b/tests/rule_arg_glued/ok_one_param.asm index 1c9e8daf..1419b5a4 100644 --- a/tests/rule_arg_glued/ok_one_param.asm +++ b/tests/rule_arg_glued/ok_one_param.asm @@ -9,5 +9,8 @@ ld r 0 ; = 0x5500 ld r12 ; = 0x550c ld r(6 + 6) ; = 0x550c ld r 6 + 6 ; = 0x550c +ld r6 + 6 ; = 0x550c ld r257 ; = 0x5501 -ld r 0xff ; = 0x55ff \ No newline at end of file +ld r 0xff ; = 0x55ff +ld r0xff ; = 0x55ff +ld r0x123 ; = 0x5523 \ No newline at end of file diff --git a/tests/rule_arg_glued/ok_one_param_symbol.asm b/tests/rule_arg_glued/ok_one_param_symbol.asm new file mode 100644 index 00000000..afae47cf --- /dev/null +++ b/tests/rule_arg_glued/ok_one_param_symbol.asm @@ -0,0 +1,10 @@ +#ruledef test +{ + ld r{x} => 0x55 @ x`8 +} + +x = 0x12 +ld rx ; = 0x5512 +ld r x + 6 ; = 0x5518 +ld r(x + 6) ; = 0x5518 +ld rx + 6 ; = 0x5518 \ No newline at end of file diff --git a/tests/rule_arg_glued/ok_two_params.asm b/tests/rule_arg_glued/ok_two_params.asm index acfce756..600ff24f 100644 --- a/tests/rule_arg_glued/ok_two_params.asm +++ b/tests/rule_arg_glued/ok_two_params.asm @@ -6,5 +6,10 @@ ld r0, 0x12 ; = 0x550012 ld r(0), 0x12 ; = 0x550012 ld r 0, 0x34 ; = 0x550034 +ld r 6 + 6, 0x12 ; = 0x550c12 +ld r(6 + 6), 0x12 ; = 0x550c12 +ld r6 + 6, 0x12 ; = 0x550c12 ld r257, 0x102 ; = 0x550102 -ld r 0xff, 0x12 ; = 0x55ff12 \ No newline at end of file +ld r 0xff, 0x12 ; = 0x55ff12 +ld r0xff, 0x12 ; = 0x55ff12 +ld r0x123, 0x12 ; = 0x552312 \ No newline at end of file diff --git a/tests/rule_arg_glued/ok_two_params_symbol.asm b/tests/rule_arg_glued/ok_two_params_symbol.asm new file mode 100644 index 00000000..018292da --- /dev/null +++ b/tests/rule_arg_glued/ok_two_params_symbol.asm @@ -0,0 +1,10 @@ +#ruledef test +{ + ld r{x}, {y} => 0x55 @ x`8 @ y`8 +} + +x = 0x12 +ld rx, x ; = 0x551212 +ld r x + 6, x ; = 0x551812 +ld r(x + 6), x ; = 0x551812 +ld rx + 6, x ; = 0x551812 \ No newline at end of file