Skip to content

Commit

Permalink
Merge pull request #579 from schungx/master
Browse files Browse the repository at this point in the history
Version 1.8.0.
  • Loading branch information
schungx committed Jul 1, 2022
2 parents d680fe9 + 54db9a2 commit 60e3661
Show file tree
Hide file tree
Showing 31 changed files with 532 additions and 594 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Bug fixes
Reserved Symbols
----------------

* `?`, `??`, `?.` and `!.` are now reserved symbols.
* `?`, `??`, `?.`, `?[` and `!.` are now reserved symbols.

Deprecated API's
----------------
Expand All @@ -29,7 +29,7 @@ Deprecated API's
New features
------------

* The _Elvis operator_ (`?.`) is now supported for property access and method calls.
* The _Elvis operators_ (`?.` and `?[`) are now supported for property access, method calls and indexing.
* The _null-coalescing operator_ (`??`) is now supported to short-circuit `()` values.

Enhancements
Expand All @@ -41,6 +41,7 @@ Enhancements
* Originally, the debugger's custom state uses the same state as `EvalState::tag()` (which is the same as `NativeCallContext::tag()`). It is now split into its own variable accessible under `Debugger::state()`.
* Non-borrowed string keys can now be deserialized for object maps via `serde`.
* `Scope::get` is added to get a reference to a variable's value.
* Variable resolvers can now return a _shared_ value which can be mutated.


Version 1.7.0
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ members = [".", "codegen"]

[package]
name = "rhai"
version = "1.7.0"
version = "1.8.0"
rust-version = "1.57"
edition = "2018"
authors = ["Jonathan Turner", "Lukáš Hozda", "Stephen Chung", "jhwgh1968"]
Expand Down
2 changes: 1 addition & 1 deletion src/api/custom_syntax.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Module implementing custom syntax for [`Engine`].

use crate::ast::Expr;
use crate::func::native::SendSync;
use crate::func::SendSync;
use crate::parser::ParseResult;
use crate::tokenizer::{is_valid_identifier, Token};
use crate::types::dynamic::Variant;
Expand Down
7 changes: 1 addition & 6 deletions src/api/optimize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,7 @@ impl Engine {
.shared_lib()
.iter_fn()
.filter(|f| f.func.is_script())
.map(|f| {
f.func
.get_script_fn_def()
.expect("script-defined function")
.clone()
})
.map(|f| f.func.get_script_fn_def().unwrap().clone())
.collect();

crate::optimizer::optimize_into_ast(
Expand Down
8 changes: 3 additions & 5 deletions src/api/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,7 @@ impl Engine {
let param_type_names: crate::StaticVec<_> = F::param_names()
.iter()
.map(|ty| format!("_: {}", self.format_type_name(ty)))
.chain(std::iter::once(
self.format_type_name(F::return_type_name()).into(),
))
.chain(Some(self.format_type_name(F::return_type_name()).into()))
.collect();

#[cfg(feature = "metadata")]
Expand Down Expand Up @@ -993,7 +991,7 @@ impl Engine {
if !name.contains(separator.as_ref()) {
if !module.is_indexed() {
// Index the module (making a clone copy if necessary) if it is not indexed
let mut module = crate::func::native::shared_take_or_clone(module);
let mut module = crate::func::shared_take_or_clone(module);
module.build_index();
root.insert(name.into(), module.into());
} else {
Expand All @@ -1011,7 +1009,7 @@ impl Engine {
root.insert(sub_module.into(), m.into());
} else {
let m = root.remove(sub_module).expect("contains sub-module");
let mut m = crate::func::native::shared_take_or_clone(m);
let mut m = crate::func::shared_take_or_clone(m);
register_static_module_raw(m.sub_modules_mut(), remainder, module);
m.build_index();
root.insert(sub_module.into(), m.into());
Expand Down
4 changes: 2 additions & 2 deletions src/api/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,15 @@ fn map_std_type_name(name: &str, shorthands: bool) -> &str {
}

#[cfg(not(feature = "no_float"))]
if name == type_name::<crate::packages::iter_basic::float::StepFloatRange>() {
if name == type_name::<crate::packages::iter_basic::StepRange<crate::FLOAT>>() {
return if shorthands {
"range"
} else {
"StepFloatRange"
};
}
#[cfg(feature = "decimal")]
if name == type_name::<crate::packages::iter_basic::decimal::StepDecimalRange>() {
if name == type_name::<crate::packages::iter_basic::StepRange<rust_decimal::Decimal>>() {
return if shorthands {
"range"
} else {
Expand Down
11 changes: 4 additions & 7 deletions src/ast/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,8 +615,7 @@ impl AST {

#[cfg(not(feature = "no_function"))]
if !other.lib.is_empty() {
crate::func::native::shared_make_mut(&mut self.lib)
.merge_filtered(&other.lib, &_filter);
crate::func::shared_make_mut(&mut self.lib).merge_filtered(&other.lib, &_filter);
}

#[cfg(not(feature = "no_module"))]
Expand All @@ -629,10 +628,8 @@ impl AST {
self.set_resolver(other.resolver.unwrap());
}
(_, _) => {
let resolver =
crate::func::native::shared_make_mut(self.resolver.as_mut().unwrap());
let other_resolver =
crate::func::native::shared_take_or_clone(other.resolver.unwrap());
let resolver = crate::func::shared_make_mut(self.resolver.as_mut().unwrap());
let other_resolver = crate::func::shared_take_or_clone(other.resolver.unwrap());
for (k, v) in other_resolver {
resolver.insert(k, crate::func::shared_take_or_clone(v));
}
Expand Down Expand Up @@ -673,7 +670,7 @@ impl AST {
filter: impl Fn(FnNamespace, FnAccess, &str, usize) -> bool,
) -> &mut Self {
if !self.lib.is_empty() {
crate::func::native::shared_make_mut(&mut self.lib).retain_script_functions(filter);
crate::func::shared_make_mut(&mut self.lib).retain_script_functions(filter);
}
self
}
Expand Down
3 changes: 2 additions & 1 deletion src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ pub enum Expr {
///
/// ### Flags
///
/// [`NEGATED`][ASTFlags::NEGATED] = `?[` ... `]` (`[` ... `]` if unset)
/// [`BREAK`][ASTFlags::BREAK] = terminate the chain (recurse into the chain if unset)
Index(Box<BinaryExpr>, ASTFlags, Position),
/// lhs `&&` rhs
Expand Down Expand Up @@ -827,7 +828,7 @@ impl Expr {
#[cfg(not(feature = "no_object"))]
Token::Period | Token::Elvis => return true,
#[cfg(not(feature = "no_index"))]
Token::LeftBracket => return true,
Token::LeftBracket | Token::QuestionBracket => return true,
_ => (),
}

Expand Down
5 changes: 5 additions & 0 deletions src/eval/chaining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ impl Engine {
match chain_type {
#[cfg(not(feature = "no_index"))]
ChainType::Indexing => {
// Check for existence with the null conditional operator
if _parent_options.contains(ASTFlags::NEGATED) && target.is::<()>() {
return Ok((Dynamic::UNIT, false));
}

let pos = rhs.start_position();

match rhs {
Expand Down
29 changes: 25 additions & 4 deletions src/eval/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl Engine {
let target_is_shared = false;

if target_is_shared {
lock_guard = target.write_lock::<Dynamic>().expect("`Dynamic`");
lock_guard = target.write_lock::<Dynamic>().unwrap();
lhs_ptr_inner = &mut *lock_guard;
} else {
lhs_ptr_inner = &mut *target;
Expand Down Expand Up @@ -181,7 +181,20 @@ impl Engine {
}
} else {
// Normal assignment
*target.as_mut() = new_val;

#[cfg(not(feature = "no_closure"))]
if target.is_shared() {
// Handle case where target is a `Dynamic` shared value
// (returned by a variable resolver, for example)
*target.write_lock::<Dynamic>().unwrap() = new_val;
} else {
*target.as_mut() = new_val;
}

#[cfg(feature = "no_closure")]
{
*target.as_mut() = new_val;
}
}

target.propagate_changed_value(op_info.pos)
Expand Down Expand Up @@ -250,7 +263,15 @@ impl Engine {

let var_name = lhs.get_variable_name(false).expect("`Expr::Variable`");

if !lhs_ptr.is_ref() {
#[cfg(not(feature = "no_closure"))]
// Also handle case where target is a `Dynamic` shared value
// (returned by a variable resolver, for example)
let is_temp_result = !lhs_ptr.is_ref() && !lhs_ptr.is_shared();
#[cfg(feature = "no_closure")]
let is_temp_result = !lhs_ptr.is_ref();

// Cannot assign to temp result from expression
if is_temp_result {
return Err(
ERR::ErrorAssignmentToConstant(var_name.to_string(), pos).into()
);
Expand Down Expand Up @@ -950,7 +971,7 @@ impl Engine {
if !export.is_empty() {
if !module.is_indexed() {
// Index the module (making a clone copy if necessary) if it is not indexed
let mut m = crate::func::native::shared_take_or_clone(module);
let mut m = crate::func::shared_take_or_clone(module);
m.build_index();
global.push_import(export.name.clone(), m);
} else {
Expand Down
6 changes: 3 additions & 3 deletions src/func/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ pub trait FuncArgs {
///
/// impl FuncArgs for Options {
/// fn parse<ARGS: Extend<Dynamic>>(self, args: &mut ARGS) {
/// args.extend(std::iter::once(self.foo.into()));
/// args.extend(std::iter::once(self.bar.into()));
/// args.extend(std::iter::once(self.baz.into()));
/// args.extend(Some(self.foo.into()));
/// args.extend(Some(self.bar.into()));
/// args.extend(Some(self.baz.into()));
/// }
/// }
///
Expand Down

0 comments on commit 60e3661

Please sign in to comment.