Compare commits

...

2 commits

Author SHA1 Message Date
Raptorox
8d2582756d
refactor token names 2026-05-21 17:28:21 +02:00
Raptorox
a3d9723a36
move Expr out of parser 2026-05-21 17:26:14 +02:00
6 changed files with 65 additions and 63 deletions

View file

@ -1,4 +1,4 @@
use crate::parser::{BinaryOp, Expr, UnaryOp};
use crate::expr::{BinaryOp, Expr, UnaryOp};
pub struct Evaluator {
ast: Expr

45
src/expr.rs Normal file
View file

@ -0,0 +1,45 @@
#[derive(Debug, Clone)]
pub enum BinaryOp {
Add,
Sub,
Mul,
Div,
Mod
}
#[derive(Debug, Clone)]
pub enum UnaryOp {
Neg
}
pub fn prefix_bp(op: &UnaryOp) -> u8 {
match op {
UnaryOp::Neg => 5
}
}
pub fn infix_bp(op: &BinaryOp) -> (u8, u8) {
match op {
BinaryOp::Add | BinaryOp::Sub => (1, 2),
BinaryOp::Mul | BinaryOp::Div | BinaryOp::Mod => (3, 4)
}
}
#[derive(Debug, Clone)]
pub enum Expr {
Number(i64),
Ident(String),
EOL,
Binary {
op: BinaryOp,
left: Box<Expr>,
right: Box<Expr>
},
Unary {
op: UnaryOp,
right: Box<Expr>
}
}

View file

@ -54,11 +54,11 @@ impl Lexer {
Some(b'0' ..= b'9') => self.number(),
Some(b'a' ..= b'z' | b'A' ..= b'Z') => self.ident(),
Some(b'+') => {self.advance(); Some(Token::Add)},
Some(b'-') => {self.advance(); Some(Token::Sub)},
Some(b'*') => {self.advance(); Some(Token::Mul)},
Some(b'/') => {self.advance(); Some(Token::Div)},
Some(b'%') => {self.advance(); Some(Token::Mod)},
Some(b'+') => {self.advance(); Some(Token::Plus)},
Some(b'-') => {self.advance(); Some(Token::Minus)},
Some(b'*') => {self.advance(); Some(Token::Asterisk)},
Some(b'/') => {self.advance(); Some(Token::Slash)},
Some(b'%') => {self.advance(); Some(Token::Percent)},
Some(b'(') => {self.advance(); Some(Token::LParen)},
Some(b')') => {self.advance(); Some(Token::RParen)},

View file

@ -1,6 +1,7 @@
use std::{fs::File, io::Read};
mod token;
mod expr;
mod lexer;
use lexer::Lexer;
mod parser;
@ -30,7 +31,7 @@ fn main() -> std::io::Result<()> {
loop {
let parsed = parser.parse();
match parsed {
parser::Expr::EOL => break,
expr::Expr::EOL => break,
_ => {
println!("AST: {:?}", parsed);
let eval = Evaluator::new(parsed);

View file

@ -1,49 +1,5 @@
use crate::token::Token;
#[derive(Debug, Clone)]
pub enum BinaryOp {
Add,
Sub,
Mul,
Div,
Mod
}
#[derive(Debug, Clone)]
pub enum UnaryOp {
Neg
}
fn prefix_bp(op: &UnaryOp) -> u8 {
match op {
UnaryOp::Neg => 5
}
}
fn infix_bp(op: &BinaryOp) -> (u8, u8) {
match op {
BinaryOp::Add | BinaryOp::Sub => (1, 2),
BinaryOp::Mul | BinaryOp::Div | BinaryOp::Mod => (3, 4)
}
}
#[derive(Debug, Clone)]
pub enum Expr {
Number(i64),
Ident(String),
EOL,
Binary {
op: BinaryOp,
left: Box<Expr>,
right: Box<Expr>
},
Unary {
op: UnaryOp,
right: Box<Expr>
}
}
use crate::expr::{Expr, UnaryOp, BinaryOp, infix_bp, prefix_bp};
pub struct Parser {
tokens: Vec<Token>,
@ -90,7 +46,7 @@ impl Parser {
fn parse_prefix(&mut self) -> Expr {
match self.peek() {
Some(Token::Sub) => {
Some(Token::Minus) => {
self.advance();
let op = UnaryOp::Neg;
@ -108,11 +64,11 @@ impl Parser {
loop {
let op = match self.peek() {
Some(Token::Add) => BinaryOp::Add,
Some(Token::Sub) => BinaryOp::Sub,
Some(Token::Mul) => BinaryOp::Mul,
Some(Token::Div) => BinaryOp::Div,
Some(Token::Mod) => BinaryOp::Mod,
Some(Token::Plus) => BinaryOp::Add,
Some(Token::Minus) => BinaryOp::Sub,
Some(Token::Asterisk) => BinaryOp::Mul,
Some(Token::Slash) => BinaryOp::Div,
Some(Token::Percent) => BinaryOp::Mod,
_ => break
};

View file

@ -4,11 +4,11 @@ pub enum Token {
Ident(String),
// Operators
Add,
Sub,
Mul,
Div,
Mod,
Plus,
Minus,
Asterisk,
Slash,
Percent,
// Parentheses
LParen,