finished expression parsing, primary, multiplicitive, additive

This commit is contained in:
2026-07-09 12:15:09 -05:00
parent 7ee19e4ab7
commit 6fb41c7331
4 changed files with 63 additions and 22 deletions
+3
View File
@@ -0,0 +1,3 @@
{
"cSpell.words": ["Peekable"]
}
+1 -1
View File
@@ -1,6 +1,6 @@
use std::process; use std::process;
use crate::parser::{self, Parser}; use crate::parser::Parser;
pub fn repl() { pub fn repl() {
// Read-Eval-Print Loop // Read-Eval-Print Loop
+1 -1
View File
@@ -40,7 +40,7 @@ pub mod interpreter {
match token.as_str() { match token.as_str() {
"(" => Some(Token::OpenParen), "(" => Some(Token::OpenParen),
")" => Some(Token::CloseParen), ")" => Some(Token::CloseParen),
"+" | "-" | "*" | "/" => Some(Token::BinaryOperator(token)), "+" | "-" | "*" | "/" | "%" => Some(Token::BinaryOperator(token)),
"=" => Some(Token::Equals), "=" => Some(Token::Equals),
_ => { _ => {
+58 -20
View File
@@ -1,6 +1,6 @@
use std::process; use std::process;
use crate::ast::{BinaryExpr, Expr, Identifier, NodeType, NumericLiteral, Program, Stmt}; use crate::ast::{BinaryExpr, Identifier, NodeType, NumericLiteral, Program};
use crate::lexer::interpreter; use crate::lexer::interpreter;
pub struct Parser { pub struct Parser {
@@ -13,38 +13,56 @@ impl Parser {
tokens: interpreter::tokenize(source_code).into_iter().peekable(), tokens: interpreter::tokenize(source_code).into_iter().peekable(),
} }
} }
pub fn produce_ast(&mut self) -> Program { pub fn produce_ast(&mut self) -> Program {
let mut program = Program { body: vec![] }; let mut program = Program { body: vec![] };
while let Some(t) = self.tokens.next() { // Keep parsing statements until we hit EOF
program.body.push(self.parse_stmt(t)); while let Some(token) = self.tokens.peek() {
if matches!(token, interpreter::Token::EOF) {
break;
}
program.body.push(self.parse_stmt());
} }
program program
} }
fn parse_stmt(&mut self, t: interpreter::Token) -> NodeType { fn parse_stmt(&mut self) -> NodeType {
// skip to parse_expr self.parse_expr()
self.parse_expr(t)
} }
fn parse_expr(&mut self, t: interpreter::Token) -> NodeType { fn parse_expr(&mut self) -> NodeType {
self.parse_additive_expr(t) self.parse_additive_expr()
} }
fn parse_primary_expr(&mut self, t: interpreter::Token) -> NodeType { fn parse_primary_expr(&mut self) -> NodeType {
use crate::ast::NodeType; use crate::ast::NodeType;
use interpreter::Token; use interpreter::Token;
// Advance and grab the current token
let t = match self.tokens.next() {
Some(token) => token,
None => return NodeType::EOF,
};
match t { match t {
Token::Identifier(i) => NodeType::Identifier(Identifier { symbol: i.clone() }), Token::Identifier(i) => NodeType::Identifier(Identifier { symbol: i.clone() }),
Token::Number(n) => NodeType::NumericLiteral(NumericLiteral { Token::Number(n) => NodeType::NumericLiteral(NumericLiteral {
value: n.parse().expect( value: n.parse().expect(&format!("Failed to parse number: {}", n)),
format!("Failed to parse source code, {} was not a number", n).as_str(),
),
}), }),
Token::EOF => NodeType::EOF, Token::EOF => NodeType::EOF,
Token::OpenParen => {
let expr = self.parse_expr();
match self.tokens.next() {
Some(Token::CloseParen) => expr,
_ => {
eprintln!("Expected closing parenthesis...");
process::exit(1);
}
}
}
_ => { _ => {
eprintln!("Unexpected token: {}", t); eprintln!("Unexpected token: {}", t);
process::exit(1); process::exit(1);
@@ -52,8 +70,8 @@ impl Parser {
} }
} }
fn parse_additive_expr(&mut self, t: interpreter::Token) -> NodeType { fn parse_additive_expr(&mut self) -> NodeType {
let mut left = self.parse_primary_expr(t); let mut left = self.parse_multiplicative_expr();
while let Some(interpreter::Token::BinaryOperator(operator)) = self.tokens.peek() { while let Some(interpreter::Token::BinaryOperator(operator)) = self.tokens.peek() {
if operator != "+" && operator != "-" { if operator != "+" && operator != "-" {
@@ -61,12 +79,32 @@ impl Parser {
} }
let operator = operator.clone(); let operator = operator.clone();
self.tokens.next(); self.tokens.next(); // Consume the operator
let right = match self.tokens.next() { let right = self.parse_multiplicative_expr();
Some(token) => self.parse_primary_expr(token),
None => break, left = NodeType::BinaryExpr(BinaryExpr {
}; left: Box::new(left),
right: Box::new(right),
operator,
});
}
left
}
fn parse_multiplicative_expr(&mut self) -> NodeType {
let mut left = self.parse_primary_expr();
while let Some(interpreter::Token::BinaryOperator(operator)) = self.tokens.peek() {
if operator != "*" && operator != "/" && operator != "%" {
break;
}
let operator = operator.clone();
self.tokens.next(); // Consume the operator
let right = self.parse_primary_expr();
left = NodeType::BinaryExpr(BinaryExpr { left = NodeType::BinaryExpr(BinaryExpr {
left: Box::new(left), left: Box::new(left),