Last active
October 19, 2017 17:52
-
-
Save Yoric/2390f0367515c079172be2526349b294 to your computer and use it in GitHub Desktop.
Living AST Specifications
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// # Documentation of the JavaScript AST, level ES5 | |
// # Interfaces. | |
// | |
// Unless specified otherwise in comments, the order of fields does NOT matter. | |
interface ArrayExpression :< Expression { | |
elements: [Expression | ElisionExpression] = []; | |
} | |
interface AssignmentExpression :< Expression { | |
operator: AssignmentOperator; // MUST appear before `left`, `right` | |
left: Pattern | Expression; | |
right: Expression; | |
} | |
interface BINJS:Scope { | |
// Names declared with `var` (or an implicit `var`) in this var-scope. Empty unless this is a function scope. | |
BINJS:VarDeclaredNames: [string] = []; | |
// Names declared with `let` (or an implicit `let`) in this lexical scope. | |
BINJS:LetDeclaredNames: [string] = []; | |
// Names declared with `const` (or an implicit `const`) in this lexical scope. | |
BINJS:ConstDeclaredNames: [string] = []; | |
// Names declared in this scope and captured in an inner function. | |
BINJS:CapturedNames: [string] = []; | |
// ``true` if either in this scope or in a subscope, we have a call to the built-in function `eval()`. | |
BINJS:HasDirectEval: bool = false; | |
} | |
interface BinaryExpression :< Expression { | |
operator: BinaryOperator; // MUST appear before `left`, `right` | |
left: Expression; | |
right: Expression; | |
} | |
interface BlockStatement :< Statement { | |
BINJS:Scope: BINJS:Scope = null; // MUST appear before `body` | |
body: [Statement | FunctionDeclaration] = []; | |
} | |
interface BooleanLiteral :< Literal { | |
value: bool = false; | |
} | |
interface BracketExpression :< Expression { | |
object: Expression; | |
property: Expression; | |
} | |
interface BreakStatement :< Statement { | |
label: Identifier = null; | |
} | |
interface CallExpression :< Expression { | |
callee: Expression; | |
arguments: [Expression] = []; | |
} | |
interface CatchClause { | |
BINJS:Scope: BINJS:Scope = null; // MUST appear before `body` | |
param: Pattern; | |
body: BlockStatement; | |
} | |
interface ComputedPropertyName { | |
property: Expression; | |
} | |
interface ConditionalExpression :< Expression { | |
test: Expression; | |
alternate: Expression; | |
consequent: Expression; | |
} | |
interface ContinueStatement :< Statement { | |
label: Identifier = null; | |
} | |
interface DebuggerStatement :< Statement { | |
} | |
interface Declaration :< Statement { | |
} | |
interface DoWhileStatement :< Statement { | |
body: Statement; | |
test: Expression; | |
} | |
interface DotExpression :< Expression { | |
object: Expression; | |
property: Identifier; | |
} | |
interface ElisionExpression { | |
} | |
interface EmptyStatement :< Statement { | |
} | |
interface Expression { | |
} | |
interface ExpressionStatement :< Statement { | |
expression: Expression; | |
} | |
interface ForInStatement :< Statement { | |
BINJS:Scope: BINJS:Scope = null; // MUST appear before `body` | |
left: VariableDeclaration | Expression; | |
right: Expression; | |
body: Statement; | |
} | |
interface ForStatement :< Statement { | |
BINJS:Scope: BINJS:Scope = null; // MUST appear before `body` | |
init: VariableDeclaration | Expression = null; | |
test: Expression = null; | |
update: Expression = null; | |
body: Statement; | |
} | |
interface Function { | |
id: Identifier = null; | |
BINJS:Scope: BINJS:Scope = null; // MUST appear before `body` | |
directives: [string] = []; // MUST appear before `body` | |
params: [Pattern] = []; | |
body: BlockStatement; | |
} | |
interface FunctionDeclaration :< Function { | |
id: Identifier; | |
} | |
interface FunctionExpression :< Expression, Function { | |
} | |
interface Identifier :< Expression, Pattern { | |
name: string; | |
} | |
interface IfStatement :< Statement { | |
test: Expression; | |
consequent: Statement; | |
alternate: Statement = null; | |
} | |
interface LabeledStatement :< Statement { | |
label: Identifier; // MUST appear before `body` | |
body: Statement; | |
} | |
interface Literal :< Expression { | |
} | |
interface LogicalExpression :< Expression { | |
operator: LogicalOperator; // MUST appear before `left`, `right` | |
left: Expression; | |
right: Expression; | |
} | |
interface NewExpression :< Expression { | |
callee: Expression; | |
arguments: [Expression] = []; | |
} | |
interface NullLiteral :< Literal { | |
} | |
interface NumericLiteral :< Literal { | |
value: number = 0; | |
} | |
interface ObjectExpression :< Expression { | |
properties: [ObjectProperty | ObjectMethod | ObjectGetter | ObjectSetter] = []; | |
} | |
interface ObjectGetter :< ObjectMember, Function { | |
} | |
interface ObjectMember { | |
key: StringLiteral | NumericLiteral | Identifier | ComputedPropertyName; | |
} | |
interface ObjectMethod :< ObjectMember, Function { | |
} | |
interface ObjectProperty :< ObjectMember { | |
value: Expression; | |
} | |
interface ObjectSetter :< ObjectMember, Function { | |
} | |
interface Pattern { | |
} | |
// Root of the AST. | |
interface Program { | |
BINJS:Scope: BINJS:Scope = null; // MUST appear before `body` | |
directives: [string] = []; // MUST appear before `body` | |
body: [Statement | FunctionDeclaration] = []; | |
} | |
interface RegExpLiteral :< Literal { | |
pattern: string; | |
flags: string; | |
} | |
interface ReturnStatement :< Statement { | |
argument: Expression = null; | |
} | |
interface SequenceExpression :< Expression { | |
expressions: [Expression] = []; | |
} | |
interface Statement { | |
} | |
interface StringLiteral :< Literal { | |
value: string; | |
} | |
interface SwitchCase { | |
test: Expression = null; | |
consequent: [Statement | FunctionDeclaration] = []; | |
} | |
interface SwitchStatement :< Statement { | |
discriminant: Expression; | |
cases: [SwitchCase] = []; | |
} | |
interface ThisExpression :< Expression { | |
} | |
interface ThrowStatement :< Statement { | |
argument: Expression; | |
} | |
interface TryStatement :< Statement { | |
block: BlockStatement; | |
handler: CatchClause = null; | |
finalizer: BlockStatement = null; | |
} | |
interface UnaryExpression :< Expression { | |
operator: UnaryOperator; // MUST appear before `argument` | |
prefix: bool = false; // MUST appear before `argument` | |
argument: Expression; | |
} | |
interface UpdateExpression :< Expression { | |
operator: UpdateOperator; // MUST appear before `argument` | |
prefix: bool = false; // MUST appear before `argument` | |
argument: Expression; | |
} | |
interface VariableDeclaration :< Declaration { | |
declarations: [VariableDeclarator] /* Non-empty */; | |
kind: VariableKind; | |
} | |
interface VariableDeclarator { | |
id: Pattern; | |
init: Expression = null; | |
} | |
interface WhileStatement :< Statement { | |
test: Expression; | |
body: Statement; | |
} | |
interface WithStatement :< Statement { | |
object: Expression; | |
body: Statement; | |
} | |
// # Enums. | |
// | |
// The order of enum values does NOT matter. | |
enum AssignmentOperator { | |
"=", | |
"+=", | |
"-=", | |
"*=", | |
"/=", | |
"%=", | |
"<<=", | |
">>=", | |
">>>=", | |
"|=", | |
"^=", | |
"&=", | |
} | |
enum BinaryOperator { | |
"==", | |
"!=", | |
"===", | |
"!==", | |
"<", | |
"<=", | |
">", | |
">=", | |
"<<", | |
">>", | |
">>>", | |
"+", | |
"-", | |
"*", | |
"/", | |
"%", | |
"|", | |
"^", | |
"&", | |
"in", | |
"instanceof", | |
} | |
enum LogicalOperator { | |
"||", | |
"&&", | |
} | |
enum UnaryOperator { | |
"-", | |
"+", | |
"!", | |
"~", | |
"typeof", | |
"void", | |
"delete", | |
} | |
enum UpdateOperator { | |
"++", | |
"--", | |
} | |
enum VariableKind { | |
"let", | |
"var", | |
"const", | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment