From 63684d00425ffea5c5c30ad3bf546bc01a3d0dd3 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 8 Apr 2015 08:17:33 -0600 Subject: [PATCH] Add the ability to get the return value from 'use' --- cheatsheet.md | 11 ++++++++++ .../chaiscript/language/chaiscript_engine.hpp | 22 ++++++++++++++----- unittests/eval.chai | 2 ++ unittests/eval_file.chai | 10 +++++++++ unittests/use.chai | 4 +++- unittests/use.inc | 1 + 6 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 unittests/eval_file.chai diff --git a/cheatsheet.md b/cheatsheet.md index b8be1a92..fc229acb 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -258,4 +258,15 @@ print(get_value(m)); // prints "Value Is: a" +# Built In Functions + +## Evaluation + +``` +eval("4 + 5") // dynamically eval script string and returns value of last statement +eval_file("filename") // evals file and returns value of last statement +use("filename") // evals file exactly once and returns value of last statement + // if the file had already been 'used' nothing happens and undefined is returned +``` + diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index b4e52693..9ee75d68 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -297,6 +297,15 @@ namespace chaiscript } } + /// Evaluates the given string, used during eval() inside of a script + const Boxed_Value internal_eval_file(const std::string &t_filename) { + try { + return do_eval(load_file(t_filename), t_filename, true); + } catch (const exception::eval_error &t_ee) { + throw Boxed_Value(t_ee); + } + } + /// Evaluates the given string, used during eval() inside of a script @@ -369,6 +378,7 @@ namespace chaiscript m_engine.add(fun(static_cast(&ChaiScript::load_module), this), "load_module"); m_engine.add(fun(&ChaiScript::use, this), "use"); + m_engine.add(fun(&ChaiScript::internal_eval_file, this), "eval_file"); m_engine.add(fun(&ChaiScript::internal_eval, this), "eval"); m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval"); @@ -457,7 +467,7 @@ namespace chaiscript union cast_union { - void (ChaiScript::*in_ptr)(const std::string&); + Boxed_Value (ChaiScript::*in_ptr)(const std::string&); void *out_ptr; }; @@ -531,7 +541,7 @@ namespace chaiscript /// requested file. /// /// \param[in] t_filename Filename to load and evaluate - void use(const std::string &t_filename) + Boxed_Value use(const std::string &t_filename) { for (const auto &path : m_usepaths) { @@ -541,15 +551,17 @@ namespace chaiscript chaiscript::detail::threading::unique_lock l(m_use_mutex); chaiscript::detail::threading::unique_lock l2(m_mutex); + Boxed_Value retval; + if (m_used_files.count(appendedpath) == 0) { l2.unlock(); - eval_file(appendedpath); + retval = eval_file(appendedpath); l2.lock(); m_used_files.insert(appendedpath); - } + } - return; // return, we loaded it, or it was already loaded + return retval; // return, we loaded it, or it was already loaded } catch (const exception::file_not_found_error &) { // failed to load, try the next path } diff --git a/unittests/eval.chai b/unittests/eval.chai index 2f18aa41..4db72da2 100644 --- a/unittests/eval.chai +++ b/unittests/eval.chai @@ -1 +1,3 @@ assert_equal(7, eval("3 + 4")) + + diff --git a/unittests/eval_file.chai b/unittests/eval_file.chai new file mode 100644 index 00000000..be9934e1 --- /dev/null +++ b/unittests/eval_file.chai @@ -0,0 +1,10 @@ + +try { + eval_file("use.inc") + assert(true) + + //we expect this second eval_file to fail because of a function redefinition + eval_file("use.inc") + assert(false) +} catch (e) { +} diff --git a/unittests/use.chai b/unittests/use.chai index efd587da..317cced2 100644 --- a/unittests/use.chai +++ b/unittests/use.chai @@ -1,4 +1,5 @@ -use("use.inc") +var newfun = use("use.inc"); + assert_equal("hello", greet()) @@ -7,3 +8,4 @@ use("use.inc") assert_equal("hello", greet()) +assert_equal("world", newfun()) diff --git a/unittests/use.inc b/unittests/use.inc index 28970935..0f9fea77 100644 --- a/unittests/use.inc +++ b/unittests/use.inc @@ -2,3 +2,4 @@ def greet { return("hello") } +fun(){ "world" }