diff options
Diffstat (limited to 'src/ast.rs')
-rw-r--r-- | src/ast.rs | 78 |
1 files changed, 73 insertions, 5 deletions
@@ -56,6 +56,17 @@ pub enum Statement { | |||
56 | Declaration(Declaration), | 56 | Declaration(Declaration), |
57 | } | 57 | } |
58 | 58 | ||
59 | impl Statement { | ||
60 | #[cfg(test)] | ||
61 | pub fn decl(ty: Type, ident: &str, init: Expr) -> Self { | ||
62 | Self::Declaration(Declaration { | ||
63 | ty, | ||
64 | name: ident.to_owned(), | ||
65 | init: Some(init.boxed()), | ||
66 | }) | ||
67 | } | ||
68 | } | ||
69 | |||
59 | #[derive(Debug, Eq, PartialEq, Clone)] | 70 | #[derive(Debug, Eq, PartialEq, Clone)] |
60 | pub enum Expr { | 71 | pub enum Expr { |
61 | Node, | 72 | Node, |
@@ -77,11 +88,30 @@ impl Expr { | |||
77 | Box::new(self) | 88 | Box::new(self) |
78 | } | 89 | } |
79 | 90 | ||
80 | pub fn as_ident(self) -> Option<Identifier> { | 91 | #[cfg(test)] |
81 | match self { | 92 | pub fn bin(lhs: Expr, op: &str, rhs: Expr) -> Expr { |
82 | Self::Ident(i) => Some(i), | 93 | use std::str::FromStr; |
83 | _ => None, | 94 | Self::Bin(lhs.boxed(), BinOp::from_str(op).unwrap(), rhs.boxed()) |
84 | } | 95 | } |
96 | |||
97 | #[cfg(test)] | ||
98 | pub fn ident(i: &str) -> Expr { | ||
99 | Self::Ident(i.to_owned()) | ||
100 | } | ||
101 | |||
102 | #[cfg(test)] | ||
103 | pub fn call<const N: usize>(fun: &str, params: [Expr; N]) -> Expr { | ||
104 | Self::Call(Call { | ||
105 | function: fun.to_owned(), | ||
106 | parameters: params.to_vec(), | ||
107 | }) | ||
108 | } | ||
109 | |||
110 | #[cfg(test)] | ||
111 | pub fn list<const N: usize>(items: [Expr; N]) -> Expr { | ||
112 | Self::List(List { | ||
113 | items: items.to_vec() | ||
114 | }) | ||
85 | } | 115 | } |
86 | } | 116 | } |
87 | 117 | ||
@@ -99,6 +129,44 @@ pub enum BinOp { | |||
99 | Assign(AssignOp), | 129 | Assign(AssignOp), |
100 | } | 130 | } |
101 | 131 | ||
132 | impl std::str::FromStr for BinOp { | ||
133 | type Err = (); | ||
134 | fn from_str(val: &str) -> Result<Self, Self::Err> { | ||
135 | match val { | ||
136 | "+" => Ok(Self::Arith(ArithOp::Add)), | ||
137 | "-" => Ok(Self::Arith(ArithOp::Sub)), | ||
138 | "*" => Ok(Self::Arith(ArithOp::Mul)), | ||
139 | "/" => Ok(Self::Arith(ArithOp::Div)), | ||
140 | "%" => Ok(Self::Arith(ArithOp::Mod)), | ||
141 | ">" => Ok(Self::Cmp(CmpOp::Gt)), | ||
142 | "<" => Ok(Self::Cmp(CmpOp::Lt)), | ||
143 | ">=" => Ok(Self::Cmp(CmpOp::Gte)), | ||
144 | "<=" => Ok(Self::Cmp(CmpOp::Lte)), | ||
145 | "==" => Ok(Self::Cmp(CmpOp::Eq)), | ||
146 | "!=" => Ok(Self::Cmp(CmpOp::Neq)), | ||
147 | "&&" => Ok(Self::Logic(LogicOp::And)), | ||
148 | "||" => Ok(Self::Logic(LogicOp::Or)), | ||
149 | "=" => Ok(Self::Assign(AssignOp { op: None })), | ||
150 | "+=" => Ok(Self::Assign(AssignOp { | ||
151 | op: Some(ArithOp::Add), | ||
152 | })), | ||
153 | "-=" => Ok(Self::Assign(AssignOp { | ||
154 | op: Some(ArithOp::Sub), | ||
155 | })), | ||
156 | "*=" => Ok(Self::Assign(AssignOp { | ||
157 | op: Some(ArithOp::Mul), | ||
158 | })), | ||
159 | "/=" => Ok(Self::Assign(AssignOp { | ||
160 | op: Some(ArithOp::Div), | ||
161 | })), | ||
162 | "%=" => Ok(Self::Assign(AssignOp { | ||
163 | op: Some(ArithOp::Mod), | ||
164 | })), | ||
165 | _ => Err(()), | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | |||
102 | // + - * / | 170 | // + - * / |
103 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | 171 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] |
104 | pub enum ArithOp { | 172 | pub enum ArithOp { |