mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-11 05:51:38 +00:00
More stdlib setup
This commit is contained in:
854
src/ast.ts
854
src/ast.ts
@ -1,71 +1,3 @@
|
||||
/*
|
||||
|
||||
Similar to TypeScript's syntax tree of node interfaces, but class-based.
|
||||
|
||||
Node ~ NodeKind
|
||||
├ ExportMember
|
||||
├ Expression
|
||||
│ ├ LiteralExpression ~ LiteralKind
|
||||
│ │ ├ ArrayLiteralExpression
|
||||
│ │ ├ FloatLiteralExpression
|
||||
│ │ ├ IntegerLiteralExpression
|
||||
│ │ ├ RegexpLiteralExpression
|
||||
│ │ └ StringLiteralExpression
|
||||
│ ├ AssertionExpression
|
||||
│ ├ BinaryExpression
|
||||
│ ├ CallExpression
|
||||
│ ├ ElementAccessExpression
|
||||
│ ├ IdentifierExpression
|
||||
│ ├ ParenthesizedExpression
|
||||
│ ├ NewExpression
|
||||
│ ├ PropertyAccessExpression
|
||||
│ ├ TernaryExpression
|
||||
│ └ UnaryExpression
|
||||
│ ├ UnaryPostfixExpression
|
||||
│ └ UnaryPrefixExpression
|
||||
├ Statement
|
||||
│ ├ BlockStatement
|
||||
│ ├ BreakStatement
|
||||
│ ├ ContinueStatement
|
||||
│ ├ DeclarationStatement
|
||||
│ │ ├ ClassDeclaration <> TypeParameter
|
||||
│ │ ├ EnumDeclaration <> EnumValueDeclaration
|
||||
│ │ ├ EnumValueDeclaration
|
||||
│ │ ├ FieldDeclaration
|
||||
│ │ ├ FunctionDeclaration <> TypeParameter, Parameter
|
||||
│ │ │ └ MethodDeclaration
|
||||
│ │ ├ ImportDeclaration
|
||||
│ │ ├ InterfaceDeclaration
|
||||
│ │ ├ NamespaceDeclaration
|
||||
│ │ └ VariableDeclaration
|
||||
│ ├ DoStatement
|
||||
│ ├ EmptyStatement
|
||||
│ ├ ExportImportStatement
|
||||
│ ├ ExportStatement <> ExportMember
|
||||
│ ├ ExpressionStatement
|
||||
│ ├ ForStatement
|
||||
│ ├ IfStatement
|
||||
│ ├ ImportStatement <> ImportDeclaration
|
||||
│ ├ ReturnStatement
|
||||
│ ├ SwitchStatement <> SwitchCase
|
||||
│ ├ ThrowStatement
|
||||
│ ├ TryStatement
|
||||
│ ├ VariableStatement <> VariableDeclaration
|
||||
│ └ WhileStatement
|
||||
├ Parameter
|
||||
├ Source
|
||||
├ SwitchCase
|
||||
├ TypeNode
|
||||
└ TypeParameter
|
||||
|
||||
All nodes are backwards-serializable to their respective source except that
|
||||
formatting is lost, long integers become hex literals and semicolons will be
|
||||
inserted. Useful for testing.
|
||||
|
||||
serialize(node)
|
||||
|
||||
*/
|
||||
|
||||
import { GETTER_PREFIX, SETTER_PREFIX, PATH_DELIMITER, PARENT_SUBST, STATIC_DELIMITER, INSTANCE_DELIMITER } from "./constants";
|
||||
import { Token, Tokenizer, operatorTokenToString, Range } from "./tokenizer";
|
||||
import { CharCode } from "./util/charcode";
|
||||
@ -74,17 +6,7 @@ import { normalize as normalizePath, resolve as resolvePath } from "./util/path"
|
||||
|
||||
export { Range } from "./tokenizer";
|
||||
|
||||
/** Base class of all AST nodes. */
|
||||
export abstract class Node {
|
||||
|
||||
kind: NodeKind;
|
||||
range: Range;
|
||||
parent: Node | null = null;
|
||||
|
||||
/** Serializes this node to its TypeScript representation. */
|
||||
abstract serialize(sb: string[]): void;
|
||||
}
|
||||
|
||||
/** Indicates the kind of a node. */
|
||||
export enum NodeKind {
|
||||
|
||||
SOURCE,
|
||||
@ -145,58 +67,31 @@ export enum NodeKind {
|
||||
WHILE
|
||||
}
|
||||
|
||||
// types
|
||||
/** Base class of all nodes. */
|
||||
export abstract class Node {
|
||||
|
||||
export class TypeNode extends Node {
|
||||
/** Node kind indicator. */
|
||||
kind: NodeKind;
|
||||
/** Source range. */
|
||||
range: Range;
|
||||
/** Parent node. */
|
||||
parent: Node | null = null;
|
||||
|
||||
kind = NodeKind.TYPE;
|
||||
identifier: IdentifierExpression;
|
||||
parameters: TypeNode[];
|
||||
nullable: bool;
|
||||
/** Serializes this node to its TypeScript representation. Note that formatting is lost and long integers become hex literals. */
|
||||
abstract serialize(sb: string[]): void;
|
||||
|
||||
static create(identifier: IdentifierExpression, parameters: TypeNode[], nullable: bool, range: Range): TypeNode {
|
||||
// types
|
||||
|
||||
static createType(identifier: IdentifierExpression, typeArguments: TypeNode[], isNullable: bool, range: Range): TypeNode {
|
||||
const type: TypeNode = new TypeNode();
|
||||
type.range = range;
|
||||
type.identifier = identifier;
|
||||
type.parameters = parameters;
|
||||
type.nullable = nullable;
|
||||
type.typeArguments = typeArguments;
|
||||
type.isNullable = isNullable;
|
||||
return type;
|
||||
}
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
this.identifier.serialize(sb);
|
||||
if (this.parameters.length) {
|
||||
sb.push("<");
|
||||
for (let i: i32 = 0, k: i32 = this.parameters.length; i < k; ++i) {
|
||||
if (i > 0)
|
||||
sb.push(", ");
|
||||
this.parameters[i].serialize(sb);
|
||||
}
|
||||
sb.push(">");
|
||||
}
|
||||
if (this.nullable)
|
||||
sb.push(" | null");
|
||||
}
|
||||
}
|
||||
|
||||
export class TypeParameter extends Node {
|
||||
|
||||
kind = NodeKind.TYPEPARAMETER;
|
||||
identifier: IdentifierExpression;
|
||||
extendsType: TypeNode | null;
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
this.identifier.serialize(sb);
|
||||
if (this.extendsType) {
|
||||
sb.push(" extends ");
|
||||
(<TypeNode>this.extendsType).serialize(sb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// expressions
|
||||
|
||||
export abstract class Expression extends Node {
|
||||
// expressions
|
||||
|
||||
static createIdentifier(name: string, range: Range): IdentifierExpression {
|
||||
const expr: IdentifierExpression = new IdentifierExpression();
|
||||
@ -362,8 +257,370 @@ export abstract class Expression extends Node {
|
||||
(expr.expression = expression).parent = expr;
|
||||
return expr;
|
||||
}
|
||||
|
||||
// statements
|
||||
|
||||
static createBlock(statements: Statement[], range: Range): BlockStatement {
|
||||
const stmt: BlockStatement = new BlockStatement();
|
||||
stmt.range = range;
|
||||
for (let i: i32 = 0, k: i32 = (stmt.statements = statements).length; i < k; ++i) statements[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createBreak(label: IdentifierExpression | null, range: Range): BreakStatement {
|
||||
const stmt: BreakStatement = new BreakStatement();
|
||||
stmt.range = range;
|
||||
if (stmt.label = label) (<IdentifierExpression>label).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createClass(identifier: IdentifierExpression, typeParameters: TypeParameter[], extendsType: TypeNode | null, implementsTypes: TypeNode[], members: DeclarationStatement[], modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): ClassDeclaration {
|
||||
const stmt: ClassDeclaration = new ClassDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
for (i = 0, k = (stmt.typeParameters = typeParameters).length; i < k; ++i) typeParameters[i].parent = stmt;
|
||||
if (stmt.extendsType = extendsType) (<TypeNode>extendsType).parent = stmt;
|
||||
for (i = 0, k = (stmt.implementsTypes = implementsTypes).length; i < k; ++i) implementsTypes[i].parent = stmt;
|
||||
for (i = 0, k = (stmt.members = members).length; i < k; ++i) members[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createContinue(label: IdentifierExpression | null, range: Range): ContinueStatement {
|
||||
const stmt: ContinueStatement = new ContinueStatement();
|
||||
stmt.range = range;
|
||||
if (stmt.label = label) (<IdentifierExpression>label).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createDecorator(expression: Expression, args: Expression[], range: Range): Decorator {
|
||||
const stmt: Decorator = new Decorator();
|
||||
stmt.range = range;
|
||||
(stmt.expression = expression).parent = stmt;
|
||||
for (let i: i32 = 0, k: i32 = (stmt.arguments = args).length; i < k; ++i) args[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createDo(statement: Statement, condition: Expression, range: Range): DoStatement {
|
||||
const stmt: DoStatement = new DoStatement();
|
||||
stmt.range = range;
|
||||
(stmt.statement = statement).parent = stmt;
|
||||
(stmt.condition = condition).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createEmpty(range: Range): EmptyStatement {
|
||||
const stmt: EmptyStatement = new EmptyStatement();
|
||||
stmt.range = range;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createEnum(identifier: IdentifierExpression, members: EnumValueDeclaration[], modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): EnumDeclaration {
|
||||
const stmt: EnumDeclaration = new EnumDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
for (i = 0, k = (stmt.members = members).length; i < k; ++i) members[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createEnumValue(identifier: IdentifierExpression, value: Expression | null, range: Range): EnumValueDeclaration {
|
||||
const stmt: EnumValueDeclaration = new EnumValueDeclaration();
|
||||
stmt.range = range;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
if (stmt.value = value) (<Expression>value).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createExport(members: ExportMember[], path: StringLiteralExpression | null, modifiers: Modifier[] | null, range: Range): ExportStatement {
|
||||
const stmt: ExportStatement = new ExportStatement();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
for (i = 0, k = (stmt.members = members).length; i < k; ++i) members[i].parent = stmt;
|
||||
stmt.path = path;
|
||||
stmt.normalizedPath = path ? resolvePath(normalizePath(path.value), range.source.normalizedPath) : null;
|
||||
stmt.internalPath = stmt.normalizedPath ? mangleInternalPath(stmt.normalizedPath) : null;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createExportImport(identifier: IdentifierExpression, asIdentifier: IdentifierExpression, range: Range): ExportImportStatement {
|
||||
const stmt: ExportImportStatement = new ExportImportStatement();
|
||||
stmt.range = range;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
(stmt.asIdentifier = asIdentifier).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createExportMember(identifier: IdentifierExpression, externalIdentifier: IdentifierExpression | null, range: Range): ExportMember {
|
||||
const elem: ExportMember = new ExportMember();
|
||||
elem.range = range;
|
||||
(elem.identifier = identifier).parent = elem;
|
||||
(elem.externalIdentifier = externalIdentifier ? <IdentifierExpression>externalIdentifier : identifier).parent = elem;
|
||||
return elem;
|
||||
}
|
||||
|
||||
/** Creates an expression statement. */
|
||||
static createExpression(expression: Expression): ExpressionStatement {
|
||||
const stmt: ExpressionStatement = new ExpressionStatement();
|
||||
stmt.range = expression.range;
|
||||
(stmt.expression = expression).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createIf(condition: Expression, statement: Statement, elseStatement: Statement | null, range: Range): IfStatement {
|
||||
const stmt: IfStatement = new IfStatement();
|
||||
stmt.range = range;
|
||||
(stmt.condition = condition).parent = stmt;
|
||||
(stmt.statement = statement).parent = stmt;
|
||||
if (stmt.elseStatement = elseStatement) (<Statement>elseStatement).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createImport(declarations: ImportDeclaration[], path: StringLiteralExpression, range: Range): ImportStatement {
|
||||
const stmt: ImportStatement = new ImportStatement();
|
||||
stmt.range = range;
|
||||
for (let i: i32 = 0, k: i32 = (stmt.declarations = declarations).length; i < k; ++i) declarations[i].parent = stmt;
|
||||
stmt.path = path;
|
||||
stmt.normalizedPath = resolvePath(normalizePath(path.value), range.source.normalizedPath);
|
||||
stmt.internalPath = mangleInternalPath(stmt.normalizedPath);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createImportDeclaration(externalIdentifier: IdentifierExpression, identifier: IdentifierExpression | null, range: Range): ImportDeclaration {
|
||||
const elem: ImportDeclaration = new ImportDeclaration();
|
||||
elem.range = range;
|
||||
(elem.identifier = identifier ? <IdentifierExpression>identifier : externalIdentifier).parent = elem;
|
||||
(elem.externalIdentifier = externalIdentifier).parent = elem;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createInterface(identifier: IdentifierExpression, extendsType: TypeNode | null, members: DeclarationStatement[], modifiers: Modifier[] | null, range: Range): InterfaceDeclaration {
|
||||
const stmt: InterfaceDeclaration = new InterfaceDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
if (stmt.extendsType = extendsType) (<TypeNode>extendsType).parent = stmt;
|
||||
for (i = 0, k = (stmt.members = members).length; i < k; ++i) members[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createField(identifier: IdentifierExpression, type: TypeNode | null, initializer: Expression | null, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): FieldDeclaration {
|
||||
const stmt: FieldDeclaration = new FieldDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
if (stmt.type = type) (<TypeNode>type).parent = stmt;
|
||||
if (stmt.initializer = initializer) (<Expression>initializer).parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createFor(initializer: Statement | null, condition: Expression | null, incrementor: Expression | null, statement: Statement, range: Range): ForStatement {
|
||||
const stmt: ForStatement = new ForStatement();
|
||||
stmt.range = range;
|
||||
if (stmt.initializer = initializer) (<Statement>initializer).parent = stmt;
|
||||
if (stmt.condition = condition) (<Expression>condition).parent = stmt;
|
||||
if (stmt.incrementor = incrementor) (<Expression>incrementor).parent = stmt;
|
||||
(stmt.statement = statement).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createTypeParameter(identifier: IdentifierExpression, extendsType: TypeNode | null, range: Range): TypeParameter {
|
||||
const elem: TypeParameter = new TypeParameter();
|
||||
elem.range = range;
|
||||
(elem.identifier = identifier).parent = elem;
|
||||
if (elem.extendsType = extendsType) (<TypeNode>extendsType).parent = elem;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createParameter(identifier: IdentifierExpression, type: TypeNode | null, initializer: Expression | null, multiple: bool, range: Range): Parameter {
|
||||
const elem: Parameter = new Parameter();
|
||||
elem.range = range;
|
||||
(elem.identifier = identifier).parent = elem;
|
||||
if (elem.type = type) (<TypeNode>type).parent = elem;
|
||||
if (elem.initializer = initializer) (<Expression>initializer).parent = elem;
|
||||
elem.multiple = multiple;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createFunction(identifier: IdentifierExpression, typeParameters: TypeParameter[], parameters: Parameter[], returnType: TypeNode | null, statements: Statement[] | null, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): FunctionDeclaration {
|
||||
const stmt: FunctionDeclaration = new FunctionDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
for (i = 0, k = (stmt.typeParameters = typeParameters).length; i < k; ++i) typeParameters[i].parent = stmt;
|
||||
for (i = 0, k = (stmt.parameters = parameters).length; i < k; ++i) parameters[i].parent = stmt;
|
||||
if (stmt.returnType = returnType) (<TypeNode>returnType).parent = stmt;
|
||||
if (stmt.statements = statements) for (i = 0, k = (<Statement[]>statements).length; i < k; ++i) (<Statement[]>statements)[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createMethod(identifier: IdentifierExpression, typeParameters: TypeParameter[], parameters: Parameter[], returnType: TypeNode | null, statements: Statement[] | null, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): MethodDeclaration {
|
||||
const stmt: MethodDeclaration = new MethodDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
for (i = 0, k = (stmt.typeParameters = typeParameters).length; i < k; ++i) typeParameters[i].parent = stmt;
|
||||
for (i = 0, k = (stmt.parameters = parameters).length; i < k; ++i) parameters[i].parent = stmt;
|
||||
if (stmt.returnType = returnType) (<TypeNode>returnType).parent = stmt;;
|
||||
if (stmt.statements = statements) for (i = 0, k = (<Statement[]>statements).length; i < k; ++i) (<Statement[]>statements)[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createModifier(kind: ModifierKind, range: Range): Modifier {
|
||||
const elem: Modifier = new Modifier();
|
||||
elem.range = range;
|
||||
elem.modifierKind = kind;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createNamespace(identifier: IdentifierExpression, members: Statement[], modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): NamespaceDeclaration {
|
||||
const stmt: NamespaceDeclaration = new NamespaceDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
for (i = 0, k = (stmt.members = members).length; i < k; ++i) members[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createReturn(expression: Expression | null, range: Range): ReturnStatement {
|
||||
const stmt: ReturnStatement = new ReturnStatement();
|
||||
stmt.range = range;
|
||||
if (stmt.expression = expression) (<Expression>expression).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createSwitch(expression: Expression, cases: SwitchCase[], range: Range): SwitchStatement {
|
||||
const stmt: SwitchStatement = new SwitchStatement();
|
||||
stmt.range = range;
|
||||
(stmt.expression = expression).parent = stmt;
|
||||
for (let i: i32 = 0, k: i32 = (stmt.cases = cases).length; i < k; ++i) cases[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createSwitchCase(label: Expression | null, statements: Statement[], range: Range): SwitchCase {
|
||||
const elem: SwitchCase = new SwitchCase();
|
||||
elem.range = range;
|
||||
if (elem.label = label) (<Expression>label).parent = elem;
|
||||
for (let i: i32 = 0, k: i32 = (elem.statements = statements).length; i < k; ++i) statements[i].parent = elem;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createThrow(expression: Expression, range: Range): ThrowStatement {
|
||||
const stmt: ThrowStatement = new ThrowStatement();
|
||||
stmt.range = range;
|
||||
(stmt.expression = expression).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createTry(statements: Statement[], catchVariable: IdentifierExpression | null, catchStatements: Statement[] | null, finallyStatements: Statement[] | null, range: Range): TryStatement {
|
||||
const stmt: TryStatement = new TryStatement();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
for (i = 0, k = (stmt.statements = statements).length; i < k; ++i) statements[i].parent = stmt;
|
||||
if (stmt.catchVariable = catchVariable) (<IdentifierExpression>catchVariable).parent = stmt;
|
||||
if (stmt.catchStatements = catchStatements) for (i = 0, k = (<Statement[]>catchStatements).length; i < k; ++i) (<Statement[]>catchStatements)[i].parent = stmt;
|
||||
if (stmt.finallyStatements = finallyStatements) for (i = 0, k = (<Statement[]>finallyStatements).length; i < k; ++i) (<Statement[]>finallyStatements)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createVariable(declarations: VariableDeclaration[], modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): VariableStatement {
|
||||
const stmt: VariableStatement = new VariableStatement();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
for (i = 0, k = (stmt.declarations = declarations).length; i < k; ++i) declarations[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createVariableDeclaration(identifier: IdentifierExpression, type: TypeNode | null, initializer: Expression | null, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): VariableDeclaration {
|
||||
const elem: VariableDeclaration = new VariableDeclaration();
|
||||
elem.range = range;
|
||||
(elem.identifier = identifier).parent = elem;
|
||||
if (elem.type = type) (<TypeNode>type).parent = elem;
|
||||
if (elem.initializer = initializer) (<Expression>initializer).parent = elem;
|
||||
elem.modifiers = modifiers;
|
||||
elem.decorators = decorators;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createWhile(condition: Expression, statement: Statement, range: Range): WhileStatement {
|
||||
const stmt: WhileStatement = new WhileStatement();
|
||||
stmt.range = range;
|
||||
(stmt.condition = condition).parent = stmt;
|
||||
(stmt.statement = statement).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
}
|
||||
|
||||
// types
|
||||
|
||||
/** Represents a type annotation. */
|
||||
export class TypeNode extends Node {
|
||||
|
||||
kind = NodeKind.TYPE;
|
||||
|
||||
/** Identifier reference. */
|
||||
identifier: IdentifierExpression;
|
||||
/** Type argument references. */
|
||||
typeArguments: TypeNode[];
|
||||
/** Whether nullable or not. */
|
||||
isNullable: bool;
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
this.identifier.serialize(sb);
|
||||
if (this.typeArguments.length) {
|
||||
sb.push("<");
|
||||
for (let i: i32 = 0, k: i32 = this.typeArguments.length; i < k; ++i) {
|
||||
if (i > 0)
|
||||
sb.push(", ");
|
||||
this.typeArguments[i].serialize(sb);
|
||||
}
|
||||
sb.push(">");
|
||||
}
|
||||
if (this.isNullable)
|
||||
sb.push(" | null");
|
||||
}
|
||||
}
|
||||
|
||||
/** Represents a type parameter. */
|
||||
export class TypeParameter extends Node {
|
||||
|
||||
kind = NodeKind.TYPEPARAMETER;
|
||||
|
||||
/** Identifier reference. */
|
||||
identifier: IdentifierExpression;
|
||||
/** Extended type reference, if any. */
|
||||
extendsType: TypeNode | null;
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
this.identifier.serialize(sb);
|
||||
if (this.extendsType) {
|
||||
sb.push(" extends ");
|
||||
(<TypeNode>this.extendsType).serialize(sb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// expressions
|
||||
|
||||
/** Base class of all expression nodes. */
|
||||
export abstract class Expression extends Node { }
|
||||
|
||||
export class IdentifierExpression extends Expression {
|
||||
|
||||
kind = NodeKind.IDENTIFIER;
|
||||
@ -658,313 +915,8 @@ export enum ModifierKind {
|
||||
SET,
|
||||
}
|
||||
|
||||
export abstract class Statement extends Node {
|
||||
|
||||
static createBlock(statements: Statement[], range: Range): BlockStatement {
|
||||
const stmt: BlockStatement = new BlockStatement();
|
||||
stmt.range = range;
|
||||
for (let i: i32 = 0, k: i32 = (stmt.statements = statements).length; i < k; ++i) statements[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createBreak(label: IdentifierExpression | null, range: Range): BreakStatement {
|
||||
const stmt: BreakStatement = new BreakStatement();
|
||||
stmt.range = range;
|
||||
if (stmt.label = label) (<IdentifierExpression>label).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createClass(identifier: IdentifierExpression, typeParameters: TypeParameter[], extendsType: TypeNode | null, implementsTypes: TypeNode[], members: DeclarationStatement[], modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): ClassDeclaration {
|
||||
const stmt: ClassDeclaration = new ClassDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
for (i = 0, k = (stmt.typeParameters = typeParameters).length; i < k; ++i) typeParameters[i].parent = stmt;
|
||||
if (stmt.extendsType = extendsType) (<TypeNode>extendsType).parent = stmt;
|
||||
for (i = 0, k = (stmt.implementsTypes = implementsTypes).length; i < k; ++i) implementsTypes[i].parent = stmt;
|
||||
for (i = 0, k = (stmt.members = members).length; i < k; ++i) members[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createContinue(label: IdentifierExpression | null, range: Range): ContinueStatement {
|
||||
const stmt: ContinueStatement = new ContinueStatement();
|
||||
stmt.range = range;
|
||||
if (stmt.label = label) (<IdentifierExpression>label).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createDecorator(expression: Expression, args: Expression[], range: Range): Decorator {
|
||||
const stmt: Decorator = new Decorator();
|
||||
stmt.range = range;
|
||||
(stmt.expression = expression).parent = stmt;
|
||||
for (let i: i32 = 0, k: i32 = (stmt.arguments = args).length; i < k; ++i) args[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createDo(statement: Statement, condition: Expression, range: Range): DoStatement {
|
||||
const stmt: DoStatement = new DoStatement();
|
||||
stmt.range = range;
|
||||
(stmt.statement = statement).parent = stmt;
|
||||
(stmt.condition = condition).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createEmpty(range: Range): EmptyStatement {
|
||||
const stmt: EmptyStatement = new EmptyStatement();
|
||||
stmt.range = range;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createEnum(identifier: IdentifierExpression, members: EnumValueDeclaration[], modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): EnumDeclaration {
|
||||
const stmt: EnumDeclaration = new EnumDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
for (i = 0, k = (stmt.members = members).length; i < k; ++i) members[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createEnumValue(identifier: IdentifierExpression, value: Expression | null, range: Range): EnumValueDeclaration {
|
||||
const stmt: EnumValueDeclaration = new EnumValueDeclaration();
|
||||
stmt.range = range;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
if (stmt.value = value) (<Expression>value).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createExport(members: ExportMember[], path: StringLiteralExpression | null, modifiers: Modifier[] | null, range: Range): ExportStatement {
|
||||
const stmt: ExportStatement = new ExportStatement();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
for (i = 0, k = (stmt.members = members).length; i < k; ++i) members[i].parent = stmt;
|
||||
stmt.path = path;
|
||||
stmt.normalizedPath = path ? resolvePath(normalizePath(path.value), range.source.normalizedPath) : null;
|
||||
stmt.internalPath = stmt.normalizedPath ? mangleInternalPath(stmt.normalizedPath) : null;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createExportImport(identifier: IdentifierExpression, asIdentifier: IdentifierExpression, range: Range): ExportImportStatement {
|
||||
const stmt: ExportImportStatement = new ExportImportStatement();
|
||||
stmt.range = range;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
(stmt.asIdentifier = asIdentifier).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createExportMember(identifier: IdentifierExpression, externalIdentifier: IdentifierExpression | null, range: Range): ExportMember {
|
||||
const elem: ExportMember = new ExportMember();
|
||||
elem.range = range;
|
||||
(elem.identifier = identifier).parent = elem;
|
||||
(elem.externalIdentifier = externalIdentifier ? <IdentifierExpression>externalIdentifier : identifier).parent = elem;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createExpression(expression: Expression): ExpressionStatement {
|
||||
const stmt: ExpressionStatement = new ExpressionStatement();
|
||||
stmt.range = expression.range;
|
||||
(stmt.expression = expression).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createIf(condition: Expression, statement: Statement, elseStatement: Statement | null, range: Range): IfStatement {
|
||||
const stmt: IfStatement = new IfStatement();
|
||||
stmt.range = range;
|
||||
(stmt.condition = condition).parent = stmt;
|
||||
(stmt.statement = statement).parent = stmt;
|
||||
if (stmt.elseStatement = elseStatement) (<Statement>elseStatement).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createImport(declarations: ImportDeclaration[], path: StringLiteralExpression, range: Range): ImportStatement {
|
||||
const stmt: ImportStatement = new ImportStatement();
|
||||
stmt.range = range;
|
||||
for (let i: i32 = 0, k: i32 = (stmt.declarations = declarations).length; i < k; ++i) declarations[i].parent = stmt;
|
||||
stmt.path = path;
|
||||
stmt.normalizedPath = resolvePath(normalizePath(path.value), range.source.normalizedPath);
|
||||
stmt.internalPath = mangleInternalPath(stmt.normalizedPath);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createImportDeclaration(externalIdentifier: IdentifierExpression, identifier: IdentifierExpression | null, range: Range): ImportDeclaration {
|
||||
const elem: ImportDeclaration = new ImportDeclaration();
|
||||
elem.range = range;
|
||||
(elem.identifier = identifier ? <IdentifierExpression>identifier : externalIdentifier).parent = elem;
|
||||
(elem.externalIdentifier = externalIdentifier).parent = elem;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createInterface(identifier: IdentifierExpression, extendsType: TypeNode | null, members: DeclarationStatement[], modifiers: Modifier[] | null, range: Range): InterfaceDeclaration {
|
||||
const stmt: InterfaceDeclaration = new InterfaceDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
if (stmt.extendsType = extendsType) (<TypeNode>extendsType).parent = stmt;
|
||||
for (i = 0, k = (stmt.members = members).length; i < k; ++i) members[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createField(identifier: IdentifierExpression, type: TypeNode | null, initializer: Expression | null, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): FieldDeclaration {
|
||||
const stmt: FieldDeclaration = new FieldDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
if (stmt.type = type) (<TypeNode>type).parent = stmt;
|
||||
if (stmt.initializer = initializer) (<Expression>initializer).parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createFor(initializer: Statement | null, condition: Expression | null, incrementor: Expression | null, statement: Statement, range: Range): ForStatement {
|
||||
const stmt: ForStatement = new ForStatement();
|
||||
stmt.range = range;
|
||||
if (stmt.initializer = initializer) (<Statement>initializer).parent = stmt;
|
||||
if (stmt.condition = condition) (<Expression>condition).parent = stmt;
|
||||
if (stmt.incrementor = incrementor) (<Expression>incrementor).parent = stmt;
|
||||
(stmt.statement = statement).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createTypeParameter(identifier: IdentifierExpression, extendsType: TypeNode | null, range: Range): TypeParameter {
|
||||
const elem: TypeParameter = new TypeParameter();
|
||||
elem.range = range;
|
||||
(elem.identifier = identifier).parent = elem;
|
||||
if (elem.extendsType = extendsType) (<TypeNode>extendsType).parent = elem;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createParameter(identifier: IdentifierExpression, type: TypeNode | null, initializer: Expression | null, multiple: bool, range: Range): Parameter {
|
||||
const elem: Parameter = new Parameter();
|
||||
elem.range = range;
|
||||
(elem.identifier = identifier).parent = elem;
|
||||
if (elem.type = type) (<TypeNode>type).parent = elem;
|
||||
if (elem.initializer = initializer) (<Expression>initializer).parent = elem;
|
||||
elem.multiple = multiple;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createFunction(identifier: IdentifierExpression, typeParameters: TypeParameter[], parameters: Parameter[], returnType: TypeNode | null, statements: Statement[] | null, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): FunctionDeclaration {
|
||||
const stmt: FunctionDeclaration = new FunctionDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
for (i = 0, k = (stmt.typeParameters = typeParameters).length; i < k; ++i) typeParameters[i].parent = stmt;
|
||||
for (i = 0, k = (stmt.parameters = parameters).length; i < k; ++i) parameters[i].parent = stmt;
|
||||
if (stmt.returnType = returnType) (<TypeNode>returnType).parent = stmt;
|
||||
if (stmt.statements = statements) for (i = 0, k = (<Statement[]>statements).length; i < k; ++i) (<Statement[]>statements)[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createMethod(identifier: IdentifierExpression, typeParameters: TypeParameter[], parameters: Parameter[], returnType: TypeNode | null, statements: Statement[] | null, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): MethodDeclaration {
|
||||
const stmt: MethodDeclaration = new MethodDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
for (i = 0, k = (stmt.typeParameters = typeParameters).length; i < k; ++i) typeParameters[i].parent = stmt;
|
||||
for (i = 0, k = (stmt.parameters = parameters).length; i < k; ++i) parameters[i].parent = stmt;
|
||||
if (stmt.returnType = returnType) (<TypeNode>returnType).parent = stmt;;
|
||||
if (stmt.statements = statements) for (i = 0, k = (<Statement[]>statements).length; i < k; ++i) (<Statement[]>statements)[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createModifier(kind: ModifierKind, range: Range): Modifier {
|
||||
const elem: Modifier = new Modifier();
|
||||
elem.range = range;
|
||||
elem.modifierKind = kind;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createNamespace(identifier: IdentifierExpression, members: Statement[], modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): NamespaceDeclaration {
|
||||
const stmt: NamespaceDeclaration = new NamespaceDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
(stmt.identifier = identifier).parent = stmt;
|
||||
for (i = 0, k = (stmt.members = members).length; i < k; ++i) members[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createReturn(expression: Expression | null, range: Range): ReturnStatement {
|
||||
const stmt: ReturnStatement = new ReturnStatement();
|
||||
stmt.range = range;
|
||||
if (stmt.expression = expression) (<Expression>expression).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createSwitch(expression: Expression, cases: SwitchCase[], range: Range): SwitchStatement {
|
||||
const stmt: SwitchStatement = new SwitchStatement();
|
||||
stmt.range = range;
|
||||
(stmt.expression = expression).parent = stmt;
|
||||
for (let i: i32 = 0, k: i32 = (stmt.cases = cases).length; i < k; ++i) cases[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createSwitchCase(label: Expression | null, statements: Statement[], range: Range): SwitchCase {
|
||||
const elem: SwitchCase = new SwitchCase();
|
||||
elem.range = range;
|
||||
if (elem.label = label) (<Expression>label).parent = elem;
|
||||
for (let i: i32 = 0, k: i32 = (elem.statements = statements).length; i < k; ++i) statements[i].parent = elem;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createThrow(expression: Expression, range: Range): ThrowStatement {
|
||||
const stmt: ThrowStatement = new ThrowStatement();
|
||||
stmt.range = range;
|
||||
(stmt.expression = expression).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createTry(statements: Statement[], catchVariable: IdentifierExpression | null, catchStatements: Statement[] | null, finallyStatements: Statement[] | null, range: Range): TryStatement {
|
||||
const stmt: TryStatement = new TryStatement();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
for (i = 0, k = (stmt.statements = statements).length; i < k; ++i) statements[i].parent = stmt;
|
||||
if (stmt.catchVariable = catchVariable) (<IdentifierExpression>catchVariable).parent = stmt;
|
||||
if (stmt.catchStatements = catchStatements) for (i = 0, k = (<Statement[]>catchStatements).length; i < k; ++i) (<Statement[]>catchStatements)[i].parent = stmt;
|
||||
if (stmt.finallyStatements = finallyStatements) for (i = 0, k = (<Statement[]>finallyStatements).length; i < k; ++i) (<Statement[]>finallyStatements)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createVariable(declarations: VariableDeclaration[], modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): VariableStatement {
|
||||
const stmt: VariableStatement = new VariableStatement();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
for (i = 0, k = (stmt.declarations = declarations).length; i < k; ++i) declarations[i].parent = stmt;
|
||||
if (stmt.modifiers = modifiers) for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i) (<Modifier[]>modifiers)[i].parent = stmt;
|
||||
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createVariableDeclaration(identifier: IdentifierExpression, type: TypeNode | null, initializer: Expression | null, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): VariableDeclaration {
|
||||
const elem: VariableDeclaration = new VariableDeclaration();
|
||||
elem.range = range;
|
||||
(elem.identifier = identifier).parent = elem;
|
||||
if (elem.type = type) (<TypeNode>type).parent = elem;
|
||||
if (elem.initializer = initializer) (<Expression>initializer).parent = elem;
|
||||
elem.modifiers = modifiers;
|
||||
elem.decorators = decorators;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createWhile(condition: Expression, statement: Statement, range: Range): WhileStatement {
|
||||
const stmt: WhileStatement = new WhileStatement();
|
||||
stmt.range = range;
|
||||
(stmt.condition = condition).parent = stmt;
|
||||
(stmt.statement = statement).parent = stmt;
|
||||
return stmt;
|
||||
}
|
||||
}
|
||||
/** Base class of all statement nodes. */
|
||||
export abstract class Statement extends Node { }
|
||||
|
||||
export class Source extends Node {
|
||||
|
||||
@ -1064,11 +1016,7 @@ export class ClassDeclaration extends DeclarationStatement {
|
||||
get internalName(): string {
|
||||
if (this._cachedInternalName !== null)
|
||||
return this._cachedInternalName;
|
||||
const globalDecorator: Decorator | null = this.decorators ? getDecoratorByName("global", this.decorators) : null;
|
||||
if (globalDecorator)
|
||||
return this._cachedInternalName = this.identifier.name;
|
||||
else
|
||||
return this._cachedInternalName = mangleInternalName(this);
|
||||
return this._cachedInternalName = mangleInternalName(this);
|
||||
}
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
@ -1350,11 +1298,7 @@ export class FunctionDeclaration extends DeclarationStatement {
|
||||
get internalName(): string {
|
||||
if (this._cachedInternalName !== null)
|
||||
return this._cachedInternalName;
|
||||
const globalDecorator: Decorator | null = this.decorators ? getDecoratorByName("global", this.decorators) : null;
|
||||
if (globalDecorator && globalDecorator.expression.kind == NodeKind.IDENTIFIER && (<IdentifierExpression>globalDecorator.expression).name == "global")
|
||||
return this._cachedInternalName = this.identifier.name;
|
||||
else
|
||||
return this._cachedInternalName = mangleInternalName(this);
|
||||
return this._cachedInternalName = mangleInternalName(this);
|
||||
}
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
@ -1591,21 +1535,25 @@ export class Modifier extends Node {
|
||||
modifierKind: ModifierKind;
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
sb.push(this.toString());
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
switch (this.modifierKind) {
|
||||
case ModifierKind.ABSTRACT: sb.push("abstract"); break;
|
||||
case ModifierKind.ASYNC: sb.push("async"); break;
|
||||
case ModifierKind.CONST: sb.push("const"); break;
|
||||
case ModifierKind.DECLARE: sb.push("declare"); break;
|
||||
case ModifierKind.EXPORT: sb.push("export"); break;
|
||||
case ModifierKind.GET: sb.push("get"); break;
|
||||
case ModifierKind.IMPORT: sb.push("import"); break;
|
||||
case ModifierKind.PRIVATE: sb.push("private"); break;
|
||||
case ModifierKind.PROTECTED: sb.push("protected"); break;
|
||||
case ModifierKind.PUBLIC: sb.push("public"); break;
|
||||
case ModifierKind.READONLY: sb.push("readonly"); break;
|
||||
case ModifierKind.SET: sb.push("set"); break;
|
||||
case ModifierKind.STATIC: sb.push("static"); break;
|
||||
default: throw new Error("unexpected modifier kind");
|
||||
case ModifierKind.ABSTRACT: return "abstract";
|
||||
case ModifierKind.ASYNC: return "async";
|
||||
case ModifierKind.CONST: return "const";
|
||||
case ModifierKind.DECLARE: return "declare";
|
||||
case ModifierKind.EXPORT: return "export";
|
||||
case ModifierKind.GET: return "get";
|
||||
case ModifierKind.IMPORT: return "import";
|
||||
case ModifierKind.PRIVATE: return "private";
|
||||
case ModifierKind.PROTECTED: return "protected";
|
||||
case ModifierKind.PUBLIC: return "public";
|
||||
case ModifierKind.READONLY: return "readonly";
|
||||
case ModifierKind.SET: return "set";
|
||||
case ModifierKind.STATIC: return "static";
|
||||
default: return "INVALID_MODIFIER";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,11 +99,11 @@ export function initialize(program: Program): void {
|
||||
if (program.target == Target.WASM64) {
|
||||
program.elements.set("isize", <Element>program.elements.get("i64"));
|
||||
program.elements.set("usize", <Element>program.elements.get("u64"));
|
||||
addConstant(program, "HEAP_START", Type.usize64);
|
||||
addConstant(program, "HEAP_BASE", Type.usize64);
|
||||
} else {
|
||||
program.elements.set("isize", <Element>program.elements.get("i32"));
|
||||
program.elements.set("usize", <Element>program.elements.get("u32"));
|
||||
addConstant(program, "HEAP_START", Type.usize32);
|
||||
addConstant(program, "HEAP_BASE", Type.usize32);
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,6 +126,7 @@ function addFunction(program: Program, name: string, isGeneric: bool = false): F
|
||||
return prototype;
|
||||
}
|
||||
|
||||
/** Compiles a get of a built-in global. */
|
||||
export function compileGetGlobal(compiler: Compiler, global: Global): ExpressionRef {
|
||||
switch (global.internalName) {
|
||||
|
||||
@ -141,8 +142,8 @@ export function compileGetGlobal(compiler: Compiler, global: Global): Expression
|
||||
compiler.currentType = Type.f64;
|
||||
return compiler.module.createF64(Infinity);
|
||||
|
||||
case "HEAP_START": // never inlined
|
||||
return compiler.module.createGetGlobal("HEAP_START", typeToNativeType(<Type>global.type));
|
||||
case "HEAP_BASE": // constant, but never inlined
|
||||
return compiler.module.createGetGlobal("HEAP_BASE", typeToNativeType(compiler.currentType = <Type>global.type));
|
||||
|
||||
default:
|
||||
throw new Error("not implemented: " + global.internalName);
|
||||
@ -162,8 +163,7 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty
|
||||
let tempLocal0: Local;
|
||||
let tempLocal1: Local;
|
||||
|
||||
let type: Type;
|
||||
var ftype: FunctionTypeRef;
|
||||
let ftype: FunctionTypeRef;
|
||||
|
||||
switch (prototype.internalName) {
|
||||
|
||||
|
@ -215,9 +215,9 @@ export class Compiler extends DiagnosticEmitter {
|
||||
// set up memory
|
||||
const initial: U64 = this.memoryOffset.clone();
|
||||
if (this.options.target == Target.WASM64)
|
||||
this.module.addGlobal("HEAP_START", NativeType.I64, false, this.module.createI64(initial.lo, initial.hi));
|
||||
this.module.addGlobal("HEAP_BASE", NativeType.I64, false, this.module.createI64(initial.lo, initial.hi));
|
||||
else
|
||||
this.module.addGlobal("HEAP_START", NativeType.I32, false, this.module.createI32(initial.lo));
|
||||
this.module.addGlobal("HEAP_BASE", NativeType.I32, false, this.module.createI32(initial.lo));
|
||||
|
||||
// determine initial page size
|
||||
const initialOverlaps: U64 = initial.clone();
|
||||
|
198
src/parser.ts
198
src/parser.ts
@ -117,10 +117,10 @@ export class Parser extends DiagnosticEmitter {
|
||||
let modifiers: Modifier[] | null = null;
|
||||
|
||||
if (tn.skip(Token.EXPORT))
|
||||
modifiers = addModifier(Statement.createModifier(ModifierKind.EXPORT, tn.range()), modifiers);
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.EXPORT, tn.range()), modifiers);
|
||||
|
||||
if (tn.skip(Token.DECLARE)) {
|
||||
modifiers = addModifier(Statement.createModifier(ModifierKind.DECLARE, tn.range()), modifiers);
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.DECLARE, tn.range()), modifiers);
|
||||
tn.peek(true);
|
||||
if (tn.nextTokenOnNewLine)
|
||||
this.error(DiagnosticCode.Line_break_not_permitted_here, tn.range(tn.pos)); // recoverable, compatibility
|
||||
@ -132,7 +132,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
switch (tn.next()) {
|
||||
|
||||
case Token.CONST:
|
||||
modifiers = addModifier(Statement.createModifier(ModifierKind.CONST, tn.range()), modifiers);
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.CONST, tn.range()), modifiers);
|
||||
|
||||
if (tn.skip(Token.ENUM)) {
|
||||
statement = this.parseEnum(tn, modifiers, decorators);
|
||||
@ -161,7 +161,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode._0_expected, tn.range(tn.pos), "class");
|
||||
break;
|
||||
}
|
||||
modifiers = addModifier(Statement.createModifier(ModifierKind.ABSTRACT, tn.range()), modifiers);
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.ABSTRACT, tn.range()), modifiers);
|
||||
// fall through
|
||||
|
||||
case Token.CLASS:
|
||||
@ -236,7 +236,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
|
||||
// void
|
||||
if (token == Token.VOID)
|
||||
return TypeNode.create(Expression.createIdentifier("void", tn.range()), [], false, tn.range(startPos, tn.pos));
|
||||
return Node.createType(Node.createIdentifier("void", tn.range()), [], false, tn.range(startPos, tn.pos));
|
||||
|
||||
let type: TypeNode;
|
||||
|
||||
@ -256,20 +256,20 @@ export class Parser extends DiagnosticEmitter {
|
||||
|
||||
// this
|
||||
} else if (token == Token.THIS) {
|
||||
type = TypeNode.create(Expression.createThis(tn.range()), [], false, tn.range(startPos, tn.pos));
|
||||
type = Node.createType(Node.createThis(tn.range()), [], false, tn.range(startPos, tn.pos));
|
||||
|
||||
// true
|
||||
} else if (token == Token.TRUE || token == Token.FALSE) {
|
||||
type = TypeNode.create(Expression.createIdentifier("bool", tn.range()), [], false, tn.range(startPos, tn.pos));
|
||||
type = Node.createType(Node.createIdentifier("bool", tn.range()), [], false, tn.range(startPos, tn.pos));
|
||||
|
||||
// string literal
|
||||
} else if (token == Token.STRINGLITERAL) {
|
||||
tn.readString();
|
||||
type = TypeNode.create(Expression.createIdentifier("string", tn.range()), [], false, tn.range(startPos, tn.pos));
|
||||
type = Node.createType(Node.createIdentifier("string", tn.range()), [], false, tn.range(startPos, tn.pos));
|
||||
|
||||
// Name
|
||||
} else if (token == Token.IDENTIFIER) {
|
||||
const identifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const identifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const parameters: TypeNode[] = new Array();
|
||||
let nullable: bool = false;
|
||||
|
||||
@ -297,7 +297,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
type = TypeNode.create(identifier, parameters, nullable, tn.range(startPos, tn.pos));
|
||||
type = Node.createType(identifier, parameters, nullable, tn.range(startPos, tn.pos));
|
||||
|
||||
} else {
|
||||
if (!suppressErrors)
|
||||
@ -325,7 +325,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
type = TypeNode.create(Expression.createIdentifier("Array", bracketRange), [ type ], nullable, tn.range(startPos, tn.pos));
|
||||
type = Node.createType(Node.createIdentifier("Array", bracketRange), [ type ], nullable, tn.range(startPos, tn.pos));
|
||||
if (nullable)
|
||||
break;
|
||||
}
|
||||
@ -340,11 +340,11 @@ export class Parser extends DiagnosticEmitter {
|
||||
const startPos: i32 = tn.tokenPos;
|
||||
if (tn.skip(Token.IDENTIFIER)) {
|
||||
let name: string = tn.readIdentifier();
|
||||
let expression: Expression = Expression.createIdentifier(name, tn.range(startPos, tn.pos));
|
||||
let expression: Expression = Node.createIdentifier(name, tn.range(startPos, tn.pos));
|
||||
while (tn.skip(Token.DOT)) {
|
||||
if (tn.skip(Token.IDENTIFIER)) {
|
||||
name = tn.readIdentifier();
|
||||
expression = Expression.createPropertyAccess(expression, Expression.createIdentifier(name, tn.range()), tn.range(startPos, tn.pos));
|
||||
expression = Node.createPropertyAccess(expression, Node.createIdentifier(name, tn.range()), tn.range(startPos, tn.pos));
|
||||
} else {
|
||||
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
||||
return null;
|
||||
@ -353,7 +353,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
if (tn.skip(Token.OPENPAREN)) {
|
||||
const args: Expression[] | null = this.parseArguments(tn);
|
||||
if (args)
|
||||
return Statement.createDecorator(expression, <Expression[]>args, tn.range(startPos, tn.pos));
|
||||
return Node.createDecorator(expression, <Expression[]>args, tn.range(startPos, tn.pos));
|
||||
} else
|
||||
this.error(DiagnosticCode._0_expected, tn.range(), "(");
|
||||
} else
|
||||
@ -373,7 +373,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
members.push(<VariableDeclaration>member);
|
||||
} while (tn.skip(Token.COMMA));
|
||||
|
||||
const ret: VariableStatement = Statement.createVariable(members, modifiers, decorators, tn.range(startPos, tn.pos));
|
||||
const ret: VariableStatement = Node.createVariable(members, modifiers, decorators, tn.range(startPos, tn.pos));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
}
|
||||
@ -384,7 +384,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
||||
return null;
|
||||
}
|
||||
const identifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const identifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
|
||||
let type: TypeNode | null = null;
|
||||
if (tn.skip(Token.COLON))
|
||||
@ -403,7 +403,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
else if (!type) // neither type nor initializer
|
||||
this.error(DiagnosticCode.Type_expected, tn.range(tn.pos)); // recoverable
|
||||
}
|
||||
return Statement.createVariableDeclaration(identifier, type, initializer, parentModifiers, parentDecorators, Range.join(identifier.range, tn.range()));
|
||||
return Node.createVariableDeclaration(identifier, type, initializer, parentModifiers, parentDecorators, Range.join(identifier.range, tn.range()));
|
||||
}
|
||||
|
||||
parseEnum(tn: Tokenizer, modifiers: Modifier[] | null, decorators: Decorator[] | null): EnumDeclaration | null {
|
||||
@ -413,7 +413,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
||||
return null;
|
||||
}
|
||||
const identifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const identifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
if (tn.next() != Token.OPENBRACE) {
|
||||
this.error(DiagnosticCode._0_expected, tn.range(), "{");
|
||||
return null;
|
||||
@ -431,7 +431,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
const ret: EnumDeclaration = Statement.createEnum(identifier, members, modifiers, decorators, tn.range(startPos, tn.pos));
|
||||
const ret: EnumDeclaration = Node.createEnum(identifier, members, modifiers, decorators, tn.range(startPos, tn.pos));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
}
|
||||
@ -442,14 +442,14 @@ export class Parser extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
||||
return null;
|
||||
}
|
||||
const identifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const identifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
let value: Expression | null = null;
|
||||
if (tn.skip(Token.EQUALS)) {
|
||||
value = this.parseExpression(tn, Precedence.COMMA + 1);
|
||||
if (!value)
|
||||
return null;
|
||||
}
|
||||
return Statement.createEnumValue(identifier, value, Range.join(identifier.range, tn.range()));
|
||||
return Node.createEnumValue(identifier, value, Range.join(identifier.range, tn.range()));
|
||||
}
|
||||
|
||||
parseReturn(tn: Tokenizer): ReturnStatement | null {
|
||||
@ -460,7 +460,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
if (!expr)
|
||||
return null;
|
||||
}
|
||||
const ret: ReturnStatement = Statement.createReturn(expr, tn.range());
|
||||
const ret: ReturnStatement = Node.createReturn(expr, tn.range());
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
}
|
||||
@ -487,14 +487,14 @@ export class Parser extends DiagnosticEmitter {
|
||||
parseTypeParameter(tn: Tokenizer): TypeParameter | null {
|
||||
// Identifier ('extends' Type)?
|
||||
if (tn.next() == Token.IDENTIFIER) {
|
||||
const identifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const identifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
let extendsType: TypeNode | null = null;
|
||||
if (tn.skip(Token.EXTENDS)) {
|
||||
extendsType = this.parseType(tn);
|
||||
if (!extendsType)
|
||||
return null;
|
||||
}
|
||||
return Statement.createTypeParameter(identifier, extendsType, Range.join(identifier.range, tn.range()));
|
||||
return Node.createTypeParameter(identifier, extendsType, Range.join(identifier.range, tn.range()));
|
||||
} else
|
||||
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
||||
return null;
|
||||
@ -529,7 +529,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
if (tn.skip(Token.IDENTIFIER)) {
|
||||
if (!multiple)
|
||||
startRange = tn.range();
|
||||
const identifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const identifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
let type: TypeNode | null = null;
|
||||
if (tn.skip(Token.COLON)) {
|
||||
type = this.parseType(tn);
|
||||
@ -542,7 +542,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
if (!initializer)
|
||||
return null;
|
||||
}
|
||||
return Statement.createParameter(identifier, type, initializer, multiple, Range.join(<Range>startRange, tn.range()));
|
||||
return Node.createParameter(identifier, type, initializer, multiple, Range.join(<Range>startRange, tn.range()));
|
||||
} else
|
||||
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
||||
return null;
|
||||
@ -556,7 +556,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode.Identifier_expected, tn.range(tn.pos));
|
||||
return null;
|
||||
}
|
||||
const identifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const identifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
let typeParameters: TypeParameter[] | null = null;
|
||||
if (tn.skip(Token.LESSTHAN)) {
|
||||
typeParameters = this.parseTypeParameters(tn);
|
||||
@ -607,7 +607,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
}
|
||||
} else if (!isDeclare)
|
||||
this.error(DiagnosticCode.Function_implementation_is_missing_or_not_immediately_following_the_declaration, tn.range(tn.pos));
|
||||
const ret: FunctionDeclaration = Statement.createFunction(identifier, typeParameters, <Parameter[]>parameters, returnType, statements, modifiers, decorators, tn.range(startPos, tn.pos));
|
||||
const ret: FunctionDeclaration = Node.createFunction(identifier, typeParameters, <Parameter[]>parameters, returnType, statements, modifiers, decorators, tn.range(startPos, tn.pos));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
}
|
||||
@ -621,7 +621,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
: tn.tokenPos;
|
||||
|
||||
if (tn.skip(Token.IDENTIFIER)) {
|
||||
const identifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const identifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
let typeParameters: TypeParameter[] | null;
|
||||
|
||||
if (tn.skip(Token.LESSTHAN)) {
|
||||
@ -659,7 +659,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
members.push(<DeclarationStatement>member);
|
||||
} while (!tn.skip(Token.CLOSEBRACE));
|
||||
}
|
||||
return Statement.createClass(identifier, <TypeParameter[]>typeParameters, extendsType, implementsTypes, members, modifiers, decorators, tn.range(startPos, tn.pos));
|
||||
return Node.createClass(identifier, <TypeParameter[]>typeParameters, extendsType, implementsTypes, members, modifiers, decorators, tn.range(startPos, tn.pos));
|
||||
} else
|
||||
this.error(DiagnosticCode._0_expected, tn.range(), "{");
|
||||
} else
|
||||
@ -683,34 +683,34 @@ export class Parser extends DiagnosticEmitter {
|
||||
let modifiers: Modifier[] | null = null;
|
||||
|
||||
if (tn.skip(Token.PUBLIC))
|
||||
modifiers = addModifier(Statement.createModifier(ModifierKind.PUBLIC, tn.range()), modifiers);
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.PUBLIC, tn.range()), modifiers);
|
||||
else if (tn.skip(Token.PRIVATE))
|
||||
modifiers = addModifier(Statement.createModifier(ModifierKind.PRIVATE, tn.range()), modifiers);
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.PRIVATE, tn.range()), modifiers);
|
||||
else if (tn.skip(Token.PROTECTED))
|
||||
modifiers = addModifier(Statement.createModifier(ModifierKind.PROTECTED, tn.range()), modifiers);
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.PROTECTED, tn.range()), modifiers);
|
||||
|
||||
if (tn.skip(Token.STATIC))
|
||||
modifiers = addModifier(Statement.createModifier(ModifierKind.STATIC, tn.range()), modifiers);
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.STATIC, tn.range()), modifiers);
|
||||
else if (tn.skip(Token.ABSTRACT))
|
||||
modifiers = addModifier(Statement.createModifier(ModifierKind.ABSTRACT, tn.range()), modifiers);
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.ABSTRACT, tn.range()), modifiers);
|
||||
|
||||
if (tn.skip(Token.READONLY))
|
||||
modifiers = addModifier(Statement.createModifier(ModifierKind.READONLY, tn.range()), modifiers);
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.READONLY, tn.range()), modifiers);
|
||||
|
||||
let isGetter: bool = false;
|
||||
let isSetter: bool = false;
|
||||
if (tn.skip(Token.GET)) {
|
||||
modifiers = addModifier(Statement.createModifier(ModifierKind.GET, tn.range()), modifiers);
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.GET, tn.range()), modifiers);
|
||||
isGetter = true;
|
||||
} else if (tn.skip(Token.SET)) { // can't be both
|
||||
modifiers = addModifier(Statement.createModifier(ModifierKind.SET, tn.range()), modifiers);
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.SET, tn.range()), modifiers);
|
||||
isSetter = true;
|
||||
}
|
||||
|
||||
if (tn.skip(Token.IDENTIFIER) || tn.skip(Token.CONSTRUCTOR)) {
|
||||
const identifier: IdentifierExpression = tn.token == Token.CONSTRUCTOR
|
||||
? Expression.createConstructor(tn.range())
|
||||
: Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
? Node.createConstructor(tn.range())
|
||||
: Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
let typeParameters: TypeParameter[] | null;
|
||||
if (tn.skip(Token.LESSTHAN)) {
|
||||
if (identifier.kind == NodeKind.CONSTRUCTOR)
|
||||
@ -769,7 +769,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode.Function_implementation_is_missing_or_not_immediately_following_the_declaration, tn.range()); // recoverable
|
||||
}
|
||||
|
||||
const ret: MethodDeclaration = Statement.createMethod(identifier, <TypeParameter[]>typeParameters, <Parameter[]>parameters, returnType, statements, modifiers, decorators, Range.join(startRange, tn.range()));
|
||||
const ret: MethodDeclaration = Node.createMethod(identifier, <TypeParameter[]>typeParameters, <Parameter[]>parameters, returnType, statements, modifiers, decorators, Range.join(startRange, tn.range()));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
|
||||
@ -794,7 +794,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
if (!initializer)
|
||||
return null;
|
||||
}
|
||||
const ret: FieldDeclaration = Statement.createField(identifier, type, initializer, modifiers, decorators, Range.join(startRange, tn.range()));
|
||||
const ret: FieldDeclaration = Node.createField(identifier, type, initializer, modifiers, decorators, Range.join(startRange, tn.range()));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
}
|
||||
@ -807,7 +807,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
// at 'namespace': Identifier '{' (Variable | Function)* '}'
|
||||
const startRange: Range = modifiers && modifiers.length ? modifiers[0].range : tn.range();
|
||||
if (tn.skip(Token.IDENTIFIER)) {
|
||||
const identifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const identifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
if (tn.skip(Token.OPENBRACE)) {
|
||||
const members: Statement[] = new Array();
|
||||
while (!tn.skip(Token.CLOSEBRACE)) {
|
||||
@ -816,7 +816,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
members.push(member);
|
||||
}
|
||||
const ret: NamespaceDeclaration = Statement.createNamespace(identifier, members, modifiers, decorators, Range.join(startRange, tn.range()));
|
||||
const ret: NamespaceDeclaration = Node.createNamespace(identifier, members, modifiers, decorators, Range.join(startRange, tn.range()));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
} else
|
||||
@ -846,13 +846,13 @@ export class Parser extends DiagnosticEmitter {
|
||||
let path: StringLiteralExpression | null = null;
|
||||
if (tn.skip(Token.FROM)) {
|
||||
if (tn.skip(Token.STRINGLITERAL))
|
||||
path = Expression.createStringLiteral(tn.readString(), tn.range());
|
||||
path = Node.createStringLiteral(tn.readString(), tn.range());
|
||||
else {
|
||||
this.error(DiagnosticCode.String_literal_expected, tn.range());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
const ret: ExportStatement = Statement.createExport(members, path, modifiers, Range.join(startRange, tn.range()));
|
||||
const ret: ExportStatement = Node.createExport(members, path, modifiers, Range.join(startRange, tn.range()));
|
||||
if (ret.normalizedPath && !this.seenlog.has(<string>ret.normalizedPath)) {
|
||||
this.backlog.push(<string>ret.normalizedPath);
|
||||
this.seenlog.add(<string>ret.normalizedPath);
|
||||
@ -867,17 +867,17 @@ export class Parser extends DiagnosticEmitter {
|
||||
parseExportMember(tn: Tokenizer): ExportMember | null {
|
||||
// Identifier ('as' Identifier)?
|
||||
if (tn.skip(Token.IDENTIFIER)) {
|
||||
const identifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const identifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
let asIdentifier: IdentifierExpression | null = null;
|
||||
if (tn.skip(Token.AS)) {
|
||||
if (tn.skip(Token.IDENTIFIER))
|
||||
asIdentifier = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
asIdentifier = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
else {
|
||||
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return Statement.createExportMember(identifier, asIdentifier, asIdentifier ? Range.join(identifier.range, asIdentifier.range) : identifier.range);
|
||||
return Node.createExportMember(identifier, asIdentifier, asIdentifier ? Range.join(identifier.range, asIdentifier.range) : identifier.range);
|
||||
} else
|
||||
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
||||
return null;
|
||||
@ -902,8 +902,8 @@ export class Parser extends DiagnosticEmitter {
|
||||
}
|
||||
if (tn.skip(Token.FROM)) {
|
||||
if (tn.skip(Token.STRINGLITERAL)) {
|
||||
const path: StringLiteralExpression = Expression.createStringLiteral(tn.readString(), tn.range());
|
||||
const ret: ImportStatement = Statement.createImport(members, path, Range.join(startRange, tn.range()));
|
||||
const path: StringLiteralExpression = Node.createStringLiteral(tn.readString(), tn.range());
|
||||
const ret: ImportStatement = Node.createImport(members, path, Range.join(startRange, tn.range()));
|
||||
if (!this.seenlog.has(ret.normalizedPath)) {
|
||||
this.backlog.push(ret.normalizedPath);
|
||||
this.seenlog.add(ret.normalizedPath);
|
||||
@ -922,17 +922,17 @@ export class Parser extends DiagnosticEmitter {
|
||||
parseImportDeclaration(tn: Tokenizer): ImportDeclaration | null {
|
||||
// Identifier ('as' Identifier)?
|
||||
if (tn.skip(Token.IDENTIFIER)) {
|
||||
const identifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const identifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
let asIdentifier: IdentifierExpression | null = null;
|
||||
if (tn.skip(Token.AS)) {
|
||||
if (tn.skip(Token.IDENTIFIER))
|
||||
asIdentifier = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
asIdentifier = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
else {
|
||||
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return Statement.createImportDeclaration(identifier, asIdentifier, asIdentifier ? Range.join(identifier.range, asIdentifier.range) : identifier.range);
|
||||
return Node.createImportDeclaration(identifier, asIdentifier, asIdentifier ? Range.join(identifier.range, asIdentifier.range) : identifier.range);
|
||||
} else
|
||||
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
||||
return null;
|
||||
@ -941,11 +941,11 @@ export class Parser extends DiagnosticEmitter {
|
||||
parseExportImport(tn: Tokenizer, startRange: Range): ExportImportStatement | null {
|
||||
// at 'export' 'import': Identifier ('=' Identifier)? ';'?
|
||||
if (tn.skip(Token.IDENTIFIER)) {
|
||||
const asIdentifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const asIdentifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
if (tn.skip(Token.EQUALS)) {
|
||||
if (tn.skip(Token.IDENTIFIER)) {
|
||||
const identifier: IdentifierExpression = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const ret: ExportImportStatement = Statement.createExportImport(identifier, asIdentifier, Range.join(startRange, tn.range()));
|
||||
const identifier: IdentifierExpression = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
const ret: ExportImportStatement = Node.createExportImport(identifier, asIdentifier, Range.join(startRange, tn.range()));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
} else
|
||||
@ -967,7 +967,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return this.parseBreak(tn);
|
||||
|
||||
case Token.CONST:
|
||||
return this.parseVariable(tn, [ Statement.createModifier(ModifierKind.CONST, tn.range()) ], null);
|
||||
return this.parseVariable(tn, [ Node.createModifier(ModifierKind.CONST, tn.range()) ], null);
|
||||
|
||||
case Token.CONTINUE:
|
||||
return this.parseContinue(tn);
|
||||
@ -994,7 +994,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return this.parseReturn(tn);
|
||||
|
||||
case Token.SEMICOLON:
|
||||
return Statement.createEmpty(tn.range(tn.tokenPos));
|
||||
return Node.createEmpty(tn.range(tn.tokenPos));
|
||||
|
||||
case Token.SWITCH:
|
||||
return this.parseSwitchStatement(tn);
|
||||
@ -1024,7 +1024,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
statements.push(statement);
|
||||
}
|
||||
const ret: BlockStatement = Statement.createBlock(statements, tn.range(startPos, tn.pos));
|
||||
const ret: BlockStatement = Node.createBlock(statements, tn.range(startPos, tn.pos));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
}
|
||||
@ -1034,9 +1034,9 @@ export class Parser extends DiagnosticEmitter {
|
||||
let identifier: IdentifierExpression | null = null;
|
||||
if (tn.peek(true) == Token.IDENTIFIER && !tn.nextTokenOnNewLine) {
|
||||
tn.next(true);
|
||||
identifier = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
identifier = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
}
|
||||
const ret: ContinueStatement = Statement.createBreak(identifier, tn.range());
|
||||
const ret: ContinueStatement = Node.createBreak(identifier, tn.range());
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
}
|
||||
@ -1046,9 +1046,9 @@ export class Parser extends DiagnosticEmitter {
|
||||
let identifier: IdentifierExpression | null = null;
|
||||
if (tn.peek(true) == Token.IDENTIFIER && !tn.nextTokenOnNewLine) {
|
||||
tn.next(true);
|
||||
identifier = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
identifier = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
}
|
||||
const ret: ContinueStatement = Statement.createContinue(identifier, tn.range());
|
||||
const ret: ContinueStatement = Node.createContinue(identifier, tn.range());
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
}
|
||||
@ -1065,7 +1065,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
if (!condition)
|
||||
return null;
|
||||
if (tn.skip(Token.CLOSEPAREN)) {
|
||||
const ret: DoStatement = Statement.createDo(<Statement>statement, <Expression>condition, tn.range(startPos, tn.pos));
|
||||
const ret: DoStatement = Node.createDo(<Statement>statement, <Expression>condition, tn.range(startPos, tn.pos));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
}
|
||||
@ -1082,7 +1082,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
const expr: Expression | null = this.parseExpression(tn);
|
||||
if (!expr)
|
||||
return null;
|
||||
const ret: ExpressionStatement = Statement.createExpression(expr);
|
||||
const ret: ExpressionStatement = Node.createExpression(expr);
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
}
|
||||
@ -1120,7 +1120,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
const statement: Statement | null = this.parseStatement(tn);
|
||||
if (!statement)
|
||||
return null;
|
||||
return Statement.createFor(initializer, condition ? condition.expression : null, incrementor, statement, tn.range(startPos, tn.pos));
|
||||
return Node.createFor(initializer, condition ? condition.expression : null, incrementor, statement, tn.range(startPos, tn.pos));
|
||||
} else
|
||||
this.error(DiagnosticCode._0_expected, tn.range(), ";");
|
||||
} else
|
||||
@ -1147,7 +1147,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
if (!elseStatement)
|
||||
return null;
|
||||
}
|
||||
return Statement.createIf(<Expression>condition, <Statement>statement, elseStatement, Range.join(startRange, tn.range()));
|
||||
return Node.createIf(<Expression>condition, <Statement>statement, elseStatement, Range.join(startRange, tn.range()));
|
||||
}
|
||||
this.error(DiagnosticCode._0_expected, tn.range(), ")");
|
||||
} else
|
||||
@ -1171,7 +1171,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
cases.push(<SwitchCase>case_);
|
||||
}
|
||||
const ret: SwitchStatement = Statement.createSwitch(condition, cases, tn.range(startPos, tn.pos));
|
||||
const ret: SwitchStatement = Node.createSwitch(condition, cases, tn.range(startPos, tn.pos));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
} else
|
||||
@ -1199,7 +1199,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
statements.push(<Statement>statement);
|
||||
}
|
||||
return Statement.createSwitchCase(<Expression>label, statements, tn.range(startPos, tn.pos));
|
||||
return Node.createSwitchCase(<Expression>label, statements, tn.range(startPos, tn.pos));
|
||||
} else
|
||||
this.error(DiagnosticCode._0_expected, tn.range(), ":");
|
||||
|
||||
@ -1213,7 +1213,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
statements.push(<Statement>statement);
|
||||
}
|
||||
return Statement.createSwitchCase(null, statements, tn.range(startPos, tn.pos));
|
||||
return Node.createSwitchCase(null, statements, tn.range(startPos, tn.pos));
|
||||
} else
|
||||
this.error(DiagnosticCode._0_expected, tn.range(), ":");
|
||||
|
||||
@ -1229,7 +1229,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
const expression: Expression | null = this.parseExpression(tn);
|
||||
if (!expression)
|
||||
return null;
|
||||
const ret: ThrowStatement = Statement.createThrow(<Expression>expression, tn.range(startPos, tn.pos));
|
||||
const ret: ThrowStatement = Node.createThrow(<Expression>expression, tn.range(startPos, tn.pos));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
}
|
||||
@ -1257,7 +1257,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
||||
return null;
|
||||
}
|
||||
catchVariable = Expression.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
catchVariable = Node.createIdentifier(tn.readIdentifier(), tn.range());
|
||||
if (!tn.skip(Token.CLOSEPAREN)) {
|
||||
this.error(DiagnosticCode._0_expected, tn.range(), ")");
|
||||
return null;
|
||||
@ -1291,7 +1291,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode._0_expected, tn.range(), "catch");
|
||||
return null;
|
||||
}
|
||||
const ret: TryStatement = Statement.createTry(statements, catchVariable, catchStatements, finallyStatements, Range.join(startRange, tn.range()));
|
||||
const ret: TryStatement = Node.createTry(statements, catchVariable, catchStatements, finallyStatements, Range.join(startRange, tn.range()));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
} else
|
||||
@ -1310,7 +1310,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
const statement: Statement | null = this.parseStatement(tn);
|
||||
if (!statement)
|
||||
return null;
|
||||
const ret: WhileStatement = Statement.createWhile(<Expression>expression, <Statement>statement, Range.join(startRange, tn.range()));
|
||||
const ret: WhileStatement = Node.createWhile(<Expression>expression, <Statement>statement, Range.join(startRange, tn.range()));
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ret;
|
||||
} else
|
||||
@ -1329,11 +1329,11 @@ export class Parser extends DiagnosticEmitter {
|
||||
let expr: Expression | null = null;
|
||||
|
||||
if (token == Token.NULL)
|
||||
return Expression.createNull(tn.range());
|
||||
return Node.createNull(tn.range());
|
||||
if (token == Token.TRUE)
|
||||
return Expression.createTrue(tn.range());
|
||||
return Node.createTrue(tn.range());
|
||||
if (token == Token.FALSE)
|
||||
return Expression.createFalse(tn.range());
|
||||
return Node.createFalse(tn.range());
|
||||
|
||||
let p: Precedence = determinePrecedencePrefix(token);
|
||||
if (p != Precedence.INVALID) {
|
||||
@ -1347,7 +1347,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
if (!operand)
|
||||
return null;
|
||||
if (operand.kind == NodeKind.CALL)
|
||||
return Expression.createNew((<CallExpression>operand).expression, (<CallExpression>operand).typeArguments, (<CallExpression>operand).arguments, tn.range(startPos, tn.pos));
|
||||
return Node.createNew((<CallExpression>operand).expression, (<CallExpression>operand).typeArguments, (<CallExpression>operand).arguments, tn.range(startPos, tn.pos));
|
||||
this.error(DiagnosticCode.Operation_not_supported, tn.range());
|
||||
return null;
|
||||
} else
|
||||
@ -1357,7 +1357,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
if (token == Token.PLUS_PLUS || token == Token.MINUS_MINUS)
|
||||
if ((<Expression>operand).kind != NodeKind.IDENTIFIER && (<Expression>operand).kind != NodeKind.ELEMENTACCESS && (<Expression>operand).kind != NodeKind.PROPERTYACCESS)
|
||||
this.error(DiagnosticCode.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access, (<Expression>operand).range);
|
||||
return Expression.createUnaryPrefix(token, <Expression>operand, tn.range(startPos, tn.pos));
|
||||
return Node.createUnaryPrefix(token, <Expression>operand, tn.range(startPos, tn.pos));
|
||||
}
|
||||
|
||||
switch (token) {
|
||||
@ -1371,7 +1371,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode._0_expected, tn.range(), ")");
|
||||
return null;
|
||||
}
|
||||
return Expression.createParenthesized(expr, tn.range(startPos, tn.pos));
|
||||
return Node.createParenthesized(expr, tn.range(startPos, tn.pos));
|
||||
}
|
||||
|
||||
// ArrayLiteralExpression
|
||||
@ -1393,7 +1393,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return Expression.createArrayLiteral(elementExpressions, tn.range(startPos, tn.pos));
|
||||
return Node.createArrayLiteral(elementExpressions, tn.range(startPos, tn.pos));
|
||||
}
|
||||
|
||||
// AssertionExpression (unary prefix)
|
||||
@ -1408,37 +1408,37 @@ export class Parser extends DiagnosticEmitter {
|
||||
expr = this.parseExpression(tn, Precedence.CALL);
|
||||
if (!expr)
|
||||
return null;
|
||||
return Expression.createAssertion(AssertionKind.PREFIX, <Expression>expr, <TypeNode>toType, tn.range(startPos, tn.pos));
|
||||
return Node.createAssertion(AssertionKind.PREFIX, <Expression>expr, <TypeNode>toType, tn.range(startPos, tn.pos));
|
||||
}
|
||||
|
||||
// IdentifierExpression
|
||||
case Token.IDENTIFIER:
|
||||
return Expression.createIdentifier(tn.readIdentifier(), tn.range(startPos, tn.pos));
|
||||
return Node.createIdentifier(tn.readIdentifier(), tn.range(startPos, tn.pos));
|
||||
|
||||
case Token.THIS:
|
||||
return Expression.createThis(tn.range(startPos, tn.pos));
|
||||
return Node.createThis(tn.range(startPos, tn.pos));
|
||||
|
||||
case Token.CONSTRUCTOR:
|
||||
return Expression.createConstructor(tn.range(startPos, tn.pos));
|
||||
return Node.createConstructor(tn.range(startPos, tn.pos));
|
||||
|
||||
case Token.SUPER:
|
||||
return Expression.createSuper(tn.range(startPos, tn.pos));
|
||||
return Node.createSuper(tn.range(startPos, tn.pos));
|
||||
|
||||
// StringLiteralExpression
|
||||
case Token.STRINGLITERAL:
|
||||
return Expression.createStringLiteral(tn.readString(), tn.range(startPos, tn.pos));
|
||||
return Node.createStringLiteral(tn.readString(), tn.range(startPos, tn.pos));
|
||||
|
||||
// IntegerLiteralExpression
|
||||
case Token.INTEGERLITERAL:
|
||||
return Expression.createIntegerLiteral(tn.readInteger(), tn.range(startPos, tn.pos));
|
||||
return Node.createIntegerLiteral(tn.readInteger(), tn.range(startPos, tn.pos));
|
||||
|
||||
// FloatLiteralExpression
|
||||
case Token.FLOATLITERAL:
|
||||
return Expression.createFloatLiteral(tn.readFloat(), tn.range(startPos, tn.pos));
|
||||
return Node.createFloatLiteral(tn.readFloat(), tn.range(startPos, tn.pos));
|
||||
|
||||
// RegexpLiteralExpression
|
||||
case Token.REGEXPLITERAL:
|
||||
return Expression.createRegexpLiteral(tn.readRegexp(), tn.range(startPos, tn.pos));
|
||||
return Node.createRegexpLiteral(tn.readRegexp(), tn.range(startPos, tn.pos));
|
||||
|
||||
default:
|
||||
this.error(DiagnosticCode.Expression_expected, tn.range());
|
||||
@ -1500,7 +1500,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
const args: Expression[] | null = this.parseArguments(tn);
|
||||
if (!args)
|
||||
return null;
|
||||
expr = Expression.createCall(expr, <TypeNode[]>(typeArguments ? typeArguments : []), args, tn.range(startPos, tn.pos));
|
||||
expr = Node.createCall(expr, <TypeNode[]>(typeArguments ? typeArguments : []), args, tn.range(startPos, tn.pos));
|
||||
}
|
||||
|
||||
let token: Token;
|
||||
@ -1515,7 +1515,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
const toType: TypeNode | null = this.parseType(tn);
|
||||
if (!toType)
|
||||
return null;
|
||||
expr = Expression.createAssertion(AssertionKind.AS, expr, toType, tn.range(startPos, tn.pos));
|
||||
expr = Node.createAssertion(AssertionKind.AS, expr, toType, tn.range(startPos, tn.pos));
|
||||
|
||||
// ElementAccessExpression
|
||||
} else if (token == Token.OPENBRACKET) {
|
||||
@ -1524,7 +1524,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
|
||||
if (tn.skip(Token.CLOSEBRACKET))
|
||||
expr = Expression.createElementAccess(<Expression>expr, <Expression>next, tn.range(startPos, tn.pos));
|
||||
expr = Node.createElementAccess(<Expression>expr, <Expression>next, tn.range(startPos, tn.pos));
|
||||
else {
|
||||
this.error(DiagnosticCode._0_expected, tn.range(), "]");
|
||||
return null;
|
||||
@ -1534,7 +1534,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
} else if (token == Token.PLUS_PLUS || token == Token.MINUS_MINUS) {
|
||||
if (expr.kind != NodeKind.IDENTIFIER && expr.kind != NodeKind.ELEMENTACCESS && expr.kind != NodeKind.PROPERTYACCESS)
|
||||
this.error(DiagnosticCode.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access, expr.range);
|
||||
expr = Expression.createUnaryPostfix(token, expr, tn.range(startPos, tn.pos));
|
||||
expr = Node.createUnaryPostfix(token, expr, tn.range(startPos, tn.pos));
|
||||
|
||||
// TernaryExpression
|
||||
} else if (token == Token.QUESTION) {
|
||||
@ -1545,7 +1545,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
const ifElse: Expression | null = this.parseExpression(tn);
|
||||
if (!ifElse)
|
||||
return null;
|
||||
expr = Expression.createTernary(<Expression>expr, <Expression>ifThen, <Expression>ifElse, tn.range(startPos, tn.pos));
|
||||
expr = Node.createTernary(<Expression>expr, <Expression>ifThen, <Expression>ifElse, tn.range(startPos, tn.pos));
|
||||
} else {
|
||||
this.error(DiagnosticCode._0_expected, tn.range(), ":");
|
||||
return null;
|
||||
@ -1559,11 +1559,11 @@ export class Parser extends DiagnosticEmitter {
|
||||
// PropertyAccessExpression
|
||||
if (token == Token.DOT) {
|
||||
if (next.kind == NodeKind.IDENTIFIER) {
|
||||
expr = Expression.createPropertyAccess(<Expression>expr, <IdentifierExpression>next, tn.range(startPos, tn.pos));
|
||||
expr = Node.createPropertyAccess(<Expression>expr, <IdentifierExpression>next, tn.range(startPos, tn.pos));
|
||||
} else if (next.kind == NodeKind.CALL) { // amend
|
||||
let propertyCall: CallExpression = <CallExpression>next;
|
||||
if (propertyCall.expression.kind == NodeKind.IDENTIFIER) {
|
||||
propertyCall.expression = Expression.createPropertyAccess(<Expression>expr, <IdentifierExpression>propertyCall.expression, tn.range(startPos, tn.pos));
|
||||
propertyCall.expression = Node.createPropertyAccess(<Expression>expr, <IdentifierExpression>propertyCall.expression, tn.range(startPos, tn.pos));
|
||||
} else
|
||||
throw new Error("unexpected expression kind");
|
||||
expr = propertyCall;
|
||||
@ -1574,7 +1574,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
|
||||
// BinaryExpression
|
||||
} else
|
||||
expr = Expression.createBinary(token, <Expression>expr, <Expression>next, tn.range(startPos, tn.pos));
|
||||
expr = Node.createBinary(token, <Expression>expr, <Expression>next, tn.range(startPos, tn.pos));
|
||||
}
|
||||
}
|
||||
return expr;
|
||||
|
112
src/program.ts
112
src/program.ts
@ -672,10 +672,10 @@ export class Program extends DiagnosticEmitter {
|
||||
resolveType(node: TypeNode, contextualTypeArguments: Map<string,Type> | null = null, reportNotFound: bool = true): Type | null {
|
||||
|
||||
// resolve parameters
|
||||
const k: i32 = node.parameters.length;
|
||||
const k: i32 = node.typeArguments.length;
|
||||
const paramTypes: Type[] = new Array(k);
|
||||
for (let i: i32 = 0; i < k; ++i) {
|
||||
const paramType: Type | null = this.resolveType(node.parameters[i], contextualTypeArguments, reportNotFound);
|
||||
const paramType: Type | null = this.resolveType(node.typeArguments[i], contextualTypeArguments, reportNotFound);
|
||||
if (!paramType)
|
||||
return null;
|
||||
paramTypes[i] = <Type>paramType;
|
||||
@ -806,30 +806,34 @@ function hasDecorator(name: string, decorators: Decorator[] | null): bool {
|
||||
|
||||
/** Indicates the specific kind of an {@link Element}. */
|
||||
export enum ElementKind {
|
||||
/** A {@link ClassPrototype}. */
|
||||
CLASS_PROTOTYPE,
|
||||
/** A {@link Class}. */
|
||||
CLASS,
|
||||
/** A {@link Global}. */
|
||||
GLOBAL,
|
||||
/** A {@link Local}. */
|
||||
LOCAL,
|
||||
/** An {@link Enum}. */
|
||||
ENUM,
|
||||
/** An {@link EnumValue}. */
|
||||
ENUMVALUE,
|
||||
/** A {@link FieldPrototype}. */
|
||||
FIELD_PROTOTYPE,
|
||||
/** A {@link Field}. */
|
||||
FIELD,
|
||||
/** A {@link FunctionPrototype}. */
|
||||
FUNCTION_PROTOTYPE,
|
||||
/** A {@link Function}. */
|
||||
FUNCTION,
|
||||
/** A {@link Global}. */
|
||||
GLOBAL,
|
||||
/** A {@link ClassPrototype}. */
|
||||
CLASS_PROTOTYPE,
|
||||
/** A {@link Class}. */
|
||||
CLASS,
|
||||
/** An {@link InterfacePrototype}. */
|
||||
INTERFACE_PROTOTYPE,
|
||||
/** An {@link Interface}. */
|
||||
INTERFACE,
|
||||
/** A {@link Local}. */
|
||||
LOCAL,
|
||||
/** A {@link FieldPrototype}. */
|
||||
FIELD_PROTOTYPE,
|
||||
/** A {@link Field}. */
|
||||
FIELD,
|
||||
/** A {@link PropertyPrototype}. */
|
||||
PROPERTY_PROTOTYPE,
|
||||
/** A {@link Property}. */
|
||||
PROPERTY,
|
||||
/** A {@link Namespace}. */
|
||||
NAMESPACE
|
||||
}
|
||||
@ -1113,7 +1117,11 @@ export class FunctionPrototype extends Element {
|
||||
case ModifierKind.DECLARE: this.isDeclared = true; break;
|
||||
case ModifierKind.GET: this.isGetter = true; break;
|
||||
case ModifierKind.SET: this.isSetter = true; break;
|
||||
case ModifierKind.STATIC: break; // already handled
|
||||
case ModifierKind.STATIC:
|
||||
case ModifierKind.ABSTRACT:
|
||||
case ModifierKind.PRIVATE:
|
||||
case ModifierKind.PROTECTED:
|
||||
case ModifierKind.PUBLIC: break; // already handled
|
||||
default: throw new Error("unexpected modifier");
|
||||
}
|
||||
}
|
||||
@ -1360,7 +1368,11 @@ export class Function extends Element {
|
||||
this.tempI32s = this.tempI64s = this.tempF32s = this.tempF64s = null;
|
||||
}
|
||||
|
||||
/** Returns the TypeScript representation of this function. */
|
||||
toString(): string { return this.prototype.simpleName; }
|
||||
|
||||
/** Returns the function type TypeScript representation of this function.*/
|
||||
toTypeString(): string { throw new Error("not implemented"); }
|
||||
}
|
||||
|
||||
/** A yet unresolved instance field prototype. */
|
||||
@ -1416,6 +1428,76 @@ export class Field extends Element {
|
||||
}
|
||||
}
|
||||
|
||||
/** A yet unresolved property. */
|
||||
export class PropertyPrototype extends Element {
|
||||
|
||||
kind = ElementKind.PROPERTY_PROTOTYPE;
|
||||
|
||||
/** Simple name. */
|
||||
simpleName: string;
|
||||
/** Parent class prototype. */
|
||||
classPrototype: ClassPrototype;
|
||||
/** Getter declaration reference. */
|
||||
getterDeclaration: FunctionDeclaration | null;
|
||||
/** Setter declaration reference. */
|
||||
setterDeclaration: FunctionDeclaration | null;
|
||||
|
||||
/** Constructs a new propery prototype. */
|
||||
constructor(classPrototype: ClassPrototype, simpleName: string, internalName: string, getterDeclaration: FunctionDeclaration | null = null, setterDeclaration: FunctionDeclaration | null = null) {
|
||||
super(classPrototype.program, internalName);
|
||||
this.simpleName = simpleName;
|
||||
this.classPrototype = classPrototype;
|
||||
|
||||
let i: i32, k: i32;
|
||||
if ((this.getterDeclaration = getterDeclaration) && this.getterDeclaration.modifiers) {
|
||||
assert(this.getterDeclaration.typeParameters.length == 0);
|
||||
assert(this.getterDeclaration.parameters.length == 0);
|
||||
for (i = 0, k = this.getterDeclaration.modifiers.length; i < k; ++i) {
|
||||
switch (this.getterDeclaration.modifiers[i].modifierKind) {
|
||||
case ModifierKind.EXPORT: this.isExported = true; break;
|
||||
case ModifierKind.GET:
|
||||
case ModifierKind.STATIC: break; // already handled
|
||||
default: assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((this.setterDeclaration = setterDeclaration) && this.setterDeclaration.modifiers) {
|
||||
assert(this.setterDeclaration.typeParameters.length == 0);
|
||||
assert(this.setterDeclaration.parameters.length == 1);
|
||||
for (i = 0, k = this.setterDeclaration.modifiers.length; i < k; ++i) {
|
||||
switch (this.setterDeclaration.modifiers[i].modifierKind) {
|
||||
case ModifierKind.EXPORT: this.isExported = true; break;
|
||||
case ModifierKind.SET:
|
||||
case ModifierKind.STATIC: break; // already handled
|
||||
default: assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** A resolved property. */
|
||||
export class Property extends Element {
|
||||
|
||||
kind = ElementKind.PROPERTY;
|
||||
|
||||
/** Prototype reference. */
|
||||
prototype: PropertyPrototype;
|
||||
/** Property type. */
|
||||
type: Type;
|
||||
/** Getter function. */
|
||||
getter: Function | null = null;
|
||||
/** Setter function. */
|
||||
setter: Function | null = null;
|
||||
|
||||
/** Constructs a new property. */
|
||||
constructor(prototype: PropertyPrototype, internalName: string, type: Type) {
|
||||
super(prototype.program, internalName);
|
||||
this.flags = prototype.flags;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
/** A yet unresolved class prototype. */
|
||||
export class ClassPrototype extends Element {
|
||||
|
||||
|
78
src/types.ts
78
src/types.ts
@ -1,6 +1,7 @@
|
||||
import { Class } from "./program";
|
||||
import { Class, Function } from "./program";
|
||||
import { sb } from "./util/sb";
|
||||
|
||||
/** Indicates the kind of a type. */
|
||||
export const enum TypeKind {
|
||||
|
||||
// signed integers
|
||||
@ -22,18 +23,30 @@ export const enum TypeKind {
|
||||
F32,
|
||||
F64,
|
||||
|
||||
// other
|
||||
VOID
|
||||
// SYMBOL ?
|
||||
}
|
||||
|
||||
/** Represents a resolved type. */
|
||||
export class Type {
|
||||
|
||||
/** Type kind. */
|
||||
kind: TypeKind;
|
||||
/** Size in bits. */
|
||||
size: i32;
|
||||
/** Size in bytes. */
|
||||
byteSize: i32;
|
||||
/** Underlying class type, if a class type. */
|
||||
classType: Class | null;
|
||||
nullable: bool = false;
|
||||
nullableType: Type | null = null; // cached, of this type
|
||||
/** Underlying function type, if a function type. */
|
||||
functionType: Function | null;
|
||||
/** Whether nullable or not. */
|
||||
isNullable: bool = false;
|
||||
/** Respective nullable type, if nullable. */
|
||||
nullableType: Type | null = null;
|
||||
|
||||
/** Constructs a new resolved type. */
|
||||
constructor(kind: TypeKind, size: i32) {
|
||||
this.kind = kind;
|
||||
this.size = size;
|
||||
@ -41,31 +54,51 @@ export class Type {
|
||||
this.classType = null;
|
||||
}
|
||||
|
||||
/** Sign-extending 32-bit shift, if a small signed integer. */
|
||||
get smallIntegerShift(): i32 { return 32 - this.size; }
|
||||
/** Truncating 32-bit mask, if a small unsigned integer. */
|
||||
get smallIntegerMask(): i32 { return -1 >>> (32 - this.size); }
|
||||
|
||||
/** Tests if this type is of any integer kind. */
|
||||
get isAnyInteger(): bool { return this.kind >= TypeKind.I8 && this.kind <= TypeKind.BOOL; }
|
||||
/** Tests if this type is of any small integer kind. */
|
||||
get isSmallInteger(): bool { return this.size != 0 && this.size < 32; }
|
||||
/** Tests if this type is of any long integer kind. */
|
||||
get isLongInteger(): bool { return this.size == 64 && this.kind != TypeKind.F64; }
|
||||
/** Tests if this type is of any unsigned integer kind. */
|
||||
get isUnsignedInteger(): bool { return this.kind >= TypeKind.U8 && this.kind <= TypeKind.BOOL; }
|
||||
/** Tests if this type is of any signed integer kind. */
|
||||
get isSignedInteger(): bool { return this.kind >= TypeKind.I8 && this.kind <= TypeKind.ISIZE; }
|
||||
/** Tests if this type is of any size kind, i.e., `isize` or `usize`. */
|
||||
get isAnySize(): bool { return this.kind == TypeKind.ISIZE || this.kind == TypeKind.USIZE; }
|
||||
/** Tests if this type is of any float kind, i.e., `f32` or `f64`. */
|
||||
get isAnyFloat(): bool { return this.kind == TypeKind.F32 || this.kind == TypeKind.F64; }
|
||||
|
||||
/** Composes a class type from this type and a class. */
|
||||
asClass(classType: Class): Type {
|
||||
assert(this.kind == TypeKind.USIZE);
|
||||
const ret: Type = new Type(this.kind, this.size);
|
||||
ret.classType = classType;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Composes a function type from this type and a function. */
|
||||
asFunction(functionType: Function): Type {
|
||||
assert(this.kind == TypeKind.USIZE);
|
||||
const ret: Type = new Type(this.kind, this.size);
|
||||
ret.functionType = functionType;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Composes the respective nullable type of this type. */
|
||||
asNullable(): Type {
|
||||
if (this.kind != TypeKind.USIZE)
|
||||
throw new Error("unexpected non-usize nullable");
|
||||
if (!this.nullableType)
|
||||
(this.nullableType = new Type(this.kind, this.size)).nullable = true;
|
||||
assert(this.kind == TypeKind.USIZE);
|
||||
if (this.isNullable && !this.nullableType)
|
||||
(this.nullableType = new Type(this.kind, this.size)).isNullable = true;
|
||||
return <Type>this.nullableType;
|
||||
}
|
||||
|
||||
/** Converts this type to its TypeScript representation. */
|
||||
toString(kindOnly: bool = false): string {
|
||||
switch (this.kind) {
|
||||
case TypeKind.I8: return "i8";
|
||||
@ -77,35 +110,56 @@ export class Type {
|
||||
case TypeKind.U16: return "u16";
|
||||
case TypeKind.U32: return "u32";
|
||||
case TypeKind.U64: return "u64";
|
||||
case TypeKind.USIZE: return this.classType != null && !kindOnly ? this.classType.toString() : "usize";
|
||||
case TypeKind.USIZE:
|
||||
if (kindOnly) return "usize";
|
||||
return this.classType ? this.classType.toString()
|
||||
: this.functionType ? this.functionType.toTypeString()
|
||||
: "usize";
|
||||
case TypeKind.BOOL: return "bool";
|
||||
case TypeKind.F32: return "f32";
|
||||
case TypeKind.F64: return "f64";
|
||||
case TypeKind.VOID: return "void";
|
||||
default:
|
||||
throw new Error("unexpected type kind");
|
||||
default: assert(false); return "INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/** An 8-bit signed integer. */
|
||||
static readonly i8: Type = new Type(TypeKind.I8, 8);
|
||||
/** A 16-bit signed integer. */
|
||||
static readonly i16: Type = new Type(TypeKind.I16, 16);
|
||||
/** A 32-bit signed integer. */
|
||||
static readonly i32: Type = new Type(TypeKind.I32, 32);
|
||||
/** A 64-bit signed integer. */
|
||||
static readonly i64: Type = new Type(TypeKind.I64, 64);
|
||||
/** A 32-bit signed size. WASM32 only. */
|
||||
static readonly isize32: Type = new Type(TypeKind.I32, 32);
|
||||
/** A 64-bit signed size. WASM64 only. */
|
||||
static readonly isize64: Type = new Type(TypeKind.I64, 64);
|
||||
/** An 8-bit unsigned integer. */
|
||||
static readonly u8: Type = new Type(TypeKind.U8, 8);
|
||||
/** A 16-bit unsigned integer. */
|
||||
static readonly u16: Type = new Type(TypeKind.U16, 16);
|
||||
/** A 32-bit unsigned integer. */
|
||||
static readonly u32: Type = new Type(TypeKind.U32, 32);
|
||||
/** A 64-bit unsigned integer. */
|
||||
static readonly u64: Type = new Type(TypeKind.U64, 64);
|
||||
/** A 32-bit unsigned size. WASM32 only. */
|
||||
static readonly usize32: Type = new Type(TypeKind.U32, 32);
|
||||
/** A 64-bit unsigned size. WASM64 only. */
|
||||
static readonly usize64: Type = new Type(TypeKind.U64, 64);
|
||||
/** A 1-bit unsigned integer. */
|
||||
static readonly bool: Type = new Type(TypeKind.BOOL, 1);
|
||||
/** A 32-bit float. */
|
||||
static readonly f32: Type = new Type(TypeKind.F32, 32);
|
||||
/** A 64-bit float. */
|
||||
static readonly f64: Type = new Type(TypeKind.F64, 64);
|
||||
/** No return type. */
|
||||
static readonly void: Type = new Type(TypeKind.VOID, 0);
|
||||
static readonly infer: Type = Type.void;
|
||||
/** Special type used in type inference. Alias of {@link Type.void}. */
|
||||
static readonly auto: Type = Type.void;
|
||||
}
|
||||
|
||||
/** Converts an array of types to its combined string representation. Usually type arguments. */
|
||||
export function typesToString(types: Type[], prefix: string = "<", postfix: string = ">"): string {
|
||||
const k: i32 = types.length;
|
||||
if (!k)
|
||||
@ -113,5 +167,5 @@ export function typesToString(types: Type[], prefix: string = "<", postfix: stri
|
||||
sb.length = 0;
|
||||
for (let i: i32 = 0; i < k; ++i)
|
||||
sb[i] = types[i].toString();
|
||||
return prefix + sb.join(",") + postfix;
|
||||
return prefix + sb.join(", ") + postfix;
|
||||
}
|
||||
|
88
std/assembly.d.ts
vendored
88
std/assembly.d.ts
vendored
@ -157,8 +157,8 @@ declare function unreachable(): any; // sic
|
||||
declare const NaN: f32 | f64;
|
||||
/** Positive infinity as a 32-bit or 64-bit float depending on context. */
|
||||
declare const Infinity: f32 | f64;
|
||||
/** Heap start offset. */
|
||||
declare const HEAP_START: usize;
|
||||
/** Heap base offset. */
|
||||
declare const HEAP_BASE: usize;
|
||||
/** Determines the byte size of the specified core or class type. Compiles to a constant. */
|
||||
declare function sizeof<T>(): usize;
|
||||
/** Changes the type of a value to another one. Useful for casting class instances to their pointer values and vice-versa. */
|
||||
@ -174,18 +174,72 @@ declare function parseInt(str: string, radix?: i32): f64;
|
||||
/** Parses a string to a 64-bit float. */
|
||||
declare function parseFloat(str: string): f64;
|
||||
|
||||
// Internal decorators (not yet implemented)
|
||||
|
||||
/** Annotates an element being part of the global namespace. */
|
||||
declare function global(): any;
|
||||
/** Annotates a function being always inlined. */
|
||||
declare function inline(): any;
|
||||
/** Annotates a class using a C-style memory layout. */
|
||||
declare function struct(): any;
|
||||
|
||||
// Standard library (not yet implemented)
|
||||
|
||||
interface Array<T> {}
|
||||
/** Class representing a sequence of values of type `T`. */
|
||||
declare class Array<T> {
|
||||
|
||||
/** Current maximum capacity of the array. */
|
||||
readonly capacity: i32;
|
||||
|
||||
/** Current length of the array. */
|
||||
length: i32;
|
||||
|
||||
/** Constructs a new array. */
|
||||
constructor(capacity?: i32);
|
||||
}
|
||||
|
||||
/** Class representing a sequence of characters. */
|
||||
declare class String {
|
||||
static fromCharCode(ls: i32, hs?: i32): string;
|
||||
static fromCharCodes(arr: u16[]): string;
|
||||
static fromCodePoint(cp: i32): string;
|
||||
static fromCodePoints(arr: i32[]): string;
|
||||
}
|
||||
|
||||
/** Class for representing a runtime error. Base class of all errors. */
|
||||
declare class Error {
|
||||
|
||||
/** Error name. */
|
||||
name: string;
|
||||
|
||||
/** Message provided on construction. */
|
||||
message: string;
|
||||
|
||||
/** Stack trace. */
|
||||
stack: string;
|
||||
|
||||
/** Constructs a new error, optionally with a message. */
|
||||
constructor(message?: string);
|
||||
}
|
||||
|
||||
/** Class for indicating an error when a value is not in the set or range of allowed values. */
|
||||
declare class RangeError extends Error { }
|
||||
|
||||
/** A static class representing the heap. */
|
||||
declare class Heap {
|
||||
|
||||
/** Gets the amount of used heap space, in bytes. */
|
||||
static readonly used: usize;
|
||||
|
||||
/** Gets the amount of free heap space, in bytes. */
|
||||
static readonly free: usize;
|
||||
|
||||
/** Gets the size of the heap, in bytes. */
|
||||
static readonly size: usize;
|
||||
|
||||
/** Allocates a chunk of memory and returns a pointer to it. */
|
||||
static allocate(size: usize): usize;
|
||||
|
||||
/** Disposes a chunk of memory by its pointer. */
|
||||
static dispose(ptr: usize): void;
|
||||
|
||||
/** Copies a chunk of memory from one location to another. */
|
||||
static copy(dest: usize, src: usize, n: usize): usize;
|
||||
|
||||
private constructor();
|
||||
}
|
||||
|
||||
interface Boolean {}
|
||||
interface Function {}
|
||||
interface IArguments {}
|
||||
@ -193,9 +247,7 @@ interface Number {}
|
||||
interface Object {}
|
||||
interface RegExp {}
|
||||
|
||||
declare class String {
|
||||
static fromCharCode(ls: i32, hs?: i32): string;
|
||||
static fromCharCodes(arr: u16[]): string;
|
||||
static fromCodePoint(cp: i32): string;
|
||||
static fromCodePoints(arr: i32[]): string;
|
||||
}
|
||||
// Internal decorators (not yet implemented)
|
||||
|
||||
/** Annotates an element being part of the global namespace. */
|
||||
declare function global(): any;
|
||||
|
@ -1,25 +1,13 @@
|
||||
// Multiple options:
|
||||
// 1. C-like with no 'length' or 'push'
|
||||
// 2. Descriptors that can be constructed from lower level arrays
|
||||
|
||||
@global()
|
||||
class Array<T> {
|
||||
export class Array<T> {
|
||||
|
||||
readonly capacity: i32;
|
||||
length: i32;
|
||||
ptr: usize;
|
||||
|
||||
static fromPtr<T>(ptr: usize, capacity: i32): Array<T> {
|
||||
assert(capacity >= 0);
|
||||
const arr: Array<T> = new Array(0);
|
||||
store<i32>(changetype<Array<T>, usize>(arr), capacity);
|
||||
arr.length = ptr;
|
||||
arr.ptr = ptr;
|
||||
return arr;
|
||||
}
|
||||
|
||||
constructor(capacity: i32 = 0) {
|
||||
assert(capacity >= 0);
|
||||
if (capacity < 0)
|
||||
throw new RangeError("invalid array length");
|
||||
this.capacity = this.length = capacity;
|
||||
if (capacity > 0) {
|
||||
this.ptr = Heap.allocate(<usize>capacity);
|
||||
@ -35,5 +23,5 @@ class Array<T> {
|
||||
Heap.dispose(changetype<this,usize>(this));
|
||||
}
|
||||
|
||||
static test(): void {}
|
||||
// TODO
|
||||
}
|
||||
|
16
std/assembly/error.ts
Normal file
16
std/assembly/error.ts
Normal file
@ -0,0 +1,16 @@
|
||||
@global()
|
||||
export class Error {
|
||||
|
||||
name: string = "Error";
|
||||
message: string;
|
||||
stack: string = ""; // TODO
|
||||
|
||||
constructor(message: string = "") {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
@global()
|
||||
export class RangeError extends Error {
|
||||
name: string = "RangeError";
|
||||
}
|
@ -2,10 +2,16 @@ const ALIGN_LOG2: usize = 3;
|
||||
const ALIGN_SIZE: usize = 1 << ALIGN_LOG2;
|
||||
const ALIGN_MASK: usize = ALIGN_SIZE - 1;
|
||||
|
||||
let HEAP_OFFSET: usize = HEAP_START; // HEAP_START is a constant generated by the compiler
|
||||
let HEAP_OFFSET: usize = HEAP_BASE; // HEAP_BASE is a constant generated by the compiler
|
||||
|
||||
// TODO: maybe tlsf
|
||||
|
||||
@global()
|
||||
class Heap {
|
||||
export class Heap {
|
||||
|
||||
static get used(): usize { return HEAP_OFFSET - HEAP_BASE; }
|
||||
static get free(): usize { return (<usize>current_memory() << 16) - HEAP_OFFSET; }
|
||||
static get size(): usize { return (<usize>current_memory() << 16) - HEAP_BASE; }
|
||||
|
||||
static allocate(size: usize): usize {
|
||||
if (!size) return 0;
|
||||
@ -23,20 +29,8 @@ class Heap {
|
||||
// just a big chunk of non-disposable memory for now
|
||||
}
|
||||
|
||||
static get used(): usize {
|
||||
return HEAP_OFFSET - HEAP_START;
|
||||
}
|
||||
|
||||
static get free(): usize {
|
||||
return (<usize>current_memory() << 16) - HEAP_OFFSET;
|
||||
}
|
||||
|
||||
static get size(): usize {
|
||||
return (<usize>current_memory() << 16) - HEAP_START;
|
||||
}
|
||||
|
||||
static copy(dest: usize, src: usize, n: usize): usize {
|
||||
assert(dest >= HEAP_START);
|
||||
assert(dest >= HEAP_BASE);
|
||||
|
||||
// the following is based on musl's implementation of memcpy
|
||||
let dst: usize = dest;
|
||||
@ -179,4 +173,6 @@ class Heap {
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
private constructor() {}
|
||||
}
|
||||
|
4
std/assembly/map.ts
Normal file
4
std/assembly/map.ts
Normal file
@ -0,0 +1,4 @@
|
||||
@global()
|
||||
export class Map<K,V> {
|
||||
// TODO
|
||||
}
|
4
std/assembly/set.ts
Normal file
4
std/assembly/set.ts
Normal file
@ -0,0 +1,4 @@
|
||||
@global()
|
||||
export class Set<T> {
|
||||
// TODO
|
||||
}
|
4
std/assembly/string.ts
Normal file
4
std/assembly/string.ts
Normal file
@ -0,0 +1,4 @@
|
||||
@global()
|
||||
export class String {
|
||||
// TODO
|
||||
}
|
@ -37,7 +37,7 @@ Object.defineProperties(
|
||||
"MAX_VALUE": { value: 4294967295, writable: false }
|
||||
});
|
||||
Object.defineProperties(
|
||||
globalScope["bool"] = function bool(value) { return Boolean(value); }
|
||||
globalScope["bool"] = function bool(value) { return !!value; }
|
||||
, {
|
||||
"MIN_VALUE": { value: 0, writable: false },
|
||||
"MAX_VALUE": { value: 1, writable: false }
|
||||
|
3
std/portable/heap.d.ts
vendored
3
std/portable/heap.d.ts
vendored
@ -15,4 +15,7 @@ declare class Heap {
|
||||
|
||||
/** Gets the size of the heap, in bytes. */
|
||||
static readonly size: usize;
|
||||
|
||||
/** Copies a chunk of memory from one location to another. */
|
||||
static copy(dest: usize, src: usize, n: usize): usize;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -58,7 +58,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
[program.exports]
|
||||
|
||||
;)
|
||||
|
@ -5,7 +5,7 @@
|
||||
(global $binary/I (mut i64) (i64.const 0))
|
||||
(global $binary/f (mut f32) (f32.const 0))
|
||||
(global $binary/F (mut f64) (f64.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -861,7 +861,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
binary/b
|
||||
binary/i
|
||||
binary/I
|
||||
|
@ -6,7 +6,7 @@
|
||||
(global $builtins/b (mut i32) (i32.const 0))
|
||||
(global $builtins/F (mut f64) (f64.const 0))
|
||||
(global $builtins/s (mut i32) (i32.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -1078,7 +1078,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
builtins/b
|
||||
builtins/i
|
||||
builtins/I
|
||||
|
@ -3,7 +3,7 @@
|
||||
(type $fff (func (param f32 f32) (result f32)))
|
||||
(type $v (func))
|
||||
(global $class/Animal.MAX (mut i32) (i32.const 1))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -86,7 +86,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
class/Animal
|
||||
class/Animal.MAX
|
||||
class/Animal.add
|
||||
|
@ -1,7 +1,7 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(import "env" "external" (func $declare/external))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "external" (func $declare/external))
|
||||
(export "memory" (memory $0))
|
||||
@ -51,7 +51,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
declare/external
|
||||
[program.exports]
|
||||
declare/external
|
||||
|
@ -1,6 +1,6 @@
|
||||
(module
|
||||
(type $iv (func (param i32)))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "loopDo" (func $do/loopDo))
|
||||
(export "loopDoInDo" (func $do/loopDoInDo))
|
||||
@ -96,7 +96,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
do/loopDo
|
||||
do/loopDoInDo
|
||||
[program.exports]
|
||||
|
@ -15,7 +15,7 @@
|
||||
(global $enum/Mixed.FOUR i32 (i32.const 4))
|
||||
(global $enum/NonConstant.ZERO (mut i32) (i32.const 0))
|
||||
(global $enum/NonConstant.ONE (mut i32) (i32.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -81,7 +81,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
enum/Implicit
|
||||
enum/Explicit
|
||||
enum/Mixed
|
||||
|
@ -3,7 +3,7 @@
|
||||
(type $v (func))
|
||||
(global $export/a i32 (i32.const 1))
|
||||
(global $export/b i32 (i32.const 2))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "add" (func $export/add))
|
||||
(export "renamed_sub" (func $export/sub))
|
||||
@ -75,7 +75,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
export/add
|
||||
export/sub
|
||||
export/a
|
||||
|
@ -1,7 +1,7 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(global $for/i (mut i32) (i32.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -192,7 +192,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
for/i
|
||||
[program.exports]
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
(global $../../examples/game-of-life/assembly/game-of-life/w (mut i32) (i32.const 0))
|
||||
(global $../../examples/game-of-life/assembly/game-of-life/h (mut i32) (i32.const 0))
|
||||
(global $../../examples/game-of-life/assembly/game-of-life/s (mut i32) (i32.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "init" (func $../../examples/game-of-life/assembly/game-of-life/init))
|
||||
(export "step" (func $../../examples/game-of-life/assembly/game-of-life/step))
|
||||
@ -353,7 +353,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
../../examples/game-of-life/assembly/game-of-life/w
|
||||
../../examples/game-of-life/assembly/game-of-life/h
|
||||
../../examples/game-of-life/assembly/game-of-life/s
|
||||
|
@ -4,7 +4,7 @@
|
||||
(type $iiiiv (func (param i32 i32 i32 i32)))
|
||||
(global $../../examples/i64-polyfill/assembly/i64/hi (mut i32) (i32.const 0))
|
||||
(global $../../examples/i64-polyfill/assembly/i64/lo (mut i32) (i32.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "getHi" (func $../../examples/i64-polyfill/assembly/i64/getHi))
|
||||
(export "getLo" (func $../../examples/i64-polyfill/assembly/i64/getLo))
|
||||
@ -1234,7 +1234,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
../../examples/i64-polyfill/assembly/i64/lo
|
||||
../../examples/i64-polyfill/assembly/i64/hi
|
||||
../../examples/i64-polyfill/assembly/i64/getLo
|
||||
|
@ -1,6 +1,6 @@
|
||||
(module
|
||||
(type $ii (func (param i32) (result i32)))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "ifThenElse" (func $if/ifThenElse))
|
||||
(export "ifThen" (func $if/ifThen))
|
||||
@ -91,7 +91,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
if/ifThenElse
|
||||
if/ifThen
|
||||
if/ifThenElseBlock
|
||||
|
@ -3,7 +3,7 @@
|
||||
(type $v (func))
|
||||
(global $export/a i32 (i32.const 1))
|
||||
(global $export/b i32 (i32.const 2))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -86,7 +86,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
export/add
|
||||
export/sub
|
||||
export/a
|
||||
|
@ -22,7 +22,7 @@
|
||||
(global $f32.MAX_SAFE_INTEGER f32 (f32.const 16777215))
|
||||
(global $f64.MIN_SAFE_INTEGER f64 (f64.const -9007199254740991))
|
||||
(global $f64.MAX_SAFE_INTEGER f64 (f64.const 9007199254740991))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -152,7 +152,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
[program.exports]
|
||||
|
||||
;)
|
||||
|
@ -1,6 +1,6 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -184,7 +184,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
[program.exports]
|
||||
|
||||
;)
|
||||
|
@ -4,7 +4,7 @@
|
||||
(global $logical/I (mut i64) (i64.const 0))
|
||||
(global $logical/f (mut f32) (f32.const 0))
|
||||
(global $logical/F (mut f64) (f64.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -300,7 +300,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
logical/i
|
||||
logical/I
|
||||
logical/f
|
||||
|
@ -3,7 +3,7 @@
|
||||
(type $v (func))
|
||||
(global $memcpy/base i32 (i32.const 8))
|
||||
(global $memcpy/dest (mut i32) (i32.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memcpy" (func $memcpy/memcpy))
|
||||
(export "memory" (memory $0))
|
||||
@ -2098,7 +2098,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
memcpy/memcpy
|
||||
memcpy/base
|
||||
memcpy/dest
|
||||
|
@ -1,7 +1,7 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(global $namespace/Outer.Inner.aVar (mut i32) (i32.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "test" (func $namespace/test))
|
||||
(export "memory" (memory $0))
|
||||
@ -62,7 +62,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
namespace/Outer
|
||||
namespace/Outer.Inner
|
||||
namespace/Outer.Inner.aVar
|
||||
|
@ -4,7 +4,7 @@
|
||||
(global $portable-conversions/I (mut i64) (i64.const 0))
|
||||
(global $portable-conversions/f (mut f32) (f32.const 0))
|
||||
(global $portable-conversions/F (mut f64) (f64.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -374,7 +374,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
portable-conversions/i
|
||||
portable-conversions/I
|
||||
portable-conversions/f
|
||||
|
@ -3,7 +3,7 @@
|
||||
(type $v (func))
|
||||
(global $export/a i32 (i32.const 1))
|
||||
(global $export/b i32 (i32.const 2))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "add" (func $export/add))
|
||||
(export "renamed_sub" (func $export/sub))
|
||||
@ -91,7 +91,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
export/add
|
||||
export/sub
|
||||
export/a
|
||||
|
@ -1,11 +0,0 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $start (; 0 ;) (type $v)
|
||||
(block $__inlined_func$Array.test
|
||||
(nop)
|
||||
)
|
||||
)
|
||||
)
|
@ -1,12 +1,4 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $Array.test (; 0 ;) (type $v)
|
||||
(nop)
|
||||
)
|
||||
(func $start (; 1 ;) (type $v)
|
||||
(call $Array.test)
|
||||
)
|
||||
)
|
||||
|
@ -1,2 +1 @@
|
||||
// Array.fromPtr<i32>(1);
|
||||
Array.test();
|
||||
|
@ -1,14 +1,7 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $Array.test (; 0 ;) (type $v)
|
||||
)
|
||||
(func $start (; 1 ;) (type $v)
|
||||
(call $Array.test)
|
||||
)
|
||||
)
|
||||
(;
|
||||
[program.elements]
|
||||
@ -55,21 +48,30 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
Array
|
||||
Array.fromPtr
|
||||
Array.test
|
||||
Error
|
||||
RangeError
|
||||
heap/ALIGN_LOG2
|
||||
heap/ALIGN_SIZE
|
||||
heap/ALIGN_MASK
|
||||
heap/HEAP_OFFSET
|
||||
Heap
|
||||
Heap.allocate
|
||||
Heap.dispose
|
||||
Heap.get_used
|
||||
Heap.get_free
|
||||
Heap.get_size
|
||||
Heap.allocate
|
||||
Heap.dispose
|
||||
Heap.copy
|
||||
Map
|
||||
Set
|
||||
String
|
||||
[program.exports]
|
||||
|
||||
Array
|
||||
Error
|
||||
RangeError
|
||||
Heap
|
||||
Map
|
||||
Set
|
||||
String
|
||||
;)
|
||||
|
@ -4,7 +4,7 @@
|
||||
(type $v (func))
|
||||
(global $heap/HEAP_OFFSET (mut i32) (i32.const 0))
|
||||
(global $std/heap/ptr (mut i32) (i32.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -100,7 +100,7 @@
|
||||
(func $start (; 1 ;) (type $v)
|
||||
(local $0 i32)
|
||||
(set_global $heap/HEAP_OFFSET
|
||||
(get_global $HEAP_START)
|
||||
(get_global $HEAP_BASE)
|
||||
)
|
||||
(set_global $std/heap/ptr
|
||||
(call $Heap.allocate
|
||||
|
@ -4,7 +4,7 @@
|
||||
(type $v (func))
|
||||
(global $heap/HEAP_OFFSET (mut i32) (i32.const 0))
|
||||
(global $std/heap/ptr (mut i32) (i32.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -102,7 +102,7 @@
|
||||
)
|
||||
(func $start (; 2 ;) (type $v)
|
||||
(set_global $heap/HEAP_OFFSET
|
||||
(get_global $HEAP_START)
|
||||
(get_global $HEAP_BASE)
|
||||
)
|
||||
(set_global $std/heap/ptr
|
||||
(call $Heap.allocate
|
||||
|
@ -8,7 +8,7 @@
|
||||
(global $heap/ALIGN_SIZE i32 (i32.const 8))
|
||||
(global $heap/ALIGN_MASK i32 (i32.const 7))
|
||||
(global $std/heap/ptr (mut i32) (i32.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -113,7 +113,7 @@
|
||||
)
|
||||
(func $start (; 2 ;) (type $v)
|
||||
(set_global $heap/HEAP_OFFSET
|
||||
(get_global $HEAP_START)
|
||||
(get_global $HEAP_BASE)
|
||||
)
|
||||
(set_global $std/heap/ptr
|
||||
(call $Heap.allocate
|
||||
@ -170,22 +170,31 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
Array
|
||||
Array.fromPtr
|
||||
Array.test
|
||||
Error
|
||||
RangeError
|
||||
heap/ALIGN_LOG2
|
||||
heap/ALIGN_SIZE
|
||||
heap/ALIGN_MASK
|
||||
heap/HEAP_OFFSET
|
||||
Heap
|
||||
Heap.allocate
|
||||
Heap.dispose
|
||||
Heap.get_used
|
||||
Heap.get_free
|
||||
Heap.get_size
|
||||
Heap.allocate
|
||||
Heap.dispose
|
||||
Heap.copy
|
||||
Map
|
||||
Set
|
||||
String
|
||||
std/heap/ptr
|
||||
[program.exports]
|
||||
|
||||
Array
|
||||
Error
|
||||
RangeError
|
||||
Heap
|
||||
Map
|
||||
Set
|
||||
String
|
||||
;)
|
||||
|
@ -1,6 +1,6 @@
|
||||
(module
|
||||
(type $ii (func (param i32) (result i32)))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "doSwitch" (func $switch/doSwitch))
|
||||
(export "doSwitchDefaultFirst" (func $switch/doSwitchDefaultFirst))
|
||||
@ -190,7 +190,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
switch/doSwitch
|
||||
switch/doSwitchDefaultFirst
|
||||
switch/doSwitchDefaultOmitted
|
||||
|
@ -1,7 +1,7 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(global $ternary/a (mut i32) (i32.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -78,7 +78,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
ternary/a
|
||||
[program.exports]
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
(global $tlsf/CONTROL$SL_BITMAP_OFFSET i32 (i32.const 20))
|
||||
(global $tlsf/SL_INDEX_COUNT i32 (i32.const 32))
|
||||
(global $tlsf/CONTROL$BLOCKS_OFFSET i32 (i32.const 112))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "control$construct" (func $tlsf/control$construct))
|
||||
(export "memory" (memory $0))
|
||||
@ -373,7 +373,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
tlsf/fls
|
||||
tlsf/ffs
|
||||
tlsf/ALIGN_SIZE_LOG2
|
||||
|
@ -4,7 +4,7 @@
|
||||
(global $unary/I (mut i64) (i64.const 0))
|
||||
(global $unary/f (mut f32) (f32.const 0))
|
||||
(global $unary/F (mut f64) (f64.const 0))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
@ -666,7 +666,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
unary/i
|
||||
unary/I
|
||||
unary/f
|
||||
|
@ -1,6 +1,6 @@
|
||||
(module
|
||||
(type $iv (func (param i32)))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(global $HEAP_BASE i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "loopWhile" (func $while/loopWhile))
|
||||
(export "loopWhileInWhile" (func $while/loopWhileInWhile))
|
||||
@ -105,7 +105,7 @@
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
HEAP_START
|
||||
HEAP_BASE
|
||||
while/loopWhile
|
||||
while/loopWhileInWhile
|
||||
[program.exports]
|
||||
|
Reference in New Issue
Block a user