kravl_parser/syntax/
ast.rs

1use syntax::tokens::{
2    TokenType,
3    Token,
4    BinOp,
5};
6
7use syntax::lexer::Lexer;
8
9#[derive(Debug, Clone)]
10pub enum Statement {
11    If(Box<Expression>, Box<Statement>),
12    IfElse(Box<Expression>, Box<Statement>, Box<Statement>),
13    Variable(String, Box<Expression>),
14    Block(Box<Vec<Statement>>),
15    Expression(Box<Expression>),
16    Assignment(String, Box<Expression>),
17}
18
19#[derive(Debug, Clone)]
20pub enum Expression {
21    Integer(i64),
22    Float(f64),
23    Text(String),
24    Bool(bool),
25    Call(Box<Expression>, Box<Vec<Expression>>),
26    Assignment(Box<Expression>, Box<Expression>),
27    Dot(Box<Expression>, Box<Expression>),
28    Index(String, Box<Expression>),
29    Array(Box<Vec<Expression>>),
30    Identifier(String),
31    Operation(Box<Expression>, BinOp, Box<Expression>),
32    Definition(Option<String>, Box<Vec<String>>, Box<Vec<Statement>>, Option<String>),
33    Lambda(Box<Vec<String>>, Box<Statement>, Option<String>),
34    Return(Box<Expression>),
35}
36
37pub struct Parser {
38    lexer: Lexer,
39}
40
41impl Parser {
42    pub fn new() -> Parser {
43        Parser {
44            lexer: Lexer::new(),
45        }
46    }
47
48    pub fn from(lexer: Lexer) -> Parser {
49        Parser {
50            lexer: lexer,
51        }
52    }
53
54    pub fn parse_from_tokens(tokens: Vec<Token>) -> Result<Vec<Statement>, String> {
55        let mut parser = Parser::from(Lexer::from(tokens));
56
57        parser.parse_full()
58    }
59
60    fn parse_bin_op(&mut self, expr: Expression) -> Result<Expression, String> {
61        let mut expr_list = vec!(expr);
62        let mut oper_list: Vec<(BinOp, u8)> = Vec::new();
63
64        oper_list.push(Lexer::bin_op(
65            &self.lexer.current_token_content()[..]
66        ).unwrap());
67
68        self.lexer.next_token();
69
70        expr_list.push(try!(self.parse_word()));
71
72        let mut done = false;
73
74        while expr_list.len() > 1 {
75
76            if !done && self.lexer.next_token() {
77                if self.lexer.current_token().token_type != TokenType::BinOp {
78                    self.lexer.previous_token();
79                    done = true;
80
81                    continue
82                }
83
84                let (op, prec) = Lexer::bin_op(&self.lexer.current_token_content()[..]).unwrap();
85
86                if prec > oper_list.last().unwrap().1 {
87
88                    let left = expr_list.pop().unwrap();
89                    let right = expr_list.pop().unwrap();
90
91                    expr_list.push(Expression::Operation(
92                        Box::new(left),
93                        oper_list.pop().unwrap().0,
94                        Box::new(right),
95                    ));
96
97                    self.lexer.next_token();
98
99                    expr_list.push(try!(self.parse_word()));
100                    oper_list.push((op, prec));
101
102                    continue
103                }
104                self.lexer.next_token();
105
106                expr_list.push(try!(self.parse_word()));
107                oper_list.push((op, prec));
108            }
109
110            let left = expr_list.pop().unwrap();
111            let right = expr_list.pop().unwrap();
112
113            let oper = Expression::Operation(
114                Box::new(left),
115                oper_list.pop().unwrap().0,
116                Box::new(right),
117            );
118
119            expr_list.push(oper);
120        }
121
122        Ok(expr_list.pop().unwrap())
123    }
124
125    fn parse_word(&mut self) -> Result<Expression, String> {
126        match self.lexer.current_token().token_type {
127            TokenType::Integer => {
128                Ok(Expression::Integer(
129                    self.lexer.current_token_content().parse::<i64>().unwrap()
130                ))
131            },
132
133            TokenType::Float => {
134                Ok(Expression::Float(
135                    self.lexer.current_token_content().parse::<f64>().unwrap()
136                ))
137            },
138
139            TokenType::Text => {
140                Ok(Expression::Text(
141                    self.lexer.current_token_content()
142                ))
143            },
144
145            TokenType::True => {
146                Ok(Expression::Bool(true))
147            },
148
149            TokenType::False => {
150                Ok(Expression::Bool(false))
151            },
152
153            TokenType::LParen => {
154                self.lexer.next_token();
155
156                let expr = try!(self.parse_expression());
157
158                try!(self.lexer.match_current_token(TokenType::RParen));
159
160                self.lexer.next_token();
161
162                if self.lexer.current_token().token_type == TokenType::LParen {
163                    return self.parse_caller(expr)
164                }
165
166                self.lexer.previous_token();
167
168                Ok(expr)
169            },
170
171            TokenType::Identifier => {
172                let id = Expression::Identifier(self.lexer.current_token_content());
173
174                if self.lexer.next_token() {
175                    return match self.lexer.current_token().token_type {
176                        TokenType::BinOp => {
177                            self.parse_bin_op(id)
178                        },
179                        
180                        TokenType::LParen => {
181                            self.parse_caller(id)
182                        },
183                        
184                        _ => {
185                            self.lexer.previous_token();
186                            Ok(id)
187                        }
188                    }
189                }
190
191                Ok(id)
192            },
193            
194            TokenType::Lambda => {
195                self.lexer.next_token();
196
197                let mut arg_stack = Vec::new();
198
199                while self.lexer.current_token().token_type == TokenType::Identifier {
200                    arg_stack.push(self.lexer.current_token_content());
201                    
202                    self.lexer.next_token();
203
204                    if self.lexer.current_token().token_type == TokenType::Comma {
205                        self.lexer.next_token();
206                    }
207                }
208
209                let ret_type: Option<String>;
210
211                if self.lexer.current_token().token_type == TokenType::Arrow {
212                    self.lexer.next_token();
213
214                    if self.lexer.current_token().token_type == TokenType::Identifier {
215                        ret_type = Some(self.lexer.current_token_content());
216                    } else {
217                        ret_type = None;
218                    }
219
220                } else {
221                    ret_type = None;
222                }
223
224                self.lexer.next_token();
225
226                try!(self.lexer.match_current_token(TokenType::Colon));
227
228                self.lexer.next_token();
229
230                let block_stmt = try!(self.parse_statement());
231
232                Ok(Expression::Lambda(
233                    Box::new(arg_stack),
234                    Box::new(block_stmt),
235                    ret_type,
236                ))
237            },
238
239            TokenType::Definition => {
240                self.lexer.next_token();
241
242                let name: Option<String>;
243
244                if self.lexer.current_token().token_type == TokenType::Identifier {
245                    name = Some(self.lexer.current_token_content());
246                    self.lexer.next_token();
247                } else {
248                    name = None;
249                }
250
251                try!(self.lexer.match_current_token(TokenType::LParen));
252
253                self.lexer.next_token();
254
255                let mut arg_stack = Vec::new();
256
257                while self.lexer.current_token().token_type == TokenType::Identifier {
258                    arg_stack.push(self.lexer.current_token_content());
259                    
260                    self.lexer.next_token();
261
262                    if self.lexer.current_token().token_type == TokenType::Comma {
263                        self.lexer.next_token();
264                    }
265                }
266
267                try!(self.lexer.match_current_token(TokenType::RParen));
268
269                self.lexer.next_token();
270
271                let ret_type: Option<String>;
272
273                if self.lexer.current_token().token_type == TokenType::Arrow {
274                    self.lexer.next_token();
275
276                    if self.lexer.current_token().token_type == TokenType::Identifier {
277                        ret_type = Some(self.lexer.current_token_content());
278                    } else {
279                        ret_type = None;
280                    }
281
282                } else {
283                    ret_type = None;
284                }
285
286                self.lexer.next_token();
287
288                let block_body = try!(self.parse_block());
289
290                Ok(Expression::Definition(
291                    name,
292                    Box::new(arg_stack),
293                    Box::new(block_body),
294                    ret_type,
295                ))
296            },
297
298            TokenType::Return => {
299                self.lexer.next_token();
300
301                let expr = try!(self.parse_expression());
302
303                Ok(Expression::Return(Box::new(expr)))
304            },
305
306            _ => {
307                Err(String::from("fucked expression"))
308            }
309        }
310    }
311
312    fn parse_statement(&mut self) -> Result<Statement, String> {
313        match self.lexer.current_token().token_type {
314            TokenType::Identifier => {
315                let id = self.lexer.current_token_content();
316
317                self.lexer.next_token();
318
319                if self.lexer.current_token().token_type != TokenType::Assign {
320                    self.lexer.previous_token();
321
322                    let expr = try!(self.parse_expression());
323
324                    return Ok(Statement::Expression(Box::new(expr)))
325                }
326
327                self.lexer.next_token();
328
329                let expr = try!(self.parse_expression());
330
331                Ok(Statement::Assignment(id, Box::new(expr)))
332            },
333
334            TokenType::If => {
335                self.lexer.next_token();
336
337                let condition = try!(self.parse_expression());
338
339                self.lexer.next_token();
340
341                let body = try!(self.parse_block());
342
343                self.lexer.next_token();
344
345                if self.lexer.current_token().token_type == TokenType::Else {
346                    self.lexer.next_token();
347
348                    let else_body = try!(self.parse_block());
349
350                    return Ok(Statement::IfElse(
351                        Box::new(condition),
352                        Box::new(Statement::Block(Box::new(body))),
353                        Box::new(Statement::Block(Box::new(else_body))),
354                    ))
355                }
356
357                Ok(Statement::If(
358                    Box::new(condition),
359                    Box::new(Statement::Block(Box::new(body))),
360                ))
361            },
362
363            _ => {
364                let expr = try!(self.parse_expression());
365                Ok(Statement::Expression(Box::new(expr)))
366            }
367        }
368    }
369
370    pub fn parse_full(&mut self) -> Result<Vec<Statement>, String> {
371        let mut statement_stack = Vec::new();
372
373        loop {
374            if self.lexer.tokens_remaining() < 1 {
375                break
376            }
377
378            statement_stack.push(try!(self.parse_statement()));
379
380            self.lexer.next_token();
381        }
382
383        Ok(statement_stack)
384    }
385
386    fn parse_block(&mut self) -> Result<Vec<Statement>, String> {
387        try!(self.lexer.match_current_token(TokenType::Do));
388
389        let mut block_tokens = Vec::new();
390        let mut opened_dos   = 1;
391
392        while self.lexer.next_token() {
393            if self.lexer.current_token().token_type == TokenType::Do {
394                opened_dos += 1;     
395            } else if self.lexer.current_token().token_type == TokenType::End {
396                opened_dos -= 1;     
397            }
398
399            if opened_dos == 0 {
400                break
401            }
402
403            block_tokens.push(self.lexer.current_token().clone());
404        }
405
406        try!(self.lexer.match_current_token(TokenType::End));
407
408        Parser::parse_from_tokens(block_tokens)
409    }
410
411    fn parse_expression(&mut self) -> Result<Expression, String> {
412        let expr = try!(self.parse_word());
413
414        self.lexer.next_token();
415
416        if self.lexer.tokens_remaining() > 0 {
417            if self.lexer.current_token().token_type == TokenType::BinOp {
418                return self.parse_bin_op(expr);
419            }
420
421            self.lexer.previous_token();
422        }
423
424        Ok(expr)
425    }
426
427    // Invoked when LParen is popped
428    fn parse_caller(&mut self, callee: Expression) -> Result<Expression, String> {
429        let mut stack = Vec::new();
430
431        self.lexer.next_token();
432
433        while self.lexer.current_token().token_type != TokenType::RParen {
434            stack.push(try!(self.parse_expression()));
435            
436            self.lexer.next_token();
437
438            if self.lexer.current_token().token_type == TokenType::Comma {
439                self.lexer.next_token();
440            }
441        }
442
443        Ok(Expression::Call(Box::new(callee), Box::new(stack)))
444    }
445}