fix and refactor
This commit is contained in:
parent
bc3fb597d5
commit
296ff666cb
15 changed files with 138 additions and 114 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -772,6 +772,7 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"num-complex",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
[workspace]
|
||||
members = ["talc-lang", "talc-bin", "talc-std", "talc-macros"]
|
||||
resolver = "2"
|
||||
|
||||
[profile.release-lto]
|
||||
inherits = "release"
|
||||
lto = "fat"
|
||||
|
|
|
@ -3,6 +3,10 @@ name = "talc-bin"
|
|||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
name = "talc"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
talc-lang = { path = "../talc-lang" }
|
||||
talc-std = { path = "../talc-std" }
|
||||
|
|
|
@ -106,7 +106,7 @@ impl Highlighter for TalcHelper {
|
|||
}
|
||||
|
||||
fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
|
||||
Cow::Owned(format!("\x1b[37m{}\x1b[0m", hint))
|
||||
Cow::Owned(format!("\x1b[37m{hint}\x1b[0m"))
|
||||
}
|
||||
|
||||
fn highlight_char(&self, line: &str, _: usize, forced: bool) -> bool {
|
||||
|
|
|
@ -19,6 +19,10 @@ struct Args {
|
|||
#[arg(short, long)]
|
||||
disasm: bool,
|
||||
|
||||
/// show disassembled bytecode
|
||||
#[arg(short='H', long)]
|
||||
histfile: Option<PathBuf>,
|
||||
|
||||
/// enable or disable color
|
||||
#[arg(short, long, default_value="auto")]
|
||||
color: ColorChoice,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{cell::RefCell, io::IsTerminal, process::ExitCode, rc::Rc};
|
||||
|
||||
use clap::ColorChoice;
|
||||
use rustyline::{error::ReadlineError, history::MemHistory, ColorMode, Config, Editor};
|
||||
use rustyline::{error::ReadlineError, history::{FileHistory, History}, ColorMode, Config, Editor};
|
||||
use talc_lang::{compiler::compile_repl, symbol::Symbol, value::{function::disasm_recursive, Value}, Vm};
|
||||
|
||||
use crate::{helper::TalcHelper, Args};
|
||||
|
@ -39,21 +39,30 @@ fn get_colmode(args: &Args) -> ColorMode {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn init_rustyline(args: &Args) -> Result<Editor<TalcHelper, MemHistory>, ExitCode> {
|
||||
pub fn init_rustyline(args: &Args) -> Result<Editor<TalcHelper, FileHistory>, ExitCode> {
|
||||
let config = Config::builder()
|
||||
.auto_add_history(true)
|
||||
.color_mode(get_colmode(args))
|
||||
.check_cursor_position(true)
|
||||
.completion_type(rustyline::CompletionType::List)
|
||||
.max_history_size(4096).unwrap()
|
||||
.build();
|
||||
match rustyline::Editor::with_history(config, MemHistory::default()) {
|
||||
let mut hist = FileHistory::default();
|
||||
if let Some(f) = &args.histfile {
|
||||
if hist.load(f).is_err() {
|
||||
eprintln!("Warn: failed to load history");
|
||||
} else if hist.save(f).is_err() {
|
||||
eprintln!("Warn: failed to save history");
|
||||
}
|
||||
}
|
||||
match rustyline::Editor::with_history(config, hist) {
|
||||
Ok(rl) => Ok(rl),
|
||||
Err(ReadlineError::Io(e)) => {
|
||||
eprintln!("Error: {e}");
|
||||
eprintln!("Error creating repl: {e}");
|
||||
Err(ExitCode::FAILURE)
|
||||
},
|
||||
Err(ReadlineError::Errno(e)) => {
|
||||
eprintln!("Error: {e}");
|
||||
eprintln!("Error creating repl: {e}");
|
||||
Err(ExitCode::FAILURE)
|
||||
},
|
||||
Err(_) => Err(ExitCode::SUCCESS)
|
||||
|
@ -75,7 +84,7 @@ pub fn repl(args: &Args) -> ExitCode {
|
|||
interrupt.fetch_or(true, std::sync::atomic::Ordering::Relaxed);
|
||||
});
|
||||
if let Err(e) = ctrlc_res {
|
||||
eprintln!("Warn: couldn't set ctrl+c handler: {e}")
|
||||
eprintln!("Warn: couldn't set ctrl+c handler: {e}");
|
||||
}
|
||||
|
||||
let prev1_sym = Symbol::get("_");
|
||||
|
@ -98,6 +107,9 @@ pub fn repl(args: &Args) -> ExitCode {
|
|||
rl.set_helper(Some(TalcHelper::new(vm.clone())));
|
||||
|
||||
loop {
|
||||
if let Some(f) = &args.histfile {
|
||||
let _ = rl.save_history(f);
|
||||
}
|
||||
let line = rl.readline(">> ");
|
||||
let line = match line {
|
||||
Ok(line) => line,
|
||||
|
|
|
@ -7,6 +7,7 @@ edition = "2021"
|
|||
lalrpop-util = { version = "0.20", features = ["lexer", "unicode"] }
|
||||
num-complex = "0.4"
|
||||
num-rational = { version = "0.4", default-features = false, features = [] }
|
||||
num-traits = "*"
|
||||
thiserror = "1.0"
|
||||
lazy_static = "1.4"
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ static TABLE: OnceLock<Mutex<SymbolTable>> = OnceLock::new();
|
|||
const MAX_SYMBOL: usize = 0xff_ffff;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||
#[repr(transparent)]
|
||||
pub struct Symbol(u32);
|
||||
|
||||
fn get_table() -> &'static Mutex<SymbolTable> {
|
||||
|
|
|
@ -34,7 +34,7 @@ impl Value {
|
|||
let col = col.clone();
|
||||
let func = move |vm: &mut Vm, _| {
|
||||
match vmcalliter!(vm; ii.clone())? {
|
||||
Some(i) => Ok(col.index(i)?.to_cell()),
|
||||
Some(i) => col.index(i),
|
||||
None => Ok(Value::from(*SYM_END_ITERATION)),
|
||||
}
|
||||
};
|
||||
|
@ -82,7 +82,7 @@ impl Value {
|
|||
}
|
||||
let end = tm.split_off(r.stop as usize);
|
||||
tm.truncate(r.start as usize);
|
||||
tm.extend(vals.into_iter().chain(end))
|
||||
tm.extend(vals.into_iter().chain(end));
|
||||
},
|
||||
RangeType::Closed => {
|
||||
if r.start < 0 || r.start > tm.len() as i64 {
|
||||
|
@ -95,7 +95,7 @@ impl Value {
|
|||
}
|
||||
let end = tm.split_off(r.stop as usize + 1);
|
||||
tm.truncate(r.start as usize);
|
||||
tm.extend(vals.into_iter().chain(end))
|
||||
tm.extend(vals.into_iter().chain(end));
|
||||
},
|
||||
RangeType::Endless => {
|
||||
if r.start < 0 || r.start > tm.len() as i64 {
|
||||
|
@ -103,7 +103,7 @@ impl Value {
|
|||
"index {} out of bounds for list of length {}", r.stop, tm.len())
|
||||
}
|
||||
tm.truncate(r.start as usize);
|
||||
tm.extend(vals)
|
||||
tm.extend(vals);
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -7,6 +7,16 @@ use crate::{exception::{throw, Result}, symbol::{SYM_END_ITERATION, SYM_TYPE_ERR
|
|||
|
||||
use super::{function::{FuncAttrs, NativeFunc}, range::Range, HashValue, Value};
|
||||
|
||||
pub trait RatioExt {
|
||||
fn to_f64(&self) -> f64;
|
||||
}
|
||||
|
||||
impl RatioExt for Rational64 {
|
||||
fn to_f64(&self) -> f64 {
|
||||
num_traits::ToPrimitive::to_f64(self).unwrap_or(f64::NAN)
|
||||
}
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub fn truthy(&self) -> bool {
|
||||
match self {
|
||||
|
@ -27,11 +37,6 @@ impl Value {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
fn ratio_to_f64(r: Rational64) -> f64 {
|
||||
*r.numer() as f64 / *r.denom() as f64
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
pub fn promote(a: Value, b: Value) -> (Value, Value) {
|
||||
use Value as V;
|
||||
|
@ -39,14 +44,14 @@ pub fn promote(a: Value, b: Value) -> (Value, Value) {
|
|||
(V::Int(x), V::Ratio(..)) => (V::Ratio((*x).into()), b),
|
||||
(V::Int(x), V::Float(..)) => (V::Float(*x as f64), b),
|
||||
(V::Int(x), V::Complex(..)) => (V::Complex((*x as f64).into()), b),
|
||||
(V::Ratio(x), V::Float(..)) => (V::Float(ratio_to_f64(*x)), b),
|
||||
(V::Ratio(x), V::Complex(..)) => (V::Complex(ratio_to_f64(*x).into()), b),
|
||||
(V::Float(x), V::Complex(..)) => (V::Complex((*x).into()), b),
|
||||
(V::Ratio(x), V::Float(..)) => (V::Float(x.to_f64()), b),
|
||||
(V::Ratio(x), V::Complex(..)) => (V::Complex(x.to_f64().into()), b),
|
||||
(V::Float(x), V::Complex(..)) => (V::Complex(x.into()), b),
|
||||
(V::Ratio(..), V::Int(y)) => (a, V::Ratio((*y).into())),
|
||||
(V::Float(..), V::Int(y)) => (a, V::Float(*y as f64)),
|
||||
(V::Complex(..), V::Int(y)) => (a, V::Complex((*y as f64).into())),
|
||||
(V::Float(..), V::Ratio(y)) => (a, V::Float(ratio_to_f64(*y))),
|
||||
(V::Complex(..), V::Ratio(y)) => (a, V::Complex(ratio_to_f64(*y).into())),
|
||||
(V::Float(..), V::Ratio(y)) => (a, V::Float(y.to_f64())),
|
||||
(V::Complex(..), V::Ratio(y)) => (a, V::Complex(y.to_f64().into())),
|
||||
(V::Complex(..), V::Float(y)) => (a, V::Complex((*y).into())),
|
||||
_ => (a, b),
|
||||
}
|
||||
|
@ -183,7 +188,7 @@ impl Value {
|
|||
(V::Float(x), V::Float(y))
|
||||
=> Ok(V::Float(x.powf(y))),
|
||||
(V::Ratio(x), V::Ratio(y))
|
||||
=> Ok(V::Float(ratio_to_f64(x).powf(ratio_to_f64(y)))),
|
||||
=> Ok(V::Float(x.to_f64().powf(y.to_f64()))),
|
||||
(V::Complex(x), V::Complex(y))
|
||||
=> Ok(V::Complex(x.powc(y))),
|
||||
(l, r) => throw!(*SYM_TYPE_ERROR, "cannot exponentiate {l:#} and {r:#}")
|
||||
|
@ -209,10 +214,10 @@ impl PartialEq for Value {
|
|||
(V::Float(a), V::Int(b)) => *a == *b as f64,
|
||||
(V::Int(a), V::Complex(b)) => Complex64::from(*a as f64) == *b,
|
||||
(V::Complex(a), V::Int(b)) => *a == Complex64::from(*b as f64),
|
||||
(V::Ratio(a), V::Float(b)) => ratio_to_f64(*a) == *b,
|
||||
(V::Float(a), V::Ratio(b)) => *a == ratio_to_f64(*b),
|
||||
(V::Ratio(a), V::Complex(b)) => Complex64::from(ratio_to_f64(*a)) == *b,
|
||||
(V::Complex(a), V::Ratio(b)) => *a == Complex64::from(ratio_to_f64(*b)),
|
||||
(V::Ratio(a), V::Float(b)) => a.to_f64() == *b,
|
||||
(V::Float(a), V::Ratio(b)) => *a == b.to_f64(),
|
||||
(V::Ratio(a), V::Complex(b)) => Complex64::from(a.to_f64()) == *b,
|
||||
(V::Complex(a), V::Ratio(b)) => *a == Complex64::from(b.to_f64()),
|
||||
(V::Float(a), V::Complex(b)) => Complex64::from(*a) == *b,
|
||||
(V::Complex(a), V::Float(b)) => *a == Complex64::from(*b),
|
||||
(V::String(a), V::String(b)) => *a == *b,
|
||||
|
@ -246,8 +251,8 @@ impl PartialOrd for Value {
|
|||
(V::Ratio(a), V::Int(b)) => a.partial_cmp(&Rational64::from(*b)),
|
||||
(V::Int(a), V::Float(b)) => (*a as f64).partial_cmp(b),
|
||||
(V::Float(a), V::Int(b)) => a.partial_cmp(&(*b as f64)),
|
||||
(V::Ratio(a), V::Float(b)) => ratio_to_f64(*a).partial_cmp(b),
|
||||
(V::Float(a), V::Ratio(b)) => a.partial_cmp(&ratio_to_f64(*b)),
|
||||
(V::Ratio(a), V::Float(b)) => a.to_f64().partial_cmp(b),
|
||||
(V::Float(a), V::Ratio(b)) => a.partial_cmp(&b.to_f64()),
|
||||
(V::String(a), V::String(b)) => a.partial_cmp(b),
|
||||
(V::List(a), V::List(b)) => a.borrow().partial_cmp(&*b.borrow()),
|
||||
(V::Symbol(a), V::Symbol(b)) => a.partial_cmp(b),
|
||||
|
|
|
@ -296,7 +296,7 @@ impl Vm {
|
|||
// [a0,a1...an] -.> [[a0,a1...an]]
|
||||
I::NewList(n) => {
|
||||
let list = self.pop_n(n as usize);
|
||||
self.push(list.into())
|
||||
self.push(list.into());
|
||||
},
|
||||
// [l,a0,a1...an] -.> [l ++ [a0,a1...an]]
|
||||
I::GrowList(n) => {
|
||||
|
@ -314,7 +314,7 @@ impl Vm {
|
|||
let k = self.pop();
|
||||
table.insert(k.try_into()?, v);
|
||||
}
|
||||
self.push(table.into())
|
||||
self.push(table.into());
|
||||
},
|
||||
// [t,k0,v0...kn,vn] -> [t ++ {k0=v0...kn=vn}]
|
||||
I::GrowTable(n) => {
|
||||
|
@ -348,17 +348,17 @@ impl Vm {
|
|||
// ip = n
|
||||
I::Jump(n) => {
|
||||
self.check_interrupt()?;
|
||||
frame.ip = usize::from(n)
|
||||
frame.ip = usize::from(n);
|
||||
},
|
||||
// [v] ->, [], if v then ip = n
|
||||
I::JumpTrue(n) => if self.pop().truthy() {
|
||||
self.check_interrupt()?;
|
||||
frame.ip = usize::from(n)
|
||||
frame.ip = usize::from(n);
|
||||
},
|
||||
// [v] ->, [], if not v then ip = n
|
||||
I::JumpFalse(n) => if !self.pop().truthy() {
|
||||
self.check_interrupt()?;
|
||||
frame.ip = usize::from(n)
|
||||
frame.ip = usize::from(n);
|
||||
},
|
||||
// [v] -> [iter(v)]
|
||||
I::IterBegin => {
|
||||
|
@ -368,12 +368,11 @@ impl Vm {
|
|||
// [i,cell(v)] -> [i,v]
|
||||
// [i,nil] -> [], ip = n
|
||||
I::IterTest(n) => {
|
||||
match self.pop().iter_unpack() {
|
||||
Some(v) => self.push(v),
|
||||
None => {
|
||||
self.pop();
|
||||
frame.ip = usize::from(n)
|
||||
},
|
||||
if let Some(v) = self.pop().iter_unpack() {
|
||||
self.push(v);
|
||||
} else {
|
||||
self.pop();
|
||||
frame.ip = usize::from(n);
|
||||
}
|
||||
},
|
||||
// try_frames.push(t, stack.len())
|
||||
|
|
|
@ -132,7 +132,7 @@ pub fn tee(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
match vmcalliter!(vm; iter.clone())? {
|
||||
Some(val) => {
|
||||
vmcall!(vm; tee.clone(), val.clone())?;
|
||||
Ok(val.into())
|
||||
Ok(val)
|
||||
}
|
||||
None => Ok(Value::iter_pack(None)),
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ pub fn filter(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
};
|
||||
let res = vmcall!(vm; filter.clone(), next.clone())?;
|
||||
if res.truthy() {
|
||||
return Ok(next.into())
|
||||
return Ok(next)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -198,7 +198,7 @@ pub fn take(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
return Ok(Value::iter_pack(None))
|
||||
};
|
||||
*taken.borrow_mut() += 1;
|
||||
Ok(next.into())
|
||||
Ok(next)
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0).into())
|
||||
}
|
||||
|
@ -262,22 +262,19 @@ pub fn cycle(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
}
|
||||
let val = r.0[r.2].clone();
|
||||
r.2 = (r.2 + 1) % r.0.len();
|
||||
return Ok(val.into())
|
||||
return Ok(val)
|
||||
}
|
||||
match vmcalliter!(vm; iter.clone())? {
|
||||
Some(v) => {
|
||||
record.borrow_mut().0.push(v.clone());
|
||||
Ok(v.into())
|
||||
},
|
||||
None => {
|
||||
let mut r = record.borrow_mut();
|
||||
r.1 = true;
|
||||
if r.0.is_empty() {
|
||||
Ok(Value::iter_pack(None))
|
||||
} else {
|
||||
r.2 = (r.2 + 1) % r.0.len();
|
||||
Ok(r.0[0].clone().into())
|
||||
}
|
||||
if let Some(v) = vmcalliter!(vm; iter.clone())? {
|
||||
record.borrow_mut().0.push(v.clone());
|
||||
Ok(v)
|
||||
} else {
|
||||
let mut r = record.borrow_mut();
|
||||
r.1 = true;
|
||||
if r.0.is_empty() {
|
||||
Ok(Value::iter_pack(None))
|
||||
} else {
|
||||
r.2 = (r.2 + 1) % r.0.len();
|
||||
Ok(r.0[0].clone())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -337,7 +334,7 @@ pub fn rev(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
if lst.borrow().is_none() {
|
||||
let mut l = Vec::new();
|
||||
while let Some(x) = vmcalliter!(vm; iter.clone())? {
|
||||
l.push(x)
|
||||
l.push(x);
|
||||
}
|
||||
*lst.borrow_mut() = Some(l);
|
||||
}
|
||||
|
@ -392,12 +389,11 @@ pub fn alternate(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
let n = s.0;
|
||||
s.0 = (s.0 + 1) % iters.len();
|
||||
drop(s);
|
||||
match vmcalliter!(vm; iters[n].clone())? {
|
||||
Some(v) => Ok(v),
|
||||
None => {
|
||||
state.borrow_mut().1 = true;
|
||||
Ok(Value::iter_pack(None))
|
||||
}
|
||||
if let Some(v) = vmcalliter!(vm; iters[n].clone())? {
|
||||
Ok(v)
|
||||
} else {
|
||||
state.borrow_mut().1 = true;
|
||||
Ok(Value::iter_pack(None))
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -417,25 +413,23 @@ pub fn intersperse(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
let state = RefCell::new(Intersperse::Init);
|
||||
let f = move |vm: &mut Vm, _| {
|
||||
match state.take() {
|
||||
Intersperse::Init => match vmcalliter!(vm; iter.clone())? {
|
||||
Some(v) => {
|
||||
Intersperse::Init => {
|
||||
if let Some(v) = vmcalliter!(vm; iter.clone())? {
|
||||
*state.borrow_mut() = Intersperse::Waiting;
|
||||
Ok(v)
|
||||
},
|
||||
None => {
|
||||
} else {
|
||||
*state.borrow_mut() = Intersperse::End;
|
||||
Ok(Value::iter_pack(None))
|
||||
},
|
||||
}
|
||||
},
|
||||
Intersperse::Waiting => match vmcalliter!(vm; iter.clone())? {
|
||||
Some(v) => {
|
||||
Intersperse::Waiting => {
|
||||
if let Some(v) = vmcalliter!(vm; iter.clone())? {
|
||||
*state.borrow_mut() = Intersperse::HasNext(v);
|
||||
Ok(val.clone())
|
||||
},
|
||||
None => {
|
||||
} else {
|
||||
*state.borrow_mut() = Intersperse::End;
|
||||
Ok(Value::iter_pack(None))
|
||||
},
|
||||
}
|
||||
},
|
||||
Intersperse::HasNext(v) => {
|
||||
*state.borrow_mut() = Intersperse::Waiting;
|
||||
|
@ -460,12 +454,11 @@ pub fn chain(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
if *done_first.borrow() {
|
||||
return vmcall!(vm; iter2.clone())
|
||||
}
|
||||
match vmcalliter!(vm; iter1.clone())? {
|
||||
Some(v) => Ok(v),
|
||||
None => {
|
||||
*done_first.borrow_mut() = true;
|
||||
vmcall!(vm; iter2.clone())
|
||||
}
|
||||
if let Some(v) = vmcalliter!(vm; iter1.clone())? {
|
||||
Ok(v)
|
||||
} else {
|
||||
*done_first.borrow_mut() = true;
|
||||
vmcall!(vm; iter2.clone())
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -494,38 +487,36 @@ pub fn cartprod(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
}
|
||||
|
||||
if state.borrow().b_idx >= state.borrow().b_data.len() {
|
||||
if !state.borrow().b_done {
|
||||
let v = vmcalliter!(vm; b.clone())?;
|
||||
let mut s = state.borrow_mut();
|
||||
match v {
|
||||
Some(x) => s.b_data.push(x),
|
||||
None => {
|
||||
s.b_done = true;
|
||||
if s.b_idx == 0 {
|
||||
s.done = true;
|
||||
return Ok(Value::iter_pack(None))
|
||||
}
|
||||
s.b_idx = 0;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
if state.borrow().b_done {
|
||||
if state.borrow().b_idx == 0 {
|
||||
state.borrow_mut().done = true;
|
||||
return Ok(Value::Nil)
|
||||
}
|
||||
state.borrow_mut().b_idx = 0;
|
||||
} else {
|
||||
let v = vmcalliter!(vm; b.clone())?;
|
||||
let mut s = state.borrow_mut();
|
||||
if let Some(x) = v {
|
||||
s.b_data.push(x)
|
||||
} else {
|
||||
s.b_done = true;
|
||||
if s.b_idx == 0 {
|
||||
s.done = true;
|
||||
return Ok(Value::iter_pack(None))
|
||||
}
|
||||
s.b_idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let b_res = state.borrow().b_data[state.borrow().b_idx].clone();
|
||||
|
||||
if state.borrow().b_idx == 0 {
|
||||
match vmcalliter!(vm; a.clone())? {
|
||||
Some(v) => state.borrow_mut().a_val = v,
|
||||
None => {
|
||||
state.borrow_mut().done = true;
|
||||
return Ok(Value::iter_pack(None))
|
||||
}
|
||||
if let Some(v) = vmcalliter!(vm; a.clone())? {
|
||||
state.borrow_mut().a_val = v
|
||||
} else {
|
||||
state.borrow_mut().done = true;
|
||||
return Ok(Value::iter_pack(None))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -629,7 +620,7 @@ pub fn sum(vm: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
|
||||
let mut result = Value::Int(0);
|
||||
while let Some(value) = vmcalliter!(vm; iter.clone())? {
|
||||
result = (result + value)?
|
||||
result = (result + value)?;
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
@ -641,7 +632,7 @@ pub fn prod(vm: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
|
||||
let mut result = Value::Int(1);
|
||||
while let Some(value) = vmcalliter!(vm; iter.clone())? {
|
||||
result = (result * value)?
|
||||
result = (result * value)?;
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
|
|
@ -124,10 +124,10 @@ fn to_radix_inner(n: i64, radix: u32) -> String {
|
|||
if n < 0 {
|
||||
result.push('-' as u32 as u8);
|
||||
begin = 1;
|
||||
x = (-n) as u64
|
||||
x = (-n) as u64;
|
||||
} else {
|
||||
x = n as u64
|
||||
};
|
||||
x = n as u64;
|
||||
}
|
||||
|
||||
loop {
|
||||
let m = x % (radix as u64);
|
||||
|
@ -360,9 +360,8 @@ pub fn factors(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
x /= 3;
|
||||
factors.push(Value::Int(3));
|
||||
}
|
||||
//let lim = isqrt_inner(x);
|
||||
let mut i = 5;
|
||||
while x > 1 {
|
||||
while x >= i*i {
|
||||
while x % i == 0 {
|
||||
x /= i;
|
||||
factors.push(Value::Int(i));
|
||||
|
@ -374,6 +373,9 @@ pub fn factors(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
}
|
||||
i += 4;
|
||||
}
|
||||
if x > 1 {
|
||||
factors.push(Value::Int(x));
|
||||
}
|
||||
Ok(factors.into())
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ pub fn rand_in(vm: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
while let Some(v) = vmcalliter!(vm; iter.clone())? {
|
||||
values.push(v);
|
||||
}
|
||||
if values.len() == 0 {
|
||||
if values.is_empty() {
|
||||
throw!(*SYM_TYPE_ERROR, "rand_in: empty iterator")
|
||||
}
|
||||
let i = rand::thread_rng().gen_range(0..values.len());
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||
|
||||
use talc_lang::{exception, parse_float, parse_int, symbol::SYM_TYPE_ERROR, throw, value::{HashValue, Rational64, Value}, Vm, exception::Result};
|
||||
use talc_lang::{exception::Result, parse_float, parse_int, symbol::SYM_TYPE_ERROR, throw, exception, value::{ops::RatioExt, HashValue, Rational64, Value}, Vm};
|
||||
use talc_macros::native_func;
|
||||
|
||||
use crate::unpack_args;
|
||||
|
@ -49,7 +49,7 @@ pub fn as_(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
if val.get_type() == ty {
|
||||
return Ok(val)
|
||||
}
|
||||
match (val, ty.name().as_ref()) {
|
||||
match (val, ty.name()) {
|
||||
(_, "nil") => Ok(Value::Nil),
|
||||
(v, "string") => Ok(Value::String(v.to_string().into())),
|
||||
(v, "bool") => Ok(Value::Bool(v.truthy())),
|
||||
|
@ -59,9 +59,9 @@ pub fn as_(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
(Value::Int(x), "ratio") => Ok(Value::Ratio(x.into())),
|
||||
(Value::Int(x), "float") => Ok(Value::Float(x as f64)),
|
||||
(Value::Int(x), "complex") => Ok(Value::Complex((x as f64).into())),
|
||||
(Value::Ratio(x), "int") => Ok(Value::Int(*x.numer() / *x.denom())),
|
||||
(Value::Ratio(x), "float") => Ok(Value::Float(*x.numer() as f64 / *x.denom() as f64)),
|
||||
(Value::Ratio(x), "complex") => Ok(Value::Complex((*x.numer() as f64 / *x.denom() as f64).into())),
|
||||
(Value::Ratio(x), "int") => Ok(Value::Int(x.to_integer())),
|
||||
(Value::Ratio(x), "float") => Ok(Value::Float(x.to_f64())),
|
||||
(Value::Ratio(x), "complex") => Ok(Value::Complex(x.to_f64().into())),
|
||||
(Value::Float(x), "int") => Ok(Value::Int(x as i64)),
|
||||
(Value::Float(x), "ratio") => {
|
||||
let r = Rational64::approximate_float(x)
|
||||
|
|
Loading…
Reference in a new issue