1use crate::span::Span;
4use crate::token::Token;
5use rust_decimal::Decimal;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum UnOp {
10 Neg,
12 Fact,
14}
15
16impl UnOp {
17 pub fn from_token(token: &Token) -> Self {
18 match token {
19 Token::Minus => UnOp::Neg,
20 Token::Bang => UnOp::Fact,
21 _ => unreachable!("Invalid token for unary operator"),
22 }
23 }
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub enum BinOp {
29 Add,
31 Sub,
33 Mul,
35 Div,
37 Pow,
39 Equal,
41 NotEqual,
43 Less,
45 LessEqual,
47 Greater,
49 GreaterEqual,
51}
52
53impl BinOp {
54 pub fn from_token(token: &Token) -> Self {
55 match token {
56 Token::Plus => BinOp::Add,
57 Token::Minus => BinOp::Sub,
58 Token::Star => BinOp::Mul,
59 Token::Slash => BinOp::Div,
60 Token::Caret => BinOp::Pow,
61 Token::Equal => BinOp::Equal,
62 Token::NotEqual => BinOp::NotEqual,
63 Token::Less => BinOp::Less,
64 Token::LessEqual => BinOp::LessEqual,
65 Token::Greater => BinOp::Greater,
66 Token::GreaterEqual => BinOp::GreaterEqual,
67 _ => unreachable!("Invalid token for binary operator"),
68 }
69 }
70}
71
72#[derive(Debug, Clone)]
74pub struct Expr {
75 pub kind: ExprKind,
76 pub span: Span,
77}
78
79#[derive(Debug, Clone)]
81pub enum ExprKind {
82 Literal(Decimal),
84 Ident { name: String },
86 Unary { op: UnOp, expr: Box<Expr> },
88 Binary {
90 op: BinOp,
91 left: Box<Expr>,
92 right: Box<Expr>,
93 },
94 Call { name: String, args: Vec<Expr> },
96}
97
98impl Expr {
99 pub fn literal(value: Decimal, span: Span) -> Self {
100 Self {
101 kind: ExprKind::Literal(value),
102 span,
103 }
104 }
105
106 pub fn ident(name: String, span: Span) -> Self {
107 Self {
108 kind: ExprKind::Ident { name },
109 span,
110 }
111 }
112
113 pub fn unary(op: UnOp, expr: Expr, span: Span) -> Self {
114 Self {
115 kind: ExprKind::Unary {
116 op,
117 expr: Box::new(expr),
118 },
119 span,
120 }
121 }
122
123 pub fn binary(op: BinOp, left: Expr, right: Expr, span: Span) -> Self {
124 Self {
125 kind: ExprKind::Binary {
126 op,
127 left: Box::new(left),
128 right: Box::new(right),
129 },
130 span,
131 }
132 }
133
134 pub fn call(name: String, args: Vec<Expr>, span: Span) -> Self {
135 Self {
136 kind: ExprKind::Call { name, args },
137 span,
138 }
139 }
140}