From 347c797ddc51352281c9cec826e64027f24de7f9 Mon Sep 17 00:00:00 2001 From: Nikita Strygin Date: Fri, 1 Sep 2023 14:51:22 +0300 Subject: [PATCH] shin-asm: handle parenthesis --- shin-asm/src/db/mod.rs | 2 +- shin-asm/src/hir/lower.rs | 1 + .../src/parser/grammar/expressions/atom.rs | 12 +++++++++++ shin-asm/src/parser/syntax_kind.rs | 1 + shin-asm/src/syntax/ast/nodes/expr/mod.rs | 20 +++++++++++++++++++ shin-asm/src/syntax/ast/tokens.rs | 12 +++++++++++ .../test_data/parser/ok/0017_parenthesis.sal | 2 +- .../test_data/parser/ok/0017_parenthesis.sast | 18 +++++++++++++++++ 8 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 shin-asm/test_data/parser/ok/0017_parenthesis.sast diff --git a/shin-asm/src/db/mod.rs b/shin-asm/src/db/mod.rs index 8dd857b..92134c7 100644 --- a/shin-asm/src/db/mod.rs +++ b/shin-asm/src/db/mod.rs @@ -111,7 +111,7 @@ LABEL_3: LABEL_4: // eh, parser seems to get stuck on parenthesis - exp $result, 1 * $2 + $3 & 7 + exp $result, 1 * ($2 + $3 & 7) "# .to_string(), ); diff --git a/shin-asm/src/hir/lower.rs b/shin-asm/src/hir/lower.rs index 7e2c14e..9226bf3 100644 --- a/shin-asm/src/hir/lower.rs +++ b/shin-asm/src/hir/lower.rs @@ -88,6 +88,7 @@ impl<'a> BlockCollector<'a> { self.alloc_expr(Expr::NameRef(e.ident().unwrap().text().into()), ptr) } ast::Expr::RegisterRefExpr(e) => self.alloc_expr(Expr::RegisterRef(e.value()), ptr), + ast::Expr::ParenExpr(e) => self.collect_expr_opt(e.expr()), // TODO: handle reverse source map ast::Expr::ArrayExpr(e) => { let mut values = Vec::new(); for value in e.values() { diff --git a/shin-asm/src/parser/grammar/expressions/atom.rs b/shin-asm/src/parser/grammar/expressions/atom.rs index e17beda..2e9d31a 100644 --- a/shin-asm/src/parser/grammar/expressions/atom.rs +++ b/shin-asm/src/parser/grammar/expressions/atom.rs @@ -36,6 +36,7 @@ pub(super) fn atom_expr(p: &mut Parser<'_>) -> Option { p.bump(REGISTER_IDENT); m.complete(p, REGISTER_REF_EXPR) } + T!['('] => paren_expr(p), T!['['] => array_expr(p), T!['{'] => mapping_expr(p), _ => { @@ -46,6 +47,17 @@ pub(super) fn atom_expr(p: &mut Parser<'_>) -> Option { Some(done) } +fn paren_expr(p: &mut Parser<'_>) -> CompletedMarker { + assert!(p.at(T!['('])); + let m = p.start(); + + p.bump(T!['(']); + expr(p); + p.expect(T![')']); + + m.complete(p, PAREN_EXPR) +} + fn array_expr(p: &mut Parser<'_>) -> CompletedMarker { assert!(p.at(T!['['])); let m = p.start(); diff --git a/shin-asm/src/parser/syntax_kind.rs b/shin-asm/src/parser/syntax_kind.rs index 72b3326..722eed1 100644 --- a/shin-asm/src/parser/syntax_kind.rs +++ b/shin-asm/src/parser/syntax_kind.rs @@ -88,6 +88,7 @@ syntax_kind! { CALL_EXPR, CALL_EXPR_ARG_LIST, + PAREN_EXPR, ARRAY_EXPR, MAPPING_EXPR, diff --git a/shin-asm/src/syntax/ast/nodes/expr/mod.rs b/shin-asm/src/syntax/ast/nodes/expr/mod.rs index 3dea384..d757317 100644 --- a/shin-asm/src/syntax/ast/nodes/expr/mod.rs +++ b/shin-asm/src/syntax/ast/nodes/expr/mod.rs @@ -15,6 +15,8 @@ pub enum Expr { #[ast(transparent)] RegisterRefExpr(RegisterRefExpr), #[ast(transparent)] + ParenExpr(ParenExpr), + #[ast(transparent)] ArrayExpr(ArrayExpr), #[ast(transparent)] MappingExpr(MappingExpr), @@ -51,6 +53,24 @@ impl RegisterRefExpr { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash, AstNode)] +#[ast(kind = ARRAY_EXPR)] +pub struct ParenExpr { + pub(crate) syntax: SyntaxNode, +} + +impl ParenExpr { + pub fn l_paren_token(&self) -> Option { + support::token(self.syntax()) + } + pub fn expr(&self) -> Option { + support::child(self.syntax()) + } + pub fn r_paren_token(&self) -> Option { + support::token(self.syntax()) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash, AstNode)] #[ast(kind = ARRAY_EXPR)] pub struct ArrayExpr { diff --git a/shin-asm/src/syntax/ast/tokens.rs b/shin-asm/src/syntax/ast/tokens.rs index 93aa812..beac609 100644 --- a/shin-asm/src/syntax/ast/tokens.rs +++ b/shin-asm/src/syntax/ast/tokens.rs @@ -27,3 +27,15 @@ impl RegisterIdent { todo!() } } + +#[derive(Debug, Clone, PartialEq, Eq, Hash, AstToken)] +#[ast(kind = L_PAREN)] +pub struct LParen { + pub(crate) syntax: SyntaxToken, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash, AstToken)] +#[ast(kind = R_PAREN)] +pub struct RParen { + pub(crate) syntax: SyntaxToken, +} diff --git a/shin-asm/test_data/parser/ok/0017_parenthesis.sal b/shin-asm/test_data/parser/ok/0017_parenthesis.sal index 2c5b57f..4317e40 100644 --- a/shin-asm/test_data/parser/ok/0017_parenthesis.sal +++ b/shin-asm/test_data/parser/ok/0017_parenthesis.sal @@ -1 +1 @@ -exp $result, (1 * $2 + $3 & 7) \ No newline at end of file +HELLO (2 + 2) \ No newline at end of file diff --git a/shin-asm/test_data/parser/ok/0017_parenthesis.sast b/shin-asm/test_data/parser/ok/0017_parenthesis.sast new file mode 100644 index 0000000..2e1a870 --- /dev/null +++ b/shin-asm/test_data/parser/ok/0017_parenthesis.sast @@ -0,0 +1,18 @@ +SOURCE_FILE + INSTRUCTIONS_BLOCK + INSTRUCTION + INSTRUCTION_NAME + IDENT "HELLO" + WHITESPACE " " + INSTR_ARG_LIST + PAREN_EXPR + L_PAREN "(" + BIN_EXPR + LITERAL + INT_NUMBER "2" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")"