diff --git a/Cargo.toml b/Cargo.toml index b4ff53e9..fae83a04 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,5 @@ include = [ [features] debug_msgs = [] +no-std = [] +stdlib = [] \ No newline at end of file diff --git a/src/builtin.rs b/src/builtin.rs index 42d736a3..4e8810c4 100644 --- a/src/builtin.rs +++ b/src/builtin.rs @@ -1,9 +1,12 @@ use crate::any::Any; use crate::engine::{Array, Engine}; -use crate::fn_register::{RegisterDynamicFn, RegisterFn}; +use crate::fn_register::RegisterFn; use std::fmt::{Debug, Display}; use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Range, Rem, Shl, Shr, Sub}; +#[cfg(not(feature = "no-std"))] +use crate::fn_register::RegisterDynamicFn; + macro_rules! reg_op { ($self:expr, $x:expr, $op:expr, $( $y:ty ),*) => ( $( @@ -36,6 +39,7 @@ macro_rules! reg_func1 { ) } +#[cfg(any(not(feature = "no-std"), feature = "stdlib"))] macro_rules! reg_func2x { ($self:expr, $x:expr, $op:expr, $v:ty, $r:ty, $( $y:ty ),*) => ( $( @@ -44,6 +48,7 @@ macro_rules! reg_func2x { ) } +#[cfg(any(not(feature = "no-std"), feature = "stdlib"))] macro_rules! reg_func2y { ($self:expr, $x:expr, $op:expr, $v:ty, $r:ty, $( $y:ty ),*) => ( $( @@ -52,6 +57,7 @@ macro_rules! reg_func2y { ) } +#[cfg(any(not(feature = "no-std"), feature = "stdlib"))] macro_rules! reg_func3 { ($self:expr, $x:expr, $op:expr, $v:ty, $w:ty, $r:ty, $( $y:ty ),*) => ( $( @@ -61,8 +67,8 @@ macro_rules! reg_func3 { } impl Engine<'_> { - /// Register the built-in library. - pub(crate) fn register_builtins(&mut self) { + /// Register the core built-in library. + pub(crate) fn register_core_lib(&mut self) { fn add(x: T, y: T) -> ::Output { x + y } @@ -176,6 +182,47 @@ impl Engine<'_> { self.register_fn("+", concat); self.register_fn("==", unit_eq); + // Register print and debug + fn print_debug(x: T) -> String { + format!("{:?}", x) + } + fn print(x: T) -> String { + format!("{}", x) + } + + reg_func1!(self, "print", print, String, i8, u8, i16, u16); + reg_func1!(self, "print", print, String, i32, i64, u32, u64); + reg_func1!(self, "print", print, String, f32, f64, bool, char, String); + reg_func1!(self, "print", print_debug, String, Array); + self.register_fn("print", || "".to_string()); + self.register_fn("print", |_: ()| "".to_string()); + + reg_func1!(self, "debug", print_debug, String, i8, u8, i16, u16); + reg_func1!(self, "debug", print_debug, String, i32, i64, u32, u64); + reg_func1!(self, "debug", print_debug, String, f32, f64, bool, char); + reg_func1!(self, "debug", print_debug, String, String, Array, ()); + + // Register array iterator + self.register_iterator::(|a| { + Box::new(a.downcast_ref::().unwrap().clone().into_iter()) + }); + + // Register range function + self.register_iterator::, _>(|a| { + Box::new( + a.downcast_ref::>() + .unwrap() + .clone() + .map(|n| n.into_dynamic()), + ) + }); + + self.register_fn("range", |i1: i64, i2: i64| (i1..i2)); + } + + /// Register the built-in library. + #[cfg(any(not(feature = "no-std"), feature = "stdlib"))] + pub(crate) fn register_stdlib(&mut self) { // Register conversion functions self.register_fn("to_float", |x: i8| x as f64); self.register_fn("to_float", |x: u8| x as f64); @@ -199,26 +246,6 @@ impl Engine<'_> { self.register_fn("to_int", |ch: char| ch as i64); - // Register print and debug - fn print_debug(x: T) -> String { - format!("{:?}", x) - } - fn print(x: T) -> String { - format!("{}", x) - } - - reg_func1!(self, "print", print, String, i8, u8, i16, u16); - reg_func1!(self, "print", print, String, i32, i64, u32, u64); - reg_func1!(self, "print", print, String, f32, f64, bool, char, String); - reg_func1!(self, "print", print_debug, String, Array); - self.register_fn("print", || "".to_string()); - self.register_fn("print", |_: ()| "".to_string()); - - reg_func1!(self, "debug", print_debug, String, i8, u8, i16, u16); - reg_func1!(self, "debug", print_debug, String, i32, i64, u32, u64); - reg_func1!(self, "debug", print_debug, String, f32, f64, bool, char); - reg_func1!(self, "debug", print_debug, String, String, Array, ()); - // Register array utility functions fn push(list: &mut Array, item: T) { list.push(Box::new(item)); @@ -242,14 +269,11 @@ impl Engine<'_> { reg_func3!(self, "pad", pad, &mut Array, i64, (), String, Array, ()); self.register_dynamic_fn("pop", |list: &mut Array| { - list.pop().unwrap_or(().into_dynamic()) + list.pop().unwrap_or_else(|| ().into_dynamic()) }); - self.register_dynamic_fn("shift", |list: &mut Array| { - if list.len() > 0 { - list.remove(0) - } else { - ().into_dynamic() - } + self.register_dynamic_fn("shift", |list: &mut Array| match list.len() { + 0 => ().into_dynamic(), + _ => list.remove(0), }); self.register_fn("len", |list: &mut Array| list.len() as i64); self.register_fn("clear", |list: &mut Array| list.clear()); @@ -314,22 +338,5 @@ impl Engine<'_> { chars.iter().for_each(|&ch| s.push(ch)); } }); - - // Register array iterator - self.register_iterator::(|a| { - Box::new(a.downcast_ref::().unwrap().clone().into_iter()) - }); - - // Register range function - self.register_iterator::, _>(|a| { - Box::new( - a.downcast_ref::>() - .unwrap() - .clone() - .map(|n| n.into_dynamic()), - ) - }); - - self.register_fn("range", |i1: i64, i2: i64| (i1..i2)); } } diff --git a/src/engine.rs b/src/engine.rs index b2e62bd6..60e38b08 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -745,12 +745,25 @@ impl Engine<'_> { script_functions: HashMap::new(), type_iterators: HashMap::new(), type_names, - on_print: Box::new(|x| println!("{}", x)), // default print/debug implementations - on_debug: Box::new(|x| println!("{}", x)), + on_print: Box::new(default_print), // default print/debug implementations + on_debug: Box::new(default_print), }; - engine.register_builtins(); + engine.register_core_lib(); + + #[cfg(any(not(feature = "no-std"), feature = "stdlib"))] + engine.register_stdlib(); // Register the standard library when not no-std or stdlib is set engine } } + +/// Print/debug to stdout +#[cfg(not(feature = "no-std"))] +fn default_print(s: &str) { + println!("{}", s); +} + +/// No-op +#[cfg(feature = "no-std")] +fn default_print(_: &str) {}