extend the interpreter
This commit is contained in:
+42
-1
@@ -1,16 +1,24 @@
|
|||||||
use crate::token::lookup_ident;
|
use crate::token::lookup_ident;
|
||||||
|
|
||||||
use super::token::ASSIGN;
|
use super::token::ASSIGN;
|
||||||
|
use super::token::ASTERISK;
|
||||||
|
use super::token::BANG;
|
||||||
use super::token::COMMA;
|
use super::token::COMMA;
|
||||||
use super::token::EOF;
|
use super::token::EOF;
|
||||||
|
use super::token::EQ;
|
||||||
|
use super::token::GT;
|
||||||
use super::token::ILLEGAL;
|
use super::token::ILLEGAL;
|
||||||
use super::token::INT;
|
use super::token::INT;
|
||||||
use super::token::LBRACE;
|
use super::token::LBRACE;
|
||||||
use super::token::LPAREN;
|
use super::token::LPAREN;
|
||||||
|
use super::token::LT;
|
||||||
|
use super::token::MINUS;
|
||||||
|
use super::token::NQ;
|
||||||
use super::token::PLUS;
|
use super::token::PLUS;
|
||||||
use super::token::RBRACE;
|
use super::token::RBRACE;
|
||||||
use super::token::RPAREN;
|
use super::token::RPAREN;
|
||||||
use super::token::SEMICOLON;
|
use super::token::SEMICOLON;
|
||||||
|
use super::token::SLASH;
|
||||||
use super::token::Token;
|
use super::token::Token;
|
||||||
|
|
||||||
pub struct Lexer {
|
pub struct Lexer {
|
||||||
@@ -26,6 +34,7 @@ pub trait LexerTraits {
|
|||||||
fn read_identifier(&mut self) -> String;
|
fn read_identifier(&mut self) -> String;
|
||||||
fn skip_whitespace(&mut self);
|
fn skip_whitespace(&mut self);
|
||||||
fn read_number(&mut self) -> String;
|
fn read_number(&mut self) -> String;
|
||||||
|
fn peek_char(&self) -> u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(input_str: String) -> Lexer {
|
pub fn new(input_str: String) -> Lexer {
|
||||||
@@ -66,12 +75,34 @@ impl LexerTraits for Lexer {
|
|||||||
|
|
||||||
match c {
|
match c {
|
||||||
'\0' => tok = new_token(EOF, lit),
|
'\0' => tok = new_token(EOF, lit),
|
||||||
'=' => tok = new_token(ASSIGN, lit),
|
'=' => {
|
||||||
|
if char::from(self.peek_char()) == '=' {
|
||||||
|
self.read_char();
|
||||||
|
let lit = String::from("==");
|
||||||
|
tok = new_token_from_str(EQ, lit);
|
||||||
|
} else {
|
||||||
|
tok = new_token(ASSIGN, lit);
|
||||||
|
}
|
||||||
|
}
|
||||||
';' => tok = new_token(SEMICOLON, lit),
|
';' => tok = new_token(SEMICOLON, lit),
|
||||||
'(' => tok = new_token(LPAREN, lit),
|
'(' => tok = new_token(LPAREN, lit),
|
||||||
')' => tok = new_token(RPAREN, lit),
|
')' => tok = new_token(RPAREN, lit),
|
||||||
',' => tok = new_token(COMMA, lit),
|
',' => tok = new_token(COMMA, lit),
|
||||||
'+' => tok = new_token(PLUS, lit),
|
'+' => tok = new_token(PLUS, lit),
|
||||||
|
'-' => tok = new_token(MINUS, lit),
|
||||||
|
'!' => {
|
||||||
|
if char::from(self.peek_char()) == '=' {
|
||||||
|
self.read_char();
|
||||||
|
let lit = String::from("!=");
|
||||||
|
tok = new_token_from_str(NQ, lit);
|
||||||
|
} else {
|
||||||
|
tok = new_token(BANG, lit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'/' => tok = new_token(SLASH, lit),
|
||||||
|
'*' => tok = new_token(ASTERISK, lit),
|
||||||
|
'<' => tok = new_token(LT, lit),
|
||||||
|
'>' => tok = new_token(GT, lit),
|
||||||
'{' => tok = new_token(LBRACE, lit),
|
'{' => tok = new_token(LBRACE, lit),
|
||||||
'}' => tok = new_token(RBRACE, lit),
|
'}' => tok = new_token(RBRACE, lit),
|
||||||
_ => {
|
_ => {
|
||||||
@@ -123,6 +154,16 @@ impl LexerTraits for Lexer {
|
|||||||
let res = &res[position..read_pos];
|
let res = &res[position..read_pos];
|
||||||
String::from(res)
|
String::from(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn peek_char(&self) -> u8 {
|
||||||
|
let read_pos = self.read_pos.unwrap() as usize;
|
||||||
|
if read_pos >= self.input.len() {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
let res = self.input.as_bytes();
|
||||||
|
res[read_pos]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_token(token_type: &str, ch: u8) -> Token {
|
fn new_token(token_type: &str, ch: u8) -> Token {
|
||||||
|
|||||||
+13
-2
@@ -10,11 +10,22 @@ fn main() {
|
|||||||
let add = fn(x, y) {
|
let add = fn(x, y) {
|
||||||
x + y;
|
x + y;
|
||||||
};
|
};
|
||||||
let result = add(five, ten);";
|
let result = add(five, ten);
|
||||||
|
!-/*5;
|
||||||
|
5 < 10 > 5;
|
||||||
|
|
||||||
|
if (5 < 10) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
10 == 10;
|
||||||
|
10 != 9;";
|
||||||
|
|
||||||
let mut l = new(input.to_string());
|
let mut l = new(input.to_string());
|
||||||
|
|
||||||
for (_i, tok) in (0..37).map(|_| l.next_token()).enumerate() {
|
for (_i, tok) in (0..80).map(|_| l.next_token()).enumerate() {
|
||||||
println!("{}: {:?}", tok.type_, tok.literal);
|
println!("{}: {:?}", tok.type_, tok.literal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ pub const IDENT: &str = "IDENT";
|
|||||||
pub const INT: &str = "INT";
|
pub const INT: &str = "INT";
|
||||||
pub const ASSIGN: &str = "=";
|
pub const ASSIGN: &str = "=";
|
||||||
pub const PLUS: &str = "+";
|
pub const PLUS: &str = "+";
|
||||||
|
pub const MINUS: &str = "-";
|
||||||
|
pub const BANG: &str = "!";
|
||||||
|
pub const ASTERISK: &str = "*";
|
||||||
|
pub const SLASH: &str = "/";
|
||||||
|
pub const LT: &str = "<";
|
||||||
|
pub const GT: &str = ">";
|
||||||
pub const COMMA: &str = ",";
|
pub const COMMA: &str = ",";
|
||||||
pub const SEMICOLON: &str = ";";
|
pub const SEMICOLON: &str = ";";
|
||||||
pub const LPAREN: &str = "(";
|
pub const LPAREN: &str = "(";
|
||||||
@@ -20,11 +26,23 @@ pub const LBRACE: &str = "{";
|
|||||||
pub const RBRACE: &str = "}";
|
pub const RBRACE: &str = "}";
|
||||||
pub const FUNCTION: &str = "FUNCTION";
|
pub const FUNCTION: &str = "FUNCTION";
|
||||||
pub const LET: &str = "LET";
|
pub const LET: &str = "LET";
|
||||||
|
pub const TRUE: &str = "TRUE";
|
||||||
|
pub const FALSE: &str = "FALSE";
|
||||||
|
pub const IF: &str = "IF";
|
||||||
|
pub const ELSE: &str = "ELSE";
|
||||||
|
pub const RETURN: &str = "RETURN";
|
||||||
|
pub const EQ: &str = "EQ";
|
||||||
|
pub const NQ: &str = "NQ";
|
||||||
|
|
||||||
pub fn lookup_ident(ident: &str) -> &'static str {
|
pub fn lookup_ident(ident: &str) -> &'static str {
|
||||||
match ident {
|
match ident {
|
||||||
"fn" => FUNCTION,
|
"fn" => FUNCTION,
|
||||||
"let" => LET,
|
"let" => LET,
|
||||||
|
"true" => TRUE,
|
||||||
|
"false" => FALSE,
|
||||||
|
"if" => IF,
|
||||||
|
"else" => ELSE,
|
||||||
|
"return" => RETURN,
|
||||||
_ => IDENT,
|
_ => IDENT,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user