Add expression AST and Pratt parser with REPL
- ast.rs: Expr/ExprKind with UnaryOp, BinaryOp, StructField - parser.rs: Pratt expression parser with allow_struct_literals flag, error recovery via dummy tokens, and 19 unit tests - main.rs: interactive expression REPL (prints parsed AST)
This commit is contained in:
113
fluxc/src/ast.rs
Normal file
113
fluxc/src/ast.rs
Normal file
@@ -0,0 +1,113 @@
|
||||
use crate::token::Span;
|
||||
|
||||
// ── Operators ──────────────────────────────────────────────────────────────────
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum UnaryOp {
|
||||
Neg, // `-`
|
||||
Not, // `!`
|
||||
BitNot, // `~`
|
||||
Deref, // `*`
|
||||
AddrOf, // `&`
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum BinaryOp {
|
||||
// Logical
|
||||
Or, // `or`
|
||||
And, // `and`
|
||||
// Bitwise
|
||||
BitOr, // `|`
|
||||
BitXor, // `^`
|
||||
BitAnd, // `&`
|
||||
// Comparison
|
||||
Eq, // `==`
|
||||
Ne, // `!=`
|
||||
Lt, // `<`
|
||||
Gt, // `>`
|
||||
Le, // `<=`
|
||||
Ge, // `>=`
|
||||
// Arithmetic
|
||||
Add, // `+`
|
||||
Sub, // `-`
|
||||
Mul, // `*`
|
||||
Div, // `/`
|
||||
Rem, // `%`
|
||||
}
|
||||
|
||||
// ── Struct literal field ───────────────────────────────────────────────────────
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StructField {
|
||||
pub name: String,
|
||||
pub name_span: Span,
|
||||
pub value: Expr,
|
||||
}
|
||||
|
||||
// ── Expression ────────────────────────────────────────────────────────────────
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Expr {
|
||||
pub kind: ExprKind,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl Expr {
|
||||
pub fn new(kind: ExprKind, span: Span) -> Self {
|
||||
Self { kind, span }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ExprKind {
|
||||
// Literals
|
||||
IntLit(String),
|
||||
FloatLit(String),
|
||||
StringLit(String),
|
||||
CharLit(String),
|
||||
Bool(bool),
|
||||
|
||||
// Identifier
|
||||
Ident(String),
|
||||
|
||||
// Struct literal: `Foo { x: 1, y: 2 }`
|
||||
StructLit {
|
||||
name: String,
|
||||
name_span: Span,
|
||||
fields: Vec<StructField>,
|
||||
},
|
||||
|
||||
// Operators
|
||||
Unary {
|
||||
op: UnaryOp,
|
||||
op_span: Span,
|
||||
expr: Box<Expr>,
|
||||
},
|
||||
Binary {
|
||||
op: BinaryOp,
|
||||
op_span: Span,
|
||||
lhs: Box<Expr>,
|
||||
rhs: Box<Expr>,
|
||||
},
|
||||
|
||||
// Postfix
|
||||
Field {
|
||||
expr: Box<Expr>,
|
||||
field: String,
|
||||
field_span: Span,
|
||||
},
|
||||
Index {
|
||||
expr: Box<Expr>,
|
||||
index: Box<Expr>,
|
||||
},
|
||||
Call {
|
||||
callee: Box<Expr>,
|
||||
args: Vec<Expr>,
|
||||
},
|
||||
|
||||
// Parenthesised expression
|
||||
Group(Box<Expr>),
|
||||
|
||||
// Placeholder for parse errors — allows parsing to continue
|
||||
Error,
|
||||
}
|
||||
Reference in New Issue
Block a user