refactoring, reorganization
This commit is contained in:
parent
c5380e383e
commit
285c13f03e
19 changed files with 27 additions and 64 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -71,7 +71,6 @@ dependencies = [
|
|||
name = "complexpr"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"num-complex",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
|
@ -178,12 +177,6 @@ version = "0.7.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ea37f355c05dde75b84bba2d767906ad522e97cd9e2eef2be7a4ab7fb442c06"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.132"
|
||||
|
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# complexpr
|
||||
|
||||
the language of the FUTURE
|
|
@ -4,7 +4,6 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
lazy_static = "1.4.0"
|
||||
num-complex = "0.4.2"
|
||||
num-rational = "0.4.1"
|
||||
num-traits = "0.2.15"
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
# complexpr
|
||||
|
||||
the pinnacle of human ingenuity
|
|
@ -105,9 +105,9 @@ pub fn eval_stmt(stmt: &Stmt, env: EnvRef) -> Result<(), Unwind> {
|
|||
let name = name.ty.clone().as_ident().unwrap();
|
||||
let func = Func::Func {
|
||||
name: Some(name.clone()),
|
||||
args: args.into_iter().map(|a| a.ty.clone().as_ident().unwrap()).collect(),
|
||||
args: args.iter().map(|a| a.ty.clone().as_ident().unwrap()).collect(),
|
||||
env: env.clone(),
|
||||
func: body.as_ref().clone()
|
||||
func: Box::new(body.as_ref().clone())
|
||||
};
|
||||
env.borrow_mut().declare(name, Value::Func(func));
|
||||
},
|
||||
|
@ -173,9 +173,9 @@ pub fn eval_expr(expr: &Expr, env: EnvRef) -> Result<Value, RuntimeError> {
|
|||
Expr::Fn { args, body } => {
|
||||
let func = Func::Func {
|
||||
name: None,
|
||||
args: args.into_iter().map(|a| a.ty.clone().as_ident().unwrap()).collect(),
|
||||
env: env.clone(),
|
||||
func: body.as_ref().clone()
|
||||
args: args.iter().map(|a| a.ty.clone().as_ident().unwrap()).collect(),
|
||||
env,
|
||||
func: Box::new(body.as_ref().clone())
|
||||
};
|
||||
Ok(Value::Func(func))
|
||||
},
|
||||
|
@ -353,6 +353,7 @@ pub fn eval_pipeline(lhs: &Expr, rhs: &Expr, op: &Token, env: EnvRef) -> Result<
|
|||
eval_pipeline_inner(l, r, op).map_err(|e| e.complete(op.pos.clone()))
|
||||
}
|
||||
|
||||
#[allow(clippy::needless_collect)] // collect is necesary to allow for rev() call
|
||||
fn eval_pipeline_inner(l: Value, r: Value, op: &Token) -> Result<Value, RuntimeError> {
|
||||
match op.ty {
|
||||
TokenType::PipePoint => r.call(vec![l]),
|
||||
|
|
|
@ -91,9 +91,8 @@ fn fn_chr(args: Vec<Value>) -> Result<Value, RuntimeError> {
|
|||
fn range_inner(_: Vec<Value>, data: Rc<RefCell<Vec<Value>>>, _: Rc<RefCell<Vec<CIterator>>>) -> Result<Value, RuntimeError> {
|
||||
const ZERO: Value = Value::Int(0);
|
||||
let mut d = data.borrow_mut();
|
||||
if d[2] >= ZERO && d[0] >= d[1] {
|
||||
Ok(Value::Nil)
|
||||
} else if d[2] <= ZERO && d[0] <= d[1] {
|
||||
if d[2] >= ZERO && d[0] >= d[1]
|
||||
|| d[2] <= ZERO && d[0] <= d[1] {
|
||||
Ok(Value::Nil)
|
||||
} else {
|
||||
let res = d[0].clone();
|
||||
|
@ -113,7 +112,7 @@ fn fn_range(args: Vec<Value>) -> Result<Value, RuntimeError> {
|
|||
},
|
||||
_ => return Err("Both arguments to range must be integers".into())
|
||||
};
|
||||
return Ok(Value::Func(Func::BuiltinClosure {
|
||||
Ok(Value::Func(Func::BuiltinClosure {
|
||||
arg_count: 0,
|
||||
data: Rc::new(RefCell::new(vec![start.clone(), end.clone(), Value::Int(delta)])),
|
||||
iter_data: Rc::new(RefCell::new(vec![])),
|
||||
|
@ -122,7 +121,7 @@ fn fn_range(args: Vec<Value>) -> Result<Value, RuntimeError> {
|
|||
}
|
||||
|
||||
fn fn_len(args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||||
Ok(Value::Int(args[0].len().map_err(|e| RuntimeError::new_incomplete(e))? as i64))
|
||||
Ok(Value::Int(args[0].len().map_err(RuntimeError::new_incomplete)? as i64))
|
||||
}
|
||||
|
||||
fn fn_has(args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||||
|
@ -179,7 +178,7 @@ fn take_inner(_: Vec<Value>, data: Rc<RefCell<Vec<Value>>>, iter_data: Rc<RefCel
|
|||
}
|
||||
|
||||
fn fn_take(args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||||
return Ok(Value::Func(Func::BuiltinClosure {
|
||||
Ok(Value::Func(Func::BuiltinClosure {
|
||||
arg_count: 0,
|
||||
data: Rc::new(RefCell::new(vec![Value::Int(0), args[0].clone()])),
|
||||
iter_data: Rc::new(RefCell::new(vec![args[1].iter()?])),
|
||||
|
|
|
@ -6,6 +6,8 @@ use crate::{RuntimeError, eval::{eval_stmt, Unwind, eval_expr}, expr::Stmt, env:
|
|||
|
||||
pub type Rational = num_rational::Ratio<i64>;
|
||||
pub type Complex = num_complex::Complex64;
|
||||
pub type ClosureData = Rc<RefCell<Vec<Value>>>;
|
||||
pub type ClosureIterData = Rc<RefCell<Vec<CIterator>>>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Func {
|
||||
|
@ -13,7 +15,7 @@ pub enum Func {
|
|||
name: Option<Rc<str>>,
|
||||
args: Vec<Rc<str>>,
|
||||
env: EnvRef,
|
||||
func: Stmt,
|
||||
func: Box<Stmt>,
|
||||
},
|
||||
Builtin {
|
||||
name: Rc<str>,
|
||||
|
@ -21,9 +23,9 @@ pub enum Func {
|
|||
arg_count: usize,
|
||||
},
|
||||
BuiltinClosure {
|
||||
func: fn(Vec<Value>, Rc<RefCell<Vec<Value>>>, Rc<RefCell<Vec<CIterator>>>) -> Result<Value, RuntimeError>,
|
||||
data: Rc<RefCell<Vec<Value>>>,
|
||||
iter_data: Rc<RefCell<Vec<CIterator>>>,
|
||||
func: fn(Vec<Value>, ClosureData, ClosureIterData) -> Result<Value, RuntimeError>,
|
||||
data: ClosureData,
|
||||
iter_data: ClosureIterData,
|
||||
arg_count: usize,
|
||||
},
|
||||
Partial {
|
||||
|
@ -91,7 +93,7 @@ impl Func {
|
|||
for (k, v) in args.iter().zip(arg_values.iter()) {
|
||||
env.declare(k.clone(), v.clone());
|
||||
}
|
||||
match func {
|
||||
match func.as_ref() {
|
||||
Stmt::Expr { expr } => eval_expr(expr, env.wrap()),
|
||||
stmt => match eval_stmt(stmt, env.wrap()) {
|
||||
Ok(()) => Ok(Value::Nil),
|
||||
|
@ -211,7 +213,7 @@ impl Value {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn iter<'a>(&'a self) -> Result<CIterator, String> {
|
||||
pub fn iter(&self) -> Result<CIterator, String> {
|
||||
match self {
|
||||
Value::String(_) | Value::List(_)
|
||||
=> Ok(CIterator::Indexable { value: self.clone(), idx: 0 }),
|
||||
|
@ -318,7 +320,7 @@ impl Value {
|
|||
Value::String(s) => Ok(s.len()),
|
||||
Value::List(l) => Ok(l.borrow().len()),
|
||||
Value::Map(m) => Ok(m.borrow().len()),
|
||||
v => Err(format!("{:?} has no length", v).into())
|
||||
v => Err(format!("{:?} has no length", v))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -338,6 +340,7 @@ impl Value {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::ptr_eq)] // provided fix does not work
|
||||
impl PartialEq for Value {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
|
@ -377,7 +380,7 @@ impl PartialEq for Value {
|
|||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
true
|
||||
}
|
||||
(Self::Func(f1), Self::Func(f2)) => match (f1, f2) {
|
||||
(
|
||||
|
@ -430,7 +433,7 @@ fn hash_f64<H: std::hash::Hasher>(f: f64, state: &mut H) {
|
|||
"-inf".hash(state)
|
||||
}
|
||||
} else{
|
||||
unsafe { std::mem::transmute::<f64,u64>(f).hash(state) }
|
||||
f.to_bits().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -579,7 +582,7 @@ impl Pow<&Value> for &Value {
|
|||
|
||||
fn pow(self, other: &Value) -> Self::Output {
|
||||
use Value::*;
|
||||
const RATIO_CAST_FAIL: &'static str = "Failed to convert rational to float";
|
||||
const RATIO_CAST_FAIL: &str = "Failed to convert rational to float";
|
||||
match (self, other) {
|
||||
(Int(a), Int(b)) => match b {
|
||||
x if *x < 0 => Err(format!("Cannot raise integer {:?} to negative integer exponent {:?}", a, b)),
|
||||
|
|
32
idea.cxpr
32
idea.cxpr
|
@ -1,32 +0,0 @@
|
|||
let square = x -> x^2;
|
||||
let also_square(x) = x^2;
|
||||
|
||||
let primes = range(100) |: filter(is_prime);
|
||||
let prime_squares = range(100) |: map(square);
|
||||
let also_prime_squares = range(100) |? is_prime |: square;
|
||||
|
||||
#
|
||||
let primes_and_prime_squares = primes |& prime_squares;
|
||||
|
||||
if 49 <~ data {
|
||||
println("49 is the square of a prime");
|
||||
} else {
|
||||
println("49 is not the square of a prime");
|
||||
}
|
||||
|
||||
for p : primes {
|
||||
println(p);
|
||||
}
|
||||
|
||||
# LET IDENT(square) EQ IDENT(x) ARROW IDENT(x) CARET INT(2) SEMICOLON
|
||||
#
|
||||
# LET IDENT(data) EQ IDENT(range) LPAREN INT(100) RPAREN PIPECOLON IDENT(filter) LPAREN IDENT(is_prime) RPAREN PIPECOLON IDENT(map) LPAREN IDENT(square) RPAREN SEMICOLON
|
||||
# LET IDENT(also_data) EQ IDENT(range) LPAREN INT(100) RPAREN PIPEQUESTION IDENT(is_prime) PIPEPOINT IDENT(square) SEMICOLON
|
||||
|
||||
# D = x:(fold(map(factors(x), n:(to_int(fold(factors(x),mul)/n))), add))
|
||||
|
||||
let D = x -> {
|
||||
let facts = factors(x);
|
||||
let product = facts |> foldl(1, mul);
|
||||
return facts |: (n -> product / n) |> foldl(0, add);
|
||||
}
|
Loading…
Reference in a new issue