diff --git a/src/vm/callables.rs b/src/vm/callables.rs index bbb7f995b..55319929e 100644 --- a/src/vm/callables.rs +++ b/src/vm/callables.rs @@ -54,7 +54,7 @@ impl PublicFunction { return Err(Error::TypeError(format!("{:?}", type_sig), value.clone())) } if let Some(_) = context.variables.insert(arg.clone(), value.clone()) { - return Err(Error::MultiplyDefined(arg.clone())) + return Err(Error::VariableDefinedMultipleTimes(arg.clone())) } } eval(&self.body, env, &context) @@ -74,7 +74,7 @@ impl PrivateFunction { let arg_iterator = self.arguments.iter().zip(args.iter()); for (arg, value) in arg_iterator { if let Some(_) = context.variables.insert(arg.clone(), value.clone()) { - return Err(Error::MultiplyDefined(arg.clone())) + return Err(Error::VariableDefinedMultipleTimes(arg.clone())) } } eval(&self.body, env, &context) diff --git a/src/vm/errors.rs b/src/vm/errors.rs index 607250ea7..3d2a06ca4 100644 --- a/src/vm/errors.rs +++ b/src/vm/errors.rs @@ -26,7 +26,7 @@ pub enum Error { BadSymbolicRepresentation(String), ReservedName(String), InterpreterError(String), - MultiplyDefined(String) + VariableDefinedMultipleTimes(String) } pub type InterpreterResult = Result; diff --git a/src/vm/functions/define.rs b/src/vm/functions/define.rs index ed4dd5d60..af37fca6c 100644 --- a/src/vm/functions/define.rs +++ b/src/vm/functions/define.rs @@ -19,7 +19,7 @@ fn check_legal_define(name: &str, global_context: &GlobalContext) -> Result<()> if is_reserved(name) { Err(Error::ReservedName(name.to_string())) } else if global_context.variables.contains_key(name) || global_context.functions.contains_key(name) { - Err(Error::MultiplyDefined(name.to_string())) + Err(Error::VariableDefinedMultipleTimes(name.to_string())) } else { Ok(()) } diff --git a/src/vm/functions/mod.rs b/src/vm/functions/mod.rs index 0e2fd1d02..8cf5c5c19 100644 --- a/src/vm/functions/mod.rs +++ b/src/vm/functions/mod.rs @@ -78,7 +78,7 @@ fn special_let(args: &[SymbolicExpression], env: &mut Environment, context: &Loc } let value = eval(&binding_exps[1], env, context)?; match inner_context.variables.insert((*var_name).clone(), value) { - Some(_val) => return Err(Error::MultiplyDefined(var_name.to_string())), + Some(_val) => return Err(Error::VariableDefinedMultipleTimes(var_name.to_string())), _ => continue } } else { diff --git a/src/vm/mod.rs b/src/vm/mod.rs index 09ede1d22..8f8e1aa56 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -171,3 +171,38 @@ pub fn execute(program: &str) -> Result { let parsed = parser::parse(program)?; eval_all(&parsed, &mut *db_instance, &mut global_context) } + + +mod test { + #[test] + fn test_simple_user_function() { + // + // test program: + // (define (do_work x) (+ 5 x)) + // (define a 59) + // (do_work a) + // + + let content = [ SymbolicExpression::List( + Box::new([ SymbolicExpression::Atom("do_work".to_string()), + SymbolicExpression::Atom("a".to_string()) ])) ]; + + let func_body = SymbolicExpression::List( + Box::new([ SymbolicExpression::Atom("+".to_string()), + SymbolicExpression::AtomValue(Value::Int(5)), + SymbolicExpression::Atom("x".to_string())])); + + let func_args = vec!["x".to_string()]; + let user_function = PrivateFunction::new(func_args, func_body); + + let context = LocalContext::new(); + let mut global_context = GlobalContext::new(); + let mut db = MemoryContractDatabase::new(); + + global_context.variables.insert("a".to_string(), Value::Int(59)); + global_context.functions.insert("do_work".to_string(), user_function); + + let mut env = Environment::new(&global_context, &mut db); + assert_eq!(Ok(Value::Int(64)), eval(&content[0], &mut env, &context)); + } +} diff --git a/src/vm/tests/defines.rs b/src/vm/tests/defines.rs index 10a8d83f3..9333f7a25 100644 --- a/src/vm/tests/defines.rs +++ b/src/vm/tests/defines.rs @@ -39,7 +39,7 @@ fn test_bad_define_names() { assert_eq!(Err(Error::ReservedName("*".to_string())), execute(&test1)); assert_eq!(Err(Error::InvalidArguments("Illegal operation: attempted to re-define a value type.".to_string())), execute(&test2)); - assert_eq!(Err(Error::MultiplyDefined("foo".to_string())), + assert_eq!(Err(Error::VariableDefinedMultipleTimes("foo".to_string())), execute(&test3)); } diff --git a/src/vm/tests/simple_apply_eval.rs b/src/vm/tests/simple_apply_eval.rs index f98eb62c6..11cfa5840 100644 --- a/src/vm/tests/simple_apply_eval.rs +++ b/src/vm/tests/simple_apply_eval.rs @@ -6,38 +6,6 @@ use vm::callables::PrivateFunction; use vm::representations::SymbolicExpression; use vm::parser::parse; -#[test] -fn test_simple_user_function() { - // - // test program: - // (define (do_work x) (+ 5 x)) - // (define a 59) - // (do_work a) - // - - let content = [ SymbolicExpression::List( - Box::new([ SymbolicExpression::Atom("do_work".to_string()), - SymbolicExpression::Atom("a".to_string()) ])) ]; - - let func_body = SymbolicExpression::List( - Box::new([ SymbolicExpression::Atom("+".to_string()), - SymbolicExpression::AtomValue(Value::Int(5)), - SymbolicExpression::Atom("x".to_string())])); - - let func_args = vec!["x".to_string()]; - let user_function = PrivateFunction::new(func_args, func_body); - - let context = LocalContext::new(); - let mut global_context = GlobalContext::new(); - let mut db = MemoryContractDatabase::new(); - - global_context.variables.insert("a".to_string(), Value::Int(59)); - global_context.functions.insert("do_work".to_string(), user_function); - - let mut env = Environment::new(&global_context, &mut db); - assert_eq!(Ok(Value::Int(64)), eval(&content[0], &mut env, &context)); -} - #[test] fn test_simple_let() { /* @@ -262,7 +230,7 @@ fn test_bad_lets() { let expectations: &[Result] = &[ Err(Error::ReservedName("tx-sender".to_string())), Err(Error::ReservedName("*".to_string())), - Err(Error::MultiplyDefined("a".to_string()))]; + Err(Error::VariableDefinedMultipleTimes("a".to_string()))]; tests.iter().zip(expectations.iter()) .for_each(|(program, expectation)| assert_eq!(*expectation, execute(program)));