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>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
///
 | 
			
		||||
/// TODO: add arrays and pointers maybe
 | 
			
		||||
@@ -109,3 +91,41 @@ pub enum Ty {
 | 
			
		||||
    Float,
 | 
			
		||||
    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
 | 
			
		||||
#[derive(Debug, PartialEq)]
 | 
			
		||||
#[derive(Debug, PartialEq, Clone, Copy)]
 | 
			
		||||
pub enum TokenSymbol {
 | 
			
		||||
    // arithmetic
 | 
			
		||||
    Plus,
 | 
			
		||||
@@ -38,9 +38,7 @@ pub enum TokenSymbol {
 | 
			
		||||
 | 
			
		||||
    // relational
 | 
			
		||||
    Gt,
 | 
			
		||||
    Ge,
 | 
			
		||||
    Lt,
 | 
			
		||||
    Le,
 | 
			
		||||
    GtEq,
 | 
			
		||||
    LtEq,
 | 
			
		||||
    EqEq,
 | 
			
		||||
@@ -88,6 +86,7 @@ pub enum TokenKeyword {
 | 
			
		||||
    Loop,
 | 
			
		||||
    Break,
 | 
			
		||||
    Continue,
 | 
			
		||||
    Return,
 | 
			
		||||
 | 
			
		||||
    // primitives
 | 
			
		||||
    Int,
 | 
			
		||||
@@ -280,7 +279,7 @@ impl<'a> Lexer<'a> {
 | 
			
		||||
    fn get_alphanumeric(&mut self) -> Token {
 | 
			
		||||
        while let Some(c) = self.peek() {
 | 
			
		||||
            match c {
 | 
			
		||||
                'a'..='z' | 'A'..='Z' | '0'..='9' => {}
 | 
			
		||||
                'a'..='z' | 'A'..='Z' | '0'..='9' | '_' => {}
 | 
			
		||||
                _ => break,
 | 
			
		||||
            }
 | 
			
		||||
            self.next();
 | 
			
		||||
@@ -302,6 +301,7 @@ impl<'a> Lexer<'a> {
 | 
			
		||||
            "loop" => Keyword(Loop),
 | 
			
		||||
            "break" => Keyword(Break),
 | 
			
		||||
            "continue" => Keyword(Continue),
 | 
			
		||||
            "return" => Keyword(Return),
 | 
			
		||||
            "int" => Keyword(Int),
 | 
			
		||||
            "float" => Keyword(Float),
 | 
			
		||||
            "char" => Keyword(Char),
 | 
			
		||||
@@ -409,7 +409,7 @@ impl<'a> Lexer<'a> {
 | 
			
		||||
                    self.new_token(TokenKind::Newline)
 | 
			
		||||
                }
 | 
			
		||||
                '0'..='9' => self.get_numeric(),
 | 
			
		||||
                'a'..='z' | 'A'..='Z' => self.get_alphanumeric(),
 | 
			
		||||
                'a'..='z' | 'A'..='Z' | '_' => self.get_alphanumeric(),
 | 
			
		||||
                '\'' => self.get_char(),
 | 
			
		||||
                _ => self.get_symbol(),
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user