asgerf / parsejs.dart

JavaScript parser for Dart
BSD 2-Clause "Simplified" License
26 stars 11 forks source link

ObjectExpressions are parsed as BlockStatements #3

Closed thosakwe closed 7 years ago

thosakwe commented 7 years ago

Willing to submit a PR, but the following:

{ a: 2, b: 'a'}

is parsed as a BlockStatement, not an ObjectExpression.

asgerf commented 7 years ago

Hi,

Unfortunately that is how JS actually works. Although most JS interactive consoles has a workaround for it, this does not apply to real JS code being read from a file.

For example, here is an interactive session with node.js:

~ $ node
> { a: 2, b: 'a'}
{ a: 2, b: 'a' }

But if I read it from a file instead:

~ $ cat foo.js
{ a: 2, b: 'a'}
~ $ node foo.js
foo.js:1
(function (exports, require, module, __filename, __dirname) { { a: 2, b: 'a'}
                                                                       ^
SyntaxError: Unexpected token :
    at createScript (vm.js:53:10)
    at Object.runInThisContext (vm.js:95:10)
    at Module._compile (module.js:543:28)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)
    at run (bootstrap_node.js:427:7)
    at startup (bootstrap_node.js:148:9)

If you know you are parsing an expression, and you are willing to rely on internal API, you can call the parser directly, like this:

new Parser(new Lexer(...)).parseExpression()

But I can see the value in parsing a standalone JS expression, so I can expose this functionality in the public API if you like.

thosakwe commented 7 years ago

That would be great, thank you! I'm currently using this to write an interpreter, and this would make a REPL more feasible.

asgerf commented 7 years ago

I have released version 1.2.0 which adds the named argument parseAsExpression.

If you want to support both expressions and statements as input, you can use a wrapper like this:

Program parseInput(String text) {
  try {
    return parsejs(text, parseAsExpression: true);
  } on ParseError {
    return parsejs(text);
  }
}

I am closing this issue, but feel free to reopen if it doesn't work for you.

thosakwe commented 7 years ago

Thank you very much! Maybe one of these days I'll submit a PR to support ES6 syntax...