mirror of
https://github.com/TheM1Stery/izanami.git
synced 2025-04-20 08:51:12 +00:00
Compare commits
No commits in common. "2230c468e4b6fb75a5ec6c7777af3950dbdcaa48" and "7a43d22b7757374670d162891a40f4303841e63c" have entirely different histories.
2230c468e4
...
7a43d22b77
14
src/ast.rs
14
src/ast.rs
@ -29,11 +29,6 @@ pub enum Expr {
|
||||
name: Token,
|
||||
value: Box<Expr>,
|
||||
},
|
||||
Logical {
|
||||
left: Box<Expr>,
|
||||
op: Token,
|
||||
right: Box<Expr>,
|
||||
},
|
||||
}
|
||||
|
||||
pub enum Stmt {
|
||||
@ -43,11 +38,6 @@ pub enum Stmt {
|
||||
Expression {
|
||||
expression: Expr,
|
||||
},
|
||||
If {
|
||||
condition: Expr,
|
||||
then_branch: Box<Stmt>,
|
||||
else_branch: Option<Box<Stmt>>,
|
||||
},
|
||||
Print {
|
||||
expression: Expr,
|
||||
},
|
||||
@ -55,8 +45,4 @@ pub enum Stmt {
|
||||
name: Token,
|
||||
initializer: Option<Expr>,
|
||||
},
|
||||
While {
|
||||
condition: Expr,
|
||||
body: Box<Stmt>,
|
||||
},
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use crate::{
|
||||
ast::{Expr, Stmt},
|
||||
environment::{self, Environment},
|
||||
environment::Environment,
|
||||
token::{LiteralType, Token, TokenType},
|
||||
};
|
||||
|
||||
@ -52,22 +52,6 @@ fn execute(statement: &Stmt, environment: &Rc<RefCell<Environment>>) -> Result<(
|
||||
Stmt::Block { statements } => {
|
||||
execute_block(statements, environment)?;
|
||||
}
|
||||
Stmt::If {
|
||||
condition,
|
||||
then_branch,
|
||||
else_branch,
|
||||
} => {
|
||||
if is_truthy(&evaluate(condition, &mut environment.borrow_mut())?) {
|
||||
execute(then_branch, environment)?;
|
||||
} else if let Some(else_branch) = else_branch {
|
||||
execute(else_branch, environment)?;
|
||||
}
|
||||
}
|
||||
Stmt::While { condition, body } => {
|
||||
while is_truthy(&evaluate(condition, &mut environment.borrow_mut())?) {
|
||||
execute(body, environment)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -124,19 +108,6 @@ fn evaluate(expr: &Expr, environment: &mut Environment) -> Result<LiteralType, R
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
Expr::Logical { left, op, right } => {
|
||||
let left = evaluate(left, environment)?;
|
||||
|
||||
if op.t_type == TokenType::OR {
|
||||
if is_truthy(&left) {
|
||||
return Ok(left);
|
||||
}
|
||||
} else if !is_truthy(&left) {
|
||||
return Ok(left);
|
||||
}
|
||||
|
||||
evaluate(right, environment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
12
src/main.rs
12
src/main.rs
@ -1,16 +1,14 @@
|
||||
use std::{cmp::Ordering, env::args_os, ffi::OsString, process::ExitCode};
|
||||
use std::{env::args_os, ffi::OsString, process::ExitCode};
|
||||
|
||||
use izanami::{run_file, run_prompt, RunError};
|
||||
|
||||
fn main() -> ExitCode {
|
||||
let args: Vec<OsString> = args_os().collect();
|
||||
|
||||
match args.len().cmp(&2) {
|
||||
Ordering::Greater => {
|
||||
if args.len() > 2 {
|
||||
println!("usage: izanami [script]");
|
||||
return ExitCode::from(64);
|
||||
}
|
||||
Ordering::Equal => {
|
||||
} else if args.len() == 2 {
|
||||
let result = run_file(args[1].to_str().unwrap());
|
||||
|
||||
if let Err(RunError::FileReadError(e)) = result {
|
||||
@ -29,8 +27,7 @@ fn main() -> ExitCode {
|
||||
if let Err(RunError::ParseError) = result {
|
||||
return ExitCode::from(75);
|
||||
}
|
||||
}
|
||||
Ordering::Less => {
|
||||
} else {
|
||||
let result = run_prompt();
|
||||
|
||||
if let Err(res) = result {
|
||||
@ -38,7 +35,6 @@ fn main() -> ExitCode {
|
||||
return ExitCode::from(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExitCode::SUCCESS
|
||||
}
|
||||
|
122
src/parser.rs
122
src/parser.rs
@ -71,18 +71,9 @@ impl Parser<'_> {
|
||||
}
|
||||
|
||||
fn statement(&mut self) -> Result<Stmt, ParseError> {
|
||||
if self.match_token(&[TokenType::For]) {
|
||||
return self.for_statement();
|
||||
}
|
||||
if self.match_token(&[TokenType::If]) {
|
||||
return self.if_statement();
|
||||
}
|
||||
if self.match_token(&[TokenType::Print]) {
|
||||
return self.print_statement();
|
||||
}
|
||||
if self.match_token(&[TokenType::While]) {
|
||||
return self.while_statement();
|
||||
}
|
||||
|
||||
if self.match_token(&[TokenType::LeftBrace]) {
|
||||
return Ok(Stmt::Block {
|
||||
@ -105,86 +96,6 @@ impl Parser<'_> {
|
||||
Ok(statements)
|
||||
}
|
||||
|
||||
fn if_statement(&mut self) -> Result<Stmt, ParseError> {
|
||||
self.consume(TokenType::LeftParen, "Expect '(' after 'if'.")?;
|
||||
let condition = self.expression()?;
|
||||
self.consume(TokenType::RightParen, "Expect ')' after if condition.")?;
|
||||
|
||||
let then_branch = Box::new(self.statement()?);
|
||||
let else_branch = if self.match_token(&[TokenType::Else]) {
|
||||
Some(Box::new(self.statement()?))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(Stmt::If {
|
||||
condition,
|
||||
then_branch,
|
||||
else_branch,
|
||||
})
|
||||
}
|
||||
|
||||
fn while_statement(&mut self) -> Result<Stmt, ParseError> {
|
||||
self.consume(TokenType::LeftParen, "Expect '(' after 'while'.")?;
|
||||
let condition = self.expression()?;
|
||||
self.consume(TokenType::RightParen, "Expect ')' after while condition.")?;
|
||||
let body = Box::new(self.statement()?);
|
||||
|
||||
Ok(Stmt::While { condition, body })
|
||||
}
|
||||
|
||||
fn for_statement(&mut self) -> Result<Stmt, ParseError> {
|
||||
self.consume(TokenType::LeftParen, "Expect '(' after 'for'.")?;
|
||||
let initializer = if self.match_token(&[TokenType::Semicolon]) {
|
||||
None
|
||||
} else if self.match_token(&[TokenType::Var]) {
|
||||
Some(self.var_declaration()?)
|
||||
} else {
|
||||
Some(self.expression_statement()?)
|
||||
};
|
||||
|
||||
let condition = if !self.match_token(&[TokenType::Semicolon]) {
|
||||
Some(self.expression()?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
self.consume(TokenType::Semicolon, "Expect ';' after loop condition")?;
|
||||
|
||||
let increment = if !self.match_token(&[TokenType::RightParen]) {
|
||||
Some(self.expression()?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
self.consume(TokenType::RightParen, "Expect ')' after for clauses.")?;
|
||||
|
||||
let body = match increment {
|
||||
Some(inc) => Stmt::Block {
|
||||
statements: vec![self.statement()?, Stmt::Expression { expression: inc }],
|
||||
},
|
||||
None => self.statement()?,
|
||||
};
|
||||
|
||||
let condition = condition.unwrap_or(Expr::Literal {
|
||||
value: LiteralType::Bool(true),
|
||||
});
|
||||
|
||||
let body = Stmt::While {
|
||||
condition,
|
||||
body: Box::new(body),
|
||||
};
|
||||
|
||||
let body = match initializer {
|
||||
Some(init) => Stmt::Block {
|
||||
statements: vec![init, body],
|
||||
},
|
||||
None => body,
|
||||
};
|
||||
|
||||
Ok(body)
|
||||
}
|
||||
|
||||
fn print_statement(&mut self) -> Result<Stmt, ParseError> {
|
||||
let expression = self.expression()?;
|
||||
self.consume(TokenType::Semicolon, "Expect ';' after value.")?;
|
||||
@ -235,7 +146,7 @@ impl Parser<'_> {
|
||||
// ternary -> equality ("?" expression : ternary)? // expression grammar
|
||||
fn ternary(&mut self) -> Result<Expr, ParseError> {
|
||||
use TokenType::*;
|
||||
let expr = self.or()?;
|
||||
let expr = self.equality()?;
|
||||
|
||||
if self.match_token(&[Question]) {
|
||||
let second = self.expression()?;
|
||||
@ -251,37 +162,6 @@ impl Parser<'_> {
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
fn or(&mut self) -> Result<Expr, ParseError> {
|
||||
let mut expr = self.and()?;
|
||||
|
||||
while self.match_token(&[TokenType::OR]) {
|
||||
let op = self.previous().clone();
|
||||
let right = self.and()?;
|
||||
expr = Expr::Logical {
|
||||
left: Box::new(expr),
|
||||
op,
|
||||
right: Box::new(right),
|
||||
};
|
||||
}
|
||||
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
fn and(&mut self) -> Result<Expr, ParseError> {
|
||||
let mut expr = self.equality()?;
|
||||
while self.match_token(&[TokenType::And]) {
|
||||
let op = self.previous().clone();
|
||||
let right = self.equality()?;
|
||||
expr = Expr::Logical {
|
||||
left: Box::new(expr),
|
||||
op,
|
||||
right: Box::new(right),
|
||||
};
|
||||
}
|
||||
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
fn equality(&mut self) -> Result<Expr, ParseError> {
|
||||
use TokenType::*;
|
||||
self.left_association_binary(&[BangEqual, EqualEqual], Self::comparison)
|
||||
|
@ -18,7 +18,6 @@ pub fn pretty_print(expr: &Expr) -> String {
|
||||
} => parenthesize("?:", &[first, second, third]),
|
||||
Expr::Variable { name } => name.lexeme.clone(),
|
||||
Expr::Assign { name, value } => parenthesize(&name.lexeme, &[value]),
|
||||
Expr::Logical { left, op, right } => parenthesize(&op.lexeme, &[left, right]),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user