1 JavaScript for PLT Scheme
This package is an implementation of the ECMAScript language specified by ECMA-262 Edition 3, better known as JavaScript.
1.1 Getting Started
The easiest way to get started using JavaScript for PLT Scheme is with the main module:
(require (planet dherman/javascript:9:2)) |
This module provides everything in the entire package. Subsequent sections of this manual describe the functionality of the individual libraries included, which can also be required individually.
Examples: | ||||
> (eval-script "print(40 + 2)") | ||||
link: module mismatch, probably from old bytecode whose | ||||
dependencies have changed: variable not provided (directly | ||||
or indirectly) from module: "C:\Documents and | ||||
Settings\dherman\My | ||||
Documents\Subversion\planet\javascript\lang\lang.ss" at | ||||
source phase level: 0 in: script-begin | ||||
> (require (planet dherman/pprint)) | ||||
| ||||
|
1.2 Libraries Provided by this Package
This package includes:
A library for lexing and parsing JavaScript–see Lexing and Parsing
An extensible hierarchy of structure definitions for representing JavaScript abstract syntax–see Abstract Syntax
A library for pretty-printing JavaScript to text–see Pretty-Printing
A library implementing Parenthetical JavaScript, an S-expression based alternative syntax for JavaScript–see Parenthetical JavaScript
A library for compiling JavaScript to PLT Scheme–see Compiling to Scheme
A library implementing the JavaScript runtime, including a representation of JavaScript values in Scheme as well as the standard JavaScript library–see Runtime System
A library for evaluating JavaScript programs–see Evaluation
A library of configuration parameters–see Configuration Parameters
1.3 JavaScript Language for DrScheme
Installing this PLaneT package also automatically registers a DrScheme language called JavaScript, filed under Experimental Languages. Selecting the JavaScript language from DrScheme’s Language menu allows you to create and load JavaScript programs and interact with JavaScript at the REPL.
As of version 0.17 (released as PLaneT version 8:0), JavaScript is also available as a module language. This can be used by beginning a JavaScript source file with the line:
#lang planet dherman/javascript:9:2
You can omit the PLaneT version numbers if you prefer. Programs without the version number do not need to be updated when this PLaneT package is upgraded. However, it is then the responsibility of the programmer to address any backwards-incompatible changes to the JavaScript semantics.
1.4 Design Choices
Ref type: no expressions ever evaluate to refs at runtime. The standard allows for this possibility, but does not require it. This allows for a more efficient model of variable reference and assignment, one which matches Scheme’s more closely.
Bindings, with, and eval: code that does not occur in the syntactic context of a with statement is compiled more efficiently, using Scheme’s lexical scope. Compilation of with still complies with the standard, but is compiled to a much more inefficient form that creates a runtime representation of the environment as a linked list of objects. Similarly, in order to provide access to the caller’s environment, eval code is (dynamically) compiled to the more inefficient form.
Indirect eval: only a direct call to a lexical variable with the name eval is considered a legal call to the eval function. Attempts to call eval indirectly (e.g., via method calls or from variables with names other than eval) raise a dynamic error. This is permitted by the spec and allows for a more efficient implementation of variable reference and assignment.
Proto: I have not exposed the internal [[Prototype]] property of objects, e.g. via a __proto__ property. I may choose to do so in a read-only form later. See issue #41.
Interoperation with Scheme: There is preliminary support for interoperation with Scheme. All Scheme values are JavaScript values and vice versa. Moreover, JavaScript functions are callable in Scheme as procedures and vice versa.
1.5 Known Limitations
Some limitations that are likely to be addressed eventually:
The toString method for functions doesn’t produce their source (see issue #34).
There may be some semantic issues with exceptions (see issue #35):
return from finally blocks
suspicious uses of dynamic-wind
The standard JavaScript Error objects are not implemented, so library errors currently just throw strings.
The JavaScript standard library is only about half-implemented (see issue #36).
Some limitations that are less likely to be fixed any time soon:
Numbers are not faithful to the spec; they are just represented as Scheme bignums (see issue #38).
Regular expressions don’t work at all (see issue #39).
I haven’t done any profiling or optimizing.
1.6 Feedback and Bug Reports
Before sending feedback or bug reports, please consult the current set of registered issues. If you cannot find your issue there, feel free to file a new bug report in the online issue database.
Any other feedback may be emailed to me, Dave Herman, at dherman@ccs.neu.edu.
1.7 Acknowledgments
This package was developed by me, Dave Herman. I thank Michael Greenberg, Dave Gurnell, Leo Meyerovich, and Jay McCarthy for their helpful feedback. I also thank Richard Cobbe, Ryan Culpepper, Carl Eastlund, Matthew Flatt, and Sam Tobin-Hochstadt for helping me with my many technical questions.
1.8 History
Version 0.18 (2009-01-02) - New features including Scheme interoperability and runtime enhancements, Parenthetical JavaScript, and Harmony extensions.
Changed runtime representation to interoperate with Scheme (notably booleans and procedures).
Experimental Harmony features: tail-recursive block literals and do-expressions.
Continuation marks via a global Trace constructor.
Improvements to internal representation of objects.
New Name constructor and support for Name objects as property names.
Parenthetical JavaScript: renewed support for S-expression syntax, now with improved syntax and support for source-location tracking.
Version 0.17 (2008-11-11) - Implemented modules and more of the standard library.
Implemented Array library.
Implemented other miscellaneous standard libraries.
Fixed a bug with treating primitives as objects.
Implemented a module language, allowing interoperability with Scheme modules.
Fixed some prototype chain relationships in the standard library objects.
Implemented a #lang reader, enabling use with the Module language.
Implemented import and export declarations.
Major reimplementation of variable binding.
Correct implementation of eval that has access to the lexical environment.
API changes in eval.ss, parse.ss, and compile.ss.
Version 0.16 (2008-10-20) - Major bugfix release:
Significant re-implementation of internal environment structure.
Fixed a bug in lookup of non-string property names.
Implemented eval with proper inheritance of the environment and variable object (see 10.1.3).
Mutating with-bound variables now persists correctly.
Fixed bugs in the implementation of variable assignment in dynamic code (i.e., code under with or eval).
Indirect eval now raises a runtime exception when called.
Version 0.15 (2008-09-30) - Bugfix release:
Exported some internals from print.ss.
Exported the utilities for the S-expression representation of JavaScript.
Changed the AST structure types to be #:prefab.
Added a generic Term=? predicate to ast.ss.
Version 0.14 (2008-09-08) - Major overhaul for PLT v4, including:
New required methods for DrScheme language interface.
Scribble documentation.
Rearranged API’s for better consistency and organization (still needs more cleanup, though).
Convenience main.ss module for easy PLaneT require.
Moved all known bugs into PLaneT Trac database.
Pretty-printer uses new pprint:4 library.
Directory structure reorganization–more internal libraries under private/.
Version 0.13 (2006-08-08) - Expressions are extensible: leaf nodes are checked with custom predicates. Pretty-printing is extensible: extended nodes are printed with custom printers.
Version 0.12 (2006-07-18) - Fixed a bug related to nested with statements.
Version 0.11 (2006-07-17) - Stubbed lots of standard libraries. Some more documentation. Added parse-function-expression to parser<%> interface. Implemented reflective Function constructor. Implemented primitive constructors (except Date and RegExp). Moved language level files into subdirectory.
Version 0.10 (2006-07-13) - Implemented JavaScript `eval’ library function.
Version 0.9 (2006-07-12) - Created eval-* functions for interpreting JavaScript. Should soon be able to implement JavaScript eval. Improved tests.
Version 0.8 (2006-07-12) - Fixed bug involving nested with forms. Corrected implementation of binding of catch variables. Implemented all let forms.
Version 0.7 (2006-07-11) - Fixed some small type-related bugs with hoisting and compilation.
Version 0.6 (2006-07-11) - Fixed nested with bug.
Version 0.5 (2006-07-11) - New implementation of binding: no more evaluating to refs! Nested with forms are broken. Binding arrows are broken for top-level.
Version 0.4 (2006-07-06) - Got rid of unnecessary PLTCOLLECTS hack for testing. Fixed bugs in sexp and pretty-print due to changed AST types. Hoisting for ES4 let corrected.
Version 0.3 (2006-06-28) - Drastically improved binding implementation. Addressed serious bugs in implementation of functions. Began implementation for debug console (still disabled).
Version 0.2 (2006-06-22) - Added newly required capability-value to language level interface. Bug fixed for pretty-printer (thanks to Jay). Serialized language level settings. Broke let. (Internally: hoisting for ES4 let in place.)
Version 0.1 (2006-02-23) - Initial release. Implements most of ECMA-262 Edition 3. Primary limitations:
Lack of regular expressions
Lack of standard library
No reflection or function reification