Compare commits

..

No commits in common. "8d2582756db36a69e67ac9d0e0ac6bb3caf1529e" and "99be8a16c753575148bd0b93a6fb19748825a6c4" have entirely different histories.

6 changed files with 63 additions and 65 deletions

View file

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

View file

@ -1,45 +0,0 @@
#[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'0' ..= b'9') => self.number(),
Some(b'a' ..= b'z' | b'A' ..= b'Z') => self.ident(), Some(b'a' ..= b'z' | b'A' ..= b'Z') => self.ident(),
Some(b'+') => {self.advance(); Some(Token::Plus)}, Some(b'+') => {self.advance(); Some(Token::Add)},
Some(b'-') => {self.advance(); Some(Token::Minus)}, Some(b'-') => {self.advance(); Some(Token::Sub)},
Some(b'*') => {self.advance(); Some(Token::Asterisk)}, Some(b'*') => {self.advance(); Some(Token::Mul)},
Some(b'/') => {self.advance(); Some(Token::Slash)}, Some(b'/') => {self.advance(); Some(Token::Div)},
Some(b'%') => {self.advance(); Some(Token::Percent)}, Some(b'%') => {self.advance(); Some(Token::Mod)},
Some(b'(') => {self.advance(); Some(Token::LParen)}, Some(b'(') => {self.advance(); Some(Token::LParen)},
Some(b')') => {self.advance(); Some(Token::RParen)}, Some(b')') => {self.advance(); Some(Token::RParen)},

View file

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

View file

@ -1,5 +1,49 @@
use crate::token::Token; use crate::token::Token;
use crate::expr::{Expr, UnaryOp, BinaryOp, infix_bp, prefix_bp};
#[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>
}
}
pub struct Parser { pub struct Parser {
tokens: Vec<Token>, tokens: Vec<Token>,
@ -46,7 +90,7 @@ impl Parser {
fn parse_prefix(&mut self) -> Expr { fn parse_prefix(&mut self) -> Expr {
match self.peek() { match self.peek() {
Some(Token::Minus) => { Some(Token::Sub) => {
self.advance(); self.advance();
let op = UnaryOp::Neg; let op = UnaryOp::Neg;
@ -64,11 +108,11 @@ impl Parser {
loop { loop {
let op = match self.peek() { let op = match self.peek() {
Some(Token::Plus) => BinaryOp::Add, Some(Token::Add) => BinaryOp::Add,
Some(Token::Minus) => BinaryOp::Sub, Some(Token::Sub) => BinaryOp::Sub,
Some(Token::Asterisk) => BinaryOp::Mul, Some(Token::Mul) => BinaryOp::Mul,
Some(Token::Slash) => BinaryOp::Div, Some(Token::Div) => BinaryOp::Div,
Some(Token::Percent) => BinaryOp::Mod, Some(Token::Mod) => BinaryOp::Mod,
_ => break _ => break
}; };

View file

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