Skip to content

Commit

Permalink
Merge pull request #420 from schungx/master
Browse files Browse the repository at this point in the history
Prepare for 0.20.3.
  • Loading branch information
schungx authored Jun 22, 2021
2 parents c11ea90 + ba0cf80 commit 6006942
Show file tree
Hide file tree
Showing 9 changed files with 256 additions and 321 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Rhai Release Notes
Version 0.20.3
==============

This version adds support to index into an integer number, treating it as a bit-field.

Bug fixes
---------

Expand All @@ -13,7 +15,7 @@ Bug fixes
Breaking changes
----------------

* To keep the API consistent, strings are no longer iterable by default. Use the `chars` method to iterator the characters in a string.
* To keep the API consistent, strings are no longer iterable by default. Use the `chars` method to iterate through the characters in a string.
* `Dynamic::take_string` and `Dynamic::take_immutable_string` are renamed to `Dynamic::as_string` and `Dynamic::as_immutable_string` respectively.

New features
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ smallvec = { version = "1.6", default-features = false, features = ["union"] }
ahash = { version = "0.7", default-features = false }
num-traits = { version = "0.2", default-features = false }
smartstring = { version = "0.2.6", default-features = false }
rhai_codegen = { version = "0.4.0", path = "codegen", default-features = false }
rhai_codegen = { version = ">=0.4.0", path = "codegen", default-features = false }

[features]
default = ["smartstring/std", "ahash/std", "num-traits/std"] # remove 'smartstring/std' when smartstring is updated to support no-std
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Standard features
* Freely pass Rust values into a script as [variables](https://rhai.rs/book/language/variables.html)/[constants](https://rhai.rs/book/language/constants.html) via an external [`Scope`](https://rhai.rs/book/rust/scope.html) - all clonable Rust types are supported; no need to implement any special trait. Or tap directly into the [variable resolution process](https://rhai.rs/book/engine/var.html).
* Built-in support for most common [data types](https://rhai.rs/book/language/values-and-types.html) including booleans, [integers](https://rhai.rs/book/language/numbers.html), [floating-point numbers](https://rhai.rs/book/language/numbers.html) (including [`Decimal`](https://crates.io/crates/rust_decimal)), [strings](https://rhai.rs/book/language/strings-chars.html), [Unicode characters](https://rhai.rs/book/language/strings-chars.html), [arrays](https://rhai.rs/book/language/arrays.html) and [object maps](https://rhai.rs/book/language/object-maps.html).
* Easily [call a script-defined function](https://rhai.rs/book/engine/call-fn.html) from Rust.
* Relatively little `unsafe` code (yes there are some for performance reasons), and `unsafe` code is only used for type casting, never to get around the borrow checker.
* Relatively little `unsafe` code (yes there are some for performance reasons).
* Few dependencies - currently only [`smallvec`](https://crates.io/crates/smallvec), [`num-traits`](https://crates.io/crates/num-traits), [`ahash`](https://crates.io/crates/ahash) and [`smartstring`](https://crates.io/crates/smartstring).
* Re-entrant scripting engine can be made `Send + Sync` (via the `sync` feature).
* Compile once to [AST](https://rhai.rs/book/engine/compile.html) form for repeated evaluations.
Expand Down
4 changes: 2 additions & 2 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1498,12 +1498,12 @@ impl fmt::Debug for FnCallHashes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(script) = self.script {
if script == self.native {
write!(f, "({}=={})", script, self.native)
fmt::Debug::fmt(&self.native, f)
} else {
write!(f, "({}, {})", script, self.native)
}
} else {
write!(f, "{}", self.native)
write!(f, "{} (native only)", self.native)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl Imports {
.iter()
.enumerate()
.rev()
.find_map(|(i, key)| if *key == name { Some(i) } else { None })
.find_map(|(i, key)| if key == name { Some(i) } else { None })
}
/// Push an imported [modules][Module] onto the stack.
#[inline(always)]
Expand Down
472 changes: 218 additions & 254 deletions src/fn_builtin.rs

Large diffs are not rendered by default.

83 changes: 26 additions & 57 deletions src/fn_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ impl Engine {
.map(|a| if a.is::<ImmutableString>() {
"&str | ImmutableString | String"
} else {
self.map_type_name((*a).type_name())
self.map_type_name(a.type_name())
})
.collect::<StaticVec<_>>()
.join(", ")
Expand Down Expand Up @@ -171,8 +171,10 @@ impl Engine {
is_op_assignment: bool,
) -> &'s Option<Box<FnResolutionCacheEntry>> {
let mut hash = args.as_ref().map_or(hash_script, |args| {
let hash_params = calc_fn_params_hash(args.iter().map(|a| a.type_id()));
combine_hashes(hash_script, hash_params)
combine_hashes(
hash_script,
calc_fn_params_hash(args.iter().map(|a| a.type_id())),
)
});

&*state
Expand All @@ -188,43 +190,17 @@ impl Engine {
let mut bitmask = 1usize; // Bitmask of which parameter to replace with `Dynamic`

loop {
let func = lib
.iter()
.find_map(|m| {
m.get_fn(hash).cloned().map(|func| {
let source = m.id_raw().cloned();
FnResolutionCacheEntry { func, source }
})
})
.or_else(|| {
self.global_namespace
.get_fn(hash)
.cloned()
.map(|func| FnResolutionCacheEntry { func, source: None })
})
.or_else(|| {
self.global_modules.iter().find_map(|m| {
m.get_fn(hash).cloned().map(|func| {
let source = m.id_raw().cloned();
FnResolutionCacheEntry { func, source }
})
})
})
.or_else(|| {
mods.get_fn(hash).map(|(func, source)| {
let func = func.clone();
let source = source.cloned();
FnResolutionCacheEntry { func, source }
})
})
.or_else(|| {
self.global_sub_modules.values().find_map(|m| {
m.get_qualified_fn(hash).cloned().map(|func| {
let source = m.id_raw().cloned();
FnResolutionCacheEntry { func, source }
})
})
});
let func = lib.iter().find_map(|m| m.get_fn(hash).cloned().map(|func| FnResolutionCacheEntry {
func, source: m.id_raw().cloned()
})).or_else(|| self.global_namespace.get_fn(hash).cloned().map(|func| FnResolutionCacheEntry {
func, source: None
})).or_else(|| self.global_modules.iter().find_map(|m| m.get_fn(hash).cloned().map(|func| FnResolutionCacheEntry {
func, source: m.id_raw().cloned()
}))).or_else(|| mods.get_fn(hash).map(|(func, source)| FnResolutionCacheEntry {
func: func.clone(), source: source.cloned()
})).or_else(|| self.global_sub_modules.values().find_map(|m| m.get_qualified_fn(hash).cloned().map(|func| FnResolutionCacheEntry {
func, source: m.id_raw().cloned()
})));

match func {
// Specific version found
Expand All @@ -239,23 +215,17 @@ impl Engine {
return args.and_then(|args| {
if !is_op_assignment {
get_builtin_binary_op_fn(fn_name, &args[0], &args[1]).map(|f| {
let func = CallableFunction::from_method(
FnResolutionCacheEntry { func: CallableFunction::from_method(
Box::new(f) as Box<FnAny>
);
FnResolutionCacheEntry { func, source: None }
), source: None }
})
} else {
let (first, second) = args.split_first()
.expect("never fails because an op-assignment must have two arguments");

get_builtin_op_assignment_fn(fn_name, *first, second[0]).map(
|f| {
let func = CallableFunction::from_method(
Box::new(f) as Box<FnAny>
);
FnResolutionCacheEntry { func, source: None }
},
)
get_builtin_op_assignment_fn(fn_name, *first, second[0]).map(|f| FnResolutionCacheEntry {
func: CallableFunction::from_method(Box::new(f) as Box<FnAny>), source: None
})
}
.map(Box::new)
});
Expand Down Expand Up @@ -437,11 +407,10 @@ impl Engine {
}

// Raise error
_ => EvalAltResult::ErrorFunctionNotFound(
self.gen_call_signature(None, name, args.as_ref()),
pos,
)
.into(),
_ => {
EvalAltResult::ErrorFunctionNotFound(self.gen_call_signature(None, name, args), pos)
.into()
}
}
}

Expand Down Expand Up @@ -1451,7 +1420,7 @@ impl Engine {
Some(f) => unreachable!("unknown function type: {:?}", f),

None => EvalAltResult::ErrorFunctionNotFound(
self.gen_call_signature(Some(namespace), fn_name, args.as_ref()),
self.gen_call_signature(Some(namespace), fn_name, &args),
pos,
)
.into(),
Expand Down
6 changes: 3 additions & 3 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl<'e> ParseState<'e> {
.iter()
.rev()
.enumerate()
.find(|&(_, n)| *n == name)
.find(|&(_, n)| n == name)
.and_then(|(i, _)| NonZeroUsize::new(i + 1))
}

Expand Down Expand Up @@ -1070,8 +1070,8 @@ fn parse_primary(
let (expr, func) = parse_anon_fn(input, &mut new_state, lib, settings)?;

#[cfg(not(feature = "no_closure"))]
new_state.external_vars.iter().for_each(|(closure, pos)| {
state.access_var(closure, *pos);
new_state.external_vars.iter().for_each(|(closure, &pos)| {
state.access_var(closure, pos);
});

let hash_script = calc_fn_hash(&func.name, func.params.len());
Expand Down
2 changes: 1 addition & 1 deletion src/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ impl<'a> Scope<'a> {
.1
.as_mut()
.expect("never fails because the list is initialized");
if !list.iter().any(|a| &alias == a) {
if !list.iter().any(|a| a == &alias) {
list.push(alias);
}
self
Expand Down

0 comments on commit 6006942

Please sign in to comment.