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::rc::Rc;
use libopenbirch::environment::Environment;
use libopenbirch::environment::{Environment, EnvironmentInternalSymbolKey};
use libopenbirch::node::call::Call;
use libopenbirch::node::closure::Closure;
use libopenbirch::node::constant::Constant;
use libopenbirch::node::empty::Empty;
use libopenbirch::node::set::Set;
use libopenbirch::node::string_node::StringNode;
use libopenbirch::node::{Node, NodeEnum};
use libopenbirch::parser::{Lexer, LexerError, Parser, ParserError};
#[cfg(feature = "async")]
use termion::AsyncReader;
use termion::color;
use termion::event::Key;
use termion::input::TermReadEventsAndRaw;
@ -172,8 +169,8 @@ impl Input {
)));
}
},
termion::event::Event::Mouse(mouse_event) => {}
termion::event::Event::Unsupported(items) => {}
termion::event::Event::Mouse(_mouse_event) => {}
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))
}
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 {
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]))
}
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 {
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)]))
}
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> {
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::{
NodeEnum,
function::{self, Function, FunctionType, NativeFunctionType},
function::{Function, FunctionType, NativeFunctionType},
};
pub type EnvironmentInternalSymbolKey = u16;

View file

@ -1,19 +1,6 @@
use std::io::{self, stdout, BufRead, Write};
pub mod node;
pub mod environment;
pub mod parser;
#[cfg(test)]
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 raylib::ffi::StopAutomationEventRecording;
use rug::Float;
use super::{

View file

@ -1,6 +1,6 @@
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)]
pub struct Assign {

View file

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

View file

@ -11,7 +11,7 @@ pub struct 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()))
}

View file

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

View file

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

View file

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

View file

@ -60,7 +60,7 @@ impl 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
}
}

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;
@ -10,7 +10,7 @@ use crate::{
assign::Assign,
call::Call,
comparison::{Greater, GreaterEquals, Less, LessEquals},
constant::{Constant, ConstantValue},
constant::Constant,
divide::Divide,
equals::Equals,
exponent::Exponent,
@ -308,7 +308,7 @@ pub struct Parser<'a> {
previous: Option<Token>,
}
type Tokens<'a> = Peekable<Iter<'a, Token>>;
// type Tokens<'a> = Peekable<Iter<'a, Token>>;
impl<'a> Parser<'a> {
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
/// nothing and returns false.
#[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 *token_type == t {
self.consume();
@ -361,7 +361,7 @@ impl<'a> Parser<'a> {
}
#[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() {
(*i, tt.clone())
} else {
@ -370,7 +370,7 @@ impl<'a> Parser<'a> {
)));
};
if self.matchType(t.clone()) {
if self.match_type(t.clone()) {
Ok(true)
} else {
Err(ParserError::UnexpectedToken(
@ -388,7 +388,7 @@ impl<'a> Parser<'a> {
fn assignment(&mut self) -> Result<Rc<NodeEnum>, ParserError> {
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()));
}
@ -398,11 +398,11 @@ impl<'a> Parser<'a> {
fn equality(&mut self) -> Result<Rc<NodeEnum>, ParserError> {
// TODO: Implement equality
let expr = self.comparison()?;
if self.matchType(TokenType::Equals) {
if self.match_type(TokenType::Equals) {
let mut expressions = vec![];
loop {
expressions.push(self.comparison()?);
if !self.matchType(TokenType::Equals) {
if !self.match_type(TokenType::Equals) {
break;
}
}
@ -415,7 +415,7 @@ impl<'a> Parser<'a> {
// TODO: Implement comparison
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()
} else {
return Ok(expr);
@ -432,7 +432,7 @@ impl<'a> Parser<'a> {
let mut expressions = vec![];
loop {
expressions.push(self.term()?);
if !self.matchType(t.clone()) {
if !self.match_type(t.clone()) {
break;
}
}
@ -451,7 +451,7 @@ impl<'a> Parser<'a> {
fn term(&mut self) -> Result<Rc<NodeEnum>, ParserError> {
let expr = self.factor()?;
if self.matchType(TokenType::Plus) {
if self.match_type(TokenType::Plus) {
Ok(Rc::new(Add::new(expr, self.comparison()?).into()))
} else if let Some(Token(_, TokenType::Minus)) = self.tokens.peek() {
self.consume();
@ -481,7 +481,7 @@ impl<'a> Parser<'a> {
fn exponent(&mut self) -> Result<Rc<NodeEnum>, ParserError> {
let expr = self.call();
if self.matchType(TokenType::Hat) {
if self.match_type(TokenType::Hat) {
let right = self.unary()?;
return Ok(Exponent::new(expr?, right));
}
@ -506,17 +506,17 @@ impl<'a> Parser<'a> {
self.consume();
// 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![]);
} else {
// Parse expressions until a patching Right-Parenthesis is found
let mut parameters = vec![self.equality()?];
while self.matchType(TokenType::Comma) {
while self.match_type(TokenType::Comma) {
parameters.push(self.equality()?);
}
if !self.matchType(TokenType::RParen) {
if !self.match_type(TokenType::RParen) {
return Err(ParserError::UnexpectedToken(
i,
t.len(),
@ -528,7 +528,7 @@ impl<'a> Parser<'a> {
// the user wants function assignment sugar
//
// 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() {
} else {
let Token(i, token) = self.previous.as_ref().unwrap();
@ -590,7 +590,7 @@ impl<'a> Parser<'a> {
let expr = self.if_else()?;
if self.matchType(TokenType::LeftArrow) {
if self.match_type(TokenType::LeftArrow) {
let right = self.equality()?;
match expr.clone().as_ref() {
NodeEnum::Symbol(symbol) => {
@ -631,14 +631,14 @@ impl<'a> Parser<'a> {
}
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 _ = self.matchOrErr(TokenType::Then)?;
let _ = self.match_or_err(TokenType::Then)?;
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() {
return Err(ParserError::UnexpectedEndOfTokens(
"Expected an else or end here".to_owned(),
@ -656,7 +656,7 @@ impl<'a> Parser<'a> {
ElseBranchEnum::ElseIf(self.if_else()?)
} else {
let mut expressions = vec![];
while !self.matchType(TokenType::End) {
while !self.match_type(TokenType::End) {
if self.is_at_end() {
return Err(ParserError::UnexpectedEndOfTokens(
"Expected an end here".to_owned(),
@ -679,9 +679,9 @@ impl<'a> Parser<'a> {
}
fn set(&mut self) -> Result<Rc<NodeEnum>, ParserError> {
if self.matchType(TokenType::LSquare) {
if self.match_type(TokenType::LSquare) {
// Empty set
if self.matchType(TokenType::RSquare) {
if self.match_type(TokenType::RSquare) {
return Ok(Set::new(vec![]));
}
@ -752,7 +752,7 @@ impl<'a> Parser<'a> {
TokenType::LParen => {
let expr = self.expression()?;
if !self.matchType(TokenType::RParen) {
if !self.match_type(TokenType::RParen) {
if let Some(Token(i, t)) = self.tokens.peek() {
return Err(ParserError::UnexpectedToken(
*i,