Compare commits
2 commits
99be8a16c7
...
8d2582756d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d2582756d | ||
|
|
a3d9723a36 |
6 changed files with 65 additions and 63 deletions
|
|
@ -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
45
src/expr.rs
Normal 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>
|
||||
}
|
||||
}
|
||||
|
||||
10
src/lexer.rs
10
src/lexer.rs
|
|
@ -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)},
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
|||
10
src/token.rs
10
src/token.rs
|
|
@ -4,11 +4,11 @@ pub enum Token {
|
|||
Ident(String),
|
||||
|
||||
// Operators
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
Mod,
|
||||
Plus,
|
||||
Minus,
|
||||
Asterisk,
|
||||
Slash,
|
||||
Percent,
|
||||
|
||||
// Parentheses
|
||||
LParen,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue