diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 1a920bd..6a01d67 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -495,7 +495,6 @@ namespace chaiscript { namespace detail { - /// Special type for returned values struct Return_Value { Boxed_Value retval; diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 77ce45a..a266bc6 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -276,7 +276,7 @@ namespace chaiscript parser::ChaiScript_Parser parser; if (parser.parse(t_input, t_filename)) { //parser.show_match_stack(); - return parser.ast()->eval(m_engine); + return parser.optimized_ast()->eval(m_engine); } else { return Boxed_Value(); } diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index f6b2b12..ccd9248 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -196,6 +196,60 @@ namespace chaiscript return m_match_stack.front(); } + static void optimize_blocks(AST_NodePtr &p) + { + for (auto &c : p->children) + { + if (c->identifier == AST_Node_Type::Block) { + if (c->children.size() == 1) { + std::cout << "swapping out block child for block\n"; + c = c->children[0]; + } + } + optimize_blocks(c); + } + } + + static void optimize_returns(AST_NodePtr &p) + { + for (auto &c : p->children) + { + if (c->identifier == AST_Node_Type::Def && c->children.size() > 0) { + auto &lastchild = c->children.back(); + if (lastchild->identifier == AST_Node_Type::Block) { + auto &blocklastchild = lastchild->children.back(); + if (blocklastchild->identifier == AST_Node_Type::Return) { + if (blocklastchild->children.size() == 1) { + blocklastchild = blocklastchild->children[0]; + } + } + } + } + optimize_returns(c); + } + } + + static int count_nodes(const AST_NodePtr &p) + { + int count = 1; + for (auto &c : p->children) { + count += count_nodes(c); + } + return count; + } + + AST_NodePtr optimized_ast() { + std::cout << " Optimizing AST \n"; + AST_NodePtr p = m_match_stack.front(); + std::cout << "Node Count: " << count_nodes(p) << '\n'; + optimize_blocks(p); + std::cout << "Optimized Block Node Count: " << count_nodes(p) << '\n'; + optimize_returns(p); + std::cout << "Returns Block Node Count: " << count_nodes(p) << '\n'; + return p; + } + + /// Helper function that collects ast_nodes from a starting position to the top of the stack into a new AST node void build_match(AST_NodePtr t_t, size_t t_match_start) { int pos_line_start, pos_col_start, pos_line_stop, pos_col_stop; diff --git a/include/chaiscript/language/chaiscript_prelude.chai b/include/chaiscript/language/chaiscript_prelude.chai index 1db8702..88835c5 100644 --- a/include/chaiscript/language/chaiscript_prelude.chai +++ b/include/chaiscript/language/chaiscript_prelude.chai @@ -38,7 +38,24 @@ def eq(l, r) { def new(x) { eval(type_name(x))(); -} +} + +def clone(double x) { + double(x).copy_var_attrs(x) +} + +def clone(string x) { + string(x).copy_var_attrs(x) +} + +def clone(vector x) { + vector(x).copy_var_attrs(x) +} + + +def clone(int x) { + int(x).copy_var_attrs(x) +} def clone(x) : function_exists(type_name(x)) && call_exists(eval(type_name(x)), x) {