parser done

This commit is contained in:
SimonFJ20 2023-03-16 03:23:51 +01:00
parent 8705272a77
commit f6dd337ba1
5 changed files with 562 additions and 115 deletions

View File

@ -8,6 +8,7 @@ pub struct Node<T> {
#[derive(Debug)]
pub enum Expr {
Error(String),
Unit,
Id(String),
Int(i64),
@ -15,9 +16,15 @@ pub enum Expr {
String(String),
Bool(bool),
Array(Vec<Node<Expr>>),
Object(Vec<ObjectEntry>),
Object(Vec<Node<ObjectEntry>>),
Tuple(Vec<Node<Expr>>),
If {
condition: Box<Node<Expr>>,
truthy: Box<Node<Expr>>,
falsy: Option<Box<Node<Expr>>>,
},
Member {
subject: Box<Node<Expr>>,
value: String,
@ -39,11 +46,44 @@ pub enum Expr {
left: Box<Node<Expr>>,
right: Box<Node<Expr>>,
},
Assign {
assign_type: AssignType,
subject: Box<Node<Expr>>,
value: Box<Node<Expr>>,
},
Let {
subject: Node<Parameter>,
value: Option<Box<Node<Expr>>>,
},
Continue,
Break,
While {
condition: Box<Node<Expr>>,
body: Box<Node<Expr>>,
},
Return(Option<Box<Node<Expr>>>),
Function {
name: String,
parameters: Vec<Node<Parameter>>,
body: Box<Node<Expr>>,
},
Block {
statements: Vec<Node<Expr>>,
value: Option<Box<Node<Expr>>>,
},
Spread(Box<Node<Expr>>),
}
#[derive(Debug)]
pub enum ObjectEntry {
Pair(Box<Node<Expr>>, Box<Expr>),
Error(String),
Pair {
key: Box<Node<Expr>>,
value: Box<Node<Expr>>,
},
Spread(Box<Node<Expr>>),
}
#[derive(Debug)]
@ -73,3 +113,20 @@ pub enum BinaryType {
And,
Or,
}
#[derive(Debug)]
pub enum AssignType {
Assign,
Add,
Subtract,
Multiply,
Divide,
Modulo,
}
#[derive(Debug)]
pub enum Parameter {
Error(String),
Id { name: String, mutable: bool },
Spread(Box<Node<Parameter>>),
}

View File

@ -46,9 +46,7 @@ impl<'a> Lexer<'a> {
'=',
TokenType::PercentEqual,
)),
'=' => {
Some(self.single_or_double_char_token(TokenType::Equal, '=', TokenType::EqualEqual))
}
'=' => Some(self.equal_token()),
'!' => Some(self.single_or_double_char_token(
TokenType::Exclamation,
'=',
@ -104,7 +102,7 @@ impl<'a> Lexer<'a> {
self.step();
}
if self.done() || self.current() != '"' {
self.step_and_token(TokenType::MalformedString, start)
self.token(TokenType::MalformedString, start)
} else {
self.step_and_token(TokenType::String, start)
}
@ -213,6 +211,18 @@ impl<'a> Lexer<'a> {
}
}
fn equal_token(&mut self) -> Token {
let start = self.pos();
self.step();
if !self.done() && self.current() == '=' {
self.step_and_token(TokenType::EqualEqual, start)
} else if !self.done() && self.current() == '>' {
self.step_and_token(TokenType::EqualLessThan, start)
} else {
self.step_and_token(TokenType::Equal, start)
}
}
fn dot_token(&mut self) -> Token {
let start = self.pos();
self.step();
@ -222,6 +232,13 @@ impl<'a> Lexer<'a> {
self.step();
}
self.token(TokenType::Decimal, start)
} else if !self.done() && self.current() == '.' {
self.step();
if !self.done() && self.current() == '.' {
self.step_and_token(TokenType::DotDotDot, start)
} else {
self.token(TokenType::DotDot, start)
}
} else {
self.token(TokenType::Dot, start)
}

View File

@ -9,15 +9,33 @@ use crate::lexer::Lexer;
use crate::parser::Parser;
fn main() {
// println!("tokens = [");
// let text = "** 3.14 \"foo\" false true ( ) + += /* 1 /* 2 */ 3 */ // 4 \n 5";
// let lexer = Lexer::new(text);
// lexer.for_each(|token| {
// println!(
// " {:?} = `{}`,",
// token.token_type,
// &text[token.pos.index..token.pos.index + token.length]
// );
// });
// println!("]");
let text2 = "[1, 2, ...a]";
let lexer2 = Lexer::new(text2);
println!("tokens = [");
let text = "** 3.14 \"foo\" false true ( ) + += /* 1 /* 2 */ 3 */ // 4 \n 5";
let lexer = Lexer::new(text);
lexer.for_each(|token| {
println!(" {:?},", token);
lexer2.for_each(|token| {
println!(
" ({:?}, `{}`, [{}], {}, {}:{}),",
token.token_type,
&text2[token.pos.index..token.pos.index + token.length],
token.pos.index,
token.length,
token.pos.line,
token.pos.col,
);
});
println!("]");
let text2 = "1 + 2 * 3";
let mut parser = Parser::new(text2, Lexer::new(text2));
let expr = parser.parse_expr();
println!("ast = {:#?}", expr);

View File

@ -1,11 +1,8 @@
use crate::ast::{BinaryType, Expr, Node, UnaryType};
use crate::tokens::{Position, PositionKnowing, Token, TokenType};
use std::iter::Peekable;
use std::str::Chars;
#[derive(Debug)]
pub struct ParserError {
pos: Position,
message: String,
}
use crate::ast::{AssignType, BinaryType, Expr, Node, ObjectEntry, Parameter, UnaryType};
use crate::tokens::{PositionKnowing, Token, TokenType};
pub struct Parser<'a, Tokens>
where
@ -28,16 +25,239 @@ where
}
}
pub fn parse_expr(&mut self) -> Result<Node<Expr>, ParserError> {
pub fn parse_top_level_statements(&mut self) -> Vec<Node<Expr>> {
let mut statements = Vec::<Node<Expr>>::new();
while !self.done() {
statements.push(self.parse_statement());
}
statements
}
fn parse_block(&mut self) -> Node<Expr> {
self.step();
let mut statements = Vec::<Node<Expr>>::new();
let mut last = None;
while !self.done() && !self.current_is(TokenType::RBrace) {
if let Some(statement) = last {
statements.push(statement);
}
last = Some(self.parse_statement());
}
if self.done() || !self.current_is(TokenType::RBrace) {
statements.push(self.error("expected '}'"));
}
self.node(Expr::Block {
statements,
value: last.map(|v| Box::new(v)),
})
}
pub fn parse_statement(&mut self) -> Node<Expr> {
if self.done() {
return self.error("expected statement");
}
match self.current().token_type {
TokenType::Fn => self.parse_function(),
TokenType::Return => self.parse_function(),
TokenType::While => self.parse_function(),
TokenType::Break => self.parse_function(),
TokenType::Continue => self.parse_function(),
_ => self.parse_assign(),
}
}
fn parse_function(&mut self) -> Node<Expr> {
self.step();
if self.done() || !self.current_is(TokenType::Id) {
return self.error("expected Id");
}
let name = self.token_string(self.current());
self.step();
if self.done() || !self.current_is(TokenType::LParen) {
return self.error("expected '('");
}
self.step();
let mut parameters = Vec::<Node<Parameter>>::new();
if !self.done() && !self.current_is(TokenType::RParen) {
if self.current_is(TokenType::DotDotDot) {
self.step();
let inner = self.parse_parameter();
parameters.push(self.node(Parameter::Spread(Box::new(inner))));
} else {
parameters.push(self.parse_parameter());
while !self.done() && self.current_is(TokenType::Comma) {
self.step();
if self.current_is(TokenType::DotDotDot) {
self.step();
let inner = self.parse_parameter();
parameters.push(self.node(Parameter::Spread(Box::new(inner))));
break;
}
if self.done() || self.current_is(TokenType::RParen) {
break;
}
parameters.push(self.parse_parameter());
}
}
}
if self.done() || !self.current_is(TokenType::RParen) {
return self.error("expected ')'");
}
self.step();
if self.done() || !self.current_is(TokenType::LBrace) {
return self.error("expected '{'");
}
let body = self.parse_block();
self.node(Expr::Function {
name,
parameters,
body: Box::new(body),
})
}
fn parse_parameter(&mut self) -> Node<Parameter> {
let mutable = if !self.done() && self.current_is(TokenType::Mut) {
self.step();
true
} else {
false
};
if self.done() || !self.current_is(TokenType::Id) {
return self.node(Parameter::Error("expected Id".to_string()));
}
let name = self.token_string(self.current());
self.step_and_node(Parameter::Id { mutable, name })
}
fn parse_return(&mut self) -> Node<Expr> {
self.step();
if !self.done() && !self.current_is(TokenType::Semicolon) {
let value = self.parse_expr();
self.node(Expr::Return(Some(Box::new(value))))
} else {
self.node(Expr::Return(None))
}
}
fn parse_while(&mut self) -> Node<Expr> {
self.step();
let condition = self.parse_expr();
if self.done() || !self.current_is(TokenType::LBrace) {
return self.error("expected '{'");
}
let body = self.parse_block();
self.node(Expr::While {
condition: Box::new(condition),
body: Box::new(body),
})
}
fn parse_break(&mut self) -> Node<Expr> {
self.step_and_node(Expr::Continue)
}
fn parse_continue(&mut self) -> Node<Expr> {
self.step_and_node(Expr::Continue)
}
fn parse_let(&mut self) -> Node<Expr> {
self.step();
let subject = self.parse_parameter();
if !self.done() && self.current_is(TokenType::Equal) {
self.step();
let value = self.parse_expr();
self.node(Expr::Let {
subject,
value: Some(Box::new(value)),
})
} else {
self.node(Expr::Let {
subject,
value: None,
})
}
}
fn parse_assign(&mut self) -> Node<Expr> {
let subject = self.parse_expr();
if self.done() {
return subject;
}
match self.current().token_type {
TokenType::Equal => {
self.step();
let value = self.parse_expr();
self.node(Expr::Assign {
assign_type: AssignType::Assign,
subject: Box::new(subject),
value: Box::new(value),
})
}
TokenType::PlusEqual => {
self.step();
let value = self.parse_expr();
self.node(Expr::Assign {
assign_type: AssignType::Add,
subject: Box::new(subject),
value: Box::new(value),
})
}
TokenType::MinusEqual => {
self.step();
let value = self.parse_expr();
self.node(Expr::Assign {
assign_type: AssignType::Subtract,
subject: Box::new(subject),
value: Box::new(value),
})
}
TokenType::AsteriskEqual => {
self.step();
let value = self.parse_expr();
self.node(Expr::Assign {
assign_type: AssignType::Multiply,
subject: Box::new(subject),
value: Box::new(value),
})
}
TokenType::SlashEqual => {
self.step();
let value = self.parse_expr();
self.node(Expr::Assign {
assign_type: AssignType::Divide,
subject: Box::new(subject),
value: Box::new(value),
})
}
TokenType::PercentEqual => {
self.step();
let value = self.parse_expr();
self.node(Expr::Assign {
assign_type: AssignType::Modulo,
subject: Box::new(subject),
value: Box::new(value),
})
}
_ => subject,
}
}
fn parse_spread(&mut self) -> Node<Expr> {
self.step();
let inner = self.parse_expr();
self.node(Expr::Spread(Box::new(inner)))
}
pub fn parse_expr(&mut self) -> Node<Expr> {
self.parse_prec_or()
}
fn parse_prec_or(&mut self) -> Result<Node<Expr>, ParserError> {
let mut left = self.parse_prec_and()?;
fn parse_prec_or(&mut self) -> Node<Expr> {
let mut left = self.parse_prec_and();
while !self.done() {
if self.current_is(TokenType::Or) {
self.step();
let right = self.parse_prec_and()?;
let right = self.parse_prec_and();
left = self.node(Expr::Binary {
binary_type: BinaryType::Or,
left: Box::new(left),
@ -47,15 +267,15 @@ where
break;
}
}
Ok(left)
left
}
fn parse_prec_and(&mut self) -> Result<Node<Expr>, ParserError> {
let mut left = self.parse_prec_equal_inequal()?;
fn parse_prec_and(&mut self) -> Node<Expr> {
let mut left = self.parse_prec_equal_inequal();
while !self.done() {
if self.current_is(TokenType::And) {
self.step();
let right = self.parse_prec_equal_inequal()?;
let right = self.parse_prec_equal_inequal();
left = self.node(Expr::Binary {
binary_type: BinaryType::And,
left: Box::new(left),
@ -65,15 +285,15 @@ where
break;
}
}
Ok(left)
left
}
fn parse_prec_equal_inequal(&mut self) -> Result<Node<Expr>, ParserError> {
let mut left = self.parse_prec_lt_lte_gt_gte_in()?;
fn parse_prec_equal_inequal(&mut self) -> Node<Expr> {
let mut left = self.parse_prec_lt_lte_gt_gte_in();
while !self.done() {
if self.current_is(TokenType::EqualEqual) {
self.step();
let right = self.parse_prec_lt_lte_gt_gte_in()?;
let right = self.parse_prec_lt_lte_gt_gte_in();
left = self.node(Expr::Binary {
binary_type: BinaryType::Equal,
left: Box::new(left),
@ -81,7 +301,7 @@ where
});
} else if self.current_is(TokenType::ExclamationEqual) {
self.step();
let right = self.parse_prec_lt_lte_gt_gte_in()?;
let right = self.parse_prec_lt_lte_gt_gte_in();
left = self.node(Expr::Binary {
binary_type: BinaryType::Inequal,
left: Box::new(left),
@ -91,15 +311,15 @@ where
break;
}
}
Ok(left)
left
}
fn parse_prec_lt_lte_gt_gte_in(&mut self) -> Result<Node<Expr>, ParserError> {
let mut left = self.parse_prec_add_subtract()?;
fn parse_prec_lt_lte_gt_gte_in(&mut self) -> Node<Expr> {
let mut left = self.parse_prec_add_subtract();
while !self.done() {
if self.current_is(TokenType::LessThan) {
self.step();
let right = self.parse_prec_add_subtract()?;
let right = self.parse_prec_add_subtract();
left = self.node(Expr::Binary {
binary_type: BinaryType::LT,
left: Box::new(left),
@ -107,7 +327,7 @@ where
});
} else if self.current_is(TokenType::GreaterThan) {
self.step();
let right = self.parse_prec_add_subtract()?;
let right = self.parse_prec_add_subtract();
left = self.node(Expr::Binary {
binary_type: BinaryType::GT,
left: Box::new(left),
@ -115,7 +335,7 @@ where
});
} else if self.current_is(TokenType::LessThanEqual) {
self.step();
let right = self.parse_prec_add_subtract()?;
let right = self.parse_prec_add_subtract();
left = self.node(Expr::Binary {
binary_type: BinaryType::LTE,
left: Box::new(left),
@ -123,7 +343,7 @@ where
});
} else if self.current_is(TokenType::GreaterThanEqual) {
self.step();
let right = self.parse_prec_add_subtract()?;
let right = self.parse_prec_add_subtract();
left = self.node(Expr::Binary {
binary_type: BinaryType::GTE,
left: Box::new(left),
@ -131,7 +351,7 @@ where
});
} else if self.current_is(TokenType::In) {
self.step();
let right = self.parse_prec_add_subtract()?;
let right = self.parse_prec_add_subtract();
left = self.node(Expr::Binary {
binary_type: BinaryType::In,
left: Box::new(left),
@ -141,15 +361,15 @@ where
break;
}
}
Ok(left)
left
}
fn parse_prec_add_subtract(&mut self) -> Result<Node<Expr>, ParserError> {
let mut left = self.parse_prec_multiply_divide_modulo()?;
fn parse_prec_add_subtract(&mut self) -> Node<Expr> {
let mut left = self.parse_prec_multiply_divide_modulo();
while !self.done() {
if self.current_is(TokenType::Plus) {
self.step();
let right = self.parse_prec_multiply_divide_modulo()?;
let right = self.parse_prec_multiply_divide_modulo();
left = self.node(Expr::Binary {
binary_type: BinaryType::Add,
left: Box::new(left),
@ -157,7 +377,7 @@ where
});
} else if self.current_is(TokenType::Minus) {
self.step();
let right = self.parse_prec_multiply_divide_modulo()?;
let right = self.parse_prec_multiply_divide_modulo();
left = self.node(Expr::Binary {
binary_type: BinaryType::Subtract,
left: Box::new(left),
@ -167,15 +387,15 @@ where
break;
}
}
Ok(left)
left
}
fn parse_prec_multiply_divide_modulo(&mut self) -> Result<Node<Expr>, ParserError> {
let mut left = self.parse_prec_unary()?;
fn parse_prec_multiply_divide_modulo(&mut self) -> Node<Expr> {
let mut left = self.parse_prec_unary();
while !self.done() {
if self.current_is(TokenType::Asterisk) {
self.step();
let right = self.parse_prec_unary()?;
let right = self.parse_prec_unary();
left = self.node(Expr::Binary {
binary_type: BinaryType::Multiply,
left: Box::new(left),
@ -183,7 +403,7 @@ where
});
} else if self.current_is(TokenType::Slash) {
self.step();
let right = self.parse_prec_unary()?;
let right = self.parse_prec_unary();
left = self.node(Expr::Binary {
binary_type: BinaryType::Divide,
left: Box::new(left),
@ -191,7 +411,7 @@ where
});
} else if self.current_is(TokenType::Percent) {
self.step();
let right = self.parse_prec_unary()?;
let right = self.parse_prec_unary();
left = self.node(Expr::Binary {
binary_type: BinaryType::Modulo,
left: Box::new(left),
@ -201,21 +421,21 @@ where
break;
}
}
Ok(left)
left
}
fn parse_prec_unary(&mut self) -> Result<Node<Expr>, ParserError> {
fn parse_prec_unary(&mut self) -> Node<Expr> {
if !self.done() && self.current_is(TokenType::Not) {
self.step();
let subject = Box::new(self.parse_prec_unary()?);
self.ok_node(Expr::Unary {
let subject = Box::new(self.parse_prec_unary());
self.node(Expr::Unary {
unary_type: UnaryType::Not,
subject,
})
} else if !self.done() && self.current_is(TokenType::Minus) {
self.step();
let subject = Box::new(self.parse_prec_unary()?);
self.ok_node(Expr::Unary {
let subject = Box::new(self.parse_prec_unary());
self.node(Expr::Unary {
unary_type: UnaryType::Negate,
subject,
})
@ -223,22 +443,22 @@ where
self.step();
if !self.done() && self.current_is(TokenType::Mut) {
self.step();
let subject = Box::new(self.parse_prec_unary()?);
self.ok_node(Expr::Unary {
let subject = Box::new(self.parse_prec_unary());
self.node(Expr::Unary {
unary_type: UnaryType::ReferenceMut,
subject,
})
} else {
let subject = Box::new(self.parse_prec_unary()?);
self.ok_node(Expr::Unary {
let subject = Box::new(self.parse_prec_unary());
self.node(Expr::Unary {
unary_type: UnaryType::Reference,
subject,
})
}
} else if !self.done() && self.current_is(TokenType::Asterisk) {
self.step();
let subject = Box::new(self.parse_prec_unary()?);
self.ok_node(Expr::Unary {
let subject = Box::new(self.parse_prec_unary());
self.node(Expr::Unary {
unary_type: UnaryType::Dereference,
subject,
})
@ -247,22 +467,22 @@ where
}
}
fn parse_prec_exponentiate(&mut self) -> Result<Node<Expr>, ParserError> {
let left = self.parse_prec_member_index_call()?;
fn parse_prec_exponentiate(&mut self) -> Node<Expr> {
let left = self.parse_prec_member_index_call();
if !self.done() && self.current_is(TokenType::AsteriskEqual) {
let right = self.parse_prec_exponentiate()?;
self.step_and_ok_node(Expr::Binary {
let right = self.parse_prec_exponentiate();
self.step_and_node(Expr::Binary {
binary_type: BinaryType::Exponentiate,
left: Box::new(left),
right: Box::new(right),
})
} else {
Ok(left)
left
}
}
fn parse_prec_member_index_call(&mut self) -> Result<Node<Expr>, ParserError> {
let mut subject = self.parse_operand()?;
fn parse_prec_member_index_call(&mut self) -> Node<Expr> {
let mut subject = self.parse_operand();
while !self.done() {
if self.current_is(TokenType::Dot) {
self.step();
@ -277,7 +497,7 @@ where
});
} else if self.current_is(TokenType::LBracket) {
self.step();
let value = self.parse_expr()?;
let value = self.parse_expr();
if self.done() || !self.current_is(TokenType::RBracket) {
return self.error("expected ']'");
}
@ -289,13 +509,13 @@ where
self.step();
let mut arguments = Vec::<Node<Expr>>::new();
if !self.done() && !self.current_is(TokenType::RParen) {
arguments.push(self.parse_expr()?);
arguments.push(self.parse_expr());
while !self.done() && self.current_is(TokenType::Comma) {
self.step();
if self.done() || self.current_is(TokenType::RParen) {
self.step();
}
arguments.push(self.parse_expr()?);
arguments.push(self.parse_expr());
}
}
if self.done() || !self.current_is(TokenType::RParen) {
@ -310,82 +530,172 @@ where
break;
}
}
Ok(subject)
subject
}
fn parse_operand(&mut self) -> Result<Node<Expr>, ParserError> {
fn parse_operand(&mut self) -> Node<Expr> {
if self.done() {
return self.error("expected value, got eof");
}
match self.current().token_type {
TokenType::Id => self.step_and_ok_node(Expr::Id(self.token_string(self.current()))),
match &self.current().token_type {
TokenType::Id => self.step_and_node(Expr::Id(self.token_string(self.current()))),
TokenType::Int => {
let mut value_string = self.token_string(self.current());
self.step();
if !self.done() && self.current_is(TokenType::Decimal) {
value_string.push_str(&self.token_string(self.current()));
self.step_and_ok_node(Expr::Float(
value_string.parse::<f64>().expect("valid f64"),
))
self.step_and_node(Expr::Float(value_string.parse::<f64>().expect("valid f64")))
} else {
self.ok_node(Expr::Int((value_string).parse::<i64>().expect("valid i64")))
self.node(Expr::Int((value_string).parse::<i64>().expect("valid i64")))
}
}
TokenType::Decimal => self.step_and_ok_node(Expr::Float(
TokenType::Decimal => self.step_and_node(Expr::Float(
self.token_string(self.current())
.parse::<f64>()
.expect("valid f64"),
)),
TokenType::False => self.step_and_ok_node(Expr::Bool(false)),
TokenType::True => self.step_and_ok_node(Expr::Bool(true)),
TokenType::String => self.parse_string(),
TokenType::False => self.step_and_node(Expr::Bool(false)),
TokenType::True => self.step_and_node(Expr::Bool(true)),
TokenType::LParen => self.parse_unit_group_or_tuple(),
TokenType::LBrace => self.parse_object(),
TokenType::LBrace => self.parse_block(),
TokenType::Underscore => todo!(),
TokenType::LBracket => self.parse_array(),
TokenType::Fn => self.parse_function(),
_ => self.error("expected value"),
TokenType::If => self.parse_if(),
TokenType::MalformedString => self.error("malformed string"),
other => self.node(Expr::Error(format!("expected value, got {:?}", other))),
}
}
fn parse_unit_group_or_tuple(&mut self) -> Result<Node<Expr>, ParserError> {
fn parse_string(&mut self) -> Node<Expr> {
let value_result = parse_string_value(&self.token_string(self.current()));
self.step_and_node(match value_result {
Ok(value) => Expr::String(value),
Err(error) => Expr::Error(error),
})
}
fn parse_unit_group_or_tuple(&mut self) -> Node<Expr> {
self.step();
if !self.done() && !self.current_is(TokenType::LParen) {
todo!()
let first_value = self.parse_expr();
if !self.done() && !self.current_is(TokenType::LParen) {
todo!()
} else {
self.step_and(first_value)
}
} else {
self.step_and_ok_node(Expr::Unit)
self.step_and_node(Expr::Unit)
}
}
fn parse_object(&mut self) -> Result<Node<Expr>, ParserError> {
todo!()
fn parse_object(&mut self) -> Node<Expr> {
self.step();
let mut values = Vec::<Node<ObjectEntry>>::new();
if !self.done() && !self.current_is(TokenType::RBracket) {
if self.current_is(TokenType::DotDotDot) {
values.push(self.parse_object_entry());
} else {
values.push(self.parse_object_entry());
while !self.done() && self.current_is(TokenType::Comma) {
self.step();
if self.done() || self.current_is(TokenType::RBracket) {
break;
}
if self.current_is(TokenType::DotDotDot) {
values.push(self.parse_object_entry());
break;
}
values.push(self.parse_object_entry());
}
}
}
if self.done() || !self.current_is(TokenType::RBracket) {
return self.error("expected ']'");
}
self.step_and_node(Expr::Object(values))
}
fn parse_array(&mut self) -> Result<Node<Expr>, ParserError> {
todo!()
fn parse_object_entry(&mut self) -> Node<ObjectEntry> {
if self.done() {
return self.node(ObjectEntry::Error("expected object entry".to_string()));
}
match self.current().token_type {
TokenType::DotDotDot => {
let expr = self.parse_spread();
self.node(ObjectEntry::Spread(Box::new(expr)))
}
TokenType::String => {
let key = self.parse_string();
if self.done() || !self.current_is(TokenType::Colon) {
return self.node(ObjectEntry::Error("expected ':'".to_string()));
}
self.step();
let value = self.parse_expr();
self.node(ObjectEntry::Pair {
key: Box::new(key),
value: Box::new(value),
})
}
_ => self.node(ObjectEntry::Error("expected object entry".to_string())),
}
}
fn parse_function(&mut self) -> Result<Node<Expr>, ParserError> {
todo!()
fn parse_array(&mut self) -> Node<Expr> {
self.step();
let mut values = Vec::<Node<Expr>>::new();
if !self.done() && !self.current_is(TokenType::RBracket) {
if self.current_is(TokenType::DotDotDot) {
values.push(self.parse_spread());
} else {
values.push(self.parse_expr());
while !self.done() && self.current_is(TokenType::Comma) {
self.step();
if self.done() || self.current_is(TokenType::RBracket) {
break;
}
if self.current_is(TokenType::DotDotDot) {
values.push(self.parse_spread());
break;
}
values.push(self.parse_expr());
}
}
}
if self.done() || !self.current_is(TokenType::RBracket) {
return self.error("expected ']'");
}
self.step_and_node(Expr::Array(values))
}
fn parse_if(&mut self) -> Node<Expr> {
self.step();
let condition = self.parse_expr();
if self.done() || !self.current_is(TokenType::LBrace) {
return self.error("expected '{'");
}
let truthy = self.parse_block();
let mut falsy = None;
if !self.done() && self.current_is(TokenType::Else) {
self.step();
if self.done() || !self.current_is(TokenType::LBrace) {
return self.error("expected '{'");
}
falsy = Some(self.parse_block());
}
return self.node(Expr::If {
condition: Box::new(condition),
truthy: Box::new(truthy),
falsy: falsy.map(Box::new),
});
}
fn token_string(&self, token: &Token) -> String {
self.text[token.pos.index..token.pos.index + token.length].to_string()
}
fn step_and_ok_node<T>(&mut self, value: T) -> Result<Node<T>, ParserError> {
self.step();
self.ok_node(value)
}
fn ok_node<T>(&self, value: T) -> Result<Node<T>, ParserError> {
Ok(Node {
value,
pos: self.tokens.pos(),
})
}
fn step_and_node<T>(&mut self, value: T) -> Node<T> {
self.step();
self.node(value)
self.step_and(self.node(value))
}
fn node<T>(&self, value: T) -> Node<T> {
@ -400,11 +710,8 @@ where
value
}
fn error(&self, message: &str) -> Result<Node<Expr>, ParserError> {
Err(ParserError {
pos: self.tokens.pos(),
message: message.to_string(),
})
fn error(&self, message: &str) -> Node<Expr> {
self.node(Expr::Error(message.to_string()))
}
fn done(&self) -> bool {
@ -423,3 +730,48 @@ where
self.current_token = self.tokens.next();
}
}
fn parse_string_value(text: &str) -> Result<String, String> {
let mut input = text.chars().peekable();
let mut value = String::new();
input.next().ok_or_else(|| "invalid string".to_string())?;
while !matches!(input.peek(), Some('"')) {
value.push(unescape_char_value(&mut input)?)
}
Ok(value)
}
fn unescape_char_value(input: &mut Peekable<Chars>) -> Result<char, String> {
let step_and = |input2: &mut Peekable<Chars>, value: char| {
input2.next().ok_or("invalid string".to_string())?;
Ok(value)
};
if matches!(input.peek(), Some('\\')) {
input.next().ok_or("invalid string".to_string())?;
match input.peek() {
Some('t') => step_and(input, '\t'),
Some('r') => step_and(input, '\r'),
Some('n') => step_and(input, '\n'),
Some('0') => step_and(input, '\0'),
Some('x') => {
input.next().ok_or("invalid string".to_string())?;
let mut value = String::new();
for _ in 0..2 {
value.push(
input
.next()
.ok_or_else(|| "invalid escape sequence".to_string())?,
);
}
let int_value = value
.parse::<u8>()
.map_err(|error| format!("invalid char code: {}", error.to_string()))?;
char::from_u32(int_value.into()).ok_or_else(|| "invalid char code".to_string())
}
Some(_) => input.next().ok_or_else(|| "invalid string".to_string()),
None => Err("invalid escape sequence".to_string()),
}
} else {
input.next().ok_or("invalid string".to_string())
}
}

View File

@ -74,6 +74,9 @@ pub enum TokenType {
Colon,
Semicolon,
Ampersand,
DotDot,
DotDotDot,
EqualLessThan,
}
#[derive(Debug)]