Enable parsing of lambda captures

Closes #161
This commit is contained in:
Jason Turner 2015-03-21 20:30:52 -06:00
parent c416ca1e4d
commit 976e4ec46c
2 changed files with 42 additions and 9 deletions

View File

@ -226,6 +226,7 @@ namespace chaiscript
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
std::vector<Boxed_Value> params;
if ((this->children.size() > 1)) {
@ -706,9 +707,14 @@ namespace chaiscript
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{
std::cout << "lambda num children = " << children.size() << std::endl;
// const auto captures = get_captures(this->children[0], t_ss);
const auto captures = [&](){
std::map<std::string, Boxed_Value> named_captures;
for (const auto &capture : children[0]->children) {
named_captures.emplace(capture->children[0]->text, capture->children[0]->eval(t_ss));
}
return named_captures;
}();
const auto numparams = this->children[1]->children.size();
const auto param_names = Arg_List_AST_Node::get_arg_names(this->children[1]);
@ -717,15 +723,13 @@ namespace chaiscript
const auto &lambda_node = this->children.back();
return Boxed_Value(Proxy_Function(new dispatch::Dynamic_Proxy_Function(
[&t_ss, lambda_node, param_names](const std::vector<Boxed_Value> &t_params)
[&t_ss, lambda_node, param_names, captures](const std::vector<Boxed_Value> &t_params)
{
return detail::eval_function(t_ss, lambda_node, param_names, t_params);
return detail::eval_function(t_ss, lambda_node, param_names, t_params, captures);
},
static_cast<int>(numparams), lambda_node, param_types)));
}
private:
// std::map<std::string, Boxed_Value>
};

View File

@ -692,7 +692,7 @@ namespace chaiscript
}
/// Reads an argument from input
bool Arg() {
bool Arg(const bool t_type_allowed = true) {
const auto prev_stack_top = m_match_stack.size();
SkipWS();
@ -701,7 +701,10 @@ namespace chaiscript
}
SkipWS();
Id(true);
if (t_type_allowed) {
Id(true);
}
build_match(std::make_shared<eval::Arg_AST_Node>(), prev_stack_top);
@ -1120,6 +1123,32 @@ namespace chaiscript
}
}
/// Reads a comma-separated list of values from input. Id's only, no types allowed
bool Id_Arg_List() {
SkipWS(true);
bool retval = false;
const auto prev_stack_top = m_match_stack.size();
if (Arg(false)) {
retval = true;
while (Eol()) {}
if (Char(',')) {
do {
while (Eol()) {}
if (!Arg(false)) {
throw exception::eval_error("Unexpected value in parameter list", File_Position(m_line, m_col), *m_filename);
}
} while (Char(','));
}
}
build_match(std::make_shared<eval::Arg_List_AST_Node>(), prev_stack_top);
SkipWS(true);
return retval;
}
/// Reads a comma-separated list of values from input, for function declarations
bool Decl_Arg_List() {
SkipWS(true);
@ -1224,7 +1253,7 @@ namespace chaiscript
retval = true;
if (Char('[')) {
Arg_List();
Id_Arg_List();
if (!Char(']')) {
throw exception::eval_error("Incomplete anonymous function bind", File_Position(m_line, m_col), *m_filename);
}