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
+1 -1
View File
@@ -1,6 +1,6 @@
use std::process;
use crate::parser::{self, Parser};
use crate::parser::Parser;
pub fn repl() {
// Read-Eval-Print Loop
+1 -1
View File
@@ -40,7 +40,7 @@ pub mod interpreter {
match token.as_str() {
"(" => Some(Token::OpenParen),
")" => Some(Token::CloseParen),
"+" | "-" | "*" | "/" => Some(Token::BinaryOperator(token)),
"+" | "-" | "*" | "/" | "%" => Some(Token::BinaryOperator(token)),
"=" => Some(Token::Equals),
_ => {
+58 -20
View File
@@ -1,6 +1,6 @@
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;
pub struct Parser {
@@ -13,38 +13,56 @@ impl Parser {
tokens: interpreter::tokenize(source_code).into_iter().peekable(),
}
}
pub fn produce_ast(&mut self) -> Program {
let mut program = Program { body: vec![] };
while let Some(t) = self.tokens.next() {
program.body.push(self.parse_stmt(t));
// Keep parsing statements until we hit EOF
while let Some(token) = self.tokens.peek() {
if matches!(token, interpreter::Token::EOF) {
break;
}
program.body.push(self.parse_stmt());
}
program
}
fn parse_stmt(&mut self, t: interpreter::Token) -> NodeType {
// skip to parse_expr
self.parse_expr(t)
fn parse_stmt(&mut self) -> NodeType {
self.parse_expr()
}
fn parse_expr(&mut self, t: interpreter::Token) -> NodeType {
self.parse_additive_expr(t)
fn parse_expr(&mut self) -> NodeType {
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 interpreter::Token;
// Advance and grab the current token
let t = match self.tokens.next() {
Some(token) => token,
None => return NodeType::EOF,
};
match t {
Token::Identifier(i) => NodeType::Identifier(Identifier { symbol: i.clone() }),
Token::Number(n) => NodeType::NumericLiteral(NumericLiteral {
value: n.parse().expect(
format!("Failed to parse source code, {} was not a number", n).as_str(),
),
value: n.parse().expect(&format!("Failed to parse number: {}", n)),
}),
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);
process::exit(1);
@@ -52,8 +70,8 @@ impl Parser {
}
}
fn parse_additive_expr(&mut self, t: interpreter::Token) -> NodeType {
let mut left = self.parse_primary_expr(t);
fn parse_additive_expr(&mut self) -> NodeType {
let mut left = self.parse_multiplicative_expr();
while let Some(interpreter::Token::BinaryOperator(operator)) = self.tokens.peek() {
if operator != "+" && operator != "-" {
@@ -61,12 +79,32 @@ impl Parser {
}
let operator = operator.clone();
self.tokens.next();
self.tokens.next(); // Consume the operator
let right = match self.tokens.next() {
Some(token) => self.parse_primary_expr(token),
None => break,
};
let right = self.parse_multiplicative_expr();
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: Box::new(left),