currying dont work no more

This commit is contained in:
Snorre Ettrup Altschul 2025-02-21 21:38:15 +01:00
parent fa8aae88b4
commit ff5855af76
4 changed files with 53 additions and 11 deletions

View file

@ -1,3 +1,4 @@
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;
@ -5,7 +6,7 @@ use libopenbirch::environment::Environment;
use libopenbirch::node::constant::Constant; use libopenbirch::node::constant::Constant;
use libopenbirch::node::empty::Empty; use libopenbirch::node::empty::Empty;
use libopenbirch::node::{Node, NodeEnum}; use libopenbirch::node::{Node, NodeEnum};
use libopenbirch::parser::{Lexer, Parser, ParserError}; use libopenbirch::parser::{Lexer, LexerError, Parser, ParserError};
use malachite::base::num::basic::traits::Zero; use malachite::base::num::basic::traits::Zero;
use malachite::rational::Rational; use malachite::rational::Rational;
#[cfg(feature = "async")] #[cfg(feature = "async")]
@ -167,6 +168,10 @@ fn main() -> Result<(), io::Error> {
let mut env = Environment::new(); let mut env = Environment::new();
env.define_native_function("print", print); env.define_native_function("print", print);
env.define(
"pi",
Rc::new(Constant::new(f64::consts::PI.try_into().unwrap()).into()),
);
while let Some(source) = input.get()? { while let Some(source) = input.get()? {
input.disable_raw()?; input.disable_raw()?;
@ -176,7 +181,9 @@ fn main() -> Result<(), io::Error> {
if tokens_result.is_err() { if tokens_result.is_err() {
match tokens_result.err().unwrap() { match tokens_result.err().unwrap() {
libopenbirch::parser::LexerError::UnexpectedChar(i, exp) => print_err(i, 1, exp), LexerError::UnexpectedChar(i, exp) | LexerError::NumberParse(i, exp) => {
print_err(i, 1, exp)
}
} }
continue; continue;
} }

View file

@ -92,7 +92,8 @@ impl Environment {
self.stack_depth = 0; self.stack_depth = 0;
} }
pub fn define(&mut self, name: String, value: Rc<NodeEnum>) { pub fn define(&mut self, name: impl Into<String>, value: Rc<NodeEnum>) {
let name = name.into();
let id = if let Some(value) = self.str_to_id(&name) { let id = if let Some(value) = self.str_to_id(&name) {
*value *value
} else { } else {
@ -110,6 +111,7 @@ impl Environment {
} }
pub fn get(&self, key: &EnvironmentInternalSymbolKey) -> Option<&Rc<NodeEnum>> { pub fn get(&self, key: &EnvironmentInternalSymbolKey) -> Option<&Rc<NodeEnum>> {
eprintln!("Get {key}");
self.map.get(key) self.map.get(key)
} }
@ -123,12 +125,11 @@ impl Environment {
pub fn insert(&mut self, key: EnvironmentInternalSymbolKey, value: Rc<NodeEnum>) { pub fn insert(&mut self, key: EnvironmentInternalSymbolKey, value: Rc<NodeEnum>) {
if self.stack_depth != 0 { if self.stack_depth != 0 {
let mut shadow = false; let mut shadow = false;
if let Some(existing) = self.map.get(&key) { if self.map.get(&key).is_some() {
if !self.get_current_scope().contains(&key) { if !self.get_current_scope().contains(&key) {
// We need to shadow this variable // We need to shadow this variable
self.stack_shadows self.stack_shadows
.push((key, self.map.insert(key, value.clone()).unwrap())); .push((key, self.map.insert(key, value.clone()).unwrap()));
self.stack.push(key);
shadow = true; shadow = true;
} }
} }

View file

@ -1,5 +1,10 @@
use std::rc::Rc; use std::rc::Rc;
use malachite::{
base::{num::basic::traits::Zero, rounding_modes::RoundingMode},
rational::{Rational, conversion::primitive_float_from_rational::FloatConversionError},
};
use super::{Environment, Node, Precedence}; use super::{Environment, Node, Precedence};
pub type ConstantValue = malachite::rational::Rational; pub type ConstantValue = malachite::rational::Rational;
@ -21,7 +26,29 @@ impl Node for Constant {
} }
fn as_string(&self, _env: Option<&Environment>) -> String { fn as_string(&self, _env: Option<&Environment>) -> String {
self.value.to_string() if self.value == Rational::ZERO {
return "0".to_owned();
}
if self.value.approx_log() < 50. {
let x: Result<f64, FloatConversionError> = self.value.clone().try_into();
match x {
Ok(v) => {
return v.to_string();
}
Err(_) => {}
}
}
if let Some((man, exp, _)) = self
.value
.sci_mantissa_and_exponent_round_ref::<f64>(RoundingMode::Nearest)
{
format!("{}*2^{}", man, exp)
} else {
self.value.to_string()
}
} }
fn precedence(&self) -> Precedence { fn precedence(&self) -> Precedence {

View file

@ -101,6 +101,7 @@ pub struct Lexer<'a> {
#[derive(Debug)] #[derive(Debug)]
pub enum LexerError { pub enum LexerError {
UnexpectedChar(usize, String), UnexpectedChar(usize, String),
NumberParse(usize, String),
} }
impl<'a> Lexer<'a> { impl<'a> Lexer<'a> {
@ -137,7 +138,7 @@ impl<'a> Lexer<'a> {
loop { loop {
let d = self.source.peek(); let d = self.source.peek();
match d { match d {
Some('0'..='9') => { Some('0'..='9') | Some('e') | Some('E') => {
digit.push(*d.unwrap()); digit.push(*d.unwrap());
self.source.next(); self.source.next();
i += 1; i += 1;
@ -160,7 +161,15 @@ impl<'a> Lexer<'a> {
} }
} }
} }
let number = digit.parse::<ConstantValue>().unwrap(); let number =
if let Some(v) = ConstantValue::from_sci_string_simplest(digit.as_str()) {
v
} else {
return Err(LexerError::NumberParse(
i,
format!("Failed to convert {digit} to a number"),
));
};
tokens.push(Token(i, TokenType::Number(number))); tokens.push(Token(i, TokenType::Number(number)));
} }
@ -511,9 +520,7 @@ impl<'a> Parser<'a> {
} }
} }
return Ok(Function::new( return Ok(Function::new(FunctionType::UserFunction(right, symbols)));
FunctionType::UserFunction(right, symbols),
));
} }
_ => { _ => {
return Err(ParserError::UnexpectedNode( return Err(ParserError::UnexpectedNode(