1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
use crate::operator::{BinaryOperator, UnaryOperator}; use crate::{interner::Symbol, location::Location, operator::TernaryOperator}; #[derive(Clone, Debug, Eq, PartialEq)] pub enum Stmt { Assign { var: Symbol, value: Expr, location: Location, }, Print { values: Vec<Expr>, newline: bool, wait: bool, location: Location, }, If { arms: Vec<(Expr, Vec<Stmt>, Location)>, other: Vec<Stmt>, other_location: Location, }, While { cond: Expr, body: Vec<Stmt>, location: Location, }, Expression { expr: Expr, location: Location, }, Exit { location: Location, }, } impl Stmt { pub fn location(&self) -> Location { match self { Stmt::Assign { location, .. } | Stmt::Print { location, .. } | Stmt::While { location, .. } | Stmt::Expression { location, .. } | Stmt::Exit { location } => *location, Stmt::If { arms, .. } => arms[0].2, } } pub fn is_block(&self) -> bool { match self { Stmt::If { .. } | Stmt::While { .. } => true, Stmt::Assign { .. } | Stmt::Print { .. } | Stmt::Expression { .. } | Stmt::Exit { .. } => false, } } } #[derive(Clone, Debug, Eq, PartialEq)] pub enum Expr { Number(u32), String(Symbol), Variable(Symbol), BuiltinFunc { name: Symbol, args: Vec<Expr>, }, Nop(Box<Expr>), UnaryOp { value: Box<Expr>, op: UnaryOperator, }, BinaryOp { lhs: Box<Expr>, rhs: Box<Expr>, op: BinaryOperator, }, TernaryOp { lhs: Box<Expr>, mhs: Box<Expr>, rhs: Box<Expr>, op: TernaryOperator, }, } impl Expr { pub fn unary_op(self, op: UnaryOperator) -> Self { Expr::UnaryOp { value: Box::new(self), op, } } pub fn binary_op(self, rhs: Self, op: BinaryOperator) -> Self { Expr::BinaryOp { lhs: Box::new(self), rhs: Box::new(rhs), op, } } pub fn ternary_op(self, mhs: Self, rhs: Self, op: TernaryOperator) -> Self { Expr::TernaryOp { lhs: Box::new(self), mhs: Box::new(mhs), rhs: Box::new(rhs), op, } } }