Initial commit. Working on lexer
This commit is contained in:
commit
c84e73756f
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
target/
|
14
Cargo.lock
generated
Normal file
14
Cargo.lock
generated
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[[package]]
|
||||||
|
name = "interpreter"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[package]
|
||||||
|
name = "interpreter"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["ishanjain28 <ishanjain28@gmail.com>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
lazy_static = "1.2.0"
|
104
src/lexer/mod.rs
Normal file
104
src/lexer/mod.rs
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref IDENTMAP: HashMap<&'static str, Token> = {
|
||||||
|
let mut m = HashMap::new();
|
||||||
|
m.insert("fn", Token::Function);
|
||||||
|
m.insert("let", Token::Let);
|
||||||
|
m
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum Token {
|
||||||
|
Illegal,
|
||||||
|
EOF,
|
||||||
|
|
||||||
|
// Identifiers
|
||||||
|
Int(i64),
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
Assign,
|
||||||
|
Plus,
|
||||||
|
Multiply,
|
||||||
|
Divide,
|
||||||
|
Subtract,
|
||||||
|
|
||||||
|
// Delimiter
|
||||||
|
Comma,
|
||||||
|
Semicolon,
|
||||||
|
LParen,
|
||||||
|
RParen,
|
||||||
|
LBrace,
|
||||||
|
RBrace,
|
||||||
|
|
||||||
|
// Keywords
|
||||||
|
Function,
|
||||||
|
Let,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Lexer {
|
||||||
|
input: Vec<char>,
|
||||||
|
position: usize,
|
||||||
|
read_position: usize,
|
||||||
|
ch: char,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Lexer {
|
||||||
|
pub fn new(input: &str) -> Lexer {
|
||||||
|
Lexer {
|
||||||
|
input: input.chars().collect::<Vec<char>>(),
|
||||||
|
position: 0,
|
||||||
|
read_position: 0,
|
||||||
|
ch: '0',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_char(&mut self) {
|
||||||
|
if self.read_position >= self.input.len() {
|
||||||
|
self.ch = '0';
|
||||||
|
} else {
|
||||||
|
self.ch = self.input[self.read_position];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.position = self.read_position;
|
||||||
|
self.read_position += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_identifier(&mut self) -> String {
|
||||||
|
let pos = self.position;
|
||||||
|
while is_letter(self.ch) {
|
||||||
|
self.read_char();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.input[pos..self.position].iter().collect::<String>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for Lexer {
|
||||||
|
type Item = Token;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.read_char();
|
||||||
|
|
||||||
|
match self.ch {
|
||||||
|
'=' => Some(Token::Assign),
|
||||||
|
'+' => Some(Token::Plus),
|
||||||
|
'*' => Some(Token::Multiply),
|
||||||
|
'/' => Some(Token::Divide),
|
||||||
|
'-' => Some(Token::Subtract),
|
||||||
|
',' => Some(Token::Comma),
|
||||||
|
';' => Some(Token::Semicolon),
|
||||||
|
'(' => Some(Token::LParen),
|
||||||
|
')' => Some(Token::RParen),
|
||||||
|
'[' => Some(Token::LBrace),
|
||||||
|
']' => Some(Token::RBrace),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_letter(c: char) -> bool {
|
||||||
|
c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_'
|
||||||
|
}
|
34
src/main.rs
Normal file
34
src/main.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
|
mod lexer;
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use lexer::{Lexer, Token};
|
||||||
|
#[test]
|
||||||
|
fn new_token() {
|
||||||
|
let input = "=+()[],;";
|
||||||
|
let expected = vec![
|
||||||
|
Token::Assign,
|
||||||
|
Token::Plus,
|
||||||
|
Token::LParen,
|
||||||
|
Token::RParen,
|
||||||
|
Token::Comma,
|
||||||
|
Token::Semicolon,
|
||||||
|
Token::EOF,
|
||||||
|
];
|
||||||
|
|
||||||
|
let tokenized_output = Lexer::new(input).collect::<Vec<Token>>();
|
||||||
|
|
||||||
|
println!("{:?}", tokenized_output);
|
||||||
|
assert_eq!(expected.len(), tokenized_output.len());
|
||||||
|
|
||||||
|
for (exp, actual) in expected.into_iter().zip(tokenized_output) {
|
||||||
|
assert_eq!(actual, exp);
|
||||||
|
println!("{:?} {:?}", actual, exp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user