lexer: allow underscore for identifiers
Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
		
							
								
								
									
										56
									
								
								src/ast.rs
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								src/ast.rs
									
									
									
									
									
								
							@@ -82,24 +82,6 @@ pub struct Let {
 | 
				
			|||||||
    pub expr: Option<Expr>,
 | 
					    pub expr: Option<Expr>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Op = crate::lexer::TokenSymbol;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Lowest form of expression
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// TODO: refine
 | 
					 | 
				
			||||||
#[derive(Debug, PartialEq)]
 | 
					 | 
				
			||||||
pub enum Expr {
 | 
					 | 
				
			||||||
    Int(i32),
 | 
					 | 
				
			||||||
    Float(f32),
 | 
					 | 
				
			||||||
    Char(char),
 | 
					 | 
				
			||||||
    Op(Op, Box<Expr>, Option<Box<Expr>>),
 | 
					 | 
				
			||||||
    If(Box<Expr>, Box<Expr>, Option<Box<Expr>>),
 | 
					 | 
				
			||||||
    Block(Vec<Statement>),
 | 
					 | 
				
			||||||
    Loop(Vec<Statement>),
 | 
					 | 
				
			||||||
    Break,
 | 
					 | 
				
			||||||
    Continue,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Primitives
 | 
					/// Primitives
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// TODO: add arrays and pointers maybe
 | 
					/// TODO: add arrays and pointers maybe
 | 
				
			||||||
@@ -109,3 +91,41 @@ pub enum Ty {
 | 
				
			|||||||
    Float,
 | 
					    Float,
 | 
				
			||||||
    Char,
 | 
					    Char,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, PartialEq)]
 | 
				
			||||||
 | 
					pub struct If {
 | 
				
			||||||
 | 
					    pub cond: Box<Expr>,
 | 
				
			||||||
 | 
					    pub then: Vec<Statement>,
 | 
				
			||||||
 | 
					    pub or: Option<Box<ElseType>>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, PartialEq)]
 | 
				
			||||||
 | 
					pub enum ElseType {
 | 
				
			||||||
 | 
					    If(If),
 | 
				
			||||||
 | 
					    Else(Vec<Statement>),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Op = crate::lexer::TokenSymbol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, PartialEq)]
 | 
				
			||||||
 | 
					pub enum Literal {
 | 
				
			||||||
 | 
					    Int(i32),
 | 
				
			||||||
 | 
					    Float(f32),
 | 
				
			||||||
 | 
					    Char(char),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Lowest form of expression
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// TODO: refine
 | 
				
			||||||
 | 
					#[derive(Debug, PartialEq)]
 | 
				
			||||||
 | 
					pub enum Expr {
 | 
				
			||||||
 | 
					    Literal(Literal),
 | 
				
			||||||
 | 
					    Identifier(Rc<str>),
 | 
				
			||||||
 | 
					    Op(Op, Box<Expr>, Option<Box<Expr>>),
 | 
				
			||||||
 | 
					    If(If),
 | 
				
			||||||
 | 
					    Block(Vec<Statement>),
 | 
				
			||||||
 | 
					    Loop(Vec<Statement>),
 | 
				
			||||||
 | 
					    Break,
 | 
				
			||||||
 | 
					    Continue,
 | 
				
			||||||
 | 
					    Return(Option<Box<Expr>>),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								src/lexer.rs
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/lexer.rs
									
									
									
									
									
								
							@@ -14,7 +14,7 @@ pub enum TokenLiteral {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// All token symbols
 | 
					/// All token symbols
 | 
				
			||||||
#[derive(Debug, PartialEq)]
 | 
					#[derive(Debug, PartialEq, Clone, Copy)]
 | 
				
			||||||
pub enum TokenSymbol {
 | 
					pub enum TokenSymbol {
 | 
				
			||||||
    // arithmetic
 | 
					    // arithmetic
 | 
				
			||||||
    Plus,
 | 
					    Plus,
 | 
				
			||||||
@@ -38,9 +38,7 @@ pub enum TokenSymbol {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // relational
 | 
					    // relational
 | 
				
			||||||
    Gt,
 | 
					    Gt,
 | 
				
			||||||
    Ge,
 | 
					 | 
				
			||||||
    Lt,
 | 
					    Lt,
 | 
				
			||||||
    Le,
 | 
					 | 
				
			||||||
    GtEq,
 | 
					    GtEq,
 | 
				
			||||||
    LtEq,
 | 
					    LtEq,
 | 
				
			||||||
    EqEq,
 | 
					    EqEq,
 | 
				
			||||||
@@ -88,6 +86,7 @@ pub enum TokenKeyword {
 | 
				
			|||||||
    Loop,
 | 
					    Loop,
 | 
				
			||||||
    Break,
 | 
					    Break,
 | 
				
			||||||
    Continue,
 | 
					    Continue,
 | 
				
			||||||
 | 
					    Return,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // primitives
 | 
					    // primitives
 | 
				
			||||||
    Int,
 | 
					    Int,
 | 
				
			||||||
@@ -280,7 +279,7 @@ impl<'a> Lexer<'a> {
 | 
				
			|||||||
    fn get_alphanumeric(&mut self) -> Token {
 | 
					    fn get_alphanumeric(&mut self) -> Token {
 | 
				
			||||||
        while let Some(c) = self.peek() {
 | 
					        while let Some(c) = self.peek() {
 | 
				
			||||||
            match c {
 | 
					            match c {
 | 
				
			||||||
                'a'..='z' | 'A'..='Z' | '0'..='9' => {}
 | 
					                'a'..='z' | 'A'..='Z' | '0'..='9' | '_' => {}
 | 
				
			||||||
                _ => break,
 | 
					                _ => break,
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            self.next();
 | 
					            self.next();
 | 
				
			||||||
@@ -302,6 +301,7 @@ impl<'a> Lexer<'a> {
 | 
				
			|||||||
            "loop" => Keyword(Loop),
 | 
					            "loop" => Keyword(Loop),
 | 
				
			||||||
            "break" => Keyword(Break),
 | 
					            "break" => Keyword(Break),
 | 
				
			||||||
            "continue" => Keyword(Continue),
 | 
					            "continue" => Keyword(Continue),
 | 
				
			||||||
 | 
					            "return" => Keyword(Return),
 | 
				
			||||||
            "int" => Keyword(Int),
 | 
					            "int" => Keyword(Int),
 | 
				
			||||||
            "float" => Keyword(Float),
 | 
					            "float" => Keyword(Float),
 | 
				
			||||||
            "char" => Keyword(Char),
 | 
					            "char" => Keyword(Char),
 | 
				
			||||||
@@ -409,7 +409,7 @@ impl<'a> Lexer<'a> {
 | 
				
			|||||||
                    self.new_token(TokenKind::Newline)
 | 
					                    self.new_token(TokenKind::Newline)
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                '0'..='9' => self.get_numeric(),
 | 
					                '0'..='9' => self.get_numeric(),
 | 
				
			||||||
                'a'..='z' | 'A'..='Z' => self.get_alphanumeric(),
 | 
					                'a'..='z' | 'A'..='Z' | '_' => self.get_alphanumeric(),
 | 
				
			||||||
                '\'' => self.get_char(),
 | 
					                '\'' => self.get_char(),
 | 
				
			||||||
                _ => self.get_symbol(),
 | 
					                _ => self.get_symbol(),
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user