flycatcher_parser/
lib.rs

1//! A hand-written parser that emits an AST tree.
2
3pub mod ast;
4pub mod error;
5
6use ast::{Ast, AstMeta};
7use ast::opcode::get_operator;
8use codespan_reporting::diagnostic::{Diagnostic, Label};
9use error::ErrorKind;
10use flycatcher_lexer::{Lexer, Logos, Token};
11
12/// A Parser struct that takes an input string, tokenizes it and parses it into a more or less
13/// readable AST tree.
14pub struct Parser<'a> {
15
16    /// The name of the input file that is being parsed.  This property helps make more precise
17    /// diagnostic messages, by providing the name of the file that the diagnostic originated
18    /// from.
19    pub filename: &'a str,
20    
21    /// The string of Flycatcher input that is tokenized and parsed by the parser.  The source
22    /// is also used to emit code snippets in diagnostic messages.
23    pub source: &'a str,
24
25    /// A list of diagnostics that were created during parsing.  These are not logged to the
26    /// console by the parser, so they can be used to recieve information for IDEs and such.
27    pub diagnostics: Vec<Diagnostic<()>>,
28
29    /// The lexer that the parser recieves input tokens from.
30    lexer: Lexer<'a, Token>,
31
32}
33
34impl<'a> Parser<'a> {
35
36    /// Allocates a new parser object.  This does not start the parsing process, it only
37    /// initializes a lexer and parser and returns the parser.
38    /// 
39    /// # Arguments
40    /// - `filename`: The absolute file path to the file being parsed, if any.  If you don't
41    /// have an actual file to put here, put `@anonymous`.
42    /// - `source`: The string that will be tokenized and parsed by the parser that is allocated
43    /// by this function.
44    pub fn new(filename: &'a str, source: &'a str) -> Self {
45        Self {
46            filename,
47            source,
48            diagnostics: vec![],
49            lexer: Token::lexer(source)
50        }
51    }
52
53    /// Parses a list of Flycatcher values.  The token provided is the token used to close the
54    /// list.
55    fn parse_list(&mut self, close: Token) -> Result<Vec<AstMeta>, ErrorKind> {
56        let mut state = 0; // 0 = value, 1 = ,
57        let mut args = vec![]; // list of items in the list.
58
59        let start = self.lexer.span().start;
60
61        loop {
62            let mut peekable = self.lexer.clone();
63
64            if let Some(tok) = peekable.next() {
65                if tok == close {
66                    self.lexer.next();
67                    break;
68                }
69            }
70
71            if state == 0 {
72                state = 1;
73                match self.parse_expression() {
74                    Ok(ast) => {
75                        args.push(ast);
76                    },
77                    Err(e) => {
78                        if e == ErrorKind::EndOfFile {
79                            let label = Label::primary((), start..self.lexer.span().end)
80                                .with_message(format!("this here array never closes."));
81                            
82                            let help = Label::secondary((), self.lexer.span())
83                                .with_message("try inserting a ']' here.");
84                                        
85                            let diagnostic = Diagnostic::error()
86                                .with_code("FC0011")
87                                .with_labels(vec![label, help])
88                                .with_message(format!("array never closes."));
89                                        
90                            self.diagnostics.push(diagnostic);
91                    
92                            return Err(ErrorKind::SyntaxError);
93                        }
94
95                        return Err(e);
96                    }
97                }
98            } else if state == 1 {
99                state = 0;
100
101                if let Some(tok) = self.lexer.next() {
102                    if tok != Token::Comma {
103                        let label = Label::primary((), self.lexer.span())
104                            .with_message(format!("expected a comma here."));
105                                            
106                        let diagnostic = Diagnostic::error()
107                            .with_code("FC0012")
108                            .with_labels(vec![label])
109                            .with_message(format!("expected comma in array, got '{}'", self.lexer.slice()));
110                                            
111                        self.diagnostics.push(diagnostic);
112                        
113                        return Err(ErrorKind::SyntaxError);
114                    }
115                } else {
116                    let label = Label::primary((), start..self.lexer.span().end)
117                        .with_message(format!("this here array never closes."));
118
119                    let help = Label::secondary((), self.lexer.span())
120                        .with_message("try inserting a '[' here.");
121                                        
122                    let diagnostic = Diagnostic::error()
123                        .with_code("FC0011")
124                        .with_labels(vec![label, help])
125                        .with_message(format!("array never closes."));
126                                        
127                    self.diagnostics.push(diagnostic);
128                    
129                    return Err(ErrorKind::SyntaxError);
130                }
131            }
132        }
133
134        Ok(args)
135    }
136
137    /// Parses a single literal token from the lexer.
138    fn parse_literal(&mut self) -> Result<AstMeta, ErrorKind> {
139        if let Some(tok) = self.lexer.next() {
140            if tok == Token::Identifier {
141                // At this phase, certain keywords don't exist, like `true`, `false` and `null`,
142                // so we'll need to implement them here.
143
144                let slice = self.lexer.slice();
145
146                if slice == "true" {
147                    return Ok(
148                        AstMeta::new(
149                            self.lexer.span(),
150                            Ast::BooleanLiteral(true)
151                        )
152                    );
153                } else if slice == "false" {
154                    return Ok(
155                        AstMeta::new(
156                            self.lexer.span(),
157                            Ast::BooleanLiteral(false)
158                        )
159                    );
160                } else if slice == "null" {
161                    return Ok(
162                        AstMeta::new(
163                            self.lexer.span(),
164                            Ast::NullLiteral
165                        )
166                    );
167                }
168
169                Ok(AstMeta::new(
170                    self.lexer.span(),
171                    Ast::IdentifierLiteral(slice.into())
172                ))
173            } else if tok == Token::Number {
174                let slice = self.lexer.slice().to_string();
175
176                if slice.contains('.') || slice.contains('e') || slice.contains('E') {
177                    let f = slice.parse::<f64>().unwrap();
178                    Ok(AstMeta::new(
179                        self.lexer.span(),
180                        Ast::FloatLiteral(f)
181                    ))
182                } else {
183                    let i = slice.parse::<i64>().unwrap();
184                    Ok(AstMeta::new(
185                        self.lexer.span(),
186                        Ast::IntegerLiteral(i)
187                    ))
188                }
189                /*
190                let f = self.lexer.slice().parse::<f64>().unwrap();
191                Ok(AstMeta::new(
192                    self.lexer.span(),
193                    Ast::NumberLiteral(f)
194                ))*/
195            } else if tok == Token::String {
196                let str = &self.lexer.slice()[1..self.lexer.slice().len() - 1];
197                Ok(AstMeta::new(
198                    self.lexer.span(),
199                    Ast::StringLiteral(str.into())
200                ))
201            } else if tok == Token::OBrack {
202                // Array literal.
203                let start = self.lexer.span().start;
204                match self.parse_list(Token::CBrack) {
205                    Ok(ast) => {
206                        Ok(
207                            AstMeta::new(
208                                start..self.lexer.span().end,
209                                Ast::ListLiteral(ast)
210                            )
211                        )
212                    }
213                    Err(e) => Err(e),
214                }
215            } else if tok == Token::OParen {
216                let start = self.lexer.span().start;
217                match self.parse_expression() {
218                    Ok(ast) => {
219                        if let Some(t) = self.lexer.next() {
220                            if t != Token::CParen {
221                                let label = Label::primary((), start..self.lexer.span().end)
222                                    .with_message("expected closing parenthesis in this expression.");
223                                
224                                let diagnostic = Diagnostic::error()
225                                    .with_code("FC0016")
226                                    .with_labels(vec![label])
227                                    .with_message(format!("expected a closing parenthesis."));
228                                
229                                self.diagnostics.push(diagnostic);
230
231                                return Err(ErrorKind::SyntaxError);
232                            }
233                        } else {
234                            let label = Label::primary((), start..self.lexer.span().end)
235                                .with_message("expected closing parenthesis in this expression.");
236                                
237                            let diagnostic = Diagnostic::error()
238                                .with_code("FC0016")
239                                .with_labels(vec![label])
240                                .with_message(format!("expected a closing parenthesis."));
241                                
242                            self.diagnostics.push(diagnostic);
243
244                            return Err(ErrorKind::SyntaxError);
245                        }
246
247                        Ok(
248                            ast
249                        )
250                    }
251                    Err(e) => {
252                        if e == ErrorKind::EndOfFile {
253                            let label = Label::primary((), start..self.lexer.span().end)
254                                .with_message("expected an expression inside of these parenthesis.");
255                            
256                            let diagnostic = Diagnostic::error()
257                                .with_code("FC0015")
258                                .with_labels(vec![label])
259                                .with_message(format!("expected an expression."));
260                            
261                            self.diagnostics.push(diagnostic);
262
263                            return Err(ErrorKind::SyntaxError);
264                        }
265
266                        Err(e)
267                    },
268                }
269            } else {
270                // The token is unrecognized, so we have to give the correct error message.
271                if tok == Token::Invalid {
272                    let label = Label::primary((), self.lexer.span())
273                        .with_message("this character is unrecognized by flycatcher.");
274                    
275                    let diagnostic = Diagnostic::error()
276                        .with_code("FC0001")
277                        .with_labels(vec![label])
278                        .with_message(format!("invalid character '{}'", self.lexer.slice()));
279                    
280                    self.diagnostics.push(diagnostic);
281
282                    Err(ErrorKind::SyntaxError)
283                } else {
284                    let label = Label::primary((), self.lexer.span())
285                        .with_message("expected a proper value here");
286                    
287                    let diagnostic = Diagnostic::error()
288                        .with_code("FC0002")
289                        .with_labels(vec![label])
290                        .with_message(format!("expected a value here, got '{}'", self.lexer.slice()));
291                    
292                    self.diagnostics.push(diagnostic);
293
294                    Err(ErrorKind::SyntaxError)
295                }
296            }
297        } else {
298            // No token was found, so we return ErrorKind::EndOfFile
299            Err(ErrorKind::EndOfFile)
300        }
301    }
302
303    /// Parses an index statement, such as `item1.item2` or `item["item2"]`.
304    fn parse_index(&mut self, first: AstMeta) -> Result<AstMeta, ErrorKind> {
305        // This is the state of the parser, basically what the parser expects.  1 means that the
306        // parser expects either a `.` or a `["key"]`.  0 means that the parser expects an
307        // identifier.
308        let mut state = 1;
309        let start = first.range.start;
310
311        let mut items = vec![first];
312
313        loop {
314            // Clone the lexer to not disturb its original state, in the case that the index
315            // statement ends.
316            let mut peekable = self.lexer.clone();
317
318            if let Some(tok) = peekable.next() {
319                if state == 0 {
320                    state = 1;
321
322                    if tok == Token::Identifier {
323                        self.lexer.next();
324                        items.push(
325                            AstMeta::new(
326                                self.lexer.span(),
327                                Ast::IdentifierLiteral(self.lexer.slice().into())
328                            )
329                        );
330                        // Move on to the next token.
331                        //self.lexer.next();
332                    } else {
333                        // Trying to use a `.` to index with anything other than an identifier
334                        // always results in an error.
335                        self.lexer.next();
336                        let label = Label::primary((), start..self.lexer.span().end)
337                            .with_message(format!("expected a property name, got '{}'", self.lexer.slice()));
338    
339                        let help = Label::secondary((), self.lexer.span())
340                            .with_message(format!("try wrapping it in []: '[{}]'", self.lexer.slice()));
341                        
342                        let diagnostic = Diagnostic::error()
343                            .with_code("FC0004")
344                            .with_labels(vec![label, help])
345                            .with_message(format!("you indexed with a '.', expected a property name."));
346                        
347                        self.diagnostics.push(diagnostic);
348    
349                        return Err(ErrorKind::SyntaxError);
350                    }
351                } else if state == 1 {
352                    if tok == Token::Dot {
353                        // It's a `.`, so we can set the state to 0 and skip over it.
354                        state = 0;
355                        self.lexer.next();
356                    } else if tok == Token::OBrack {
357                        // Uses a recursive call to `parse_expression` inside of the opened
358                        // bracket, to recieve the inners ;)
359                        self.lexer.next();
360                        let start = self.lexer.span().start;
361                        match self.parse_expression() {
362                            Ok(index) => {
363                                // Check if there's a closing bracket
364
365                                if let Some(tok) = self.lexer.next() {
366                                    if tok == Token::CBrack {
367                                        items.push(
368                                            AstMeta::new(
369                                                start..self.lexer.span().end,
370                                                Ast::BracketIndex(
371                                                    index.as_box()
372                                                )
373                                            )
374                                        )
375                                    } else {
376                                        let label = Label::primary((), self.lexer.span())
377                                            .with_message(format!("expected a closing bracket before this."));
378                                        
379                                        let diagnostic = Diagnostic::error()
380                                            .with_code("FC0006")
381                                            .with_labels(vec![label])
382                                            .with_message(format!("expected a closing bracket instead of '{}'", self.lexer.slice()));
383                                        
384                                        self.diagnostics.push(diagnostic);
385                    
386                                        return Err(ErrorKind::SyntaxError);
387                                    }
388                                } else {
389                                    let label = Label::primary((), start..self.lexer.span().end)
390                                        .with_message(format!("unclosed brackets here."));
391                                    
392                                    let diagnostic = Diagnostic::error()
393                                        .with_code("FC0005")
394                                        .with_labels(vec![label])
395                                        .with_message(format!("you indexed an object with unclosed brackets."));
396                                    
397                                    self.diagnostics.push(diagnostic);
398                
399                                    return Err(ErrorKind::SyntaxError);
400                                }
401                            },
402                            Err(e) => {
403                                // We need to check if an error message has been sent, if not,
404                                // we'll need to send our own.
405                                if e == ErrorKind::EndOfFile {
406                                    // No error was emitted.
407                                    let label = Label::primary((), self.lexer.span())
408                                        .with_message(format!("unclosed brackets here."));
409                                    
410                                    let diagnostic = Diagnostic::error()
411                                        .with_code("FC0005")
412                                        .with_labels(vec![label])
413                                        .with_message(format!("you indexed an object with unclosed brackets."));
414                                    
415                                    self.diagnostics.push(diagnostic);
416                
417                                    return Err(ErrorKind::SyntaxError);
418                                }
419
420                                return Err(e);
421                            }
422                        }
423                    } else {
424                        break;
425                    }
426                }
427            } else {
428                // There was no token, if the state was 1, everything should be fine.
429                // Otherwise, the rule of no open index statements (such as `item1.item2.`)
430                // is broken.
431                if state == 0 {
432                    self.lexer.next();
433                    let label = Label::primary((), start..self.lexer.span().end)
434                        .with_message("this index expression is unclosed.");
435
436                    let help = Label::secondary((), self.lexer.span())
437                        .with_message("there is an extra period here.");
438                    
439                    let diagnostic = Diagnostic::error()
440                        .with_code("FC0003")
441                        .with_labels(vec![label, help])
442                        .with_message(format!("unclosed index expression"));
443                    
444                    self.diagnostics.push(diagnostic);
445
446                    return Err(ErrorKind::SyntaxError);
447                } else {
448                    // No actual syntax errors occurred, so we break the loop.
449                    break;
450                }
451            }
452        }
453
454        Ok(
455            AstMeta::new(
456                start..self.lexer.span().end, 
457                Ast::IndexExpression(items)
458            )
459        )
460    }
461
462    /// Parses an expression operand.
463    fn parse_secondary(&mut self) -> Result<AstMeta, ErrorKind> {
464        let mut peekable = self.lexer.clone();
465        
466        if let Some(tok) = peekable.next() {
467            if tok == Token::Dash {
468                self.lexer.next();
469
470                let start = self.lexer.span().start;
471                let end = self.lexer.span().end;
472
473                match self.parse_primary() {
474                    Ok(ast) => {
475                        return Ok(
476                            AstMeta::new(
477                                start..self.lexer.span().end,
478                                Ast::NegativeUnary(
479                                    ast.as_box()
480                                )
481                            )
482                        );
483                    },
484                    Err(e) => {
485                        if e == ErrorKind::EndOfFile {
486                            self.lexer.next();
487                            let label = Label::primary((), start..end)
488                                .with_message("expression starts here");
489        
490                            let help = Label::secondary((), self.lexer.span())
491                                .with_message("expected a value here");
492                            
493                            let diagnostic = Diagnostic::error()
494                                .with_code("FC0007")
495                                .with_labels(vec![label, help])
496                                .with_message(format!("no value found in `-` expression."));
497                            
498                            self.diagnostics.push(diagnostic);
499        
500                            return Err(ErrorKind::SyntaxError);
501                        }
502
503                        return Err(e);
504                    }
505                }
506            } if tok == Token::Plus {
507                self.lexer.next();
508
509                let start = self.lexer.span().start;
510                let end = self.lexer.span().end;
511
512                match self.parse_primary() {
513                    Ok(ast) => {
514                        return Ok(
515                            AstMeta::new(
516                                start..self.lexer.span().end,
517                                Ast::PositiveUnary(
518                                    ast.as_box()
519                                )
520                            )
521                        );
522                    },
523                    Err(e) => {
524                        if e == ErrorKind::EndOfFile {
525                            self.lexer.next();
526                            let label = Label::primary((), start..end)
527                                .with_message("expression starts here");
528        
529                            let help = Label::secondary((), self.lexer.span())
530                                .with_message("expected a value here");
531                            
532                            let diagnostic = Diagnostic::error()
533                                .with_code("FC0007")
534                                .with_labels(vec![label, help])
535                                .with_message(format!("no value found in `+` expression."));
536                            
537                            self.diagnostics.push(diagnostic);
538        
539                            return Err(ErrorKind::SyntaxError);
540                        }
541
542                        return Err(e);
543                    }
544                }
545            } else {
546                return self.parse_literal()
547            }
548        }
549
550        return Err(ErrorKind::EndOfFile);
551    }
552
553    /// Parses a binary expression with operator precedence, providing a minimum precedence for
554    /// operators.
555    fn parse_binary(&mut self, mut left: AstMeta, min: usize) -> Result<AstMeta, ErrorKind> {
556        let mut tok = self.lexer.clone().next();
557
558        while let Some(lookahead) = tok {
559            if let Some(op) = get_operator(lookahead) {
560                if op.precedence() >= min {
561                    self.lexer.next();
562                    let mut right = match self.parse_primary() {
563                        Ok(ast) => ast,
564                        Err(e) => {
565                            if e == ErrorKind::EndOfFile {
566                                // No error was emitted.
567                                let label = Label::primary((), self.lexer.span())
568                                    .with_message(format!("expected right hand side of expression here."));
569                                
570                                let diagnostic = Diagnostic::error()
571                                    .with_code("FC0010")
572                                    .with_labels(vec![label])
573                                    .with_message(format!("expected right hand side of expression."));
574                                
575                                self.diagnostics.push(diagnostic);
576        
577                                return Err(ErrorKind::SyntaxError);
578                            }
579        
580                            return Err(e);
581                        }
582                    };
583        
584                    tok = self.lexer.clone().next();
585        
586                    while let Some(lookahead2) = tok {
587                        if let Some(op2) = get_operator(lookahead2) {
588                            if op2.precedence() >= op.precedence() {
589                                right = match self.parse_binary(right, min + 1) {
590                                    Ok(ast) => ast,
591                                    Err(e) => {
592                                        if e == ErrorKind::EndOfFile {
593                                            // No error was emitted.
594                                            let label = Label::primary((), self.lexer.span())
595                                                .with_message(format!("expected right hand side of expression here."));
596                                            
597                                            let diagnostic = Diagnostic::error()
598                                                .with_code("FC0010")
599                                                .with_labels(vec![label])
600                                                .with_message(format!("expected right hand side of expression."));
601                                            
602                                            self.diagnostics.push(diagnostic);
603                    
604                                            return Err(ErrorKind::SyntaxError);
605                                        }
606                    
607                                        return Err(e);
608                                    }
609                                };
610        
611                                tok = self.lexer.clone().next();
612                            } else {
613                                break;
614                            }
615
616                        } else {
617                            break;
618                        }
619                    }
620
621
622                    left = AstMeta::new(
623                        left.range.start..self.lexer.span().end,
624                        Ast::BinaryExpression(
625                            op,
626                            left.as_box(),
627                            right.as_box()
628                        )
629                    );
630                    tok = self.lexer.clone().next();
631                } else {
632                    self.lexer.next();
633                    break;
634                }
635            } else {
636                break;
637            }
638        }
639        
640        Ok(left)
641        /*
642        loop {
643            let mut peekable = self.lexer.clone();
644
645            if let Some(tok) = peekable.next() {
646                if let Some(op) = get_operator(tok) {
647                    if op.precedence() >= min {
648
649                    } else {
650                        break;
651                    }
652                } else {
653                    // The next token isn't an operator, which means the expression is ending.
654                    break;
655                }
656            }
657        }*/
658        /*
659        let peekable = self.lexer.clone();
660
661        if let Some(lookahead) = peekable.next() {
662
663        }*/
664    }
665
666    /// Recursively parses function calls and object indexes.
667    fn parse_opt_ending(&mut self, left: AstMeta) -> Result<AstMeta, ErrorKind> {
668        if let Some(tok) = self.lexer.clone().next() {
669            if tok == Token::OParen {
670                self.lexer.next();
671                match self.parse_list(Token::CParen) {
672                    Ok(args) => {
673                        return self.parse_opt_ending(
674                            AstMeta::new(
675                                left.range.start..self.lexer.span().end,
676                                Ast::FunctionCall(
677                                    left.as_box(),
678                                    args
679                                )
680                            )
681                        )
682                    },
683                    Err(e) => {
684                        if e == ErrorKind::EndOfFile {
685                            // Throw our own diagnostic messages.
686                            // No error was emitted.
687                            let label = Label::primary((), left.range.start..self.lexer.span().end)
688                                .with_message(format!("this function call's argument list is never closed."));
689                            
690                            let help = Label::secondary((), self.lexer.span())
691                                .with_message("try inserting a ')' here.");
692                                        
693                            let diagnostic = Diagnostic::error()
694                                .with_code("FC0013")
695                                .with_labels(vec![label, help])
696                                .with_message(format!("argument list never closes."));
697                                        
698                            self.diagnostics.push(diagnostic);
699                    
700                            return Err(ErrorKind::SyntaxError);
701                        }
702
703                        return Err(e);
704                    }
705                }
706            } else if tok == Token::Dot || tok == Token::OBrack {
707                let l = left.clone();
708                match self.parse_index(left) {
709                    Ok(args) => {
710                        return self.parse_opt_ending(args)
711                    },
712                    Err(e) => {
713                        if e == ErrorKind::EndOfFile {
714                            // Throw our own diagnostic messages.
715                            // No error was emitted.
716                            let start = l.range.start;
717                            let label = Label::primary((), start..self.lexer.span().end)
718                                .with_message(format!("this function call's argument list is never closed."));
719                            
720                            let help = Label::secondary((), self.lexer.span())
721                                .with_message("try inserting a ')' here.");
722                                        
723                            let diagnostic = Diagnostic::error()
724                                .with_code("FC0013")
725                                .with_labels(vec![label, help])
726                                .with_message(format!("argument list never closes."));
727                                        
728                            self.diagnostics.push(diagnostic);
729                    
730                            return Err(ErrorKind::SyntaxError);
731                        }
732
733                        return Err(e);
734                    }
735                }
736            }
737        }
738
739        self.parse_binary(left, 0)
740    }
741
742    /// Wraps the parse_literal function and allows function calls.
743    fn parse_primary(&mut self) -> Result<AstMeta, ErrorKind> {
744        if let Some(tok) = self.lexer.clone().next() {
745            if tok == Token::Exclaimation {
746                self.lexer.next();
747
748                let start = self.lexer.span().start;
749
750                match self.parse_primary() {
751                    Ok(ast) => {
752                        return Ok(
753                            AstMeta::new(
754                                start..self.lexer.span().end,
755                                Ast::NotUnary(
756                                    ast.as_box()
757                                )
758                            )
759                        )
760                    },
761                    Err(e) => {
762                        if e == ErrorKind::EndOfFile {
763                            let label = Label::primary((), start..self.lexer.span().end)
764                                .with_message(format!("'!' expression requires an operand (a.k.a, another expression)."));
765                            
766                            let help = Label::secondary((), self.lexer.span())
767                                .with_message("expected an expression here, we see the end of the file.");
768                                            
769                            let diagnostic = Diagnostic::error()
770                                .with_code("FC0014")
771                                .with_labels(vec![label, help])
772                                .with_message(format!("expected an expression."));
773                                            
774                            self.diagnostics.push(diagnostic);
775                        
776                            return Err(ErrorKind::SyntaxError);
777                        }
778
779                        return Err(e)
780                    },
781                }
782            } else if tok == Token::PreprocessorIdentifier {
783                // Preprocessors do nothing at the base parsing phase.
784                self.lexer.next();
785                let name = self.lexer.slice();
786                let start = self.lexer.span().start;
787                //let name_end = self.lexer.span().end;
788
789                let n = AstMeta::new(
790                    self.lexer.span(),
791                    Ast::IdentifierLiteral(name[1..].into())
792                );
793
794                if let Some(arg) = self.lexer.clone().next() {
795                    if arg == Token::String {
796                        self.lexer.next();
797                        let t = self.lexer.slice();
798
799                        return Ok(
800                            AstMeta::new(
801                                start..self.lexer.span().end,
802                                Ast::PreprocessorStatement(
803                                    n.as_box(),
804                                    vec![
805                                        AstMeta::new(
806                                            self.lexer.span(), 
807                                            Ast::StringLiteral(t[1..t.len() - 1].into())
808                                        )
809                                    ]
810                                )
811                            )
812                        )
813                    } else if arg == Token::OParen {
814                        self.lexer.next();
815
816                        match self.parse_list(Token::CParen) {
817                            Ok(ast) => {
818                                return Ok(
819                                    AstMeta::new(
820                                        start..self.lexer.span().end,
821                                        Ast::PreprocessorStatement(
822                                            n.as_box(),
823                                            ast
824                                        )
825                                    )
826                                )
827                            },
828                            Err(e) => return Err(e)
829                        }
830                    } else if arg == Token::OBrack {
831                        self.lexer.next();
832
833                        match self.parse_list(Token::CBrack) {
834                            Ok(ast) => {
835                                return Ok(
836                                    AstMeta::new(
837                                        start..self.lexer.span().end,
838                                        Ast::PreprocessorStatement(
839                                            n.as_box(),
840                                            ast
841                                        )
842                                    )
843                                )
844                            },
845                            Err(e) => return Err(e)
846                        }
847                    } else if arg == Token::Identifier {
848                        self.lexer.next();
849                        let t = self.lexer.slice();
850
851                        return Ok(
852                            AstMeta::new(
853                                start..self.lexer.span().end,
854                                Ast::PreprocessorStatement(
855                                    n.as_box(),
856                                    vec![
857                                        AstMeta::new(
858                                            self.lexer.span(), 
859                                            Ast::IdentifierLiteral(t.into())
860                                        )
861                                    ]
862                                )
863                            )
864                        )
865                    } else {
866                        return Ok(
867                            AstMeta::new(
868                                start..self.lexer.span().end,
869                                Ast::PreprocessorStatement(
870                                    n.as_box(),
871                                    vec![]
872                                )
873                            )
874                        )
875                    }
876                } else {
877                    return Ok(
878                        AstMeta::new(
879                            start..self.lexer.span().end,
880                            Ast::PreprocessorStatement(
881                                n.as_box(),
882                                vec![]
883                            )
884                        )
885                    )
886                }
887            } else {
888                match self.parse_secondary() {
889                    Ok(ast) => return self.parse_opt_ending(ast),
890                    Err(e) => return Err(e),
891                }
892            }
893        }
894
895        Err(ErrorKind::EndOfFile)
896    }
897
898    /// Parses a single expression from the lexer, returning a single AST object that represents
899    /// it, or an ErrorKind enum object describing how it ended.  If `Err(ErrorKind::EndOfFile)`
900    /// was returned, that only means that there was no expression left, not that an actual
901    /// error occurred.
902    pub fn parse_expression(&mut self) -> Result<AstMeta, ErrorKind> {
903        self.parse_primary()
904    }
905
906    /// Iterates through all tokens until there is no tokens left to read.  This will return all
907    /// of the AST items found while parsing, if no errors occur.
908    pub fn parse(&mut self) -> Result<Vec<AstMeta>, ErrorKind> {
909        let mut ast = vec![];
910        loop {
911            // Ignore semicolons by peeking into the lexer's tokens, if there is in fact a
912            // semicolon, it should be skipped over.
913
914            if let Some(tok) = self.lexer.clone().next() {
915                if tok == Token::Semicolon {
916                    // Skip over the semicolon and continue the loop.
917                    self.lexer.next();
918                    continue;
919                }
920
921                match self.parse_expression() {
922                    Ok(item) => {
923                        ast.push(item);
924
925                        if let Some(tok) = self.lexer.clone().next() {
926                            if tok == Token::Semicolon {
927                                // Skip over the semicolon and continue the loop.
928                                self.lexer.next();
929                                continue;
930                            } else {
931                                let label = Label::primary((), self.lexer.span())
932                                    .with_message(format!("you should add a semicolon after this."));
933                                                
934                                let diagnostic = Diagnostic::warning()
935                                    .with_code("FC0015")
936                                    .with_labels(vec![label])
937                                    .with_message(format!("add semicolon to the end of this statement."))
938                                    .with_notes(vec!["expressions without semicolons can lead to\nunexpected behavior.".into()]);
939                                self.diagnostics.push(diagnostic);
940                            }
941                        }
942                    },
943                    Err(e) => {
944                        if e == ErrorKind::EndOfFile {
945                            break;
946                        }
947
948                        return Err(e)
949                    }
950                }
951            } else {
952                break;
953            }
954        }
955
956        Ok(ast)
957    }
958
959}