Move some concat functions to builtin.

This commit is contained in:
Stephen Chung 2020-10-10 22:13:55 +08:00
parent 836b4de925
commit 994e5a4251
4 changed files with 60 additions and 29 deletions

View File

@ -17,12 +17,12 @@ To add more functionalities to a _raw_ `Engine`, load [packages] into it.
Built-in Operators Built-in Operators
------------------ ------------------
| Operators | Assignment operators | Supported for types (see [standard types]) | | Operators | Assignment operators | Supported for types (see [standard types]) |
| ------------------------ | ---------------------------- | ----------------------------------------------------------------------------- | | ------------------------- | ---------------------------- | ----------------------------------------------------------------------------- |
| `+`, | `+=` | `INT`, `FLOAT` (if not [`no_float`]), `ImmutableString` | | `+`, | `+=` | `INT`, `FLOAT` (if not [`no_float`]), `char`, `ImmutableString` |
| `-`, `*`, `/`, `%`, `~`, | `-=`, `*=`, `/=`, `%=`, `~=` | `INT`, `FLOAT` (if not [`no_float`]) | | `-`, `*`, `/`, `%`, `~`, | `-=`, `*=`, `/=`, `%=`, `~=` | `INT`, `FLOAT` (if not [`no_float`]) |
| `<<`, `>>`, `^`, | `<<=`, `>>=`, `^=` | `INT` | | `<<`, `>>` | `<<=`, `>>=` | `INT` |
| `&`, <code>\|</code>, | `&=`, <code>\|=</code> | `INT`, `bool` | | `&`, <code>\|</code>, `^` | `&=`, <code>\|=</code>, `^=` | `INT`, `bool` |
| `&&`, <code>\|\|</code> | | `bool` | | `&&`, <code>\|\|</code> | | `bool` |
| `==`, `!=` | | `INT`, `FLOAT` (if not [`no_float`]), `bool`, `char`, `()`, `ImmutableString` | | `==`, `!=` | | `INT`, `FLOAT` (if not [`no_float`]), `bool`, `char`, `()`, `ImmutableString` |
| `>`, `>=`, `<`, `<=` | | `INT`, `FLOAT` (if not [`no_float`]), `char`, `()`, `ImmutableString` | | `>`, `>=`, `<`, `<=` | | `INT`, `FLOAT` (if not [`no_float`]), `char`, `()`, `ImmutableString` |

View File

@ -7,11 +7,11 @@ To use custom types for [`print`] and [`debug`], or convert its value into a [st
it is necessary that the following functions be registered (assuming the custom type it is necessary that the following functions be registered (assuming the custom type
is `T : Display + Debug`): is `T : Display + Debug`):
| Function | Signature | Typical implementation | Usage | | Function | Signature | Typical implementation | Usage |
| ----------- | ------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------- | | ----------- | ---------------------------------------------- | ---------------------------- | -------------------------------------------------------------------- |
| `to_string` | <code>\|s: &mut T\| -> ImmutableString</code> | `s.to_string().into()` | converts the custom type into a [string] | | `to_string` | <code>\|x: &mut T\| -> String</code> | `x.to_string()` | converts the custom type into a [string] |
| `print` | <code>\|s: &mut T\| -> ImmutableString</code> | `s.to_string().into()` | converts the custom type into a [string] for the [`print`] statement | | `print` | <code>\|x: &mut T\| -> String</code> | `x.to_string()` | converts the custom type into a [string] for the [`print`] statement |
| `debug` | <code>\|s: &mut T\| -> ImmutableString</code> | `format!("{:?}", s).into()` | converts the custom type into a [string] for the [`debug`] statement | | `debug` | <code>\|x: &mut T\| -> String</code> | `format!("{:?}", x)` | converts the custom type into a [string] for the [`debug`] statement |
| `+` | <code>\|s1: ImmutableString, s: T\| -> ImmutableString</code> | `s1 + s` | appends the custom type to another [string], for `print("Answer: " + type);` usage | | `+` | <code>\|s: &str, x: T\| -> String</code> | `format!("{}{}", s, x)` | concatenates the custom type with another [string] |
| `+` | <code>\|s: T, s2: ImmutableString\| -> ImmutableString</code> | `s.to_string().push_str(&s2).into();` | appends another [string] to the custom type, for `print(type + " is the answer");` usage | | `+` | <code>\|x: &mut T, s: &str\| -> String</code> | `x.to_string().push_str(s);` | concatenates another [string] with the custom type |
| `+=` | <code>\|s1: &mut ImmutableString, s: T\|</code> | `s1 += s.to_string()` | appends the custom type to an existing [string], for `s += type;` usage | | `+=` | <code>\|s: &mut ImmutableString, x: T\|</code> | `s += x.to_string()` | appends the custom type to an existing [string] |

View File

@ -1239,8 +1239,28 @@ pub fn run_builtin_binary_op(
use crate::packages::arithmetic::arith_basic::INT::functions::*; use crate::packages::arithmetic::arith_basic::INT::functions::*;
let args_type = x.type_id(); let args_type = x.type_id();
let second_type = y.type_id();
if y.type_id() != args_type { if second_type != args_type {
if args_type == TypeId::of::<char>() && second_type == TypeId::of::<ImmutableString>() {
let x = x.clone().cast::<char>();
let y = &*y.read_lock::<ImmutableString>().unwrap();
match op {
"+" => return Ok(Some(format!("{}{}", x, y).into())),
_ => (),
}
} else if args_type == TypeId::of::<ImmutableString>()
&& second_type == TypeId::of::<char>()
{
let x = &*x.read_lock::<ImmutableString>().unwrap();
let y = y.clone().cast::<char>();
match op {
"+" => return Ok(Some((x + y).into())),
_ => (),
}
}
return Ok(None); return Ok(None);
} }
@ -1317,6 +1337,7 @@ pub fn run_builtin_binary_op(
let y = y.clone().cast::<char>(); let y = y.clone().cast::<char>();
match op { match op {
"+" => return Ok(Some(format!("{}{}", x, y).into())),
"==" => return Ok(Some((x == y).into())), "==" => return Ok(Some((x == y).into())),
"!=" => return Ok(Some((x != y).into())), "!=" => return Ok(Some((x != y).into())),
">" => return Ok(Some((x > y).into())), ">" => return Ok(Some((x > y).into())),
@ -1367,8 +1388,19 @@ pub fn run_builtin_op_assignment(
use crate::packages::arithmetic::arith_basic::INT::functions::*; use crate::packages::arithmetic::arith_basic::INT::functions::*;
let args_type = x.type_id(); let args_type = x.type_id();
let second_type = y.type_id();
if second_type != args_type {
if args_type == TypeId::of::<ImmutableString>() && second_type == TypeId::of::<char>() {
let y = y.read_lock::<char>().unwrap().deref().clone();
let mut x = x.write_lock::<ImmutableString>().unwrap();
match op {
"+=" => return Ok(Some(*x += y)),
_ => (),
}
}
if y.type_id() != args_type {
return Ok(None); return Ok(None);
} }
@ -1417,6 +1449,14 @@ pub fn run_builtin_op_assignment(
"|=" => return Ok(Some(*x = *x || y)), "|=" => return Ok(Some(*x = *x || y)),
_ => (), _ => (),
} }
} else if args_type == TypeId::of::<char>() {
let y = y.read_lock::<char>().unwrap().deref().clone();
let mut x = x.write_lock::<Dynamic>().unwrap();
match op {
"+=" => return Ok(Some(*x = format!("{}{}", *x, y).into())),
_ => (),
}
} else if args_type == TypeId::of::<ImmutableString>() { } else if args_type == TypeId::of::<ImmutableString>() {
let y = y.read_lock::<ImmutableString>().unwrap().deref().clone(); let y = y.read_lock::<ImmutableString>().unwrap().deref().clone();
let mut x = x.write_lock::<ImmutableString>().unwrap(); let mut x = x.write_lock::<ImmutableString>().unwrap();

View File

@ -43,7 +43,7 @@ macro_rules! reg_functions {
} }
def_package!(crate:MoreStringPackage:"Additional string utilities, including string building.", lib, { def_package!(crate:MoreStringPackage:"Additional string utilities, including string building.", lib, {
reg_functions!(lib += basic; INT, bool, char, FnPtr); reg_functions!(lib += basic; INT, bool, FnPtr);
#[cfg(not(feature = "only_i32"))] #[cfg(not(feature = "only_i32"))]
#[cfg(not(feature = "only_i64"))] #[cfg(not(feature = "only_i64"))]
@ -139,15 +139,6 @@ mod string_functions {
s s
} }
#[rhai_fn(name = "+=")]
pub fn append_char(s: &mut ImmutableString, ch: char) {
*s += ch;
}
#[rhai_fn(name = "+=")]
pub fn append_string(s: &mut ImmutableString, add: ImmutableString) {
*s += &add;
}
#[rhai_fn(name = "len", get = "len")] #[rhai_fn(name = "len", get = "len")]
pub fn len(s: &str) -> INT { pub fn len(s: &str) -> INT {
s.chars().count() as INT s.chars().count() as INT