This commit is contained in:
Snorre 2025-02-24 15:26:49 +01:00
parent 9da6f7d302
commit 40fef756df
12 changed files with 70 additions and 59 deletions

View file

@ -2,17 +2,14 @@ use std::f64;
use std::io::{self, StdoutLock, Write, stdout}; use std::io::{self, StdoutLock, Write, stdout};
use std::rc::Rc; use std::rc::Rc;
use libopenbirch::environment::Environment; use libopenbirch::environment::{Environment, EnvironmentInternalSymbolKey};
use libopenbirch::node::call::Call; use libopenbirch::node::call::Call;
use libopenbirch::node::closure::Closure;
use libopenbirch::node::constant::Constant; use libopenbirch::node::constant::Constant;
use libopenbirch::node::empty::Empty; use libopenbirch::node::empty::Empty;
use libopenbirch::node::set::Set; use libopenbirch::node::set::Set;
use libopenbirch::node::string_node::StringNode; use libopenbirch::node::string_node::StringNode;
use libopenbirch::node::{Node, NodeEnum}; use libopenbirch::node::{Node, NodeEnum};
use libopenbirch::parser::{Lexer, LexerError, Parser, ParserError}; use libopenbirch::parser::{Lexer, LexerError, Parser, ParserError};
#[cfg(feature = "async")]
use termion::AsyncReader;
use termion::color; use termion::color;
use termion::event::Key; use termion::event::Key;
use termion::input::TermReadEventsAndRaw; use termion::input::TermReadEventsAndRaw;
@ -172,8 +169,8 @@ impl Input {
))); )));
} }
}, },
termion::event::Event::Mouse(mouse_event) => {} termion::event::Event::Mouse(_mouse_event) => {}
termion::event::Event::Unsupported(items) => {} termion::event::Event::Unsupported(_items) => {}
} }
} }
} }
@ -310,7 +307,7 @@ fn map(args: &Vec<Rc<NodeEnum>>, env: &mut Environment) -> Result<Rc<NodeEnum>,
Ok(Set::new(out)) Ok(Set::new(out))
} }
fn get(args: &Vec<Rc<NodeEnum>>, env: &mut Environment) -> Result<Rc<NodeEnum>, String> { fn get(args: &Vec<Rc<NodeEnum>>, _env: &mut Environment) -> Result<Rc<NodeEnum>, String> {
if args.len() != 2 { if args.len() != 2 {
Err(format!("Expected 2 argument but got {}", args.len()))? Err(format!("Expected 2 argument but got {}", args.len()))?
} }
@ -380,7 +377,7 @@ fn benchmark(args: &Vec<Rc<NodeEnum>>, env: &mut Environment) -> Result<Rc<NodeE
Ok(Set::new(vec![time_str, time_const, result])) Ok(Set::new(vec![time_str, time_const, result]))
} }
fn head(args: &Vec<Rc<NodeEnum>>, env: &mut Environment) -> Result<Rc<NodeEnum>, String> { fn head(args: &Vec<Rc<NodeEnum>>, _env: &mut Environment) -> Result<Rc<NodeEnum>, String> {
if args.len() != 1 { if args.len() != 1 {
Err(format!("Expected 1 argument but got {}", args.len()))? Err(format!("Expected 1 argument but got {}", args.len()))?
} }
@ -405,6 +402,33 @@ fn head(args: &Vec<Rc<NodeEnum>>, env: &mut Environment) -> Result<Rc<NodeEnum>,
Ok(Set::new(vec![head, Set::new(tail)])) Ok(Set::new(vec![head, Set::new(tail)]))
} }
fn diff(args: &Vec<Rc<NodeEnum>>, _env: &mut Environment) -> Result<Rc<NodeEnum>, String> {
if args.len() != 2 {
return Err(format!("Expected 1-2 argument but got {}", args.len()));
}
let expr = args.first().unwrap().clone();
let var = if let NodeEnum::Symbol(symbol) = args.get(1).unwrap().as_ref() {
symbol.get_value()
} else {
return Err(format!(
"Argument 2 is expected to be a Symbol but got a {}",
args.get(1).unwrap().type_str()
));
};
todo!()
}
fn diff_internally(
expr: Rc<NodeEnum>,
var: EnvironmentInternalSymbolKey,
env: &mut Environment,
) -> Result<Rc<NodeEnum>, String> {
todo!()
}
fn main() -> Result<(), io::Error> { fn main() -> Result<(), io::Error> {
let mut input = Input::new(); let mut input = Input::new();

View file

@ -1,8 +1,8 @@
use std::{collections::HashMap, rc::Rc, thread::current}; use std::{collections::HashMap, rc::Rc};
use crate::node::{ use crate::node::{
NodeEnum, NodeEnum,
function::{self, Function, FunctionType, NativeFunctionType}, function::{Function, FunctionType, NativeFunctionType},
}; };
pub type EnvironmentInternalSymbolKey = u16; pub type EnvironmentInternalSymbolKey = u16;

View file

@ -1,19 +1,6 @@
use std::io::{self, stdout, BufRead, Write};
pub mod node; pub mod node;
pub mod environment; pub mod environment;
pub mod parser; pub mod parser;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
fn main() {
loop {
print!("> ");
let _ = stdout().flush();
let mut line = String::new();
let stdin = io::stdin();
stdin.lock().read_line(&mut line).unwrap();
}
}

View file

@ -1,6 +1,5 @@
use std::rc::Rc; use std::rc::Rc;
use raylib::ffi::StopAutomationEventRecording;
use rug::Float; use rug::Float;
use super::{ use super::{

View file

@ -1,6 +1,6 @@
use std::rc::Rc; use std::rc::Rc;
use super::{Environment, Node, NodeEnum, Precedence, empty::Empty, symbol}; use super::{Environment, Node, NodeEnum, Precedence, empty::Empty};
#[derive(Debug, Clone, PartialEq, PartialOrd)] #[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct Assign { pub struct Assign {

View file

@ -5,7 +5,7 @@ use crate::{
node::{closure::Closure, function::FunctionType}, node::{closure::Closure, function::FunctionType},
}; };
use super::{Node, NodeEnum, Precedence, closure}; use super::{Node, NodeEnum, Precedence};
#[derive(Debug, Clone, PartialEq, PartialOrd)] #[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct Call { pub struct Call {

View file

@ -11,7 +11,7 @@ pub struct Closure {
} }
impl Node for Closure { impl Node for Closure {
fn evaluate(&self, env: &mut Environment) -> Result<Rc<NodeEnum>, String> { fn evaluate(&self, _env: &mut Environment) -> Result<Rc<NodeEnum>, String> {
Ok(Rc::new(self.clone().into())) Ok(Rc::new(self.clone().into()))
} }

View file

@ -8,7 +8,7 @@ pub struct Empty {
} }
impl PartialEq for Empty { impl PartialEq for Empty {
fn eq(&self, other: &Self) -> bool { fn eq(&self, _other: &Self) -> bool {
true true
} }
} }

View file

@ -2,7 +2,7 @@ use std::rc::Rc;
use crate::environment::Environment; use crate::environment::Environment;
use super::{closure::Closure, symbol::Symbol, Node, NodeEnum, Precedence}; use super::{symbol::Symbol, Node, NodeEnum, Precedence};
pub type NativeFunctionType = pub type NativeFunctionType =
fn(&Vec<Rc<NodeEnum>>, env: &mut Environment) -> Result<Rc<NodeEnum>, String>; fn(&Vec<Rc<NodeEnum>>, env: &mut Environment) -> Result<Rc<NodeEnum>, String>;
@ -19,7 +19,7 @@ pub struct Function {
} }
impl Node for Function { impl Node for Function {
fn evaluate(&self, env: &mut Environment) -> Result<Rc<NodeEnum>, String> { fn evaluate(&self, _env: &mut Environment) -> Result<Rc<NodeEnum>, String> {
Ok(Rc::new(self.clone().into())) Ok(Rc::new(self.clone().into()))
// Ok(Rc::new( // Ok(Rc::new(
@ -42,11 +42,11 @@ impl Node for Function {
match &self.function { match &self.function {
FunctionType::Native(name, _) => format!("(Native Function `{name}`)"), FunctionType::Native(name, _) => format!("(Native Function `{name}`)"),
FunctionType::UserFunction(body, args) => format!( FunctionType::UserFunction(body, args) => format!(
"({} -> {})", "([{}] -> {})",
args.iter() args.iter()
.map(|x| x.as_string(env)) .map(|x| x.as_string(env))
.reduce(|acc, e| format!("{acc}, {e}")) .reduce(|acc, e| format!("{acc}, {e}"))
.unwrap_or("()".to_owned()), .unwrap_or("[]".to_owned()),
body.as_string(env) body.as_string(env)
), ),
} }

View file

@ -190,6 +190,7 @@ impl Multiply {
} }
} }
#[allow(dead_code)]
fn move_constants_to_left( fn move_constants_to_left(
left: Rc<NodeEnum>, left: Rc<NodeEnum>,
right: Rc<NodeEnum>, right: Rc<NodeEnum>,
@ -199,7 +200,7 @@ impl Multiply {
(NodeEnum::Constant(_), NodeEnum::Multiply(_)) (NodeEnum::Constant(_), NodeEnum::Multiply(_))
| (NodeEnum::Symbol(_), NodeEnum::Symbol(_)) => Ok(Self::new_rc(left, right)), | (NodeEnum::Symbol(_), NodeEnum::Symbol(_)) => Ok(Self::new_rc(left, right)),
(NodeEnum::Multiply(m), NodeEnum::Constant(c)) => Ok(Self::new_rc( (NodeEnum::Multiply(m), NodeEnum::Constant(_c)) => Ok(Self::new_rc(
right.clone(), right.clone(),
Self::move_constants_to_left(m.left.clone(), m.right.clone())?, Self::move_constants_to_left(m.left.clone(), m.right.clone())?,
)), )),

View file

@ -60,7 +60,7 @@ impl Symbol {
} }
impl PartialOrd for Symbol { impl PartialOrd for Symbol {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { fn partial_cmp(&self, _other: &Self) -> Option<std::cmp::Ordering> {
None None
} }
} }

View file

@ -1,4 +1,4 @@
use std::{env, iter::Peekable, rc::Rc, slice::Iter, str::Chars, vec::IntoIter}; use std::{iter::Peekable, rc::Rc, str::Chars, vec::IntoIter};
use rug::Float; use rug::Float;
@ -10,7 +10,7 @@ use crate::{
assign::Assign, assign::Assign,
call::Call, call::Call,
comparison::{Greater, GreaterEquals, Less, LessEquals}, comparison::{Greater, GreaterEquals, Less, LessEquals},
constant::{Constant, ConstantValue}, constant::Constant,
divide::Divide, divide::Divide,
equals::Equals, equals::Equals,
exponent::Exponent, exponent::Exponent,
@ -308,7 +308,7 @@ pub struct Parser<'a> {
previous: Option<Token>, previous: Option<Token>,
} }
type Tokens<'a> = Peekable<Iter<'a, Token>>; // type Tokens<'a> = Peekable<Iter<'a, Token>>;
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
pub fn new(tokens: Vec<Token>, env: &'a mut Environment) -> Self { pub fn new(tokens: Vec<Token>, env: &'a mut Environment) -> Self {
@ -350,7 +350,7 @@ impl<'a> Parser<'a> {
/// Checks if the next token is `t`, if it is then consume it and return true. Otherwise does /// Checks if the next token is `t`, if it is then consume it and return true. Otherwise does
/// nothing and returns false. /// nothing and returns false.
#[inline] #[inline]
fn matchType<'b>(&'b mut self, t: TokenType) -> bool { fn match_type<'b>(&'b mut self, t: TokenType) -> bool {
if let Some(Token(_, token_type)) = self.tokens.peek() { if let Some(Token(_, token_type)) = self.tokens.peek() {
if *token_type == t { if *token_type == t {
self.consume(); self.consume();
@ -361,7 +361,7 @@ impl<'a> Parser<'a> {
} }
#[inline] #[inline]
fn matchOrErr(&mut self, t: TokenType) -> Result<bool, ParserError> { fn match_or_err(&mut self, t: TokenType) -> Result<bool, ParserError> {
let (i, tt) = if let Some(Token(i, tt)) = self.tokens.peek() { let (i, tt) = if let Some(Token(i, tt)) = self.tokens.peek() {
(*i, tt.clone()) (*i, tt.clone())
} else { } else {
@ -370,7 +370,7 @@ impl<'a> Parser<'a> {
))); )));
}; };
if self.matchType(t.clone()) { if self.match_type(t.clone()) {
Ok(true) Ok(true)
} else { } else {
Err(ParserError::UnexpectedToken( Err(ParserError::UnexpectedToken(
@ -388,7 +388,7 @@ impl<'a> Parser<'a> {
fn assignment(&mut self) -> Result<Rc<NodeEnum>, ParserError> { fn assignment(&mut self) -> Result<Rc<NodeEnum>, ParserError> {
let expr = self.equality()?; let expr = self.equality()?;
if self.matchType(TokenType::ColonEquals) { if self.match_type(TokenType::ColonEquals) {
return Ok(Rc::new(Assign::new(expr, self.equality()?).into())); return Ok(Rc::new(Assign::new(expr, self.equality()?).into()));
} }
@ -398,11 +398,11 @@ impl<'a> Parser<'a> {
fn equality(&mut self) -> Result<Rc<NodeEnum>, ParserError> { fn equality(&mut self) -> Result<Rc<NodeEnum>, ParserError> {
// TODO: Implement equality // TODO: Implement equality
let expr = self.comparison()?; let expr = self.comparison()?;
if self.matchType(TokenType::Equals) { if self.match_type(TokenType::Equals) {
let mut expressions = vec![]; let mut expressions = vec![];
loop { loop {
expressions.push(self.comparison()?); expressions.push(self.comparison()?);
if !self.matchType(TokenType::Equals) { if !self.match_type(TokenType::Equals) {
break; break;
} }
} }
@ -415,7 +415,7 @@ impl<'a> Parser<'a> {
// TODO: Implement comparison // TODO: Implement comparison
let expr = self.term()?; let expr = self.term()?;
let t = if let Some(Token(i, t)) = self.tokens.peek() { let t = if let Some(Token(_i, t)) = self.tokens.peek() {
t.clone() t.clone()
} else { } else {
return Ok(expr); return Ok(expr);
@ -432,7 +432,7 @@ impl<'a> Parser<'a> {
let mut expressions = vec![]; let mut expressions = vec![];
loop { loop {
expressions.push(self.term()?); expressions.push(self.term()?);
if !self.matchType(t.clone()) { if !self.match_type(t.clone()) {
break; break;
} }
} }
@ -451,7 +451,7 @@ impl<'a> Parser<'a> {
fn term(&mut self) -> Result<Rc<NodeEnum>, ParserError> { fn term(&mut self) -> Result<Rc<NodeEnum>, ParserError> {
let expr = self.factor()?; let expr = self.factor()?;
if self.matchType(TokenType::Plus) { if self.match_type(TokenType::Plus) {
Ok(Rc::new(Add::new(expr, self.comparison()?).into())) Ok(Rc::new(Add::new(expr, self.comparison()?).into()))
} else if let Some(Token(_, TokenType::Minus)) = self.tokens.peek() { } else if let Some(Token(_, TokenType::Minus)) = self.tokens.peek() {
self.consume(); self.consume();
@ -481,7 +481,7 @@ impl<'a> Parser<'a> {
fn exponent(&mut self) -> Result<Rc<NodeEnum>, ParserError> { fn exponent(&mut self) -> Result<Rc<NodeEnum>, ParserError> {
let expr = self.call(); let expr = self.call();
if self.matchType(TokenType::Hat) { if self.match_type(TokenType::Hat) {
let right = self.unary()?; let right = self.unary()?;
return Ok(Exponent::new(expr?, right)); return Ok(Exponent::new(expr?, right));
} }
@ -506,17 +506,17 @@ impl<'a> Parser<'a> {
self.consume(); self.consume();
// Calls can have 0 arguments, so check and return early // Calls can have 0 arguments, so check and return early
if self.matchType(TokenType::RParen) { if self.match_type(TokenType::RParen) {
expr = Call::new(expr, vec![]); expr = Call::new(expr, vec![]);
} else { } else {
// Parse expressions until a patching Right-Parenthesis is found // Parse expressions until a patching Right-Parenthesis is found
let mut parameters = vec![self.equality()?]; let mut parameters = vec![self.equality()?];
while self.matchType(TokenType::Comma) { while self.match_type(TokenType::Comma) {
parameters.push(self.equality()?); parameters.push(self.equality()?);
} }
if !self.matchType(TokenType::RParen) { if !self.match_type(TokenType::RParen) {
return Err(ParserError::UnexpectedToken( return Err(ParserError::UnexpectedToken(
i, i,
t.len(), t.len(),
@ -528,7 +528,7 @@ impl<'a> Parser<'a> {
// the user wants function assignment sugar // the user wants function assignment sugar
// //
// Ie f(x) := x*5 => f := x -> x*5 // Ie f(x) := x*5 => f := x -> x*5
if self.matchType(TokenType::ColonEquals) { if self.match_type(TokenType::ColonEquals) {
if let NodeEnum::Symbol(_) = expr.as_ref() { if let NodeEnum::Symbol(_) = expr.as_ref() {
} else { } else {
let Token(i, token) = self.previous.as_ref().unwrap(); let Token(i, token) = self.previous.as_ref().unwrap();
@ -590,7 +590,7 @@ impl<'a> Parser<'a> {
let expr = self.if_else()?; let expr = self.if_else()?;
if self.matchType(TokenType::LeftArrow) { if self.match_type(TokenType::LeftArrow) {
let right = self.equality()?; let right = self.equality()?;
match expr.clone().as_ref() { match expr.clone().as_ref() {
NodeEnum::Symbol(symbol) => { NodeEnum::Symbol(symbol) => {
@ -631,14 +631,14 @@ impl<'a> Parser<'a> {
} }
fn if_else(&mut self) -> Result<Rc<NodeEnum>, ParserError> { fn if_else(&mut self) -> Result<Rc<NodeEnum>, ParserError> {
if self.matchType(TokenType::If) { if self.match_type(TokenType::If) {
let condition = self.equality()?; let condition = self.equality()?;
let _ = self.matchOrErr(TokenType::Then)?; let _ = self.match_or_err(TokenType::Then)?;
let mut expressions = vec![]; let mut expressions = vec![];
while !(self.matchType(TokenType::End) || self.matchType(TokenType::Else)) { while !(self.match_type(TokenType::End) || self.match_type(TokenType::Else)) {
if self.is_at_end() { if self.is_at_end() {
return Err(ParserError::UnexpectedEndOfTokens( return Err(ParserError::UnexpectedEndOfTokens(
"Expected an else or end here".to_owned(), "Expected an else or end here".to_owned(),
@ -656,7 +656,7 @@ impl<'a> Parser<'a> {
ElseBranchEnum::ElseIf(self.if_else()?) ElseBranchEnum::ElseIf(self.if_else()?)
} else { } else {
let mut expressions = vec![]; let mut expressions = vec![];
while !self.matchType(TokenType::End) { while !self.match_type(TokenType::End) {
if self.is_at_end() { if self.is_at_end() {
return Err(ParserError::UnexpectedEndOfTokens( return Err(ParserError::UnexpectedEndOfTokens(
"Expected an end here".to_owned(), "Expected an end here".to_owned(),
@ -679,9 +679,9 @@ impl<'a> Parser<'a> {
} }
fn set(&mut self) -> Result<Rc<NodeEnum>, ParserError> { fn set(&mut self) -> Result<Rc<NodeEnum>, ParserError> {
if self.matchType(TokenType::LSquare) { if self.match_type(TokenType::LSquare) {
// Empty set // Empty set
if self.matchType(TokenType::RSquare) { if self.match_type(TokenType::RSquare) {
return Ok(Set::new(vec![])); return Ok(Set::new(vec![]));
} }
@ -752,7 +752,7 @@ impl<'a> Parser<'a> {
TokenType::LParen => { TokenType::LParen => {
let expr = self.expression()?; let expr = self.expression()?;
if !self.matchType(TokenType::RParen) { if !self.match_type(TokenType::RParen) {
if let Some(Token(i, t)) = self.tokens.peek() { if let Some(Token(i, t)) = self.tokens.peek() {
return Err(ParserError::UnexpectedToken( return Err(ParserError::UnexpectedToken(
*i, *i,