maximecb/Higgs — pull request #85 by robotlolita (2014-03-15 14:18:47+00:00)
Title: Proposed solution for new Function(...) - Fixes #26

This implements the `new Function` constructor as per ECMAScript 5 http://es5.github.io/#x15.3.2.1 algorithm. But there are a couple of things worth note, and a couple of problems to address before it can be merged, so this is more of a PR to initiate a discussion.

First, as discussed in #26, ES5 expects this implementation to throw SyntaxErrors in case of a mal-formed `FormalParameterList` and `FunctionBody`. The former is easy to address by leaving it to the internal Higgs parser, one just needs to make sure none of the arguments will contain a closing parenthesis — though I just noticed the current implementation doesn't handle comments, I'm unsure whether this breaks something yet.

The latter is a lot more difficult, since the grammar is much more complex. The ideal would be for Higgs to expose a function that would test if some string is a valid `FunctionBody` using the internal parser, but since this is a lot of work, I've done a cheap hack based on @teebrz's suggestion, where I just make sure all brackets are balanced, leaving the rest of the work for Higgs' internal parser. This does require handling string literals and comments, I'm not sure if there's any other construct I've overlooked here that would allow brackets to have a different meaning. This does pose some overhead, since the string has to be verified twice, but the algorithm runs in linear time, and there is no need for backtracking or lots of expensive function calls, so I think it's a good compromise.

The second problem is related to executing this function in the global scope. Higgs provides the `$ir_eval_str(fn)` function for doing a global eval, but this internal function throws only internal exceptions, that aren't reifed to the JavaScript side. As such, all the tests that rely on this function throwing exceptions in the case of a mal-formed function don't work. Is there an alternative to this that would throw exceptions on the JavaScript side of things?

There are a few things I've overlooked in the algorithm (like having to convert the function body using ToString), but I'm going to fix these.

Another thing I'm unsure on how to proceed is the organisation of these helper functions. The things on the standard library run on the global namespace. Should I wrap the whole file in a function expression and lift the helper functions to the outer scope, to avoid re-creating them every time the Function constructor is called?

Hm, I think that's about it. Feel free to point any other mistake I've overlooked.