First pass with bitwise
This commit is contained in:
@@ -525,6 +525,28 @@ impl<'a> Compiler<'a> {
|
|||||||
temp_name: Some(result_name),
|
temp_name: Some(result_name),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
Expression::BitwiseNot(inner_expr) => {
|
||||||
|
// Compile bitwise NOT using the NOT instruction
|
||||||
|
let (inner_str, cleanup) = self.compile_operand(*inner_expr, scope)?;
|
||||||
|
let result_name = self.next_temp_name();
|
||||||
|
let result_loc =
|
||||||
|
scope.add_variable(result_name.clone(), LocationRequest::Temp, None)?;
|
||||||
|
let result_reg = self.resolve_register(&result_loc)?;
|
||||||
|
|
||||||
|
self.write_instruction(
|
||||||
|
Instruction::Not(Operand::Register(result_reg), inner_str),
|
||||||
|
Some(expr.span),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
if let Some(name) = cleanup {
|
||||||
|
scope.free_temp(name, None)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Some(CompileLocation {
|
||||||
|
location: result_loc,
|
||||||
|
temp_name: Some(result_name),
|
||||||
|
}))
|
||||||
|
}
|
||||||
Expression::TupleDeclaration(tuple_decl) => {
|
Expression::TupleDeclaration(tuple_decl) => {
|
||||||
self.expression_tuple_declaration(tuple_decl.node, scope)?;
|
self.expression_tuple_declaration(tuple_decl.node, scope)?;
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@@ -889,6 +911,32 @@ impl<'a> Compiler<'a> {
|
|||||||
}
|
}
|
||||||
(var_loc, None)
|
(var_loc, None)
|
||||||
}
|
}
|
||||||
|
Expression::BitwiseNot(_) => {
|
||||||
|
// Compile the bitwise NOT expression
|
||||||
|
let result = self.expression(expr, scope)?;
|
||||||
|
let var_loc = scope.add_variable(
|
||||||
|
name_str.clone(),
|
||||||
|
LocationRequest::Persist,
|
||||||
|
Some(name_span),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
if let Some(res) = result {
|
||||||
|
// Move result from temp to new persistent variable
|
||||||
|
let result_reg = self.resolve_register(&res.location)?;
|
||||||
|
self.emit_variable_assignment(&var_loc, Operand::Register(result_reg))?;
|
||||||
|
|
||||||
|
// Free the temp result
|
||||||
|
if let Some(name) = res.temp_name {
|
||||||
|
scope.free_temp(name, None)?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(Error::Unknown(
|
||||||
|
format!("`{name_str}` bitwise NOT expression did not produce a value"),
|
||||||
|
Some(name_span),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
(var_loc, None)
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::Unknown(
|
return Err(Error::Unknown(
|
||||||
format!("`{name_str}` declaration of this type is not supported/implemented."),
|
format!("`{name_str}` declaration of this type is not supported/implemented."),
|
||||||
@@ -2121,6 +2169,7 @@ impl<'a> Compiler<'a> {
|
|||||||
| BinaryExpression::Divide(l, r)
|
| BinaryExpression::Divide(l, r)
|
||||||
| BinaryExpression::Exponent(l, r)
|
| BinaryExpression::Exponent(l, r)
|
||||||
| BinaryExpression::Modulo(l, r) => (fold_expression(l)?, fold_expression(r)?),
|
| BinaryExpression::Modulo(l, r) => (fold_expression(l)?, fold_expression(r)?),
|
||||||
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
match expr {
|
match expr {
|
||||||
@@ -2189,6 +2238,24 @@ impl<'a> Compiler<'a> {
|
|||||||
BinaryExpression::Modulo(l, r) => {
|
BinaryExpression::Modulo(l, r) => {
|
||||||
(|into, lhs, rhs| Instruction::Mod(into, lhs, rhs), l, r)
|
(|into, lhs, rhs| Instruction::Mod(into, lhs, rhs), l, r)
|
||||||
}
|
}
|
||||||
|
BinaryExpression::BitwiseAnd(l, r) => {
|
||||||
|
(|into, lhs, rhs| Instruction::And(into, lhs, rhs), l, r)
|
||||||
|
}
|
||||||
|
BinaryExpression::BitwiseOr(l, r) => {
|
||||||
|
(|into, lhs, rhs| Instruction::Or(into, lhs, rhs), l, r)
|
||||||
|
}
|
||||||
|
BinaryExpression::BitwiseXor(l, r) => {
|
||||||
|
(|into, lhs, rhs| Instruction::Xor(into, lhs, rhs), l, r)
|
||||||
|
}
|
||||||
|
BinaryExpression::LeftShift(l, r) => {
|
||||||
|
(|into, lhs, rhs| Instruction::Sll(into, lhs, rhs), l, r)
|
||||||
|
}
|
||||||
|
BinaryExpression::RightShiftArithmetic(l, r) => {
|
||||||
|
(|into, lhs, rhs| Instruction::Sra(into, lhs, rhs), l, r)
|
||||||
|
}
|
||||||
|
BinaryExpression::RightShiftLogical(l, r) => {
|
||||||
|
(|into, lhs, rhs| Instruction::Srl(into, lhs, rhs), l, r)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let span = Self::merge_spans(left_expr.span, right_expr.span);
|
let span = Self::merge_spans(left_expr.span, right_expr.span);
|
||||||
|
|||||||
@@ -232,12 +232,22 @@ pub enum Instruction<'a> {
|
|||||||
/// `sle dst a b` - Set if Less or Equal
|
/// `sle dst a b` - Set if Less or Equal
|
||||||
SetLe(Operand<'a>, Operand<'a>, Operand<'a>),
|
SetLe(Operand<'a>, Operand<'a>, Operand<'a>),
|
||||||
|
|
||||||
/// `and dst a b` - Logical AND
|
/// `and dst a b` - Bitwise AND
|
||||||
And(Operand<'a>, Operand<'a>, Operand<'a>),
|
And(Operand<'a>, Operand<'a>, Operand<'a>),
|
||||||
/// `or dst a b` - Logical OR
|
/// `or dst a b` - Bitwise OR
|
||||||
Or(Operand<'a>, Operand<'a>, Operand<'a>),
|
Or(Operand<'a>, Operand<'a>, Operand<'a>),
|
||||||
/// `xor dst a b` - Logical XOR
|
/// `xor dst a b` - Bitwise XOR
|
||||||
Xor(Operand<'a>, Operand<'a>, Operand<'a>),
|
Xor(Operand<'a>, Operand<'a>, Operand<'a>),
|
||||||
|
/// `nor dst a b` - Bitwise NOR
|
||||||
|
Nor(Operand<'a>, Operand<'a>, Operand<'a>),
|
||||||
|
/// `not dst a` - Bitwise NOT
|
||||||
|
Not(Operand<'a>, Operand<'a>),
|
||||||
|
/// `sll dst a b` - Logical Left Shift
|
||||||
|
Sll(Operand<'a>, Operand<'a>, Operand<'a>),
|
||||||
|
/// `sra dst a b` - Arithmetic Right Shift
|
||||||
|
Sra(Operand<'a>, Operand<'a>, Operand<'a>),
|
||||||
|
/// `srl dst a b` - Logical Right Shift
|
||||||
|
Srl(Operand<'a>, Operand<'a>, Operand<'a>),
|
||||||
|
|
||||||
/// `push val` - Push to Stack
|
/// `push val` - Push to Stack
|
||||||
Push(Operand<'a>),
|
Push(Operand<'a>),
|
||||||
@@ -338,6 +348,11 @@ impl<'a> fmt::Display for Instruction<'a> {
|
|||||||
Instruction::And(dst, a, b) => write!(f, "and {} {} {}", dst, a, b),
|
Instruction::And(dst, a, b) => write!(f, "and {} {} {}", dst, a, b),
|
||||||
Instruction::Or(dst, a, b) => write!(f, "or {} {} {}", dst, a, b),
|
Instruction::Or(dst, a, b) => write!(f, "or {} {} {}", dst, a, b),
|
||||||
Instruction::Xor(dst, a, b) => write!(f, "xor {} {} {}", dst, a, b),
|
Instruction::Xor(dst, a, b) => write!(f, "xor {} {} {}", dst, a, b),
|
||||||
|
Instruction::Nor(dst, a, b) => write!(f, "nor {} {} {}", dst, a, b),
|
||||||
|
Instruction::Not(dst, a) => write!(f, "not {} {}", dst, a),
|
||||||
|
Instruction::Sll(dst, a, b) => write!(f, "sll {} {} {}", dst, a, b),
|
||||||
|
Instruction::Sra(dst, a, b) => write!(f, "sra {} {} {}", dst, a, b),
|
||||||
|
Instruction::Srl(dst, a, b) => write!(f, "srl {} {} {}", dst, a, b),
|
||||||
Instruction::Push(val) => write!(f, "push {}", val),
|
Instruction::Push(val) => write!(f, "push {}", val),
|
||||||
Instruction::Pop(dst) => write!(f, "pop {}", dst),
|
Instruction::Pop(dst) => write!(f, "pop {}", dst),
|
||||||
Instruction::Peek(dst) => write!(f, "peek {}", dst),
|
Instruction::Peek(dst) => write!(f, "peek {}", dst),
|
||||||
|
|||||||
@@ -294,12 +294,12 @@ impl<'a> Parser<'a> {
|
|||||||
// Handle Infix operators (Binary, Logical, Assignment)
|
// Handle Infix operators (Binary, Logical, Assignment)
|
||||||
if self_matches_peek!(
|
if self_matches_peek!(
|
||||||
self,
|
self,
|
||||||
TokenType::Symbol(s) if s.is_operator() || s.is_comparison() || s.is_logical() || matches!(s, Symbol::Assign | Symbol::Question)
|
TokenType::Symbol(s) if s.is_operator() || s.is_comparison() || s.is_logical() || s.is_bitwise() || matches!(s, Symbol::Assign | Symbol::Question)
|
||||||
) {
|
) {
|
||||||
return Ok(Some(self.infix(lhs)?));
|
return Ok(Some(self.infix(lhs)?));
|
||||||
} else if self_matches_current!(
|
} else if self_matches_current!(
|
||||||
self,
|
self,
|
||||||
TokenType::Symbol(s) if s.is_operator() || s.is_comparison() || s.is_logical() || matches!(s, Symbol::Assign | Symbol::Question)
|
TokenType::Symbol(s) if s.is_operator() || s.is_comparison() || s.is_logical() || s.is_bitwise() || matches!(s, Symbol::Assign | Symbol::Question)
|
||||||
) {
|
) {
|
||||||
self.tokenizer.seek(SeekFrom::Current(-1))?;
|
self.tokenizer.seek(SeekFrom::Current(-1))?;
|
||||||
return Ok(Some(self.infix(lhs)?));
|
return Ok(Some(self.infix(lhs)?));
|
||||||
@@ -608,6 +608,23 @@ impl<'a> Parser<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TokenType::Symbol(Symbol::BitwiseNot) => {
|
||||||
|
let start_span = self.current_span();
|
||||||
|
self.assign_next()?;
|
||||||
|
let inner_expr = self.unary()?.ok_or(Error::UnexpectedEOF)?;
|
||||||
|
let inner_with_postfix = self.parse_postfix(inner_expr)?;
|
||||||
|
let combined_span = Span {
|
||||||
|
start_line: start_span.start_line,
|
||||||
|
start_col: start_span.start_col,
|
||||||
|
end_line: inner_with_postfix.span.end_line,
|
||||||
|
end_col: inner_with_postfix.span.end_col,
|
||||||
|
};
|
||||||
|
Some(Spanned {
|
||||||
|
span: combined_span,
|
||||||
|
node: Expression::BitwiseNot(boxed!(inner_with_postfix)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::UnexpectedToken(
|
return Err(Error::UnexpectedToken(
|
||||||
self.current_span(),
|
self.current_span(),
|
||||||
@@ -699,6 +716,20 @@ impl<'a> Parser<'a> {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TokenType::Symbol(Symbol::BitwiseNot) => {
|
||||||
|
self.assign_next()?;
|
||||||
|
let inner = self.get_infix_child_node()?;
|
||||||
|
let span = Span {
|
||||||
|
start_line: start_span.start_line,
|
||||||
|
start_col: start_span.start_col,
|
||||||
|
end_line: inner.span.end_line,
|
||||||
|
end_col: inner.span.end_col,
|
||||||
|
};
|
||||||
|
Spanned {
|
||||||
|
span,
|
||||||
|
node: Expression::BitwiseNot(boxed!(inner)),
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::UnexpectedToken(
|
return Err(Error::UnexpectedToken(
|
||||||
self.current_span(),
|
self.current_span(),
|
||||||
@@ -777,6 +808,7 @@ impl<'a> Parser<'a> {
|
|||||||
| Expression::Variable(_)
|
| Expression::Variable(_)
|
||||||
| Expression::Ternary(_)
|
| Expression::Ternary(_)
|
||||||
| Expression::Negation(_)
|
| Expression::Negation(_)
|
||||||
|
| Expression::BitwiseNot(_)
|
||||||
| Expression::MemberAccess(_)
|
| Expression::MemberAccess(_)
|
||||||
| Expression::MethodCall(_)
|
| Expression::MethodCall(_)
|
||||||
| Expression::Tuple(_) => {}
|
| Expression::Tuple(_) => {}
|
||||||
@@ -796,7 +828,7 @@ impl<'a> Parser<'a> {
|
|||||||
// Include Assign in the operator loop
|
// Include Assign in the operator loop
|
||||||
while token_matches!(
|
while token_matches!(
|
||||||
temp_token,
|
temp_token,
|
||||||
TokenType::Symbol(s) if s.is_operator() || s.is_comparison() || s.is_logical() || matches!(s, Symbol::Assign | Symbol::Question | Symbol::Colon)
|
TokenType::Symbol(s) if s.is_operator() || s.is_comparison() || s.is_logical() || s.is_bitwise() || matches!(s, Symbol::Assign | Symbol::Question | Symbol::Colon)
|
||||||
) {
|
) {
|
||||||
let operator = match temp_token.token_type {
|
let operator = match temp_token.token_type {
|
||||||
TokenType::Symbol(s) => s,
|
TokenType::Symbol(s) => s,
|
||||||
@@ -869,6 +901,24 @@ impl<'a> Parser<'a> {
|
|||||||
Symbol::Minus => {
|
Symbol::Minus => {
|
||||||
BinaryExpression::Subtract(boxed!(left), boxed!(right))
|
BinaryExpression::Subtract(boxed!(left), boxed!(right))
|
||||||
}
|
}
|
||||||
|
Symbol::LeftShift => {
|
||||||
|
BinaryExpression::LeftShift(boxed!(left), boxed!(right))
|
||||||
|
}
|
||||||
|
Symbol::RightShiftArithmetic => {
|
||||||
|
BinaryExpression::RightShiftArithmetic(boxed!(left), boxed!(right))
|
||||||
|
}
|
||||||
|
Symbol::RightShiftLogical => {
|
||||||
|
BinaryExpression::RightShiftLogical(boxed!(left), boxed!(right))
|
||||||
|
}
|
||||||
|
Symbol::BitwiseAnd => {
|
||||||
|
BinaryExpression::BitwiseAnd(boxed!(left), boxed!(right))
|
||||||
|
}
|
||||||
|
Symbol::BitwiseOr => {
|
||||||
|
BinaryExpression::BitwiseOr(boxed!(left), boxed!(right))
|
||||||
|
}
|
||||||
|
Symbol::Caret => {
|
||||||
|
BinaryExpression::BitwiseXor(boxed!(left), boxed!(right))
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -895,7 +945,22 @@ impl<'a> Parser<'a> {
|
|||||||
// --- PRECEDENCE LEVEL 3: Additive (+, -) ---
|
// --- PRECEDENCE LEVEL 3: Additive (+, -) ---
|
||||||
process_binary_ops!(Symbol::Plus | Symbol::Minus, BinaryExpression);
|
process_binary_ops!(Symbol::Plus | Symbol::Minus, BinaryExpression);
|
||||||
|
|
||||||
// --- PRECEDENCE LEVEL 4: Comparison (<, >, <=, >=) ---
|
// --- PRECEDENCE LEVEL 4: Shift Operations (<<, >>, >>>) ---
|
||||||
|
process_binary_ops!(
|
||||||
|
Symbol::LeftShift | Symbol::RightShiftArithmetic | Symbol::RightShiftLogical,
|
||||||
|
BinaryExpression
|
||||||
|
);
|
||||||
|
|
||||||
|
// --- PRECEDENCE LEVEL 5: Bitwise AND (&) ---
|
||||||
|
process_binary_ops!(Symbol::BitwiseAnd, BinaryExpression);
|
||||||
|
|
||||||
|
// --- PRECEDENCE LEVEL 6: Bitwise XOR (^) ---
|
||||||
|
process_binary_ops!(Symbol::Caret, BinaryExpression);
|
||||||
|
|
||||||
|
// --- PRECEDENCE LEVEL 7: Bitwise OR (|) ---
|
||||||
|
process_binary_ops!(Symbol::BitwiseOr, BinaryExpression);
|
||||||
|
|
||||||
|
// --- PRECEDENCE LEVEL 8: Comparison (<, >, <=, >=) ---
|
||||||
let mut current_iteration = 0;
|
let mut current_iteration = 0;
|
||||||
for (i, operator) in operators.iter().enumerate() {
|
for (i, operator) in operators.iter().enumerate() {
|
||||||
if operator.is_comparison() && !matches!(operator, Symbol::Equal | Symbol::NotEqual) {
|
if operator.is_comparison() && !matches!(operator, Symbol::Equal | Symbol::NotEqual) {
|
||||||
|
|||||||
@@ -45,6 +45,12 @@ pub enum BinaryExpression<'a> {
|
|||||||
Subtract(Box<Spanned<Expression<'a>>>, Box<Spanned<Expression<'a>>>),
|
Subtract(Box<Spanned<Expression<'a>>>, Box<Spanned<Expression<'a>>>),
|
||||||
Exponent(Box<Spanned<Expression<'a>>>, Box<Spanned<Expression<'a>>>),
|
Exponent(Box<Spanned<Expression<'a>>>, Box<Spanned<Expression<'a>>>),
|
||||||
Modulo(Box<Spanned<Expression<'a>>>, Box<Spanned<Expression<'a>>>),
|
Modulo(Box<Spanned<Expression<'a>>>, Box<Spanned<Expression<'a>>>),
|
||||||
|
BitwiseAnd(Box<Spanned<Expression<'a>>>, Box<Spanned<Expression<'a>>>),
|
||||||
|
BitwiseOr(Box<Spanned<Expression<'a>>>, Box<Spanned<Expression<'a>>>),
|
||||||
|
BitwiseXor(Box<Spanned<Expression<'a>>>, Box<Spanned<Expression<'a>>>),
|
||||||
|
LeftShift(Box<Spanned<Expression<'a>>>, Box<Spanned<Expression<'a>>>),
|
||||||
|
RightShiftArithmetic(Box<Spanned<Expression<'a>>>, Box<Spanned<Expression<'a>>>),
|
||||||
|
RightShiftLogical(Box<Spanned<Expression<'a>>>, Box<Spanned<Expression<'a>>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> std::fmt::Display for BinaryExpression<'a> {
|
impl<'a> std::fmt::Display for BinaryExpression<'a> {
|
||||||
@@ -56,6 +62,12 @@ impl<'a> std::fmt::Display for BinaryExpression<'a> {
|
|||||||
BinaryExpression::Subtract(l, r) => write!(f, "({} - {})", l, r),
|
BinaryExpression::Subtract(l, r) => write!(f, "({} - {})", l, r),
|
||||||
BinaryExpression::Exponent(l, r) => write!(f, "({} ** {})", l, r),
|
BinaryExpression::Exponent(l, r) => write!(f, "({} ** {})", l, r),
|
||||||
BinaryExpression::Modulo(l, r) => write!(f, "({} % {})", l, r),
|
BinaryExpression::Modulo(l, r) => write!(f, "({} % {})", l, r),
|
||||||
|
BinaryExpression::BitwiseAnd(l, r) => write!(f, "({} & {})", l, r),
|
||||||
|
BinaryExpression::BitwiseOr(l, r) => write!(f, "({} | {})", l, r),
|
||||||
|
BinaryExpression::BitwiseXor(l, r) => write!(f, "({} ^ {})", l, r),
|
||||||
|
BinaryExpression::LeftShift(l, r) => write!(f, "({} << {})", l, r),
|
||||||
|
BinaryExpression::RightShiftArithmetic(l, r) => write!(f, "({} >> {})", l, r),
|
||||||
|
BinaryExpression::RightShiftLogical(l, r) => write!(f, "({} >>> {})", l, r),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -367,6 +379,7 @@ pub enum Expression<'a> {
|
|||||||
Binary(Spanned<BinaryExpression<'a>>),
|
Binary(Spanned<BinaryExpression<'a>>),
|
||||||
Block(Spanned<BlockExpression<'a>>),
|
Block(Spanned<BlockExpression<'a>>),
|
||||||
Break(Span),
|
Break(Span),
|
||||||
|
BitwiseNot(Box<Spanned<Expression<'a>>>),
|
||||||
ConstDeclaration(Spanned<ConstDeclarationExpression<'a>>),
|
ConstDeclaration(Spanned<ConstDeclarationExpression<'a>>),
|
||||||
Continue(Span),
|
Continue(Span),
|
||||||
Declaration(Spanned<Cow<'a, str>>, Box<Spanned<Expression<'a>>>),
|
Declaration(Spanned<Cow<'a, str>>, Box<Spanned<Expression<'a>>>),
|
||||||
@@ -398,6 +411,7 @@ impl<'a> std::fmt::Display for Expression<'a> {
|
|||||||
Expression::Binary(e) => write!(f, "{}", e),
|
Expression::Binary(e) => write!(f, "{}", e),
|
||||||
Expression::Block(e) => write!(f, "{}", e),
|
Expression::Block(e) => write!(f, "{}", e),
|
||||||
Expression::Break(_) => write!(f, "break"),
|
Expression::Break(_) => write!(f, "break"),
|
||||||
|
Expression::BitwiseNot(e) => write!(f, "(~{})", e),
|
||||||
Expression::ConstDeclaration(e) => write!(f, "{}", e),
|
Expression::ConstDeclaration(e) => write!(f, "{}", e),
|
||||||
Expression::Continue(_) => write!(f, "continue"),
|
Expression::Continue(_) => write!(f, "continue"),
|
||||||
Expression::Declaration(id, e) => write!(f, "(let {} = {})", id, e),
|
Expression::Declaration(id, e) => write!(f, "(let {} = {})", id, e),
|
||||||
@@ -439,4 +453,3 @@ impl<'a> std::fmt::Display for Expression<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -172,6 +172,23 @@ pub enum TokenType<'a> {
|
|||||||
#[token(";", symbol!(Semicolon))]
|
#[token(";", symbol!(Semicolon))]
|
||||||
#[token(":", symbol!(Colon))]
|
#[token(":", symbol!(Colon))]
|
||||||
#[token(",", symbol!(Comma))]
|
#[token(",", symbol!(Comma))]
|
||||||
|
#[token("?", symbol!(Question))]
|
||||||
|
#[token(".", symbol!(Dot))]
|
||||||
|
#[token("%", symbol!(Percent))]
|
||||||
|
#[token("~", symbol!(BitwiseNot))]
|
||||||
|
// Multi-character tokens must be defined before their single-character prefixes
|
||||||
|
// For tokens like >> and >>>, define >>> before >> to ensure correct matching
|
||||||
|
#[token(">>>", symbol!(RightShiftLogical))]
|
||||||
|
#[token(">>", symbol!(RightShiftArithmetic))]
|
||||||
|
#[token("<<", symbol!(LeftShift))]
|
||||||
|
#[token("==", symbol!(Equal))]
|
||||||
|
#[token("!=", symbol!(NotEqual))]
|
||||||
|
#[token("&&", symbol!(LogicalAnd))]
|
||||||
|
#[token("||", symbol!(LogicalOr))]
|
||||||
|
#[token("<=", symbol!(LessThanOrEqual))]
|
||||||
|
#[token(">=", symbol!(GreaterThanOrEqual))]
|
||||||
|
#[token("**", symbol!(Exp))]
|
||||||
|
// Single-character tokens
|
||||||
#[token("+", symbol!(Plus))]
|
#[token("+", symbol!(Plus))]
|
||||||
#[token("-", symbol!(Minus))]
|
#[token("-", symbol!(Minus))]
|
||||||
#[token("*", symbol!(Asterisk))]
|
#[token("*", symbol!(Asterisk))]
|
||||||
@@ -180,17 +197,9 @@ pub enum TokenType<'a> {
|
|||||||
#[token(">", symbol!(GreaterThan))]
|
#[token(">", symbol!(GreaterThan))]
|
||||||
#[token("=", symbol!(Assign))]
|
#[token("=", symbol!(Assign))]
|
||||||
#[token("!", symbol!(LogicalNot))]
|
#[token("!", symbol!(LogicalNot))]
|
||||||
#[token(".", symbol!(Dot))]
|
|
||||||
#[token("^", symbol!(Caret))]
|
#[token("^", symbol!(Caret))]
|
||||||
#[token("%", symbol!(Percent))]
|
#[token("&", symbol!(BitwiseAnd))]
|
||||||
#[token("?", symbol!(Question))]
|
#[token("|", symbol!(BitwiseOr))]
|
||||||
#[token("==", symbol!(Equal))]
|
|
||||||
#[token("!=", symbol!(NotEqual))]
|
|
||||||
#[token("&&", symbol!(LogicalAnd))]
|
|
||||||
#[token("||", symbol!(LogicalOr))]
|
|
||||||
#[token("<=", symbol!(LessThanOrEqual))]
|
|
||||||
#[token(">=", symbol!(GreaterThanOrEqual))]
|
|
||||||
#[token("**", symbol!(Exp))]
|
|
||||||
/// Represents a symbol token
|
/// Represents a symbol token
|
||||||
Symbol(Symbol),
|
Symbol(Symbol),
|
||||||
|
|
||||||
@@ -615,6 +624,12 @@ pub enum Symbol {
|
|||||||
Percent,
|
Percent,
|
||||||
/// Represents the `?` symbol
|
/// Represents the `?` symbol
|
||||||
Question,
|
Question,
|
||||||
|
/// Represents the `&` symbol (bitwise AND)
|
||||||
|
BitwiseAnd,
|
||||||
|
/// Represents the `|` symbol (bitwise OR)
|
||||||
|
BitwiseOr,
|
||||||
|
/// Represents the `~` symbol (bitwise NOT)
|
||||||
|
BitwiseNot,
|
||||||
|
|
||||||
// Double Character Symbols
|
// Double Character Symbols
|
||||||
/// Represents the `==` symbol
|
/// Represents the `==` symbol
|
||||||
@@ -629,6 +644,12 @@ pub enum Symbol {
|
|||||||
LessThanOrEqual,
|
LessThanOrEqual,
|
||||||
/// Represents the `>=` symbol
|
/// Represents the `>=` symbol
|
||||||
GreaterThanOrEqual,
|
GreaterThanOrEqual,
|
||||||
|
/// Represents the `<<` symbol (left shift)
|
||||||
|
LeftShift,
|
||||||
|
/// Represents the `>>` symbol (arithmetic right shift)
|
||||||
|
RightShiftArithmetic,
|
||||||
|
/// Represents the `>>>` symbol (logical right shift)
|
||||||
|
RightShiftLogical,
|
||||||
/// Represents the `**` symbol
|
/// Represents the `**` symbol
|
||||||
Exp,
|
Exp,
|
||||||
}
|
}
|
||||||
@@ -643,6 +664,19 @@ impl Symbol {
|
|||||||
| Symbol::Slash
|
| Symbol::Slash
|
||||||
| Symbol::Exp
|
| Symbol::Exp
|
||||||
| Symbol::Percent
|
| Symbol::Percent
|
||||||
|
| Symbol::Caret
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_bitwise(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
Symbol::BitwiseAnd
|
||||||
|
| Symbol::BitwiseOr
|
||||||
|
| Symbol::BitwiseNot
|
||||||
|
| Symbol::LeftShift
|
||||||
|
| Symbol::RightShiftArithmetic
|
||||||
|
| Symbol::RightShiftLogical
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,6 +727,12 @@ impl std::fmt::Display for Symbol {
|
|||||||
Self::NotEqual => write!(f, "!="),
|
Self::NotEqual => write!(f, "!="),
|
||||||
Self::Dot => write!(f, "."),
|
Self::Dot => write!(f, "."),
|
||||||
Self::Caret => write!(f, "^"),
|
Self::Caret => write!(f, "^"),
|
||||||
|
Self::BitwiseAnd => write!(f, "&"),
|
||||||
|
Self::BitwiseOr => write!(f, "|"),
|
||||||
|
Self::BitwiseNot => write!(f, "~"),
|
||||||
|
Self::LeftShift => write!(f, "<<"),
|
||||||
|
Self::RightShiftArithmetic => write!(f, ">>"),
|
||||||
|
Self::RightShiftLogical => write!(f, ">>>"),
|
||||||
Self::Exp => write!(f, "**"),
|
Self::Exp => write!(f, "**"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user