Add switch expression.

This commit is contained in:
Stephen Chung
2020-11-13 18:32:18 +08:00
parent 7d1b971b39
commit 55b4907f19
19 changed files with 547 additions and 252 deletions

View File

@@ -27,7 +27,7 @@ use crate::{
use crate::fn_register::{RegisterFn, RegisterResultFn};
#[cfg(not(feature = "no_function"))]
use crate::{fn_args::FuncArgs, fn_call::ensure_no_data_race, module::Module, StaticVec};
use crate::{fn_args::FuncArgs, fn_call::ensure_no_data_race, module::Module, StaticVec, utils::get_hasher};
#[cfg(not(feature = "no_optimize"))]
use crate::optimize::optimize_into_ast;
@@ -35,6 +35,7 @@ use crate::optimize::optimize_into_ast;
use crate::stdlib::{
any::{type_name, TypeId},
boxed::Box,
hash::{Hash, Hasher},
string::String,
};
@@ -45,6 +46,13 @@ use crate::stdlib::mem;
#[cfg(not(target_arch = "wasm32"))]
use crate::stdlib::{fs::File, io::prelude::*, path::PathBuf};
/// Calculate a unique hash for a script.
fn calc_hash_for_scripts<'a>(scripts: impl IntoIterator<Item = &'a &'a str>) -> u64 {
let s = &mut get_hasher();
scripts.into_iter().for_each(|&script| script.hash(s));
s.finish()
}
/// Engine public API
impl Engine {
/// Register a function of the `Engine`.
@@ -907,8 +915,9 @@ impl Engine {
scripts: &[&str],
optimization_level: OptimizationLevel,
) -> Result<AST, ParseError> {
let hash = calc_hash_for_scripts(scripts);
let stream = self.lex(scripts, None);
self.parse(&mut stream.peekable(), scope, optimization_level)
self.parse(hash, &mut stream.peekable(), scope, optimization_level)
}
/// Read the contents of a file into a string.
@@ -1061,6 +1070,7 @@ impl Engine {
.into());
};
let hash = calc_hash_for_scripts(&scripts);
let stream = self.lex(
&scripts,
if has_null {
@@ -1073,8 +1083,12 @@ impl Engine {
None
},
);
let ast =
self.parse_global_expr(&mut stream.peekable(), &scope, OptimizationLevel::None)?;
let ast = self.parse_global_expr(
hash,
&mut stream.peekable(),
&scope,
OptimizationLevel::None,
)?;
// Handle null - map to ()
if has_null {
@@ -1155,10 +1169,11 @@ impl Engine {
script: &str,
) -> Result<AST, ParseError> {
let scripts = [script];
let hash = calc_hash_for_scripts(&scripts);
let stream = self.lex(&scripts, None);
let mut peekable = stream.peekable();
self.parse_global_expr(&mut peekable, scope, self.optimization_level)
self.parse_global_expr(hash, &mut peekable, scope, self.optimization_level)
}
/// Evaluate a script file.
@@ -1315,10 +1330,12 @@ impl Engine {
script: &str,
) -> Result<T, Box<EvalAltResult>> {
let scripts = [script];
let hash = calc_hash_for_scripts(&scripts);
let stream = self.lex(&scripts, None);
// No need to optimize a lone expression
let ast = self.parse_global_expr(&mut stream.peekable(), scope, OptimizationLevel::None)?;
let ast =
self.parse_global_expr(hash, &mut stream.peekable(), scope, OptimizationLevel::None)?;
self.eval_ast_with_scope(scope, &ast)
}
@@ -1445,8 +1462,9 @@ impl Engine {
script: &str,
) -> Result<(), Box<EvalAltResult>> {
let scripts = [script];
let hash = calc_hash_for_scripts(&scripts);
let stream = self.lex(&scripts, None);
let ast = self.parse(&mut stream.peekable(), scope, self.optimization_level)?;
let ast = self.parse(hash, &mut stream.peekable(), scope, self.optimization_level)?;
self.consume_ast_with_scope(scope, &ast)
}