Skip to content
This repository has been archived by the owner on Oct 10, 2024. It is now read-only.

Commit

Permalink
a
Browse files Browse the repository at this point in the history
  • Loading branch information
melody-notpond committed Jul 24, 2023
1 parent 84aa62e commit 3852460
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 133 deletions.
131 changes: 14 additions & 117 deletions src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,9 @@ pub enum Token<'a> {
Invalid(&'a str),
Integer(u128),
Bool(bool),
Plus,
Minus,
Astrisk,
Slash,
Percent,
Equals,
Pipe,
Colon,
Arrow,
At,
Dot,
Comma,
LParen,
Expand All @@ -25,31 +18,18 @@ pub enum Token<'a> {
RBrack,
LBrace,
RBrace,
Lt,
Le,
Gt,
Ge,
Eq,
Ne,
LogicalAnd,
LogicalOr,
Exclamation,
Def,
Do,
End,
Let,
Val,
In,
Mut,
If,
Then,
Else,
Match,
With,
As,
To,
End,
Forall,
Type,
Class,
Instance,
Where,
Operator(&'a str, bool, i32),
Symbol(&'a str),
}

Expand Down Expand Up @@ -107,33 +87,21 @@ impl<'a> Lexer<'a> {
} else {
let mut final_pos = self.pos;

enum State {
enum State<'a> {
Initial,
Invalid,
Number,
SingleChar,
Symbol,
Minus,
AppendEq,
Not,
Double,
Slash,
SingleComment,
Done(Token<'a>),
}

let mut state = State::Initial;
for c in self.contents[self.pos..].chars() {
match state {
State::Initial => match c {
'0'..='9' => state = State::Number,
'+' | '*' | '%' | '(' | ')' | '[' | ']' | '{' | '}' | ':' | '@' | ',' | '.' => {
state = State::SingleChar
}
'/' => state = State::Slash,
'|' | '&' => state = State::Double,
'<' | '>' | '=' => state = State::AppendEq,
'!' => state = State::Not,
'-' => state = State::Minus,
'#' => state = State::SingleComment,
' ' | '\t' | '\n' | '\r' => self.pos += c.len_utf8(),
'a'..='z' | 'A'..='Z' | '_' => state = State::Symbol,
_ => state = State::Invalid,
Expand All @@ -146,52 +114,19 @@ impl<'a> Lexer<'a> {
_ => break,
},

State::SingleChar => break,

State::Symbol => match c {
'a'..='z' | 'A'..='Z' | '_' | '0'..='9' => (),
_ => break,
},

State::Minus => match c {
'>' => state = State::SingleChar,
_ => break,
},

State::AppendEq => {
state = State::SingleChar;
if c != '=' {
break;
}
}

State::Not => match c {
'=' => state = State::SingleChar,
_ => break,
},

State::Double => {
state = State::SingleChar;
if c != self.contents[self.pos..].chars().next().unwrap() {
break;
}
}

State::Slash => {
if c == '/' {
self.pos += c.len_utf8() * 2;
state = State::SingleComment;
} else {
break;
}
}

State::SingleComment => {
if c == '\n' {
state = State::Initial;
}
self.pos += c.len_utf8();
}

State::Done(_) => break,
}

final_pos += c.len_utf8();
Expand All @@ -206,64 +141,26 @@ impl<'a> Lexer<'a> {

let s = &self.contents[initial_pos..final_pos];
let token = match state {
State::Initial | State::AppendEq | State::Double | State::SingleComment => {
State::Initial | State::SingleComment => {
unreachable!()
}

State::Invalid => Token::Invalid(s),
State::Number => Token::Integer(s.parse().unwrap()),
State::Not => Token::Exclamation,
State::SingleChar => match s {
"+" => Token::Plus,
"-" => Token::Minus,
"*" => Token::Astrisk,
"/" => Token::Slash,
"%" => Token::Percent,
"(" => Token::LParen,
")" => Token::RParen,
"[" => Token::LBrack,
"]" => Token::RBrack,
"{" => Token::LBrace,
"}" => Token::RBrace,
"|" => Token::Pipe,
":" => Token::Colon,
"->" => Token::Arrow,
"@" => Token::At,
"." => Token::Dot,
"," => Token::Comma,
"=" => Token::Equals,
"==" => Token::Eq,
">=" => Token::Ge,
"<=" => Token::Le,
">" => Token::Gt,
"<" => Token::Lt,
"!=" => Token::Ne,
"&" => Token::Invalid(s),
"&&" => Token::LogicalAnd,
"||" => Token::LogicalOr,
_ => unreachable!("{:?}", s),
},
State::Symbol => match s {
"true" | "false" => Token::Bool(s == "true"),
"let" => Token::Let,
"val" => Token::Val,
"in" => Token::In,
"mut" => Token::Mut,
"if" => Token::If,
"then" => Token::Then,
"else" => Token::Else,
"match" => Token::Match,
"with" => Token::With,
"to" => Token::To,
"end" => Token::End,
"forall" => Token::Forall,
"type" => Token::Type,
"class" => Token::Class,
"instance" => Token::Instance,
"where" => Token::Where,
_ => Token::Symbol(s),
},
State::Minus => Token::Minus,
State::Slash => Token::Slash,

State::Done(token) => token,
};

self.prev_tokens.push((token, initial_pos..final_pos));
Expand Down
9 changes: 4 additions & 5 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ pub enum Ast {
span: Span,
name: String,
generics: Vec<String>,
constraints: Vec<(String, Vec<Monotype>)>,
constraints: Vec<(String, Vec<String>)>,
functions: Vec<Ast>,
},

Expand Down Expand Up @@ -1701,10 +1701,9 @@ fn parse_class(lexer: &mut Lexer<'_>) -> Result<Ast, ParseError> {

let mut parameters = Vec::new();
loop {
match parse_base_type(lexer, &generics, true) {
Ok(v) => parameters.push(v),
Err(ParseError::NotStarted) => break,
Err(e) => return Err(e),
match try_token!(lexer, Some((Token::Symbol(_), _))) {
Some((Token::Symbol(s), _)) => parameters.push(s.to_string()),
_ => break,
}
}

Expand Down
Loading

0 comments on commit 3852460

Please sign in to comment.