Added print statement, various other fixes
This commit is contained in:
@@ -4,6 +4,7 @@ use super::{ whitespace_chars, Token };
|
||||
pub enum Keyword {
|
||||
Let,
|
||||
Fn,
|
||||
Print, // print is a keyword for... reasons
|
||||
}
|
||||
|
||||
macro_rules! match_keyword {
|
||||
@@ -17,5 +18,6 @@ macro_rules! match_keyword {
|
||||
pub fn parse_keyword(input: &str) -> Option<(Token, &str)> {
|
||||
match_keyword!("let", Token::Kw(Keyword::Let), input);
|
||||
match_keyword!("fn", Token::Kw(Keyword::Fn), input);
|
||||
match_keyword!("print", Token::Kw(Keyword::Print), input);
|
||||
None
|
||||
}
|
||||
|
||||
@@ -86,16 +86,61 @@ fn parse_dec_int(input: &str) -> Option<(i32, &str)> {
|
||||
Some((sign * s.parse::<i32>().unwrap(), &input[s.len()..]))
|
||||
}
|
||||
|
||||
fn parse_uint(input: &str) -> Option<(u32, &str)> {
|
||||
if input.starts_with("-") {
|
||||
return None;
|
||||
}
|
||||
input.strip_prefix("0x").map(|input| -> String {
|
||||
input.chars().take_while(|c| matches!(c, hex_chars!())).collect()
|
||||
}).filter(|s| !s.is_empty() && input.chars().nth(s.len()) == Some('u')).map(|s|
|
||||
(u32::from_str_radix(&s, 16).unwrap(), &input[(s.len() + 1)..])
|
||||
).or({
|
||||
let s: String = input.chars().take_while(|c| matches!(c, dec_chars!())).collect();
|
||||
if s.is_empty() || input.chars().nth(s.len()) != Some('u') {
|
||||
None
|
||||
} else {
|
||||
Some ((s.parse::<u32>().unwrap(), &input[(s.len() + 1)..]))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_str(input: &str) -> Option<(String, &str)> {
|
||||
let x = input.chars().next()?;
|
||||
if x != '"' {
|
||||
return None;
|
||||
}
|
||||
let mut index = 1;
|
||||
let mut terminated = false;
|
||||
while index < input.len() {
|
||||
// this is definitely stupid but idk how to do this properly
|
||||
if Some('"') == input.chars().nth(index) && Some('\'') != input.chars().nth(index - 1) {
|
||||
terminated = true;
|
||||
break;
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
if !terminated {
|
||||
return None;
|
||||
}
|
||||
Some((input.get(1..index).unwrap().to_owned().replace("\\n", "\n").replace("\\r", "\r").replace("\\0", "\0"), &input[(index + 1)..]))
|
||||
}
|
||||
|
||||
pub fn parse_literal(input: &str) -> Option<(Token, &str)> {
|
||||
if let Some((val, s)) = parse_float(input) {
|
||||
return Some((Token::Lit(TeaValue::Float(val)), s))
|
||||
}
|
||||
if let Some((val, s)) = parse_uint(input) {
|
||||
return Some((Token::Lit(TeaValue::Uint(val)), s))
|
||||
}
|
||||
if let Some((val, s)) = parse_hex_int(input) {
|
||||
return Some((Token::Lit(TeaValue::Int(val)), s))
|
||||
}
|
||||
if let Some((val, s)) = parse_dec_int(input) {
|
||||
return Some((Token::Lit(TeaValue::Int(val)), s))
|
||||
}
|
||||
if let Some((val, s)) = parse_str(input) {
|
||||
return Some((Token::Lit(TeaValue::String(val)), s))
|
||||
}
|
||||
// TODO: other values
|
||||
None
|
||||
}
|
||||
|
||||
+6
-4
@@ -8,17 +8,19 @@ pub enum Symbol {
|
||||
CloseBrace,
|
||||
OpenParen,
|
||||
CloseParen,
|
||||
Comma,
|
||||
}
|
||||
|
||||
pub fn parse_symbol(input: &str) -> Option<(Token, &str)> {
|
||||
let c: char = input.chars().next()?;
|
||||
let input = &input[1..];
|
||||
match c {
|
||||
'=' => Some((Token::Sym(Symbol::EqualSign), input)),
|
||||
';' => Some((Token::Sym(Symbol::Semicolon), input)),
|
||||
'{' => Some((Token::Sym(Symbol::OpenBrace), input)),
|
||||
'=' => Some((Token::Sym(Symbol::EqualSign), input)),
|
||||
';' => Some((Token::Sym(Symbol::Semicolon), input)),
|
||||
',' => Some((Token::Sym(Symbol::Comma), input)),
|
||||
'{' => Some((Token::Sym(Symbol::OpenBrace), input)),
|
||||
'}' => Some((Token::Sym(Symbol::CloseBrace), input)),
|
||||
'(' => Some((Token::Sym(Symbol::OpenParen), input)),
|
||||
'(' => Some((Token::Sym(Symbol::OpenParen), input)),
|
||||
')' => Some((Token::Sym(Symbol::CloseParen), input)),
|
||||
_ => None
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user