parent
b1fccce8e3
commit
c75dafac8e
15 changed files with 203 additions and 56 deletions
|
@ -101,11 +101,12 @@ fn read_init_file(args: &Args) -> Result<Option<String>, std::io::Error> {
|
|||
fn exec_line(
|
||||
vm: &mut Vm,
|
||||
line: &str,
|
||||
line_no: u32,
|
||||
args: &Args,
|
||||
c: &ReplColors,
|
||||
globals: &mut Vec<Symbol>,
|
||||
) {
|
||||
let mut ex = match parser::parse(line) {
|
||||
let mut ex = match parser::parse_from(line, line_no) {
|
||||
Ok(ex) => ex,
|
||||
Err(e) => {
|
||||
eprintln!("{}Error:{} {e}", c.error, c.reset);
|
||||
|
@ -192,11 +193,13 @@ pub fn repl(args: &Args) -> ExitCode {
|
|||
};
|
||||
|
||||
let vm = Rc::new(RefCell::new(vm));
|
||||
let mut line_no = 1;
|
||||
|
||||
rl.set_helper(Some(TalcHelper::new(vm.clone())));
|
||||
|
||||
if let Some(src) = init_src {
|
||||
exec_line(&mut vm.borrow_mut(), &src, args, &c, &mut globals);
|
||||
exec_line(&mut vm.borrow_mut(), &src, line_no, args, &c, &mut globals);
|
||||
line_no += 1;
|
||||
}
|
||||
|
||||
loop {
|
||||
|
@ -214,6 +217,7 @@ pub fn repl(args: &Args) -> ExitCode {
|
|||
}
|
||||
};
|
||||
|
||||
exec_line(&mut vm.borrow_mut(), &line, args, &c, &mut globals);
|
||||
exec_line(&mut vm.borrow_mut(), &line, line_no, args, &c, &mut globals);
|
||||
line_no += 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -240,6 +240,7 @@ pub struct TryTable {
|
|||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Chunk {
|
||||
pub lines: Vec<(u32, u32)>,
|
||||
pub consts: Vec<Value>,
|
||||
pub instrs: Vec<Instruction>,
|
||||
pub try_tables: Vec<TryTable>,
|
||||
|
@ -250,6 +251,26 @@ impl Chunk {
|
|||
Self::default()
|
||||
}
|
||||
|
||||
pub fn set_line(&mut self, line: u32) {
|
||||
let instr = self.instrs.len() as u32;
|
||||
if let Some((i, l)) = self.lines.last_mut() {
|
||||
if *i == instr {
|
||||
*l = line;
|
||||
return
|
||||
}
|
||||
}
|
||||
self.lines.push((instr, line));
|
||||
}
|
||||
|
||||
pub fn get_line(&self, instr: u32) -> Option<u32> {
|
||||
let res = self.lines.binary_search_by(|(i, _)| i.cmp(&instr));
|
||||
let n = match res {
|
||||
Ok(n) => n,
|
||||
Err(n) => n.saturating_sub(1),
|
||||
};
|
||||
self.lines.get(n).map(|(_, l)| *l)
|
||||
}
|
||||
|
||||
pub fn add_const(&mut self, v: Value) -> usize {
|
||||
assert!(
|
||||
self.consts.len() < 0xff_ffff,
|
||||
|
|
|
@ -81,13 +81,18 @@ struct Compiler<'a> {
|
|||
|
||||
pub fn compile(expr: &Expr, name: Option<Symbol>) -> Result<Function> {
|
||||
let mut comp = Compiler::new_module(name, None);
|
||||
comp.chunk.set_line(0);
|
||||
comp.expr(expr)?;
|
||||
Ok(comp.finish())
|
||||
}
|
||||
|
||||
pub fn compile_repl(expr: &Expr, globals: &mut Vec<Symbol>) -> Result<Function> {
|
||||
let mut comp = Compiler::new_repl(globals);
|
||||
comp.chunk.set_line(0);
|
||||
match &expr.kind {
|
||||
ExprKind::Block(xs) if xs.is_empty() => {
|
||||
comp.emit(I::Nil);
|
||||
}
|
||||
ExprKind::Block(xs) => {
|
||||
for x in &xs[0..xs.len() - 1] {
|
||||
comp.expr(x)?;
|
||||
|
@ -439,6 +444,7 @@ impl<'a> Compiler<'a> {
|
|||
|
||||
fn expr(&mut self, e: &Expr) -> Result<()> {
|
||||
let Expr { kind, span } = e;
|
||||
self.chunk.set_line(span.start.line);
|
||||
match kind {
|
||||
ExprKind::Block(xs) if xs.is_empty() => {
|
||||
self.emit(I::Nil);
|
||||
|
@ -845,6 +851,7 @@ impl<'a> Compiler<'a> {
|
|||
}
|
||||
|
||||
fn lvalue(&mut self, lv: &LValue) -> Result<()> {
|
||||
self.chunk.set_line(lv.span.start.line);
|
||||
match &lv.kind {
|
||||
LValueKind::Ident(i) => {
|
||||
self.emit(I::Dup);
|
||||
|
|
|
@ -1,21 +1,59 @@
|
|||
use crate::{
|
||||
lstring::LStr,
|
||||
symbol::{Symbol, SYM_MSG, SYM_TYPE},
|
||||
symbol::{Symbol, SYM_MSG, SYM_TRACE, SYM_TYPE},
|
||||
value::Value,
|
||||
};
|
||||
use std::{fmt::Display, rc::Rc};
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Exception>;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Trace {
|
||||
line: Option<u32>,
|
||||
scope: Option<Symbol>,
|
||||
}
|
||||
|
||||
impl Trace {
|
||||
pub fn from_value(value: &Value) -> Option<Self> {
|
||||
let Value::List(lst) = value else { return None };
|
||||
let lst = lst.borrow();
|
||||
if lst.len() < 2 {
|
||||
return None;
|
||||
}
|
||||
let line = match &lst[0] {
|
||||
Value::Int(s) => Some(s.to_u32()?),
|
||||
Value::Nil => None,
|
||||
_ => return None,
|
||||
};
|
||||
let scope = match &lst[1] {
|
||||
Value::Symbol(s) => Some(*s),
|
||||
Value::Nil => None,
|
||||
_ => return None,
|
||||
};
|
||||
Some(Self { line, scope })
|
||||
}
|
||||
|
||||
pub fn to_value(&self) -> Value {
|
||||
let line = self.line.map_or(Value::Nil, Value::from);
|
||||
let scope = self.scope.map_or(Value::Nil, Value::from);
|
||||
vec![line, scope].into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Exception {
|
||||
pub ty: Symbol,
|
||||
pub msg: Rc<LStr>,
|
||||
pub trace: Vec<Trace>,
|
||||
}
|
||||
|
||||
impl Exception {
|
||||
pub fn new(ty: Symbol, msg: Rc<LStr>) -> Self {
|
||||
Self { ty, msg }
|
||||
Self {
|
||||
ty,
|
||||
msg,
|
||||
trace: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_value(value: &Value) -> Option<Self> {
|
||||
|
@ -25,27 +63,54 @@ impl Exception {
|
|||
let table = table.borrow();
|
||||
let ty = table.get(&(*SYM_TYPE).into())?;
|
||||
let msg = table.get(&(*SYM_MSG).into())?;
|
||||
if let (Value::Symbol(ty), Value::String(msg)) = (ty, msg) {
|
||||
Some(Self {
|
||||
ty: *ty,
|
||||
msg: msg.clone(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
let (Value::Symbol(ty), Value::String(msg)) = (ty, msg) else {
|
||||
return None
|
||||
};
|
||||
let trace_lst = table.get(&(*SYM_TRACE).into())?;
|
||||
let Value::List(trace_lst) = trace_lst else {
|
||||
return None
|
||||
};
|
||||
let trace = trace_lst
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(Trace::from_value)
|
||||
.collect::<Option<_>>()?;
|
||||
Some(Self {
|
||||
ty: *ty,
|
||||
msg: msg.clone(),
|
||||
trace,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_value(self) -> Value {
|
||||
let trace: Vec<Value> = self.trace.iter().map(Trace::to_value).collect();
|
||||
Value::new_table(|table| {
|
||||
table.insert((*SYM_TYPE).into(), self.ty.into());
|
||||
table.insert((*SYM_MSG).into(), Value::String(self.msg));
|
||||
table.insert((*SYM_TRACE).into(), trace.into());
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add_trace(&mut self, line: Option<u32>, scope: Option<Symbol>) {
|
||||
self.trace.push(Trace { line, scope });
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Exception {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}: {}", self.ty.name(), self.msg)
|
||||
write!(f, "{}: {}", self.ty.name(), self.msg)?;
|
||||
for trace in &self.trace {
|
||||
write!(f, "\n ")?;
|
||||
if let Some(scope) = trace.scope {
|
||||
write!(f, "in {}", scope.name())?;
|
||||
} else {
|
||||
write!(f, "in <anonymous>")?;
|
||||
}
|
||||
if let Some(line) = trace.line {
|
||||
write!(f, " at {line}")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,4 +138,5 @@ macro_rules! throw {
|
|||
};
|
||||
}
|
||||
|
||||
use num::ToPrimitive;
|
||||
pub use throw;
|
||||
|
|
|
@ -393,6 +393,13 @@ impl<'a> From<&'a str> for &'a LStr {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a String> for &'a LStr {
|
||||
#[inline]
|
||||
fn from(value: &'a String) -> Self {
|
||||
Self::from(value.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a OsStr> for &'a LStr {
|
||||
#[inline]
|
||||
fn from(value: &'a OsStr) -> Self {
|
||||
|
|
|
@ -212,11 +212,20 @@ pub struct Lexer<'s> {
|
|||
|
||||
impl<'s> Lexer<'s> {
|
||||
pub fn new(src: &'s str) -> Self {
|
||||
Self::new_at(src, 1)
|
||||
}
|
||||
|
||||
pub fn new_at(src: &'s str, line: u32) -> Self {
|
||||
let pos = Pos {
|
||||
line,
|
||||
col: 0,
|
||||
idx: 0,
|
||||
};
|
||||
Self {
|
||||
src,
|
||||
chars: src.chars().peekable(),
|
||||
start_pos: Pos::new(),
|
||||
pos: Pos::new(),
|
||||
start_pos: pos,
|
||||
pos,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -229,6 +229,12 @@ impl<'s> Parser<'s> {
|
|||
}
|
||||
}
|
||||
|
||||
fn new_at(src: &'s str, line: u32) -> Self {
|
||||
Self {
|
||||
lexer: Lexer::new_at(src, line).peekable(),
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&mut self) -> Result<Token<'s>> {
|
||||
self.lexer.next().unwrap()
|
||||
}
|
||||
|
@ -739,3 +745,7 @@ impl<'s> Parser<'s> {
|
|||
pub fn parse(src: &str) -> Result<Expr> {
|
||||
Parser::new(src).parse()
|
||||
}
|
||||
|
||||
pub fn parse_from(src: &str, line: u32) -> Result<Expr> {
|
||||
Parser::new_at(src, line).parse()
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ lazy_static! {
|
|||
pub static ref SYM_END_ITERATION: Symbol = symbol!(end_iteration);
|
||||
pub static ref SYM_TYPE: Symbol = symbol!(type);
|
||||
pub static ref SYM_MSG: Symbol = symbol!(msg);
|
||||
pub static ref SYM_TRACE: Symbol = symbol!(trace);
|
||||
pub static ref SYM_TYPE_ERROR: Symbol = symbol!(type_error);
|
||||
pub static ref SYM_VALUE_ERROR: Symbol = symbol!(value_error);
|
||||
pub static ref SYM_NAME_ERROR: Symbol = symbol!(name_error);
|
||||
|
|
|
@ -75,7 +75,7 @@ impl Value {
|
|||
Some(i) => col.index(i),
|
||||
None => Ok(Value::from(*SYM_END_ITERATION)),
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(func), 0, symbol!("index...")).into())
|
||||
Ok(NativeFunc::new(Box::new(func), 0, symbol!("<index...>")).into())
|
||||
} else {
|
||||
throw!(*SYM_TYPE_ERROR, "cannot index {col:#} with {idx:#}")
|
||||
}
|
||||
|
|
|
@ -448,9 +448,21 @@ macro_rules! impl_from {
|
|||
impl_from!(bool, Bool, hash);
|
||||
impl_from!(Symbol, Symbol, hash);
|
||||
impl_from!(Range, Range, rc);
|
||||
|
||||
impl_from!(Int, Int, hash);
|
||||
impl_from!(i64, Int, into);
|
||||
impl_from!(BigInt, Int, into);
|
||||
impl_from!(i8, Int, into);
|
||||
impl_from!(i16, Int, into);
|
||||
impl_from!(i32, Int, into);
|
||||
impl_from!(i64, Int, into);
|
||||
impl_from!(isize, Int, into);
|
||||
impl_from!(u8, Int, into);
|
||||
impl_from!(u16, Int, into);
|
||||
impl_from!(u32, Int, into);
|
||||
impl_from!(u64, Int, into);
|
||||
impl_from!(usize, Int, into);
|
||||
|
||||
impl_from!(f32, Float, into);
|
||||
impl_from!(f64, Float);
|
||||
impl_from!(Ratio, Ratio, rchash);
|
||||
impl_from!(Complex64, Complex);
|
||||
|
|
|
@ -546,7 +546,7 @@ impl Value {
|
|||
range_iter.borrow_mut().next().map(Value::from),
|
||||
))
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[range]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<range iter>")).into())
|
||||
}
|
||||
Self::String(s) => {
|
||||
let byte_pos = RefCell::new(0);
|
||||
|
@ -559,7 +559,7 @@ impl Value {
|
|||
Ok(Value::from(*SYM_END_ITERATION))
|
||||
}
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[string]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<string iter>")).into())
|
||||
}
|
||||
Self::List(list) => {
|
||||
let idx = RefCell::new(0);
|
||||
|
@ -572,7 +572,7 @@ impl Value {
|
|||
Ok(Value::from(*SYM_END_ITERATION))
|
||||
}
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[list]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<list iter>")).into())
|
||||
}
|
||||
Self::Table(table) => {
|
||||
let keys: Vec<HashValue> = table.borrow().keys().cloned().collect();
|
||||
|
@ -582,7 +582,7 @@ impl Value {
|
|||
keys.borrow_mut().next().map(HashValue::into_inner),
|
||||
))
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[table]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<table iter>")).into())
|
||||
}
|
||||
_ => throw!(*SYM_TYPE_ERROR, "cannot iterate {self:#}"),
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::{
|
|||
SYM_VALUE_ERROR,
|
||||
},
|
||||
value::{
|
||||
function::{FuncAttrs, Function, NativeFunc},
|
||||
function::{Function, NativeFunc},
|
||||
HashValue, Value,
|
||||
},
|
||||
};
|
||||
|
@ -112,19 +112,20 @@ fn get_call_outcome(args: Vec<Value>) -> Result<CallOutcome> {
|
|||
Ordering::Less => {
|
||||
let remaining = attrs.arity - argc;
|
||||
let f = f.clone();
|
||||
|
||||
let name = match attrs.name {
|
||||
None => Symbol::get("<partial>"),
|
||||
Some(s) => Symbol::get(&format!("<partial {}>", s.name())),
|
||||
};
|
||||
|
||||
let nf = move |vm: &mut Vm, inner_args: Vec<Value>| {
|
||||
let mut ia = inner_args.into_iter();
|
||||
ia.next();
|
||||
let args: Vec<Value> = args.clone().into_iter().chain(ia).collect();
|
||||
vm.call_value(f.clone(), args)
|
||||
};
|
||||
let nf = NativeFunc {
|
||||
attrs: FuncAttrs {
|
||||
arity: remaining,
|
||||
name: None,
|
||||
},
|
||||
func: Box::new(nf),
|
||||
};
|
||||
|
||||
let nf = NativeFunc::new(Box::new(nf), remaining, name);
|
||||
Ok(CallOutcome::Partial(nf.into()))
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +176,10 @@ impl Vm {
|
|||
CallOutcome::Partial(v) => Ok(v),
|
||||
CallOutcome::Call(args) => match value {
|
||||
Value::Function(f) => self.run_function(f, args),
|
||||
Value::NativeFunc(f) => (f.func)(self, args),
|
||||
Value::NativeFunc(f) => (f.func)(self, args).map_err(|mut e| {
|
||||
e.add_trace(None, f.attrs.name);
|
||||
e
|
||||
}),
|
||||
_ => unreachable!("already verified by calling get_call_type"),
|
||||
},
|
||||
}
|
||||
|
@ -198,8 +202,8 @@ impl Vm {
|
|||
self.stack.truncate(init_stack_len);
|
||||
return Ok(v)
|
||||
}
|
||||
Err(e) => {
|
||||
if let Err(e) = self.handle_exception(&mut frame, e) {
|
||||
Err(exc) => {
|
||||
if let Err(e) = self.handle_exception(&mut frame, exc) {
|
||||
self.stack.truncate(init_stack_len);
|
||||
return Err(e)
|
||||
}
|
||||
|
@ -208,8 +212,14 @@ impl Vm {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_exception(&mut self, frame: &mut CallFrame, exc: Exception) -> Result<()> {
|
||||
fn handle_exception(
|
||||
&mut self,
|
||||
frame: &mut CallFrame,
|
||||
mut exc: Exception,
|
||||
) -> Result<()> {
|
||||
loop {
|
||||
let line = frame.func.chunk.get_line(frame.ip as u32);
|
||||
exc.add_trace(line, frame.func.attrs.name);
|
||||
while let Some(try_frame) = frame.try_frames.pop() {
|
||||
let table = &frame.func.chunk.try_tables[try_frame.idx];
|
||||
for catch in &table.catches {
|
||||
|
|
|
@ -223,7 +223,7 @@ pub fn sort_key(vm: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
),
|
||||
}
|
||||
};
|
||||
let nf = NativeFunc::new(Box::new(f), 2, symbol!("inner[sort_key]")).into();
|
||||
let nf = NativeFunc::new(Box::new(f), 2, symbol!("<sort_key inner>")).into();
|
||||
sort_inner(&mut list.borrow_mut(), Some(&nf), vm)?;
|
||||
Ok(list.into())
|
||||
}
|
||||
|
|
|
@ -509,7 +509,7 @@ fn tcp_listen_inner(listener: TcpListener) -> Value {
|
|||
},
|
||||
Err(e) => throw!(*SYM_IO_ERROR, "{e}"),
|
||||
};
|
||||
NativeFunc::new(Box::new(func), 0, symbol!("inner[tcp_listen]")).into()
|
||||
NativeFunc::new(Box::new(func), 0, symbol!("<tcp_listen inner>")).into()
|
||||
}
|
||||
|
||||
#[native_func(1)]
|
||||
|
|
|
@ -95,7 +95,7 @@ pub fn pairs(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
Ok(Value::iter_pack(None))
|
||||
}
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[pairs]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<pairs iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(1)]
|
||||
|
@ -104,7 +104,7 @@ pub fn once(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
|
||||
let v = RefCell::new(Some(val));
|
||||
let f = move |_: &mut Vm, _| Ok(Value::iter_pack(v.borrow_mut().take()));
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[once]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<once iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(1)]
|
||||
|
@ -112,7 +112,7 @@ pub fn forever(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
let [_, val] = unpack_args!(args);
|
||||
|
||||
let f = move |_: &mut Vm, _| Ok(val.clone());
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[forever]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<forever iterator>")).into())
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -128,7 +128,7 @@ pub fn map(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
Some(val) => Ok(vmcall!(vm; map.clone(), val)?),
|
||||
None => Ok(Value::iter_pack(None)),
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[map]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<map iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(2)]
|
||||
|
@ -143,7 +143,7 @@ pub fn tee(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
}
|
||||
None => Ok(Value::iter_pack(None)),
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[tee]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<tee iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(3)]
|
||||
|
@ -161,7 +161,7 @@ pub fn scan(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
*result.borrow_mut() = r.clone();
|
||||
Ok(r)
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[scan]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<scan iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(2)]
|
||||
|
@ -178,7 +178,7 @@ pub fn filter(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
return Ok(next)
|
||||
}
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[filter]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<filter iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(2)]
|
||||
|
@ -207,7 +207,7 @@ pub fn take(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
*taken.borrow_mut() += 1;
|
||||
Ok(next)
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[take]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<take iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(2)]
|
||||
|
@ -235,7 +235,7 @@ pub fn skip(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
}
|
||||
vmcall!(vm; iter.clone())
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[skip]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<skip iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(1)]
|
||||
|
@ -254,7 +254,7 @@ pub fn enumerate(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
Ok(Value::from(vec![n.into(), next]))
|
||||
};
|
||||
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[enumerate]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<enumerate iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(1)]
|
||||
|
@ -288,7 +288,7 @@ pub fn cycle(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
}
|
||||
};
|
||||
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[cycle]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<cycle iterator>")).into())
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default)]
|
||||
|
@ -336,7 +336,7 @@ pub fn step(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
}
|
||||
Step::End => Ok(Value::Nil),
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[step]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<step iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(1)]
|
||||
|
@ -355,7 +355,7 @@ pub fn rev(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
}
|
||||
Ok(Value::iter_pack(lst.borrow_mut().as_mut().unwrap().pop()))
|
||||
};
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[rev]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<rev iterator>")).into())
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -381,7 +381,7 @@ pub fn zip(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
Ok(Value::from(res))
|
||||
};
|
||||
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[zip]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<zip iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(1)]
|
||||
|
@ -407,7 +407,7 @@ pub fn zipn(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
Ok(Value::from(res))
|
||||
};
|
||||
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[zipn]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<zipn iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(2)]
|
||||
|
@ -434,7 +434,7 @@ pub fn alternate(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
}
|
||||
};
|
||||
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[alternate]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<alternate iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(1)]
|
||||
|
@ -466,7 +466,7 @@ pub fn alternaten(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
}
|
||||
};
|
||||
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[alternaten]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<alternaten iterator>")).into())
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -510,7 +510,7 @@ pub fn intersperse(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
Intersperse::End => Ok(Value::iter_pack(None)),
|
||||
};
|
||||
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[intersperse]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<intersperse iterator>")).into())
|
||||
}
|
||||
|
||||
#[native_func(2)]
|
||||
|
@ -532,7 +532,7 @@ pub fn chain(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
}
|
||||
};
|
||||
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[chain]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<chain iterator>")).into())
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
|
@ -597,7 +597,7 @@ pub fn cartprod(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|||
Ok(Value::from(vec![a_res, b_res]))
|
||||
};
|
||||
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("iter[cart_prod]")).into())
|
||||
Ok(NativeFunc::new(Box::new(f), 0, symbol!("<cart_prod iterator>")).into())
|
||||
}
|
||||
|
||||
//
|
||||
|
|
Loading…
Add table
Reference in a new issue