From a28dfd8695812122c1dc6648535bd35e4166af64 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 24 Sep 2011 14:21:21 -0600 Subject: [PATCH] Get & variable declarations working --- .../chaiscript/language/chaiscript_common.hpp | 2 +- .../chaiscript/language/chaiscript_eval.hpp | 46 ++++++++++++++----- .../chaiscript/language/chaiscript_parser.hpp | 5 +- unittests/var_ref_decl.chai | 19 ++++++++ 4 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 unittests/var_ref_decl.chai diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 74fb410..f8af5e1 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -112,7 +112,7 @@ namespace chaiscript struct AST_Node : std::enable_shared_from_this { public: const std::string text; - const int identifier; + const int identifier; //< \todo shouldn't this be a strongly typed enum value? std::shared_ptr filename; File_Position start, end; std::vector children; diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index e4d4d5a..aaad2c8 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -295,7 +295,16 @@ namespace chaiscript } else if (this->children[1]->text == "=") { try { if (lhs.is_undef()) { - retval = t_ss.call_function("clone", retval); + if (!this->children.empty() && + !this->children[0]->children.empty() + && this->children[0]->children[0]->identifier == AST_Node_Type::Reference) + { + /// \todo This does not handle the case of an unassigned reference variable + /// being assigned outside of its declaration + lhs.assign(retval); + } else { + retval = t_ss.call_function("clone", retval); + } retval.clear_dependencies(); } @@ -335,13 +344,21 @@ namespace chaiscript AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Var_Decl_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ - try { - t_ss.add_object(this->children[0]->text, Boxed_Value()); + if (this->children[0]->identifier == AST_Node_Type::Reference) + { + return this->children[0]->eval(t_ss); + } else { + std::string idname = this->children[0]->text; + + try { + t_ss.add_object(idname, Boxed_Value()); + } + catch (const exception::reserved_word_error &) { + throw exception::eval_error("Reserved word used as variable '" + idname + "'"); + } + return t_ss.get_object(idname); } - catch (const exception::reserved_word_error &) { - throw exception::eval_error("Reserved word used as variable '" + this->children[0]->text + "'"); - } - return t_ss.get_object(this->children[0]->text); + } }; @@ -848,16 +865,23 @@ namespace chaiscript } }; - struct Reference_Node : public AST_Node { + struct Reference_AST_Node : public AST_Node { public: - Reference_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Prefix, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Reference_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Reference, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } - virtual ~Reference_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ - return Boxed_Value(); + try { + t_ss.add_object(this->children[0]->text, Boxed_Value()); + } + catch (const exception::reserved_word_error &) { + throw exception::eval_error("Reserved word used as variable '" + this->children[0]->text + "'"); + } + return t_ss.get_object(this->children[0]->text); } + + virtual ~Reference_AST_Node() {} }; struct Prefix_AST_Node : public AST_Node { diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 797bb35..eb4eda6 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1634,8 +1634,11 @@ namespace chaiscript throw exception::eval_error("Incomplete '&' expression", File_Position(m_line, m_col), *m_filename); } - build_match(AST_NodePtr(new eval::Reference_Node()), prev_stack_top); + build_match(AST_NodePtr( + new eval::Reference_AST_Node()), prev_stack_top); } + + return retval; } /** diff --git a/unittests/var_ref_decl.chai b/unittests/var_ref_decl.chai new file mode 100644 index 0000000..58bfa24 --- /dev/null +++ b/unittests/var_ref_decl.chai @@ -0,0 +1,19 @@ +auto l = 5 +auto & k = l; + + +assert_equal(l, k) + +l = 10 + +assert_equal(10, l) +assert_equal(k, l) + +auto & j +j = l // assignment outside of declaration does *not* result in reference assignment +j = 15 + +assert_equal(15, j) +assert_equal(k, l) +assert_equal(10, l) +