On this page:
5.1Syntax
5.1.1Operators
top
up

5Parenthetical JavaScriptπŸ”— i

This package recognizes an alternative, Scheme-like front-end syntax for JavaScript, dubbed Parenthetical JavaScript (or PJS for short). If you pronounce that "pee-jays" you will make me happy.

The PJS library can be required via:

5.1SyntaxπŸ”— i

The syntax of PJS is as follows:

program-unit = (source-elt...)
source-elt = decl
| stmt
decl = (functionid(id...)source-elt...)
| (varvar-init...+)
stmt = (#%statementstmt)
| block-stmt
| (if exprstmt)
| (if exprstmtstmt)
| (do stmtexpr)
| (whileexprstmt)
| (for (varvar-init...+)exprexprstmt)
| (for exprexprexprstmt)
| (for (varid)inexprstmt)
| (for idinexprstmt)
| (continuemaybe-id)
| (breakmaybe-id)
| (returnmaybe-expr)
| (withexprstmt)
| (switchexprcase-clause...)
| (labelidstmt)
| (throwexpr)
| (trystmtcatch-clausefinally-clause)
| (trystmtcatch-clause)
| (trystmtfinally-clause)
| ()
| expr
block-stmt = (blocksource-elt...)
expr = (#%expression expr)
| (regexp stringbooleanboolean)
| (arrayarray-elt...)
| (object[idexpr]...)
| (field-refexprexpr)
| (fieldexprid)
| (newexprexpr...)
| (prefixprefix-opexpr)
| (postfixexprpostfix-op)
| (infix-opexprexprexpr...)
| (assign-opexprexpr)
| (if exprexprexpr)
| (functionid(id...)source-elt...)
| (function(id...)source-elt...)
| (begin expr...+)
| string
| number
| boolean
| null
| this
| javadot-id
javadot-id = id.id...
array-elt = expr
| ()
var-init = id
| [idexpr]
case-clause = (defaultstmt...)
| (case exprstmt...)
catch-clause = (catchidstmt)
finally-clause = (finallystmt)

5.1.1OperatorsπŸ”— i

The set of recognized operators is:

  • prefix-op : ++, --, +, -, ~, !

  • infix-op : *, /, %, +, -, <, <<, >, >>, >>>, <=, >=, ==, !=, ===, !==, &, ^, \|, &&, \|\|

  • postfix-op : ++, --

  • assign-op : =, *=, /=, %=, +=, -=, <<=, >>=, >>>=, &=, ^=, \|=

For aesthetics and consistency with Scheme, some of the JavaScript operators with awkward or obscure operator tokens are given convenient synonyms in PJS:

  • or = \|\|

  • and = &&

  • bitwise-and = &

  • bitwise-ior = \|

  • bitwise-not = ~

  • bitwise-xor = ^

5.1.2IdentifiersπŸ”— i

Identifiers in PJS (i.e., the id non-terminal in the grammar) are restricted to valid JavaScript identifiers. This ensures that, when generating actual JavaScript syntax, the exact name of a variable or object property is preserved, with no name mangling. (Since variable names are sometimes observable in JavaScript, this prevents subtle bugs where a program may change its behavior based on a particular mangling.)

5.2Resolving AmbiguitiesπŸ”— i

The grammar as presented contains several ambiguities.

5.2.1Disambiguating operators with #%keywordπŸ”— i

The following primitive operators have names that are valid JavaScript identifiers:

  • and

  • array

  • begin

  • block

  • field

  • label

  • object

  • or

  • prefix

  • postfix

  • regexp

The parsing and code generation functions maintain an environment for lexically bound variables. JavaScript variable bindings can therefore shadow these operators. For example, in the expression

(function(array)
(return(array123)))

the inner occurrence of array is parsed as a variable reference rather than an array constructor.

Operators may be disambiguated with the use of the special form #%keyword. For example, (#%keyword. array) unconditionally refers to the initial binding of array, regardless of the current environment. The above example can then be rewritten as

(function(array)
(return((#%keyword. array)123)))

Note that if JavaScript code would dynamically bind one of these names (e.g., via with or eval), the operator is not shadowed, since the static environment only tracks lexical bindings.

5.2.2Disambiguating expressions with #%expressionπŸ”— i

Expression statements introduce a few minor ambiguities into the PJS syntax. These include function declarations vs. named function expressions and if statements vs. if expressions. These are always resolved in favor of the declaration or statement form rather than the expression form, since in both cases the expression form is less likely to occur.

The expression form operator #%expression forces its argument to be parsed as an expression. For example, the expression (#%expression (if xyz)) is parsed as a conditional expression rather than a conditional statement.

5.3Syntactic ConveniencesπŸ”— i

The PJS syntax provides several additional syntactic conveniences.

5.3.1Java Dot NotationπŸ”— i

Similar to the Java Dot Notation originally introduced by JScheme, PJS permits the use of dotted identifiers as a short-hand for the obvious corresponding chains of object field references. Unlike in JScheme, it is impossible to bind a variable with a dot in its name, so dotted identifiers are always unambiguously decoded as field references.

For example, the identifier document.body.innerHTML is equivalent to the expression (field(fielddocumentbody)innerHTML).

5.3.2Multiary OperatorsπŸ”— i

Binary JavaScript operators are generalized in PJS to n-ary operators and expanded left-associatively into nested applications of the binary operator.

For example, the expression (- 4321) is equivalent to (- (- (- 43)2)1).

5.4Library ProceduresπŸ”— i

The PJS library provides procedures that operate on either syntax objects or S-expressions. The syntax object procedures maintain source location information.

5.4.1S-expression ParsersπŸ”— i

procedure

( syntax->expressionstx)Expression?

stx:syntax?
Parses the PJS expression stx.

procedure

( syntax->statementstx)Statement?

stx:syntax?
Parses the PJS statement stx.

procedure

( syntax->source-elementstx)SourceElement?

stx:syntax?
Parses the PJS source element stx.

procedure

( syntax->program-unitstx)(listof SourceElement?)

stx:syntax?
Parses the PJS program unit stx.

procedure

( sexp->expressionsexp)Expression?

sexp:sexp?
Parses the PJS expression sexp.

procedure

( sexp->statementsexp)Statement?

sexp:sexp?
Parses the PJS statement sexp.

procedure

( sexp->source-elementsexp)SourceElement?

sexp:sexp?
Parses the PJS source element sexp.

procedure

( sexp->program-unitsexp)(listof SourceElement?)

sexp:(listof sexp?)
Parses the PJS program unit sexp.

5.4.2S-expression GeneratorsπŸ”— i

procedure

( expression->syntaxexpr)syntax?

expr:Expression?
Generates a PJS representation of expr.

procedure

( statement->syntaxstmt)syntax?

stmt:Statement?
Generates a PJS representation of stmt.

procedure

( source-element->syntaxelt)syntax?

elt:SourceElement?
Generates a PJS representation of elt.

procedure

( program-unit->syntaxelts)syntax?

elts:(listof SourceElement?)
Generates a PJS representation of elts.

procedure

( expression->sexpexpr)sexp?

expr:Expression?
Generates a PJS representation of expr.

procedure

( statement->sexpstmt)sexp?

stmt:Statement?
Generates a PJS representation of stmt.

procedure

( source-element->sexpelt)sexp?

elt:SourceElement?
Generates a PJS representation of elt.

procedure

( program-unit->sexpelts)sexp?

elts:(listof SourceElement?)
Generates a PJS representation of elts.

top
up

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /