Compare commits

..

No commits in common. "2230c468e4b6fb75a5ec6c7777af3950dbdcaa48" and "7a43d22b7757374670d162891a40f4303841e63c" have entirely different histories.

5 changed files with 28 additions and 196 deletions

View File

@ -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>,
},
}

View File

@ -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)
}
}
}

View File

@ -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
}

View File

@ -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)

View File

@ -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]),
}
}