Skip to content

Instantly share code, notes, and snippets.

@Yoric
Last active October 19, 2017 17:52
Show Gist options
  • Save Yoric/2390f0367515c079172be2526349b294 to your computer and use it in GitHub Desktop.
Save Yoric/2390f0367515c079172be2526349b294 to your computer and use it in GitHub Desktop.
Living AST Specifications
// # 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