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"
|
name = "complexpr"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
|
||||||
"num-complex",
|
"num-complex",
|
||||||
"num-rational",
|
"num-rational",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
@ -178,12 +177,6 @@ version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ea37f355c05dde75b84bba2d767906ad522e97cd9e2eef2be7a4ab7fb442c06"
|
checksum = "1ea37f355c05dde75b84bba2d767906ad522e97cd9e2eef2be7a4ab7fb442c06"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lazy_static"
|
|
||||||
version = "1.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.132"
|
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"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lazy_static = "1.4.0"
|
|
||||||
num-complex = "0.4.2"
|
num-complex = "0.4.2"
|
||||||
num-rational = "0.4.1"
|
num-rational = "0.4.1"
|
||||||
num-traits = "0.2.15"
|
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 name = name.ty.clone().as_ident().unwrap();
|
||||||
let func = Func::Func {
|
let func = Func::Func {
|
||||||
name: Some(name.clone()),
|
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(),
|
env: env.clone(),
|
||||||
func: body.as_ref().clone()
|
func: Box::new(body.as_ref().clone())
|
||||||
};
|
};
|
||||||
env.borrow_mut().declare(name, Value::Func(func));
|
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 } => {
|
Expr::Fn { args, body } => {
|
||||||
let func = Func::Func {
|
let func = Func::Func {
|
||||||
name: None,
|
name: None,
|
||||||
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(),
|
env,
|
||||||
func: body.as_ref().clone()
|
func: Box::new(body.as_ref().clone())
|
||||||
};
|
};
|
||||||
Ok(Value::Func(func))
|
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()))
|
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> {
|
fn eval_pipeline_inner(l: Value, r: Value, op: &Token) -> Result<Value, RuntimeError> {
|
||||||
match op.ty {
|
match op.ty {
|
||||||
TokenType::PipePoint => r.call(vec![l]),
|
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> {
|
fn range_inner(_: Vec<Value>, data: Rc<RefCell<Vec<Value>>>, _: Rc<RefCell<Vec<CIterator>>>) -> Result<Value, RuntimeError> {
|
||||||
const ZERO: Value = Value::Int(0);
|
const ZERO: Value = Value::Int(0);
|
||||||
let mut d = data.borrow_mut();
|
let mut d = data.borrow_mut();
|
||||||
if d[2] >= ZERO && d[0] >= d[1] {
|
if d[2] >= ZERO && d[0] >= d[1]
|
||||||
Ok(Value::Nil)
|
|| d[2] <= ZERO && d[0] <= d[1] {
|
||||||
} else if d[2] <= ZERO && d[0] <= d[1] {
|
|
||||||
Ok(Value::Nil)
|
Ok(Value::Nil)
|
||||||
} else {
|
} else {
|
||||||
let res = d[0].clone();
|
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 Err("Both arguments to range must be integers".into())
|
||||||
};
|
};
|
||||||
return Ok(Value::Func(Func::BuiltinClosure {
|
Ok(Value::Func(Func::BuiltinClosure {
|
||||||
arg_count: 0,
|
arg_count: 0,
|
||||||
data: Rc::new(RefCell::new(vec![start.clone(), end.clone(), Value::Int(delta)])),
|
data: Rc::new(RefCell::new(vec![start.clone(), end.clone(), Value::Int(delta)])),
|
||||||
iter_data: Rc::new(RefCell::new(vec![])),
|
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> {
|
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> {
|
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> {
|
fn fn_take(args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||||||
return Ok(Value::Func(Func::BuiltinClosure {
|
Ok(Value::Func(Func::BuiltinClosure {
|
||||||
arg_count: 0,
|
arg_count: 0,
|
||||||
data: Rc::new(RefCell::new(vec![Value::Int(0), args[0].clone()])),
|
data: Rc::new(RefCell::new(vec![Value::Int(0), args[0].clone()])),
|
||||||
iter_data: Rc::new(RefCell::new(vec![args[1].iter()?])),
|
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 Rational = num_rational::Ratio<i64>;
|
||||||
pub type Complex = num_complex::Complex64;
|
pub type Complex = num_complex::Complex64;
|
||||||
|
pub type ClosureData = Rc<RefCell<Vec<Value>>>;
|
||||||
|
pub type ClosureIterData = Rc<RefCell<Vec<CIterator>>>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum Func {
|
pub enum Func {
|
||||||
|
@ -13,7 +15,7 @@ pub enum Func {
|
||||||
name: Option<Rc<str>>,
|
name: Option<Rc<str>>,
|
||||||
args: Vec<Rc<str>>,
|
args: Vec<Rc<str>>,
|
||||||
env: EnvRef,
|
env: EnvRef,
|
||||||
func: Stmt,
|
func: Box<Stmt>,
|
||||||
},
|
},
|
||||||
Builtin {
|
Builtin {
|
||||||
name: Rc<str>,
|
name: Rc<str>,
|
||||||
|
@ -21,9 +23,9 @@ pub enum Func {
|
||||||
arg_count: usize,
|
arg_count: usize,
|
||||||
},
|
},
|
||||||
BuiltinClosure {
|
BuiltinClosure {
|
||||||
func: fn(Vec<Value>, Rc<RefCell<Vec<Value>>>, Rc<RefCell<Vec<CIterator>>>) -> Result<Value, RuntimeError>,
|
func: fn(Vec<Value>, ClosureData, ClosureIterData) -> Result<Value, RuntimeError>,
|
||||||
data: Rc<RefCell<Vec<Value>>>,
|
data: ClosureData,
|
||||||
iter_data: Rc<RefCell<Vec<CIterator>>>,
|
iter_data: ClosureIterData,
|
||||||
arg_count: usize,
|
arg_count: usize,
|
||||||
},
|
},
|
||||||
Partial {
|
Partial {
|
||||||
|
@ -91,7 +93,7 @@ impl Func {
|
||||||
for (k, v) in args.iter().zip(arg_values.iter()) {
|
for (k, v) in args.iter().zip(arg_values.iter()) {
|
||||||
env.declare(k.clone(), v.clone());
|
env.declare(k.clone(), v.clone());
|
||||||
}
|
}
|
||||||
match func {
|
match func.as_ref() {
|
||||||
Stmt::Expr { expr } => eval_expr(expr, env.wrap()),
|
Stmt::Expr { expr } => eval_expr(expr, env.wrap()),
|
||||||
stmt => match eval_stmt(stmt, env.wrap()) {
|
stmt => match eval_stmt(stmt, env.wrap()) {
|
||||||
Ok(()) => Ok(Value::Nil),
|
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 {
|
match self {
|
||||||
Value::String(_) | Value::List(_)
|
Value::String(_) | Value::List(_)
|
||||||
=> Ok(CIterator::Indexable { value: self.clone(), idx: 0 }),
|
=> Ok(CIterator::Indexable { value: self.clone(), idx: 0 }),
|
||||||
|
@ -318,7 +320,7 @@ impl Value {
|
||||||
Value::String(s) => Ok(s.len()),
|
Value::String(s) => Ok(s.len()),
|
||||||
Value::List(l) => Ok(l.borrow().len()),
|
Value::List(l) => Ok(l.borrow().len()),
|
||||||
Value::Map(m) => Ok(m.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 {
|
impl PartialEq for Value {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
|
@ -377,7 +380,7 @@ impl PartialEq for Value {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
true
|
||||||
}
|
}
|
||||||
(Self::Func(f1), Self::Func(f2)) => match (f1, f2) {
|
(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)
|
"-inf".hash(state)
|
||||||
}
|
}
|
||||||
} else{
|
} 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 {
|
fn pow(self, other: &Value) -> Self::Output {
|
||||||
use Value::*;
|
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) {
|
match (self, other) {
|
||||||
(Int(a), Int(b)) => match b {
|
(Int(a), Int(b)) => match b {
|
||||||
x if *x < 0 => Err(format!("Cannot raise integer {:?} to negative integer exponent {:?}", a, 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