bin op stuff

This commit is contained in:
2026-05-21 07:23:11 +02:00
parent 0878b9f0b9
commit 197afbfb35
5 changed files with 45 additions and 157 deletions
+2
View File
@@ -1,6 +1,8 @@
void main() { void main() {
i32 mut x = 10; i32 mut x = 10;
x = 1 + 1;
x++; x++;
println!("hello, world {x}"); println!("hello, world {x}");
+1 -25
View File
@@ -2,30 +2,6 @@ use serde::Serialize;
use super::*; use super::*;
#[derive(Debug, Clone, Serialize)]
pub enum BinaryOp {
Plus,
Minus,
Multiply,
Divide,
Modulo,
Equal,
NotEqual,
LessThan,
GreaterThan,
LessThanOrEqual,
GreaterThanOrEqual,
And,
Or,
ShiftLeft,
ShiftRight,
RangeInclusive,
RangeExclusive,
BitAnd,
BitOr,
BitXor,
}
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub enum Expression { pub enum Expression {
Literal(Literal), Literal(Literal),
@@ -38,7 +14,7 @@ pub enum Expression {
}, },
Binary { Binary {
lhs: Box<Expression>, lhs: Box<Expression>,
op: BinaryOp, op: String,
rhs: Box<Expression>, rhs: Box<Expression>,
}, },
} }
+32 -61
View File
@@ -513,23 +513,6 @@ decrement = {
"--" "--"
} }
compound_assign = {
"="
| "+="
| "-="
| "/="
| "%="
| "&="
| "|="
| "^="
| "<<="
| ">>="
}
assign = {
compound_assign ~ expr
}
postfix = { postfix = {
field_px field_px
| call_px | call_px
@@ -540,7 +523,6 @@ postfix = {
| try_px | try_px
| increment | increment
| decrement | decrement
| assign
} }
// ------------------------------------------------------ // ------------------------------------------------------
@@ -564,51 +546,40 @@ prefix = {
} }
// ------------------------------------------------------ // ------------------------------------------------------
// OPERATORS (Arranged carefully for PEG priority matching) // OPERATORS
// ------------------------------------------------------ // ------------------------------------------------------
shl = { "<<" } bin_op = {
shr = { ">>" } "+="
range_inc = { "..=" } | "-="
range_exc = { ".." } | "/="
lte = { "<=" } | "%="
gte = { ">=" } | "&="
eq = { "==" } | "|="
neq = { "!=" } | "^="
and = { "&&" } | "<<="
or = { "||" } | ">>="
add = { "+" } | "<<"
sub = { "-" } | ">>"
mul = { "*" } | "..="
div = { "/" } | ".."
rem = { "%" } | "<="
lt = { "<" } | ">="
gt = { ">" } | "=="
bitand = { "&" } | "!="
bitor = { "|" } | "&&"
bitxor = { "^" } | "||"
| "+"
bin_op = _{ | "-"
shl | "*"
| shr | "/"
| range_inc | "%"
| range_exc | "<"
| lte | ">"
| gte | "&"
| eq | "|"
| neq | "^"
| and | "="
| or
| lt
| gt
| add
| sub
| mul
| div
| rem
| bitand
| bitor
| bitxor
} }
// ------------------------------------------------------ // ------------------------------------------------------
+5 -44
View File
@@ -18,57 +18,18 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Expression {
Rule::expr => { Rule::expr => {
static PRATT_PARSER: OnceLock<PrattParser<Rule>> = OnceLock::new(); static PRATT_PARSER: OnceLock<PrattParser<Rule>> = OnceLock::new();
let pratt = PRATT_PARSER.get_or_init(|| { let pratt = PRATT_PARSER.get_or_init(|| {
use Rule::*;
use pest::pratt_parser::{Assoc::*, Op}; use pest::pratt_parser::{Assoc::*, Op};
PrattParser::new() PrattParser::new().op(Op::infix(Rule::bin_op, Left))
.op(Op::infix(range_inc, Left) | Op::infix(range_exc, Left))
.op(Op::infix(or, Left))
.op(Op::infix(and, Left))
.op(Op::infix(bitor, Left))
.op(Op::infix(bitxor, Left))
.op(Op::infix(bitand, Left))
.op(Op::infix(eq, Left) | Op::infix(neq, Left))
.op(Op::infix(lt, Left)
| Op::infix(lte, Left)
| Op::infix(gt, Left)
| Op::infix(gte, Left))
.op(Op::infix(shl, Left) | Op::infix(shr, Left))
.op(Op::infix(add, Left) | Op::infix(sub, Left))
.op(Op::infix(mul, Left) | Op::infix(div, Left) | Op::infix(rem, Left))
}); });
pratt pratt
.map_primary(|primary_pair| Expression::try_from(primary_pair)) .map_primary(|primary_pair| Expression::try_from(primary_pair))
.map_infix(|lhs, op, rhs| { .map_infix(|expr, op, rhs| {
let bin_op = match op.as_rule() {
Rule::shl => BinaryOp::ShiftLeft,
Rule::shr => BinaryOp::ShiftRight,
Rule::range_inc => BinaryOp::RangeInclusive,
Rule::range_exc => BinaryOp::RangeExclusive,
Rule::lte => BinaryOp::LessThanOrEqual,
Rule::gte => BinaryOp::GreaterThanOrEqual,
Rule::eq => BinaryOp::Equal,
Rule::neq => BinaryOp::NotEqual,
Rule::and => BinaryOp::And,
Rule::or => BinaryOp::Or,
Rule::add => BinaryOp::Plus,
Rule::sub => BinaryOp::Minus,
Rule::mul => BinaryOp::Multiply,
Rule::div => BinaryOp::Divide,
Rule::rem => BinaryOp::Modulo,
Rule::lt => BinaryOp::LessThan,
Rule::gt => BinaryOp::GreaterThan,
Rule::bitand => BinaryOp::BitAnd,
Rule::bitor => BinaryOp::BitOr,
Rule::bitxor => BinaryOp::BitXor,
_ => return AstError::bug_unimplemented(op),
};
ast_expr!(Expression::Binary { ast_expr!(Expression::Binary {
lhs: lhs.map(Box::new), lhs: expr.map(Box::new).get_map(Box::new),
op: Ok(bin_op) as AstResult<'_, BinaryOp>, op: Ok(op.as_str().to_string()) as AstResult<'_, String>,
rhs: rhs.map(Box::new), rhs: rhs.map(Box::new).get_map(Box::new),
}) })
}) })
.parse(inner) .parse(inner)
+5 -27
View File
@@ -1,8 +1,8 @@
use mist_parser::ast::{ use mist_parser::ast::{
Attribute, BinaryOp, Block, ClassItem, EnumItem, ExprPath, ExprPathSegment, Expression, Attribute, Block, ClassItem, EnumItem, ExprPath, ExprPathSegment, Expression, FieldDecl,
FieldDecl, FunctionDecl, Generic, GenericDecl, Generics, GenericsDecl, Identifier, ImplDecl, FunctionDecl, Generic, GenericDecl, Generics, GenericsDecl, Identifier, ImplDecl, Literal,
Literal, Path, Pattern, Postfix, Prefix, Spanned, Statement, StatementBranch, TopLevel, Path, Pattern, Postfix, Prefix, Spanned, Statement, StatementBranch, TopLevel, TopLevelKind,
TopLevelKind, TypeExpr, TypeExprKind, TypePostfix, VarDecl, VarDeclStmt, Visibility, TypeExpr, TypeExprKind, TypePostfix, VarDecl, VarDeclStmt, Visibility,
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -187,29 +187,7 @@ impl GetRust for Expression {
} }
// Safely integrated to handle the tree structure built by the Pratt Parser // Safely integrated to handle the tree structure built by the Pratt Parser
Expression::Binary { lhs, op, rhs } => { Expression::Binary { lhs, op, rhs } => {
let op_str = match op { format!("{} {} {}", lhs.get_rust(), op, rhs.get_rust())
BinaryOp::Plus => "+",
BinaryOp::Minus => "-",
BinaryOp::Multiply => "*",
BinaryOp::Divide => "/",
BinaryOp::Modulo => "%",
BinaryOp::Equal => "==",
BinaryOp::NotEqual => "!=",
BinaryOp::LessThan => "<",
BinaryOp::GreaterThan => ">",
BinaryOp::LessThanOrEqual => "<=",
BinaryOp::GreaterThanOrEqual => ">=",
BinaryOp::And => "&&",
BinaryOp::Or => "||",
BinaryOp::ShiftLeft => "<<",
BinaryOp::ShiftRight => ">>",
BinaryOp::RangeInclusive => "..=",
BinaryOp::RangeExclusive => "..",
BinaryOp::BitAnd => "&",
BinaryOp::BitOr => "|",
BinaryOp::BitXor => "^",
};
format!("{} {} {}", lhs.get_rust(), op_str, rhs.get_rust())
} }
} }
} }