Added print statement, various other fixes

This commit is contained in:
2026-07-10 02:06:03 -05:00
parent 725c6aa835
commit cf3e14c9e7
10 changed files with 261 additions and 87 deletions
+2
View File
@@ -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
}
+45
View File
@@ -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
View File
@@ -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
}