Add operators, math, time, string, collection, and HOF builtins to El
This commit is contained in:
@@ -84,6 +84,21 @@ pub enum BinOp {
|
||||
Add, Sub, Mul, Div,
|
||||
Eq, NotEq, Lt, Gt, LtEq, GtEq,
|
||||
And, Or,
|
||||
Mod, // %
|
||||
BitAnd, // &
|
||||
BitOr, // | (single pipe)
|
||||
BitXor, // ^
|
||||
Shl, // <<
|
||||
Shr, // >>
|
||||
}
|
||||
|
||||
// ── Unary operators ───────────────────────────────────────────────────────────
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum UnaryOp {
|
||||
Neg, // - (unary minus)
|
||||
Not, // ! (logical not)
|
||||
BitNot, // ~
|
||||
}
|
||||
|
||||
// ── Expressions ───────────────────────────────────────────────────────────────
|
||||
@@ -94,6 +109,7 @@ pub enum Expr {
|
||||
Ident(String),
|
||||
BinOp { op: BinOp, left: Box<Expr>, right: Box<Expr> },
|
||||
UnaryNot(Box<Expr>),
|
||||
UnaryBitNot(Box<Expr>),
|
||||
Call { func: Box<Expr>, args: Vec<Expr> },
|
||||
Block(Vec<Stmt>),
|
||||
Match { subject: Box<Expr>, arms: Vec<MatchArm> },
|
||||
|
||||
@@ -11,7 +11,7 @@ mod error;
|
||||
mod parser;
|
||||
|
||||
pub use ast::{
|
||||
BinOp, Decorator, Expr, Field, Literal, MatchArm, Param, Pattern, Program, ProtocolMethod,
|
||||
BinOp, UnaryOp, Decorator, Expr, Field, Literal, MatchArm, Param, Pattern, Program, ProtocolMethod,
|
||||
SeedStmt, Stmt, TestTarget, TypeExpr, Variant,
|
||||
};
|
||||
pub use error::{ParseError, ParseErrorKind};
|
||||
|
||||
@@ -717,6 +717,48 @@ impl Parser {
|
||||
self.parse_pipe_expr()
|
||||
}
|
||||
|
||||
fn parse_bitwise_or_expr(&mut self) -> Result<Expr, ParseError> {
|
||||
let mut left = self.parse_bitwise_xor_expr()?;
|
||||
while self.eat(&Token::Pipe) {
|
||||
let right = self.parse_bitwise_xor_expr()?;
|
||||
left = Expr::BinOp { op: BinOp::BitOr, left: Box::new(left), right: Box::new(right) };
|
||||
}
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_bitwise_xor_expr(&mut self) -> Result<Expr, ParseError> {
|
||||
let mut left = self.parse_bitwise_and_expr()?;
|
||||
while self.eat(&Token::Caret) {
|
||||
let right = self.parse_bitwise_and_expr()?;
|
||||
left = Expr::BinOp { op: BinOp::BitXor, left: Box::new(left), right: Box::new(right) };
|
||||
}
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_bitwise_and_expr(&mut self) -> Result<Expr, ParseError> {
|
||||
let mut left = self.parse_shift_expr()?;
|
||||
while self.eat(&Token::Ampersand) {
|
||||
let right = self.parse_shift_expr()?;
|
||||
left = Expr::BinOp { op: BinOp::BitAnd, left: Box::new(left), right: Box::new(right) };
|
||||
}
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_shift_expr(&mut self) -> Result<Expr, ParseError> {
|
||||
let mut left = self.parse_additive()?;
|
||||
loop {
|
||||
let op = match self.peek() {
|
||||
Token::Shl => BinOp::Shl,
|
||||
Token::Shr => BinOp::Shr,
|
||||
_ => break,
|
||||
};
|
||||
self.advance();
|
||||
let right = self.parse_additive()?;
|
||||
left = Expr::BinOp { op, left: Box::new(left), right: Box::new(right) };
|
||||
}
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
/// pipe_expr = or_expr (|> ident)*
|
||||
/// `a |> f` desugars to `Call(f, [a])`
|
||||
fn parse_pipe_expr(&mut self) -> Result<Expr, ParseError> {
|
||||
@@ -766,7 +808,7 @@ impl Parser {
|
||||
}
|
||||
|
||||
fn parse_comparison(&mut self) -> Result<Expr, ParseError> {
|
||||
let mut left = self.parse_additive()?;
|
||||
let mut left = self.parse_bitwise_or_expr()?;
|
||||
loop {
|
||||
let op = match self.peek() {
|
||||
Token::Lt => BinOp::Lt,
|
||||
@@ -803,6 +845,7 @@ impl Parser {
|
||||
let op = match self.peek() {
|
||||
Token::Star => BinOp::Mul,
|
||||
Token::Slash => BinOp::Div,
|
||||
Token::Percent => BinOp::Mod,
|
||||
_ => break,
|
||||
};
|
||||
self.advance();
|
||||
@@ -817,6 +860,10 @@ impl Parser {
|
||||
let inner = self.parse_unary()?;
|
||||
return Ok(Expr::UnaryNot(Box::new(inner)));
|
||||
}
|
||||
if self.eat(&Token::Tilde) {
|
||||
let inner = self.parse_unary()?;
|
||||
return Ok(Expr::UnaryBitNot(Box::new(inner)));
|
||||
}
|
||||
self.parse_postfix()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user