diff options
| author | Thomas Voss <mail@thomasvoss.com> | 2026-03-30 22:53:28 +0200 |
|---|---|---|
| committer | Thomas Voss <mail@thomasvoss.com> | 2026-03-30 22:53:28 +0200 |
| commit | bc548238b9dd1d15ddf0af8731d356a0ca6a61ad (patch) | |
| tree | fce34d062211d1af1aa867253fae72bf26340ea5 /oryxc/src/parser.rs | |
| parent | 82ce31a7be9a67ea88c586c2792a7dcddd2a53d6 (diff) | |
Expand UnaryOperator and BinaryOperator
Diffstat (limited to 'oryxc/src/parser.rs')
| -rw-r--r-- | oryxc/src/parser.rs | 195 |
1 files changed, 158 insertions, 37 deletions
diff --git a/oryxc/src/parser.rs b/oryxc/src/parser.rs index 93adc9f..cd398fd 100644 --- a/oryxc/src/parser.rs +++ b/oryxc/src/parser.rs @@ -15,38 +15,107 @@ use crate::size; const MAX_PREC: i64 = 6; -/* Remember to edit the cases in Parser.node_leaf_*() when editing - * this list! */ #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum AstType { - Assign, /* (extra-data-lhs, extra-data-rhs) */ - BinaryOperator, /* (lhs, rhs) */ - Block, /* (extra-data, extra-data-len) */ - Dereference, /* (lhs, _) */ - Empty, /* (_, _) */ - FunCall, /* (expression, extra-data-exprs) */ - FunProto, /* (extra-data-args, extra-data-rets) */ - Function, /* (prototype, body) */ - Identifier, /* (_, _) */ - MultiDefBind, /* (extra-data-decls, extra-data-exprs) */ - Number, /* (_, _) */ - Pointer, /* (rhs, _) */ - Return, /* (extra-data, extra-data-len) */ - Root, /* (extra-data, extra-data-len) */ - String, /* (_, _) */ - UnaryOperator, /* (rhs, _) */ + AddressOf, /* (rhs, _) */ + Assign, /* (extra-data-lhs, extra-data-rhs) */ + BinaryAdd, /* (lhs, rhs) */ + BinaryBitAnd, /* (lhs, rhs) */ + BinaryBitAndNot, /* (lhs, rhs) */ + BinaryBitOr, /* (lhs, rhs) */ + BinaryBitXor, /* (lhs, rhs) */ + BinaryDivRem, /* (lhs, rhs) */ + BinaryDivide, /* (lhs, rhs) */ + BinaryEqual, /* (lhs, rhs) */ + BinaryGreaterThan, /* (lhs, rhs) */ + BinaryGreaterThanEqual, /* (lhs, rhs) */ + BinaryLeftRotate, /* (lhs, rhs) */ + BinaryLeftShift, /* (lhs, rhs) */ + BinaryLessThan, /* (lhs, rhs) */ + BinaryLessThanEqual, /* (lhs, rhs) */ + BinaryLogicalAnd, /* (lhs, rhs) */ + BinaryLogicalOr, /* (lhs, rhs) */ + BinaryModulus, /* (lhs, rhs) */ + BinaryMultiply, /* (lhs, rhs) */ + BinaryNotEqual, /* (lhs, rhs) */ + BinaryRemainder, /* (lhs, rhs) */ + BinaryRightRotate, /* (lhs, rhs) */ + BinaryRightShift, /* (lhs, rhs) */ + BinarySubtract, /* (lhs, rhs) */ + Block, /* (extra-data, extra-data-len) */ + Dereference, /* (lhs, _) */ + Empty, /* (_, _) */ + FunCall, /* (expression, extra-data-exprs) */ + FunProto, /* (extra-data-args, extra-data-rets) */ + Function, /* (prototype, body) */ + Identifier, /* (_, _) */ + MultiDefBind, /* (extra-data-decls, extra-data-exprs) */ + Number, /* (_, _) */ + Pointer, /* (rhs, _) */ + Return, /* (extra-data, extra-data-len) */ + Root, /* (extra-data, extra-data-len) */ + String, /* (_, _) */ + UnaryComplement, /* (rhs, _) */ + UnaryMinus, /* (rhs, _) */ + UnaryNegate, /* (rhs, _) */ + UnaryPlus, /* (rhs, _) */ } -/// The number of AstType variants that represent expressions/binops/etc. In -/// the places where we match/switch on just the subset of AstTypes that are -/// expressions/etc., we can static assert that this equals its current value. -/// This is useful because if a new AstType of the given subset is added and -/// these numbers are incremented, the static asserts fail everywhere where code -/// changes are required. -pub const NEXPRKINDS: usize = 10; -pub const NUNARYKINDS: usize = 5; +impl AstType { + pub fn unary_prefix_from(t: TokenType) -> Self { + const { assert!(NUNARYKINDS == 7, "missing mapping") }; + return match t { + TokenType::Ampersand => Self::AddressOf, + TokenType::Bang => Self::UnaryNegate, + TokenType::Caret => Self::Pointer, + TokenType::Minus => Self::UnaryMinus, + TokenType::Plus => Self::UnaryPlus, + TokenType::Tilde => Self::UnaryComplement, + _ => unreachable!(), + }; + } + + pub fn binary_from(t: TokenType) -> Self { + const { assert!(NBINARYKINDS == 23, "missing mapping") }; + return match t { + TokenType::Ampersand => Self::BinaryBitAnd, + TokenType::Ampersand2 => Self::BinaryLogicalAnd, + TokenType::AmpersandTilde => Self::BinaryBitAndNot, + TokenType::AngleL => Self::BinaryLessThan, + TokenType::AngleL2 => Self::BinaryLeftShift, + TokenType::AngleL3 => Self::BinaryLeftRotate, + TokenType::AngleLEquals => Self::BinaryLessThanEqual, + TokenType::AngleR => Self::BinaryGreaterThan, + TokenType::AngleR2 => Self::BinaryRightShift, + TokenType::AngleR3 => Self::BinaryRightRotate, + TokenType::AngleREquals => Self::BinaryGreaterThanEqual, + TokenType::Asterisk => Self::BinaryMultiply, + TokenType::BangEquals => Self::BinaryNotEqual, + TokenType::Bar => Self::BinaryBitOr, + TokenType::Bar2 => Self::BinaryLogicalOr, + TokenType::Equals2 => Self::BinaryEqual, + TokenType::Minus => Self::BinarySubtract, + TokenType::Percent => Self::BinaryRemainder, + TokenType::Percent2 => Self::BinaryModulus, + TokenType::Plus => Self::BinaryAdd, + TokenType::Slash => Self::BinaryDivide, + TokenType::SlashPercent => Self::BinaryDivRem, + TokenType::Tilde => Self::BinaryBitXor, + _ => unreachable!(), + }; + } +} + +/// The number of AstType variants that represent expressions/binops/etc. +/// In the places where we match/switch on just the subset of AstTypes +/// that are expressions/etc., we can static assert that this equals its +/// current value. This is useful because if a new AstType of the given +/// subset is added and these numbers are incremented, the static asserts +/// fail everywhere where code changes are required. +pub const NUNARYKINDS: usize = 7; pub const NBINARYKINDS: usize = 23; +pub const NEXPRKINDS: usize = NUNARYKINDS + NBINARYKINDS + 6; #[derive(Soars)] #[soa_derive(Debug)] @@ -162,7 +231,29 @@ impl<'a> Parser<'a> { let expr = self.extra_data[i as usize]; self.node_leaf_l(expr) }, - AstType::BinaryOperator => { + AstType::BinaryAdd + | AstType::BinaryBitAnd + | AstType::BinaryBitAndNot + | AstType::BinaryBitOr + | AstType::BinaryBitXor + | AstType::BinaryDivRem + | AstType::BinaryDivide + | AstType::BinaryEqual + | AstType::BinaryGreaterThan + | AstType::BinaryGreaterThanEqual + | AstType::BinaryLeftRotate + | AstType::BinaryLeftShift + | AstType::BinaryLessThan + | AstType::BinaryLessThanEqual + | AstType::BinaryLogicalAnd + | AstType::BinaryLogicalOr + | AstType::BinaryModulus + | AstType::BinaryMultiply + | AstType::BinaryNotEqual + | AstType::BinaryRemainder + | AstType::BinaryRightRotate + | AstType::BinaryRightShift + | AstType::BinarySubtract => { self.node_leaf_l(self.ast.sub()[node as usize].0) }, AstType::Block => { @@ -196,7 +287,12 @@ impl<'a> Parser<'a> { } }, AstType::String => node, - AstType::UnaryOperator => node, + AstType::AddressOf + | AstType::Pointer + | AstType::UnaryComplement + | AstType::UnaryMinus + | AstType::UnaryNegate + | AstType::UnaryPlus => node, }; } @@ -207,7 +303,29 @@ impl<'a> Parser<'a> { let nexprs = self.extra_data[i as usize]; self.node_leaf_r(self.extra_data[(i + nexprs) as usize]) }, - AstType::BinaryOperator => { + AstType::BinaryAdd + | AstType::BinaryBitAnd + | AstType::BinaryBitAndNot + | AstType::BinaryBitOr + | AstType::BinaryBitXor + | AstType::BinaryDivRem + | AstType::BinaryDivide + | AstType::BinaryEqual + | AstType::BinaryGreaterThan + | AstType::BinaryGreaterThanEqual + | AstType::BinaryLeftRotate + | AstType::BinaryLeftShift + | AstType::BinaryLessThan + | AstType::BinaryLessThanEqual + | AstType::BinaryLogicalAnd + | AstType::BinaryLogicalOr + | AstType::BinaryModulus + | AstType::BinaryMultiply + | AstType::BinaryNotEqual + | AstType::BinaryRemainder + | AstType::BinaryRightRotate + | AstType::BinaryRightShift + | AstType::BinarySubtract => { self.node_leaf_r(self.ast.sub()[node as usize].1) }, AstType::Block => { @@ -273,9 +391,12 @@ impl<'a> Parser<'a> { } }, AstType::String => node, - AstType::UnaryOperator => { - self.node_leaf_r(self.ast.sub()[node as usize].0) - }, + AstType::AddressOf + | AstType::Pointer + | AstType::UnaryComplement + | AstType::UnaryMinus + | AstType::UnaryNegate + | AstType::UnaryPlus => self.node_leaf_r(self.ast.sub()[node as usize].0), }; } @@ -763,13 +884,13 @@ impl<'a> Parser<'a> { | TokenType::Minus | TokenType::Plus | TokenType::Tilde => { - let i = self.cursor; + let tok = self.cursor; self.next(); let rhs = self.parse_expr(MAX_PREC)?; self.new_node(AstNode { - kind: AstType::UnaryOperator, - tok: i, - sub: SubNodes(rhs, u32::MAX), + kind: AstType::unary_prefix_from(self.get_at(tok)), + tok, + sub: SubNodes(rhs, u32::MAX), }) }, TokenType::ParenL => { @@ -853,7 +974,7 @@ impl<'a> Parser<'a> { self.next(); let rhs = self.parse_expr(prec)?; self.new_node(AstNode { - kind: AstType::BinaryOperator, + kind: AstType::binary_from(tok), tok: i, sub: SubNodes(lhs, rhs), }) |