diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 2e622c2..f0a3888 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -47,9 +47,13 @@ namespace chaiscript namespace detail { /// Helper function that will set up the scope around a function call, including handling the named function parameters - static Boxed_Value eval_function(chaiscript::detail::Dispatch_Engine &t_ss, const AST_NodePtr &t_node, const std::vector &t_param_names, const std::vector &t_vals) { + static Boxed_Value eval_function(chaiscript::detail::Dispatch_Engine &t_ss, const AST_NodePtr &t_node, const std::vector &t_param_names, const std::vector &t_vals, const std::map &t_locals=std::map()) { chaiscript::eval::detail::Scope_Push_Pop spp(t_ss); + for (const auto &local : t_locals) { + t_ss.add_object(local.first, local.second); + } + for (size_t i = 0; i < t_param_names.size(); ++i) { t_ss.add_object(t_param_names[i], t_vals[i]); } @@ -701,28 +705,28 @@ namespace chaiscript virtual ~Lambda_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{ - std::vector t_param_names; - size_t numparams = 0; + std::cout << "lambda num children = " << children.size() << std::endl; - dispatch::Param_Types param_types; +// const auto captures = get_captures(this->children[0], t_ss); - if (!this->children.empty() && (this->children[0]->identifier == AST_Node_Type::Arg_List)) { - numparams = this->children[0]->children.size(); - t_param_names = Arg_List_AST_Node::get_arg_names(this->children[0]); - param_types = Arg_List_AST_Node::get_arg_types(this->children[0], t_ss); - } + const auto numparams = this->children[1]->children.size(); + const auto param_names = Arg_List_AST_Node::get_arg_names(this->children[1]); + const auto param_types = Arg_List_AST_Node::get_arg_types(this->children[1], t_ss); const auto &lambda_node = this->children.back(); return Boxed_Value(Proxy_Function(new dispatch::Dynamic_Proxy_Function( - [&t_ss, lambda_node, t_param_names](const std::vector &t_params) + [&t_ss, lambda_node, param_names](const std::vector &t_params) { - return detail::eval_function(t_ss, lambda_node, t_param_names, t_params); + return detail::eval_function(t_ss, lambda_node, param_names, t_params); }, static_cast(numparams), lambda_node, param_types))); } + private: + // std::map + }; struct Block_AST_Node : public AST_Node { @@ -1388,7 +1392,7 @@ namespace chaiscript guard = std::make_shared (std::bind(chaiscript::eval::detail::eval_function, std::ref(t_ss), guardnode, - t_param_names, std::placeholders::_1), static_cast(numparams), guardnode); + t_param_names, std::placeholders::_1, std::map()), static_cast(numparams), guardnode); } try { @@ -1399,7 +1403,7 @@ namespace chaiscript if (function_name == class_name) { param_types.push_front(class_name, Type_Info()); t_ss.add(std::make_shared(class_name, std::make_shared(std::bind(chaiscript::eval::detail::eval_function, - std::ref(t_ss), this->children.back(), t_param_names, std::placeholders::_1), + std::ref(t_ss), this->children.back(), t_param_names, std::placeholders::_1, std::map()), static_cast(numparams), this->children.back(), param_types, l_annotation, guard)), function_name); @@ -1415,7 +1419,7 @@ namespace chaiscript std::make_shared(class_name, std::make_shared(std::bind(chaiscript::eval::detail::eval_function, std::ref(t_ss), this->children.back(), - t_param_names, std::placeholders::_1), static_cast(numparams), this->children.back(), + t_param_names, std::placeholders::_1, std::map()), static_cast(numparams), this->children.back(), param_types, l_annotation, guard), type), function_name); } catch (const std::range_error &) { param_types.push_front(class_name, Type_Info()); @@ -1424,7 +1428,7 @@ namespace chaiscript std::make_shared(class_name, std::make_shared(std::bind(chaiscript::eval::detail::eval_function, std::ref(t_ss), this->children.back(), - t_param_names, std::placeholders::_1), static_cast(numparams), this->children.back(), + t_param_names, std::placeholders::_1, std::map()), static_cast(numparams), this->children.back(), param_types, l_annotation, guard)), function_name); } } diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 117f5d6..fa1a931 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1138,8 +1138,8 @@ namespace chaiscript } } while (Char(',')); } - build_match(std::make_shared(), prev_stack_top); } + build_match(std::make_shared(), prev_stack_top); SkipWS(true); @@ -1223,13 +1223,26 @@ namespace chaiscript if (Keyword("fun")) { retval = true; + if (Char('[')) { + Arg_List(); + if (!Char(']')) { + throw exception::eval_error("Incomplete anonymous function bind", File_Position(m_line, m_col), *m_filename); + } + } else { + // make sure we always have the same number of nodes + build_match(std::make_shared(), prev_stack_top); + } + if (Char('(')) { Decl_Arg_List(); if (!Char(')')) { throw exception::eval_error("Incomplete anonymous function", File_Position(m_line, m_col), *m_filename); } + } else { + throw exception::eval_error("Incomplete anonymous function", File_Position(m_line, m_col), *m_filename); } + while (Eol()) {} if (!Block()) {