1use crate::luna_impl::position::Located;
2
3use super::{code::BinaryOperation, tokens::Token};
4
5#[derive(Debug, Clone, PartialEq)]
6pub struct Chunk(pub Vec<Located<Statement>>);
7#[derive(Debug, Clone, PartialEq)]
8pub struct Block(pub Vec<Located<Statement>>);
9#[derive(Debug, Clone, PartialEq)]
10pub enum Statement {
11 Block(Block),
12 LetBinding {
13 params: Vec<Located<Parameter>>,
14 exprs: Vec<Located<Expression>>,
15 },
16 LetElse {
17 param: Located<Parameter>,
18 expr: Located<Expression>,
19 else_case: Located<Block>,
20 },
21 Assign {
22 paths: Vec<Located<Path>>,
23 exprs: Vec<Located<Expression>>,
24 },
25 AssignOperation {
26 op: AssignOperator,
27 path: Located<Path>,
28 expr: Located<Expression>,
29 },
30 Call {
31 path: Located<Path>,
32 args: Vec<Located<Expression>>,
33 },
34 SelfCall {
35 head: Located<Path>,
36 field: Located<String>,
37 args: Vec<Located<Expression>>,
38 },
39 Fn {
40 path: Located<Path>,
41 params: Vec<Located<Parameter>>,
42 var_args: Option<Located<String>>,
43 body: Located<Block>,
44 },
45 LetFn {
46 ident: Located<String>,
47 params: Vec<Located<Parameter>>,
48 var_args: Option<Located<String>>,
49 body: Located<Block>,
50 },
51 If {
52 cond: Located<Expression>,
53 case: Located<Block>,
54 else_case: Option<Located<Block>>,
55 },
56 IfLet {
57 param: Located<Parameter>,
58 expr: Located<Expression>,
59 case: Located<Block>,
60 else_case: Option<Located<Block>>,
61 },
62 Match {
63 expr: Located<Expression>,
64 cases: Vec<(Located<Pattern>, Located<Block>)>
65 },
66 While {
67 cond: Located<Expression>,
68 body: Located<Block>,
69 },
70 WhileLet {
71 param: Located<Parameter>,
72 expr: Located<Expression>,
73 body: Located<Block>,
74 },
75 For {
76 ident: Located<String>,
77 iter: Located<Expression>,
78 body: Located<Block>,
79 },
80 Return(Option<Located<Expression>>),
81 Break,
82 Continue,
83}
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
85pub enum AssignOperator {
86 Plus,
87 Minus,
88 Star,
89 Slash,
90 Exponent,
91 Percent,
92 }
95#[derive(Debug, Clone, PartialEq)]
96pub enum Pattern {
97 Ident(String),
98 Atom(Atom),
99 Guard {
100 pattern: Box<Located<Self>>,
101 cond: Located<Expression>
102 }
103}
104#[derive(Debug, Clone, PartialEq)]
105pub enum Expression {
106 Atom(Atom),
107 Binary {
108 op: BinaryOperator,
109 left: Box<Located<Self>>,
110 right: Box<Located<Self>>,
111 },
112 Unary {
113 op: UnaryOperator,
114 right: Box<Located<Self>>,
115 },
116 Call {
117 head: Box<Located<Self>>,
118 args: Vec<Located<Expression>>,
119 },
120 SelfCall {
121 head: Box<Located<Self>>,
122 field: Located<String>,
123 args: Vec<Located<Expression>>,
124 },
125 Field {
126 head: Box<Located<Self>>,
127 field: Located<String>,
128 },
129 Index {
130 head: Box<Located<Self>>,
131 index: Box<Located<Expression>>,
132 },
133}
134#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
135pub enum BinaryOperator {
136 Plus,
137 Minus,
138 Star,
139 Slash,
140 Exponent,
141 Percent,
142 EqualEqual,
143 ExclamationEqual,
144 Less,
145 Greater,
146 LessEqual,
147 GreaterEqual,
148 Ampersand,
149 Pipe,
150}
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
152pub enum UnaryOperator {
153 Minus,
154 Exclamation,
155}
156#[derive(Debug, Clone, PartialEq)]
157pub enum Atom {
158 Path(Path),
159 Null,
160 Int(i64),
161 Float(f64),
162 Bool(bool),
163 Char(char),
164 String(String),
165 Expression(Box<Located<Expression>>),
166 Vector(Vec<Located<Expression>>),
167 Object(Vec<(Located<String>, Located<Expression>)>),
168 If {
169 cond: Box<Located<Expression>>,
170 case: Box<Located<Expression>>,
171 else_case: Box<Located<Expression>>,
172 },
173 Fn {
174 params: Vec<Located<Parameter>>,
175 var_args: Option<Located<String>>,
176 body: Located<Block>,
177 },
178}
179#[derive(Debug, Clone, PartialEq)]
180pub enum Path {
181 Ident(String),
182 Field {
183 head: Box<Located<Self>>,
184 field: Located<String>,
185 },
186 Index {
187 head: Box<Located<Self>>,
188 index: Box<Located<Expression>>,
189 },
190}
191#[derive(Debug, Clone, PartialEq)]
192pub enum Parameter {
193 Ident(String),
194 Object(Vec<Located<String>>),
195 Vector(Vec<Located<String>>),
196}
197
198impl TryFrom<&Token> for AssignOperator {
199 type Error = ();
200 fn try_from(value: &Token) -> Result<Self, Self::Error> {
201 match value {
202 Token::PlusEqual => Ok(Self::Plus),
203 Token::MinusEqual => Ok(Self::Minus),
204 Token::StarEqual => Ok(Self::Star),
205 Token::SlashEqual => Ok(Self::Slash),
206 Token::PercentEqual => Ok(Self::Percent),
207 Token::ExponentEqual => Ok(Self::Exponent),
208 _ => Err(()),
209 }
210 }
211}
212impl From<AssignOperator> for BinaryOperation {
213 fn from(value: AssignOperator) -> Self {
214 match value {
215 AssignOperator::Plus => Self::Add,
216 AssignOperator::Minus => Self::Sub,
217 AssignOperator::Star => Self::Mul,
218 AssignOperator::Slash => Self::Div,
219 AssignOperator::Exponent => Self::Pow,
220 AssignOperator::Percent => Self::Mod,
221 }
222 }
223}
224impl BinaryOperator {
225 pub const LAYERS: &'static [&'static [Self]] = &[
226 &[Self::Ampersand, Self::Pipe],
227 &[
228 Self::EqualEqual,
229 Self::ExclamationEqual,
230 Self::Less,
231 Self::Greater,
232 Self::LessEqual,
233 Self::GreaterEqual,
234 ],
235 &[Self::Plus, Self::Minus],
236 &[Self::Star, Self::Slash, Self::Percent],
237 &[Self::Exponent],
238 ];
239 pub fn layer(layer: usize) -> Option<&'static [Self]> {
240 Self::LAYERS.get(layer).cloned()
241 }
242}
243impl TryFrom<&Token> for BinaryOperator {
244 type Error = ();
245 fn try_from(value: &Token) -> Result<Self, Self::Error> {
246 match value {
247 Token::Ampersand => Ok(Self::Ampersand),
248 Token::Pipe => Ok(Self::Pipe),
249 Token::Plus => Ok(Self::Plus),
250 Token::Minus => Ok(Self::Minus),
251 Token::Star => Ok(Self::Star),
252 Token::Slash => Ok(Self::Slash),
253 Token::Percent => Ok(Self::Percent),
254 Token::Exponent => Ok(Self::Exponent),
255 Token::EqualEqual => Ok(Self::EqualEqual),
256 Token::ExclamationEqual => Ok(Self::ExclamationEqual),
257 Token::Less => Ok(Self::Less),
258 Token::Greater => Ok(Self::Greater),
259 Token::LessEqual => Ok(Self::LessEqual),
260 Token::GreaterEqual => Ok(Self::GreaterEqual),
261 _ => Err(()),
262 }
263 }
264}
265impl UnaryOperator {
266 pub const LAYERS: &'static [&'static [Self]] = &[&[Self::Exclamation], &[Self::Minus]];
267 pub fn layer(layer: usize) -> Option<&'static [Self]> {
268 Self::LAYERS.get(layer).cloned()
269 }
270}
271impl TryFrom<&Token> for UnaryOperator {
272 type Error = ();
273 fn try_from(value: &Token) -> Result<Self, Self::Error> {
274 match value {
275 Token::Exclamation => Ok(Self::Exclamation),
276 Token::Minus => Ok(Self::Minus),
277 _ => Err(()),
278 }
279 }
280}