lexer: allow underscore for identifiers

Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
2023-08-13 07:35:20 +05:30
parent 1a2563f756
commit ad57170010
2 changed files with 43 additions and 23 deletions

View File

@@ -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>>),
}

View File

@@ -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(),
} }