Small refactoring for parser

This commit is contained in:
Daniel M 2022-02-09 01:13:22 +01:00
parent 948d41fb45
commit 2312deec5b

View File

@ -15,20 +15,20 @@ pub fn parse<T: Iterator<Item = Token>, A: IntoIterator<IntoIter = T>>(tokens: A
struct Parser<T: Iterator<Item = Token>> { struct Parser<T: Iterator<Item = Token>> {
tokens: Peekable<T>, tokens: Peekable<T>,
stringstore: StringStore, string_store: StringStore,
varstack: Vec<Sid>, var_stack: Vec<Sid>,
} }
impl<T: Iterator<Item = Token>> Parser<T> { impl<T: Iterator<Item = Token>> Parser<T> {
/// Create a new parser to parse the given Token Stream /// Create a new parser to parse the given Token Stream
pub fn new<A: IntoIterator<IntoIter = T>>(tokens: A) -> Self { pub fn new<A: IntoIterator<IntoIter = T>>(tokens: A) -> Self {
let tokens = tokens.into_iter().peekable(); let tokens = tokens.into_iter().peekable();
let stringstore = StringStore::new(); let string_store = StringStore::new();
let varstack = Vec::new(); let var_stack = Vec::new();
Self { Self {
tokens, tokens,
stringstore, string_store,
varstack, var_stack,
} }
} }
@ -36,14 +36,14 @@ impl<T: Iterator<Item = Token>> Parser<T> {
let main = self.parse_scoped_block(); let main = self.parse_scoped_block();
Ast { Ast {
main, main,
stringstore: self.stringstore, stringstore: self.string_store,
} }
} }
/// Parse tokens into an abstract syntax tree. This will continuously parse statements until /// Parse tokens into an abstract syntax tree. This will continuously parse statements until
/// encountering end-of-file or a block end '}' . /// encountering end-of-file or a block end '}' .
fn parse_scoped_block(&mut self) -> BlockScope { fn parse_scoped_block(&mut self) -> BlockScope {
let framepointer = self.varstack.len(); let framepointer = self.var_stack.len();
let mut prog = Vec::new(); let mut prog = Vec::new();
loop { loop {
@ -56,7 +56,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
T!['{'] => { T!['{'] => {
self.next(); self.next();
prog.push(Statement::Block(self.parse_scoped_block())); prog.push(Statement::Block(self.parse_scoped_block()));
if !matches!(self.next(), T!['}']) { if self.next() != T!['}'] {
panic!("Error parsing block: Expectected closing braces '}}'"); panic!("Error parsing block: Expectected closing braces '}}'");
} }
} }
@ -66,7 +66,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
} }
} }
self.varstack.truncate(framepointer); self.var_stack.truncate(framepointer);
prog prog
} }
@ -82,7 +82,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
let expr = self.parse_expr(); let expr = self.parse_expr();
// After a statement, there must be a semicolon // After a statement, there must be a semicolon
if !matches!(self.next(), T![;]) { if self.next() != T![;] {
panic!("Expected semicolon after statement"); panic!("Expected semicolon after statement");
} }
@ -98,8 +98,8 @@ impl<T: Iterator<Item = Token>> Parser<T> {
match &mut expr { match &mut expr {
Expression::BinOp(BinOpType::Declare, lhs, _) => match lhs.as_mut() { Expression::BinOp(BinOpType::Declare, lhs, _) => match lhs.as_mut() {
Expression::Var(sid, sp) => { Expression::Var(sid, sp) => {
*sp = self.varstack.len(); *sp = self.var_stack.len();
self.varstack.push(*sid); self.var_stack.push(*sid);
} }
_ => panic!("Left hand side of declaration must be variable"), _ => panic!("Left hand side of declaration must be variable"),
}, },
@ -109,7 +109,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
let stmt = Statement::Expr(expr); let stmt = Statement::Expr(expr);
// After a statement, there must be a semicolon // After a statement, there must be a semicolon
if !matches!(self.next(), T![;]) { if self.next() != T![;] {
panic!("Expected semicolon after statement"); panic!("Expected semicolon after statement");
} }
@ -120,34 +120,34 @@ impl<T: Iterator<Item = Token>> Parser<T> {
/// Parse an if statement from the tokens /// Parse an if statement from the tokens
fn parse_if(&mut self) -> If { fn parse_if(&mut self) -> If {
if !matches!(self.next(), T![if]) { if self.next() != T![if] {
panic!("Error lexing if: Expected if token"); panic!("Error lexing if: Expected if token");
} }
let condition = self.parse_expr(); let condition = self.parse_expr();
if !matches!(self.next(), T!['{']) { if self.next() != T!['{'] {
panic!("Error lexing if: Expected '{{'") panic!("Error lexing if: Expected '{{'")
} }
let body_true = self.parse_scoped_block(); let body_true = self.parse_scoped_block();
if !matches!(self.next(), T!['}']) { if self.next() != T!['}'] {
panic!("Error lexing if: Expected '}}'") panic!("Error lexing if: Expected '}}'")
} }
let mut body_false = BlockScope::default(); let mut body_false = BlockScope::default();
if matches!(self.peek(), T![else]) { if self.peek() == &T![else] {
self.next(); self.next();
if !matches!(self.next(), T!['{']) { if self.next() != T!['{'] {
panic!("Error lexing if: Expected '{{'") panic!("Error lexing if: Expected '{{'")
} }
body_false = self.parse_scoped_block(); body_false = self.parse_scoped_block();
if !matches!(self.next(), T!['}']) { if self.next() != T!['}'] {
panic!("Error lexing if: Expected '}}'") panic!("Error lexing if: Expected '}}'")
} }
} }
@ -161,7 +161,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
/// Parse a loop statement from the tokens /// Parse a loop statement from the tokens
fn parse_loop(&mut self) -> Loop { fn parse_loop(&mut self) -> Loop {
if !matches!(self.next(), T![loop]) { if self.next() != T![loop] {
panic!("Error lexing loop: Expected loop token"); panic!("Error lexing loop: Expected loop token");
} }
@ -178,7 +178,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
T![;] => { T![;] => {
advancement = Some(self.parse_expr()); advancement = Some(self.parse_expr());
if !matches!(self.next(), T!['{']) { if self.next() != T!['{'] {
panic!("Error lexing loop: Expected '{{'") panic!("Error lexing loop: Expected '{{'")
} }
@ -188,7 +188,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
_ => panic!("Error lexing loop: Expected ';' or '{{'"), _ => panic!("Error lexing loop: Expected ';' or '{{'"),
} }
if !matches!(self.next(), T!['}']) { if self.next() != T!['}'] {
panic!("Error lexing loop: Expected '}}'") panic!("Error lexing loop: Expected '}}'")
} }
@ -240,33 +240,30 @@ impl<T: Iterator<Item = Token>> Parser<T> {
T![i64(val)] => Expression::I64(val), T![i64(val)] => Expression::I64(val),
// Literal String // Literal String
T![str(text)] => Expression::String(self.stringstore.intern_or_lookup(&text)), T![str(text)] => Expression::String(self.string_store.intern_or_lookup(&text)),
// Array literal. Square brackets containing the array size as expression
T!['['] => { T!['['] => {
let size = self.parse_expr(); let size = self.parse_expr();
if !matches!(self.next(), T![']']) { if self.next() != T![']'] {
panic!("Error parsing array literal: Expected closing bracket") panic!("Error parsing array literal: Expected closing bracket")
} }
Expression::ArrayLiteral(size.into()) Expression::ArrayLiteral(size.into())
} }
T![ident(name)] if matches!(self.peek(), T!['[']) => { // Array sccess, aka indexing. An ident followed by square brackets containing the
let sid = self.stringstore.intern_or_lookup(&name); // index as an expression
let stackpos = self T![ident(name)] if self.peek() == &T!['['] => {
.varstack let sid = self.string_store.intern_or_lookup(&name);
.iter() let stackpos = self.get_stackpos(sid);
.rev()
.position(|it| *it == sid)
.map(|it| self.varstack.len() - it - 1)
.unwrap_or(usize::MAX);
self.next(); self.next();
let index = self.parse_expr(); let index = self.parse_expr();
if !matches!(self.next(), T![']']) { if self.next() != T![']'] {
panic!("Error parsing array access: Expected closing bracket") panic!("Error parsing array access: Expected closing bracket")
} }
@ -274,14 +271,8 @@ impl<T: Iterator<Item = Token>> Parser<T> {
} }
T![ident(name)] => { T![ident(name)] => {
let sid = self.stringstore.intern_or_lookup(&name); let sid = self.string_store.intern_or_lookup(&name);
let stackpos = self let stackpos = self.get_stackpos(sid);
.varstack
.iter()
.rev()
.position(|it| *it == sid)
.map(|it| self.varstack.len() - it - 1)
.unwrap_or(usize::MAX);
Expression::Var(sid, stackpos) Expression::Var(sid, stackpos)
} }
@ -290,7 +281,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
let inner_expr = self.parse_expr(); let inner_expr = self.parse_expr();
// Verify that there is a closing parenthesis // Verify that there is a closing parenthesis
if !matches!(self.next(), T![')']) { if self.next() != T![')'] {
panic!("Error parsing primary expr: Exepected closing parenthesis ')'"); panic!("Error parsing primary expr: Exepected closing parenthesis ')'");
} }
@ -319,6 +310,15 @@ impl<T: Iterator<Item = Token>> Parser<T> {
} }
} }
fn get_stackpos(&self, varid: Sid) -> usize {
self.var_stack
.iter()
.rev()
.position(|it| *it == varid)
.map(|it| self.var_stack.len() - it - 1)
.unwrap_or(usize::MAX)
}
/// Get the next Token without removing it /// Get the next Token without removing it
fn peek(&mut self) -> &Token { fn peek(&mut self) -> &Token {
self.tokens.peek().unwrap_or(&T![EoF]) self.tokens.peek().unwrap_or(&T![EoF])