Acord/core/src/interp/ast.rs

97 lines
2.2 KiB
Rust

#[derive(Debug, Clone)]
pub enum Op {
Add, Sub, Mul, Div, Mod, Pow,
Eq, Neq, Lt, Gt, Lte, Gte,
And, Or, Not, Neg,
Strip,
}
#[derive(Debug, Clone)]
pub enum Stmt {
Let(String, Option<String>, Expr),
Assign(String, Expr),
PathAssign(Expr, Expr),
While(Expr, Vec<Stmt>),
IfElse(Expr, Vec<Stmt>, Option<Vec<Stmt>>),
ForLoop(String, Expr, Vec<Stmt>),
FnDef {
name: String,
params: Vec<(String, Option<String>)>,
return_type: Option<String>,
body: Vec<Stmt>,
},
Return(Expr),
Use(Vec<String>, bool),
CellAssign {
block: Option<String>,
table: String,
cell: (u32, u32),
value: Expr,
},
SolveDef {
name: String,
params: Vec<String>,
target_var: String,
source_fn: String,
source_args: Vec<String>,
result_var: String,
},
ExprStmt(Expr),
TraitDef {
name: String,
methods: Vec<String>,
},
ImplBlock {
type_name: String,
trait_name: Option<String>,
methods: Vec<Stmt>,
},
}
#[derive(Debug, Clone, PartialEq)]
pub enum CellRefTarget {
Whole,
Cell(u32, u32),
Range(u32, u32, u32, u32),
}
#[derive(Debug, Clone)]
pub enum Expr {
Num(f64),
Spice(f64, String),
Str(String),
Bool(bool),
Ident(String),
BinOp(Op, Box<Expr>, Box<Expr>),
UnaryOp(Op, Box<Expr>),
Call(String, Vec<Expr>),
Array(Vec<Expr>),
Index(Box<Expr>, Box<Expr>),
Range(Box<Expr>, Box<Expr>),
IsCheck(Box<Expr>, String),
CellRef {
block: Option<String>,
table: Option<String>,
target: CellRefTarget,
},
SolveMacro {
var: String,
source_fn: String,
},
Struct(Vec<(String, Expr)>),
Field(Box<Expr>, String),
MethodCall(Box<Expr>, String, Vec<Expr>),
StaticCall(String, String, Vec<Expr>),
}
/// checks whether an expression names a writable lvalue.
pub(crate) fn is_lvalue(expr: &Expr) -> bool {
match expr {
Expr::Ident(_) => true,
Expr::Field(inner, _) => is_lvalue(inner),
Expr::Index(inner, _) => is_lvalue(inner),
_ => false,
}
}