Fix problems with script-defined functions.
This commit is contained in:
parent
01bee6e16e
commit
3af421ae5f
@ -545,6 +545,9 @@ print(add(2, 3));
|
|||||||
```
|
```
|
||||||
|
|
||||||
Remember that functions defined in script always take `Dynamic` arguments (i.e. the arguments can be of any type).
|
Remember that functions defined in script always take `Dynamic` arguments (i.e. the arguments can be of any type).
|
||||||
|
|
||||||
|
Arguments are passed by value, so all functions are _pure_ (i.e. they never modify their arguments).
|
||||||
|
|
||||||
Furthermore, functions can only be defined at the top level, never inside a block or another function.
|
Furthermore, functions can only be defined at the top level, never inside a block or another function.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
@ -144,11 +144,6 @@ impl Engine {
|
|||||||
.map_err(|err| EvalAltResult::ErrorParsing(err))
|
.map_err(|err| EvalAltResult::ErrorParsing(err))
|
||||||
.and_then(|AST(ref os, ref fns)| {
|
.and_then(|AST(ref os, ref fns)| {
|
||||||
for f in fns {
|
for f in fns {
|
||||||
// FIX - Why are functions limited to 6 parameters?
|
|
||||||
if f.params.len() > 6 {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
self.script_fns.insert(
|
self.script_fns.insert(
|
||||||
FnSpec {
|
FnSpec {
|
||||||
ident: f.name.clone(),
|
ident: f.name.clone(),
|
||||||
|
@ -21,7 +21,7 @@ const KEYWORD_TYPE_OF: &'static str = "type_of";
|
|||||||
pub enum EvalAltResult {
|
pub enum EvalAltResult {
|
||||||
ErrorParsing(ParseError),
|
ErrorParsing(ParseError),
|
||||||
ErrorFunctionNotFound(String, Position),
|
ErrorFunctionNotFound(String, Position),
|
||||||
ErrorFunctionArgsMismatch(String, usize, Position),
|
ErrorFunctionArgsMismatch(String, usize, usize, Position),
|
||||||
ErrorBooleanArgMismatch(String, Position),
|
ErrorBooleanArgMismatch(String, Position),
|
||||||
ErrorArrayBounds(usize, i64, Position),
|
ErrorArrayBounds(usize, i64, Position),
|
||||||
ErrorStringBounds(usize, i64, Position),
|
ErrorStringBounds(usize, i64, Position),
|
||||||
@ -45,7 +45,7 @@ impl Error for EvalAltResult {
|
|||||||
match self {
|
match self {
|
||||||
Self::ErrorParsing(p) => p.description(),
|
Self::ErrorParsing(p) => p.description(),
|
||||||
Self::ErrorFunctionNotFound(_, _) => "Function not found",
|
Self::ErrorFunctionNotFound(_, _) => "Function not found",
|
||||||
Self::ErrorFunctionArgsMismatch(_, _, _) => {
|
Self::ErrorFunctionArgsMismatch(_, _, _, _) => {
|
||||||
"Function call with wrong number of arguments"
|
"Function call with wrong number of arguments"
|
||||||
}
|
}
|
||||||
Self::ErrorBooleanArgMismatch(_, _) => "Boolean operator expects boolean operands",
|
Self::ErrorBooleanArgMismatch(_, _) => "Boolean operator expects boolean operands",
|
||||||
@ -105,9 +105,11 @@ impl std::fmt::Display for EvalAltResult {
|
|||||||
write!(f, "{} '{}': {}", desc, filename, err)
|
write!(f, "{} '{}': {}", desc, filename, err)
|
||||||
}
|
}
|
||||||
Self::ErrorParsing(p) => write!(f, "Syntax error: {}", p),
|
Self::ErrorParsing(p) => write!(f, "Syntax error: {}", p),
|
||||||
Self::ErrorFunctionArgsMismatch(fun, n, pos) => {
|
Self::ErrorFunctionArgsMismatch(fun, need, n, pos) => write!(
|
||||||
write!(f, "Function '{}' expects {} argument(s) ({})", fun, n, pos)
|
f,
|
||||||
}
|
"Function '{}' expects {} argument(s) but {} found ({})",
|
||||||
|
fun, need, n, pos
|
||||||
|
),
|
||||||
Self::ErrorBooleanArgMismatch(op, pos) => {
|
Self::ErrorBooleanArgMismatch(op, pos) => {
|
||||||
write!(f, "{} operator expects boolean operands ({})", op, pos)
|
write!(f, "{} operator expects boolean operands ({})", op, pos)
|
||||||
}
|
}
|
||||||
@ -244,6 +246,15 @@ impl Engine {
|
|||||||
.into_dynamic())
|
.into_dynamic())
|
||||||
}
|
}
|
||||||
FnIntExt::Int(ref f) => {
|
FnIntExt::Int(ref f) => {
|
||||||
|
if f.params.len() != args.len() {
|
||||||
|
return Err(EvalAltResult::ErrorFunctionArgsMismatch(
|
||||||
|
spec.ident,
|
||||||
|
f.params.len(),
|
||||||
|
args.len(),
|
||||||
|
pos,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
let mut scope = Scope::new();
|
let mut scope = Scope::new();
|
||||||
|
|
||||||
scope.extend(
|
scope.extend(
|
||||||
|
@ -39,7 +39,7 @@ macro_rules! def_register {
|
|||||||
const NUM_ARGS: usize = count_args!($($par)*);
|
const NUM_ARGS: usize = count_args!($($par)*);
|
||||||
|
|
||||||
if args.len() != NUM_ARGS {
|
if args.len() != NUM_ARGS {
|
||||||
Err(EvalAltResult::ErrorFunctionArgsMismatch(fn_name.clone(), NUM_ARGS, pos))
|
Err(EvalAltResult::ErrorFunctionArgsMismatch(fn_name.clone(), NUM_ARGS, args.len(), pos))
|
||||||
} else {
|
} else {
|
||||||
#[allow(unused_variables, unused_mut)]
|
#[allow(unused_variables, unused_mut)]
|
||||||
let mut drain = args.drain(..);
|
let mut drain = args.drain(..);
|
||||||
@ -72,7 +72,7 @@ macro_rules! def_register {
|
|||||||
const NUM_ARGS: usize = count_args!($($par)*);
|
const NUM_ARGS: usize = count_args!($($par)*);
|
||||||
|
|
||||||
if args.len() != NUM_ARGS {
|
if args.len() != NUM_ARGS {
|
||||||
Err(EvalAltResult::ErrorFunctionArgsMismatch(fn_name.clone(), NUM_ARGS, pos))
|
Err(EvalAltResult::ErrorFunctionArgsMismatch(fn_name.clone(), NUM_ARGS, args.len(), pos))
|
||||||
} else {
|
} else {
|
||||||
#[allow(unused_variables, unused_mut)]
|
#[allow(unused_variables, unused_mut)]
|
||||||
let mut drain = args.drain(..);
|
let mut drain = args.drain(..);
|
||||||
|
Loading…
Reference in New Issue
Block a user