26 Commits (60821bb80b6223ffa7657383faa87fa4098b28d8)

Author SHA1 Message Date
David Majda 60821bb80b Sort "require" calls by variable names and group them
This makes things consistent and reduces thinking about "require"
ordering.
8 years ago
David Majda c134e06229 Move "use strict" directives up
Move "use strict" directives to the first line of each file. In
particular, move them above any ESLint comments, which are far less
important.

There are few exceptions:

  Executable files

    In these, the "use strict" directive must give way to the shebang.

  lib/parser.js

    Here, the "Generated by..." comment comes first. Also, ESLint
    comments are prepended in post-processing.
8 years ago
David Majda ff7193776e Avoid aligning "="
The only exception left are instances where aligning "=" helps to
express symmetry between lines.

See #443.
8 years ago
David Majda 400a3cfa3c Avoid aligning object keys
The only exception left are objects representing a mapping with simple
keys and values -- essentially tables written as object literals.

See #443.
8 years ago
David Majda 6294bb5b13 Use only "//" comments
See #443.
8 years ago
David Majda bdf91b5941 Replace "var" with "let" & "const"
This is purely a mechanical change, not taking advantage of block scope
of "let" and "const". Minimizing variable scope will come in the next
commit.

In general, "var" is converted into "let" and "const" is used only for
immutable variables of permanent character (generally spelled in
ALL_CAPS). Using it for any immutable variable regardless on its
permanence would feel confusing.

Any code which is not transpiled and needs to run in ES6 environment
(examples, code in grammars embedded in specs, ...) is kept unchanged.
This is also true for code generated by PEG.js.

See #442.
8 years ago
David Majda 959f20f6e2 Pass benchmark code through Babel before serving it to the browser
This will allow to use ES2015 constructs in benchmark code.

The change required introducing a small server, which serves both PEG.js
and benchmark code passed through Babel and bundled together. This
allowed to convert the benchmark to regular modules and to get rid of
the hackery that was previously needed to make it run both in Node.js
and in the browser.

Note the benchmark no longer exercises the browser version.

See #442.
8 years ago
David Majda 0847a69643 Rename the "PEG" variable to "peg"
So far, PEG.js was exported in a "PEG" global variable when no module
loader was detected. The same variable name was also conventionally used
when requiring it in Node.js or otherwise referring to it. This was
reflected in various places in the code, documentation, examples, etc.

This commit changes the variable name to "peg" and fixes all relevant
occurrences. The main reason for the change is that in Node.js, modules
are generally referred to by lower-case variable names, so "PEG" was
sticking out when used in Node.js projects.
8 years ago
David Majda e61c23c634 ESLint: Set environments better
Instead of setting ESLint environment to "node" globally, set it on
per-directory basis using separate .eslintrc.json files:

  Directory   Environment
  -----------------------
  bin         node
  lib         commonjs
  spec        jasmine

It was impossible to use this approach for the "benchmark" directory
which contains a mix of files used in various environments. For
benchmark/run, the environment is set inline. For the other files, as
well as spec/helpers.js, the globals are declared manually (it is
impossible to express how these files are used just by a list of
environments).

Fixes #408.
8 years ago
David Majda ee66113130 Fix ESLint errors in benchmark/run
Fix the following errors:

   37:3   error  Unexpected console statement      no-console
   38:3   error  Unexpected console statement      no-console
   42:3   error  Unexpected console statement      no-console
   43:3   error  Unexpected console statement      no-console
   44:3   error  Unexpected console statement      no-console
   51:3   error  Unexpected console statement      no-console
   64:3   error  Unexpected console statement      no-console
   68:3   error  Unexpected console statement      no-console
   74:3   error  Unexpected console statement      no-console
   75:3   error  Unexpected console statement      no-console
   76:3   error  Unexpected console statement      no-console
   77:3   error  Unexpected console statement      no-console
   78:3   error  Unexpected console statement      no-console
   79:3   error  Unexpected console statement      no-console
   80:3   error  Unexpected console statement      no-console
   81:3   error  Unexpected console statement      no-console
   82:3   error  Unexpected console statement      no-console
   94:3   error  Unexpected console statement      no-console
  126:11  error  "runCount" is already defined     no-redeclare
  169:34  error  "test" is defined but never used  no-unused-vars
  194:4   error  Unexpected trailing comma         comma-dangle
8 years ago
David Majda de1704f007 Replace |util.{puts,error}| by |console.{log,error}|
The |util.puts| and |util.error| functions are deprecated in Node.js
0.12.x.

Based on a pull request by Jan Stránský (@burningtree):

  https://github.com/pegjs/pegjs/pull/334
9 years ago
Arlo Breault 12c169e7b5 Convert PEG.js code to strict mode
* Issues #323
9 years ago
Arlo Breault 7a94f97b46 Convert benchmark files to modules 9 years ago
David Majda ff0beb5a8c benchmark/run: Always parse the -n/--run-count value as decimal integer 10 years ago
David Majda cc3a9fde2d Fix JSHint error in benchmark/run
Fixes the following JSHint error:

  benchmark/run: line 106, col 10, Wrap the /regexp/ literal in parens to disambiguate the slash operator.
10 years ago
David Majda fe1ca481ab Code generator rewrite
This is a complete rewrite of the PEG.js code generator. Its goals are:

  1. Allow optimizing the generated parser code for code size as well as
     for parsing speed.

  2. Prepare ground for future optimizations and big features (like
     incremental parsing).

  2. Replace the old template-based code-generation system with
     something more lightweight and flexible.

  4. General code cleanup (structure, style, variable names, ...).

New Architecture
----------------

The new code generator consists of two steps:

  * Bytecode generator -- produces bytecode for an abstract virtual
    machine

  * JavaScript generator -- produces JavaScript code based on the
    bytecode

The abstract virtual machine is stack-based. Originally I wanted to make
it register-based, but it turned out that all the code related to it
would be more complex and the bytecode itself would be longer (because
of explicit register specifications in instructions). The only downsides
of the stack-based approach seem to be few small inefficiencies (see
e.g. the |NIP| instruction), which seem to be insignificant.

The new generator allows optimizing for parsing speed or code size (you
can choose using the |optimize| option of the |PEG.buildParser| method
or the --optimize/-o option on the command-line).

When optimizing for size, the JavaScript generator emits the bytecode
together with its constant table and a generic bytecode interpreter.
Because the interpreter is small and the bytecode and constant table
grow only slowly with size of the grammar, the resulting parser is also
small.

When optimizing for speed, the JavaScript generator just compiles the
bytecode into JavaScript. The generated code is relatively efficient, so
the resulting parser is fast.

Internal Identifiers
--------------------

As a small bonus, all internal identifiers visible to user code in the
initializer, actions and predicates are prefixed by |peg$|. This lowers
the chance that identifiers in user code will conflict with the ones
from PEG.js. It also makes using any internals in user code ugly, which
is a good thing. This solves GH-92.

Performance
-----------

The new code generator improved parsing speed and parser code size
significantly. The generated parsers are now:

  * 39% faster when optimizing for speed

  * 69% smaller when optimizing for size (without minification)

  * 31% smaller when optimizing for size (with minification)

(Parsing speed was measured using the |benchmark/run| script. Code size
was measured by generating parsers for examples in the |examples|
directory and adding up the file sizes. Minification was done by |uglify
--ascii| in version 1.3.4.)

Final Note
----------

This is just a beginning! The new code generator lays a foundation upon
which many optimizations and improvements can (and will) be made.

Stay tuned :-)
11 years ago
David Majda 3333cdd18d Position tracking: Kill the |trackLineAndColumn| option
Getting rid of the |trackLineAndColumn| simplifies the code generator
(by unifying two paths in the code).

The |line| and |column| functions currently always compute all the
position info from scratch, which is horribly ineffective. This will be
improved in later commit(s).
12 years ago
David Majda 6f78df19d4 Make benchmark suite support the |cache| option
Both the browser and the command-line version of the benchmark suite
runner now allow users to specify a value of the |cache| option.
12 years ago
David Majda 0865e9e51a Make benchmark suite support |trackLineAndColumn| option
Both the browser and the command-line version of the benchmark suite
runner now allow users to specify a value of the |trackLineAndColumn|
option. In case of the command-line version this required a minor CLI
redesign.
12 years ago
David Majda fb5028eb90 Use |util| module instead of |sys|
|sys| emits a warning in Node.js 0.6.x.
12 years ago
David Majda f0eab4728a Use Unicode box-drawing characters for command-line benchmark table
Hopefully this works reasonably in all environments where Node.js runs.
13 years ago
David Majda 17c1531068 Make "Avg. time" column in the commmand-line benchmark table wider 13 years ago
David Majda a042f78558 Fix unit in command-line benchmark runner 13 years ago
David Majda 918dcf6ed2 Test and benchmark command-line runners can be run from any directory 13 years ago
David Majda 8f005c027b Fix encoding in |fs.readFileSync| calls ("utf-8" -> "utf8") 13 years ago
David Majda 8e63ad3b6c Add command-line runner for the benchmark suite 13 years ago