Implement 'this' context parsing and serialization; Other minor improvements

This commit is contained in:
dcodeIO 2018-05-30 16:22:56 +02:00
parent c9ed03028d
commit 9d25f78fc1
18 changed files with 1589 additions and 1464 deletions

2
dist/asc.js vendored

File diff suppressed because one or more lines are too long

2
dist/asc.js.map vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,22 +3,24 @@ import "allocator/arena";
// From The Computer Language Benchmarks Game // From The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org // http://benchmarksgame.alioth.debian.org
const SOLAR_MASS = 4.0 * Math.PI * Math.PI; type float = f64; // interchangeable f32/f64 for testing
const DAYS_PER_YEAR = 365.24;
const SOLAR_MASS = <float>(4.0 * Math.PI * Math.PI);
const DAYS_PER_YEAR: float = 365.24;
class Body { class Body {
constructor( constructor(
public x: f64, public x: float,
public y: f64, public y: float,
public z: f64, public z: float,
public vx: f64, public vx: float,
public vy: f64, public vy: float,
public vz: f64, public vz: float,
public mass: f64 public mass: float
) {} ) {}
offsetMomentum(px: f64, py: f64, pz: f64): this { offsetMomentum(px: float, py: float, pz: float): this {
this.vx = -px / SOLAR_MASS; this.vx = -px / SOLAR_MASS;
this.vy = -py / SOLAR_MASS; this.vy = -py / SOLAR_MASS;
this.vz = -pz / SOLAR_MASS; this.vz = -pz / SOLAR_MASS;
@ -85,9 +87,9 @@ class NBodySystem {
constructor( constructor(
public bodies: Body[] public bodies: Body[]
) { ) {
var px = 0.0; var px: float = 0.0;
var py = 0.0; var py: float = 0.0;
var pz = 0.0; var pz: float = 0.0;
var size = bodies.length; var size = bodies.length;
for (let i = 0; i < size; i++) { for (let i = 0; i < size; i++) {
let b = unchecked(bodies[i]); let b = unchecked(bodies[i]);
@ -99,7 +101,7 @@ class NBodySystem {
bodies[0].offsetMomentum(px, py, pz); bodies[0].offsetMomentum(px, py, pz);
} }
advance(dt: f64): void { advance(dt: float): void {
var bodies = this.bodies; var bodies = this.bodies;
var size: u32 = bodies.length; var size: u32 = bodies.length;
// var buffer = changetype<usize>(bodies.buffer_); // var buffer = changetype<usize>(bodies.buffer_);
@ -126,7 +128,7 @@ class NBodySystem {
let dz = iz - bodyj.z; let dz = iz - bodyj.z;
let distanceSq = dx * dx + dy * dy + dz * dz; let distanceSq = dx * dx + dy * dy + dz * dz;
let distance = Math.sqrt(distanceSq); let distance = <float>Math.sqrt(distanceSq);
let mag = dt / (distanceSq * distance); let mag = dt / (distanceSq * distance);
let bim = bodyim * mag; let bim = bodyim * mag;
@ -151,8 +153,8 @@ class NBodySystem {
} }
} }
energy(): f64 { energy(): float {
var e = 0.0; var e: float = 0.0;
var bodies = this.bodies; var bodies = this.bodies;
for (let i: u32 = 0, size: u32 = bodies.length; i < size; ++i) { for (let i: u32 = 0, size: u32 = bodies.length; i < size; ++i) {
@ -171,11 +173,11 @@ class NBodySystem {
e += 0.5 * bim * (vx * vx + vy * vy + vz * vz); e += 0.5 * bim * (vx * vx + vy * vy + vz * vz);
for (let j: u32 = i + 1; j < size; ++j) { for (let j: u32 = i + 1; j < size; ++j) {
let bodyj = bodies[j]; let bodyj = unchecked(bodies[j]);
let dx = ix - bodyj.x; let dx = ix - bodyj.x;
let dy = iy - bodyj.y; let dy = iy - bodyj.y;
let dz = iz - bodyj.z; let dz = iz - bodyj.z;
let distance = Math.sqrt(dx * dx + dy * dy + dz * dz); let distance = <float>Math.sqrt(dx * dx + dy * dy + dz * dz);
e -= bim * bodyj.mass / distance; e -= bim * bodyj.mass / distance;
} }
} }
@ -200,7 +202,7 @@ export function getBody(index: i32): Body | null {
return <u32>index < <u32>bodies.length ? bodies[index] : null; return <u32>index < <u32>bodies.length ? bodies[index] : null;
} }
export function step(): f64 { export function step(): float {
system.advance(0.01); system.advance(0.01);
return system.energy(); return system.energy();
} }

View File

@ -17,7 +17,7 @@ function asmFunc(global, env, buffer) {
var Math_floor = global.Math.floor; var Math_floor = global.Math.floor;
var Math_ceil = global.Math.ceil; var Math_ceil = global.Math.ceil;
var Math_sqrt = global.Math.sqrt; var Math_sqrt = global.Math.sqrt;
var abort = env.abort; var $lib_env_abort = env.abort;
var $lib_allocator_arena_startOffset = 0; var $lib_allocator_arena_startOffset = 0;
var $lib_allocator_arena_offset = 0; var $lib_allocator_arena_offset = 0;
var assembly_index_system = 0; var assembly_index_system = 0;
@ -165,7 +165,7 @@ function asmFunc(global, env, buffer) {
$1 = $1 | 0; $1 = $1 | 0;
var $2 = 0, $3 = 0, $4 = 0; var $2 = 0, $3 = 0, $4 = 0;
if ($1 >>> 0 > 268435454 >>> 0) { if ($1 >>> 0 > 268435454 >>> 0) {
abort(0 | 0, 8 | 0, 23 | 0, 39 | 0); $lib_env_abort(0 | 0, 8 | 0, 23 | 0, 39 | 0);
abort(); abort();
} }
$3 = $1 << 2 | 0; $3 = $1 << 2 | 0;
@ -189,18 +189,19 @@ function asmFunc(global, env, buffer) {
$1 = $1 | 0; $1 = $1 | 0;
var $2 = 0, $3 = 0, $4 = 0.0, $5 = 0.0, $6 = 0.0, $7 = 0.0, $72 = 0, $8 = 0, $50 = 0; var $2 = 0, $3 = 0, $4 = 0.0, $5 = 0.0, $6 = 0.0, $7 = 0.0, $72 = 0, $8 = 0, $50 = 0;
$8 = HEAP32[($1 + 4 | 0) >> 2] | 0; $8 = HEAP32[($1 + 4 | 0) >> 2] | 0;
continue_0 : do { break_0 : {
if (($2 | 0) < ($8 | 0)) { repeat_0 : do {
if (($2 | 0) >= ($8 | 0)) break break_0;
$3 = HEAPU32[(((HEAPU32[$1 >> 2] | 0) + ($2 << 2 | 0) | 0) + 8 | 0) >> 2] | 0; $3 = HEAPU32[(((HEAPU32[$1 >> 2] | 0) + ($2 << 2 | 0) | 0) + 8 | 0) >> 2] | 0;
$4 = +HEAPF64[($3 + 48 | 0) >> 3]; $4 = +HEAPF64[($3 + 48 | 0) >> 3];
$5 = $5 + +HEAPF64[($3 + 24 | 0) >> 3] * $4; $5 = $5 + +HEAPF64[($3 + 24 | 0) >> 3] * $4;
$6 = $6 + +HEAPF64[($3 + 32 | 0) >> 3] * $4; $6 = $6 + +HEAPF64[($3 + 32 | 0) >> 3] * $4;
$7 = $7 + +HEAPF64[($3 + 40 | 0) >> 3] * $4; $7 = $7 + +HEAPF64[($3 + 40 | 0) >> 3] * $4;
$2 = $2 + 1 | 0; $2 = $2 + 1 | 0;
continue continue_0; continue repeat_0;
} break repeat_0;
break continue_0; } while (1);
} while (1); };
$2 = HEAPU32[$1 >> 2] | 0; $2 = HEAPU32[$1 >> 2] | 0;
if (0 >>> 0 < ((HEAP32[$2 >> 2] | 0) >>> 2 | 0) >>> 0) $50 = HEAPU32[($2 + 8 | 0) >> 2] | 0; else abort(); if (0 >>> 0 < ((HEAP32[$2 >> 2] | 0) >>> 2 | 0) >>> 0) $50 = HEAPU32[($2 + 8 | 0) >> 2] | 0; else abort();
$2 = $50; $2 = $50;
@ -250,8 +251,9 @@ function asmFunc(global, env, buffer) {
var $2 = 0, $3 = 0.0, $9 = 0.0, $4 = 0, $5 = 0.0, $6 = 0.0, $7 = 0.0, $8 = 0, $10 = 0.0, $11 = 0.0, $12 = 0.0, $13 = 0, $14 = 0, $15 = 0.0, $16 = 0.0, $17 = 0.0, $18 = 0.0; var $2 = 0, $3 = 0.0, $9 = 0.0, $4 = 0, $5 = 0.0, $6 = 0.0, $7 = 0.0, $8 = 0, $10 = 0.0, $11 = 0.0, $12 = 0.0, $13 = 0, $14 = 0, $15 = 0.0, $16 = 0.0, $17 = 0.0, $18 = 0.0;
$13 = HEAPU32[$0 >> 2] | 0; $13 = HEAPU32[$0 >> 2] | 0;
$14 = HEAP32[($13 + 4 | 0) >> 2] | 0; $14 = HEAP32[($13 + 4 | 0) >> 2] | 0;
continue_0 : do { break_0 : {
if ($4 >>> 0 < $14 >>> 0) { repeat_0 : do {
if ($4 >>> 0 >= $14 >>> 0) break break_0;
$0 = HEAPU32[(((HEAPU32[$13 >> 2] | 0) + ($4 << 2 | 0) | 0) + 8 | 0) >> 2] | 0; $0 = HEAPU32[(((HEAPU32[$13 >> 2] | 0) + ($4 << 2 | 0) | 0) + 8 | 0) >> 2] | 0;
$15 = +HEAPF64[$0 >> 3]; $15 = +HEAPF64[$0 >> 3];
$16 = +HEAPF64[($0 + 8 | 0) >> 3]; $16 = +HEAPF64[($0 + 8 | 0) >> 3];
@ -260,9 +262,10 @@ function asmFunc(global, env, buffer) {
$6 = +HEAPF64[($0 + 32 | 0) >> 3]; $6 = +HEAPF64[($0 + 32 | 0) >> 3];
$7 = +HEAPF64[($0 + 40 | 0) >> 3]; $7 = +HEAPF64[($0 + 40 | 0) >> 3];
$18 = +HEAPF64[($0 + 48 | 0) >> 3]; $18 = +HEAPF64[($0 + 48 | 0) >> 3];
$8 = $4 + 1 | 0; break_1 : {
continue_1 : do { $8 = $4 + 1 | 0;
if ($8 >>> 0 < $14 >>> 0) { repeat_1 : do {
if ($8 >>> 0 >= $14 >>> 0) break break_1;
$2 = HEAPU32[(((HEAPU32[$13 >> 2] | 0) + ($8 << 2 | 0) | 0) + 8 | 0) >> 2] | 0; $2 = HEAPU32[(((HEAPU32[$13 >> 2] | 0) + ($8 << 2 | 0) | 0) + 8 | 0) >> 2] | 0;
$10 = $15 - +HEAPF64[$2 >> 3]; $10 = $15 - +HEAPF64[$2 >> 3];
$11 = $16 - +HEAPF64[($2 + 8 | 0) >> 3]; $11 = $16 - +HEAPF64[($2 + 8 | 0) >> 3];
@ -278,10 +281,10 @@ function asmFunc(global, env, buffer) {
HEAPF64[($2 + 32 | 0) >> 3] = +HEAPF64[($2 + 32 | 0) >> 3] + $11 * $3; HEAPF64[($2 + 32 | 0) >> 3] = +HEAPF64[($2 + 32 | 0) >> 3] + $11 * $3;
HEAPF64[($2 + 40 | 0) >> 3] = +HEAPF64[($2 + 40 | 0) >> 3] + $12 * $3; HEAPF64[($2 + 40 | 0) >> 3] = +HEAPF64[($2 + 40 | 0) >> 3] + $12 * $3;
$8 = $8 + 1 | 0; $8 = $8 + 1 | 0;
continue continue_1; continue repeat_1;
} break repeat_1;
break continue_1; } while (1);
} while (1); };
HEAPF64[($0 + 24 | 0) >> 3] = $5; HEAPF64[($0 + 24 | 0) >> 3] = $5;
HEAPF64[($0 + 32 | 0) >> 3] = $6; HEAPF64[($0 + 32 | 0) >> 3] = $6;
HEAPF64[($0 + 40 | 0) >> 3] = $7; HEAPF64[($0 + 40 | 0) >> 3] = $7;
@ -289,20 +292,21 @@ function asmFunc(global, env, buffer) {
HEAPF64[($0 + 8 | 0) >> 3] = +HEAPF64[($0 + 8 | 0) >> 3] + $1 * $6; HEAPF64[($0 + 8 | 0) >> 3] = +HEAPF64[($0 + 8 | 0) >> 3] + $1 * $6;
HEAPF64[($0 + 16 | 0) >> 3] = +HEAPF64[($0 + 16 | 0) >> 3] + $1 * $7; HEAPF64[($0 + 16 | 0) >> 3] = +HEAPF64[($0 + 16 | 0) >> 3] + $1 * $7;
$4 = $4 + 1 | 0; $4 = $4 + 1 | 0;
continue continue_0; continue repeat_0;
} break repeat_0;
break continue_0; } while (1);
} while (1); };
} }
function assembly_index_NBodySystem_energy($0) { function assembly_index_NBodySystem_energy($0) {
$0 = $0 | 0; $0 = $0 | 0;
var $1 = 0.0, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $10 = 0.0, $6 = 0.0, $7 = 0.0, $8 = 0.0, $9 = 0.0, $30 = 0.0, $39 = 0.0, $45 = 0.0, $59 = 0.0, $72 = 0, $77 = 0.0, $92 = 0.0; var $1 = 0.0, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $10 = 0.0, $6 = 0.0, $7 = 0.0, $8 = 0.0, $9 = 0.0, $30 = 0.0, $39 = 0.0, $45 = 0.0, $69 = 0.0, $84 = 0.0;
$4 = HEAPU32[$0 >> 2] | 0; break_0 : {
$5 = HEAP32[($4 + 4 | 0) >> 2] | 0; $4 = HEAPU32[$0 >> 2] | 0;
continue_0 : do { $5 = HEAP32[($4 + 4 | 0) >> 2] | 0;
if ($3 >>> 0 < $5 >>> 0) { repeat_0 : do {
$0 = HEAPU32[(((HEAPU32[$4 >> 2] | 0) + ($3 << 2 | 0) | 0) + 8 | 0) >> 2] | 0; if ($2 >>> 0 >= $5 >>> 0) break break_0;
$0 = HEAPU32[(((HEAPU32[$4 >> 2] | 0) + ($2 << 2 | 0) | 0) + 8 | 0) >> 2] | 0;
$7 = +HEAPF64[$0 >> 3]; $7 = +HEAPF64[$0 >> 3];
$8 = +HEAPF64[($0 + 8 | 0) >> 3]; $8 = +HEAPF64[($0 + 8 | 0) >> 3];
$9 = +HEAPF64[($0 + 16 | 0) >> 3]; $9 = +HEAPF64[($0 + 16 | 0) >> 3];
@ -314,29 +318,27 @@ function asmFunc(global, env, buffer) {
$45 = $39 + $1 * $1; $45 = $39 + $1 * $1;
$1 = +HEAPF64[($0 + 40 | 0) >> 3]; $1 = +HEAPF64[($0 + 40 | 0) >> 3];
$1 = $30 + .5 * $10 * ($45 + $1 * $1); $1 = $30 + .5 * $10 * ($45 + $1 * $1);
$0 = $3 + 1 | 0; break_1 : {
continue_1 : do { $0 = $2 + 1 | 0;
if ($0 >>> 0 < $5 >>> 0) { repeat_1 : do {
$59 = $7; if ($0 >>> 0 >= $5 >>> 0) break break_1;
$2 = HEAPU32[$4 >> 2] | 0; $3 = HEAPU32[(((HEAPU32[$4 >> 2] | 0) + ($0 << 2 | 0) | 0) + 8 | 0) >> 2] | 0;
if ($0 >>> 0 < ((HEAP32[$2 >> 2] | 0) >>> 2 | 0) >>> 0) $72 = HEAPU32[(($2 + ($0 << 2 | 0) | 0) + 8 | 0) >> 2] | 0; else abort(); $6 = $7 - +HEAPF64[$3 >> 3];
$2 = $72; $69 = $1;
$6 = $59 - +HEAPF64[$2 >> 3]; $1 = $8 - +HEAPF64[($3 + 8 | 0) >> 3];
$77 = $1; $84 = $6 * $6 + $1 * $1;
$1 = $8 - +HEAPF64[($2 + 8 | 0) >> 3]; $1 = $9 - +HEAPF64[($3 + 16 | 0) >> 3];
$92 = $6 * $6 + $1 * $1; $1 = $69 - $10 * +HEAPF64[($3 + 48 | 0) >> 3] / Math_sqrt($84 + $1 * $1);
$1 = $9 - +HEAPF64[($2 + 16 | 0) >> 3];
$1 = $77 - $10 * +HEAPF64[($2 + 48 | 0) >> 3] / Math_sqrt($92 + $1 * $1);
$0 = $0 + 1 | 0; $0 = $0 + 1 | 0;
continue continue_1; continue repeat_1;
} break repeat_1;
break continue_1; } while (1);
} while (1); };
$3 = $3 + 1 | 0; $2 = $2 + 1 | 0;
continue continue_0; continue repeat_0;
} break repeat_0;
break continue_0; } while (1);
} while (1); };
return +$1; return +$1;
} }
@ -348,14 +350,15 @@ function asmFunc(global, env, buffer) {
function assembly_index_bench($0) { function assembly_index_bench($0) {
$0 = $0 | 0; $0 = $0 | 0;
var $1 = 0; var $1 = 0;
continue_0 : do { break_0 : {
if ($1 >>> 0 < $0 >>> 0) { repeat_0 : do {
if ($1 >>> 0 >= $0 >>> 0) break break_0;
assembly_index_NBodySystem_advance(assembly_index_system | 0, +(.01)); assembly_index_NBodySystem_advance(assembly_index_system | 0, +(.01));
$1 = $1 + 1 | 0; $1 = $1 + 1 | 0;
continue continue_0; continue repeat_0;
} break repeat_0;
break continue_0; } while (1);
} while (1); };
} }
function start() { function start() {

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,8 @@ import {
import { import {
normalizePath, normalizePath,
resolvePath resolvePath,
CharCode
} from "./util"; } from "./util";
export { Token, Range }; export { Token, Range };
@ -180,7 +181,7 @@ export abstract class Node {
): SignatureNode { ): SignatureNode {
var sig = new SignatureNode(); var sig = new SignatureNode();
sig.range = range; sig.range = range;
sig.parameterTypes = parameters; setParent(parameters, sig); sig.parameters = parameters; setParent(parameters, sig);
sig.returnType = returnType; returnType.parent = sig; sig.returnType = returnType; returnType.parent = sig;
sig.explicitThisType = explicitThisType; if (explicitThisType) explicitThisType.parent = sig; sig.explicitThisType = explicitThisType; if (explicitThisType) explicitThisType.parent = sig;
sig.isNullable = isNullable; sig.isNullable = isNullable;
@ -1037,7 +1038,7 @@ export class SignatureNode extends CommonTypeNode {
kind = NodeKind.SIGNATURE; kind = NodeKind.SIGNATURE;
/** Accepted parameters. */ /** Accepted parameters. */
parameterTypes: ParameterNode[]; parameters: ParameterNode[];
/** Return type. */ /** Return type. */
returnType: CommonTypeNode; returnType: CommonTypeNode;
/** Explicitly provided this type, if any. */ /** Explicitly provided this type, if any. */
@ -1058,14 +1059,30 @@ export enum DecoratorKind {
/** Returns the decorator kind represented by the specified string. */ /** Returns the decorator kind represented by the specified string. */
export function stringToDecoratorKind(str: string): DecoratorKind { export function stringToDecoratorKind(str: string): DecoratorKind {
switch (str) { assert(str.length);
case "global": return DecoratorKind.GLOBAL; switch (str.charCodeAt(0)) {
case "operator": return DecoratorKind.OPERATOR; case CharCode.g: {
case "unmanaged": return DecoratorKind.UNMANAGED; if (str == "global") return DecoratorKind.GLOBAL;
case "sealed": return DecoratorKind.SEALED; break;
case "inline": return DecoratorKind.INLINE; }
default: return DecoratorKind.CUSTOM; case CharCode.i: {
if (str == "inline") return DecoratorKind.INLINE;
break;
}
case CharCode.o: {
if (str == "operator") return DecoratorKind.OPERATOR;
break;
}
case CharCode.s: {
if (str == "sealed") return DecoratorKind.SEALED;
break;
}
case CharCode.u: {
if (str == "unmanaged") return DecoratorKind.UNMANAGED;
break;
}
} }
return DecoratorKind.CUSTOM;
} }
/** Represents a decorator. */ /** Represents a decorator. */

View File

@ -4708,7 +4708,7 @@ export class Compiler extends DiagnosticEmitter {
inferredTypes.set(typeParameters[i].name.text, null); inferredTypes.set(typeParameters[i].name.text, null);
} }
// let numInferred = 0; // let numInferred = 0;
let parameterTypes = prototype.declaration.signature.parameterTypes; let parameterTypes = prototype.declaration.signature.parameters;
let numParameterTypes = parameterTypes.length; let numParameterTypes = parameterTypes.length;
let argumentExpressions = expression.arguments; let argumentExpressions = expression.arguments;
let numArguments = argumentExpressions.length; let numArguments = argumentExpressions.length;
@ -4718,7 +4718,7 @@ export class Compiler extends DiagnosticEmitter {
let name = typeNode.kind == NodeKind.TYPE ? (<TypeNode>typeNode).name.text : null; let name = typeNode.kind == NodeKind.TYPE ? (<TypeNode>typeNode).name.text : null;
let argumentExpression = i < numArguments let argumentExpression = i < numArguments
? argumentExpressions[i] ? argumentExpressions[i]
: prototype.declaration.signature.parameterTypes[i].initializer; : prototype.declaration.signature.parameters[i].initializer;
if (!argumentExpression) { // missing initializer -> too few arguments if (!argumentExpression) { // missing initializer -> too few arguments
this.error( this.error(
DiagnosticCode.Expected_0_arguments_but_got_1, DiagnosticCode.Expected_0_arguments_but_got_1,
@ -5088,7 +5088,7 @@ export class Compiler extends DiagnosticEmitter {
var numParameters = signature.parameterTypes.length; var numParameters = signature.parameterTypes.length;
for (let i = numArguments; i < numParameters; ++i) { for (let i = numArguments; i < numParameters; ++i) {
let initExpr = this.compileExpression( let initExpr = this.compileExpression(
assert(declaration.signature.parameterTypes[i].initializer), assert(declaration.signature.parameters[i].initializer),
parameterTypes[i], parameterTypes[i],
ConversionKind.IMPLICIT, ConversionKind.IMPLICIT,
WrapMode.WRAP WrapMode.WRAP
@ -5158,7 +5158,7 @@ export class Compiler extends DiagnosticEmitter {
var originalSignature = original.signature; var originalSignature = original.signature;
var originalName = original.internalName; var originalName = original.internalName;
var originalParameterTypes = originalSignature.parameterTypes; var originalParameterTypes = originalSignature.parameterTypes;
var originalParameterDeclarations = original.prototype.declaration.signature.parameterTypes; var originalParameterDeclarations = original.prototype.declaration.signature.parameters;
var commonReturnType = originalSignature.returnType; var commonReturnType = originalSignature.returnType;
var commonThisType = originalSignature.thisType; var commonThisType = originalSignature.thisType;
var isInstance = original.is(CommonFlags.INSTANCE); var isInstance = original.is(CommonFlags.INSTANCE);
@ -5345,7 +5345,7 @@ export class Compiler extends DiagnosticEmitter {
operands.length = 0; operands.length = 0;
} }
let parameterTypes = instance.signature.parameterTypes; let parameterTypes = instance.signature.parameterTypes;
let parameterNodes = instance.prototype.declaration.signature.parameterTypes; let parameterNodes = instance.prototype.declaration.signature.parameters;
let allOptionalsAreConstant = true; let allOptionalsAreConstant = true;
for (let i = numArguments; i < maxArguments; ++i) { for (let i = numArguments; i < maxArguments; ++i) {
let initializer = parameterNodes[i].initializer; let initializer = parameterNodes[i].initializer;

View File

@ -380,7 +380,7 @@ export class ASTBuilder {
sb.push("this: "); sb.push("this: ");
this.visitTypeNode(explicitThisType); this.visitTypeNode(explicitThisType);
} }
var parameters = node.parameterTypes; var parameters = node.parameters;
var numParameters = parameters.length; var numParameters = parameters.length;
if (numParameters) { if (numParameters) {
if (explicitThisType) sb.push(", "); if (explicitThisType) sb.push(", ");
@ -1003,13 +1003,19 @@ export class ASTBuilder {
} }
} }
sb.push("("); sb.push("(");
var parameterTypes = signature.parameterTypes; var parameters = signature.parameters;
var numParameterTypes = parameterTypes.length; var numParameters = parameters.length;
if (numParameterTypes) { var explicitThisType = signature.explicitThisType;
this.serializeParameter(parameterTypes[0]); if (explicitThisType) {
for (let i = 1; i < numParameterTypes; ++i) { sb.push("this: ");
this.visitTypeNode(explicitThisType);
}
if (numParameters) {
if (explicitThisType) sb.push(", ");
this.serializeParameter(parameters[0]);
for (let i = 1; i < numParameters; ++i) {
sb.push(", "); sb.push(", ");
this.serializeParameter(parameterTypes[i]); this.serializeParameter(parameters[i]);
} }
} }
var body = node.body; var body = node.body;

View File

@ -87,10 +87,12 @@ export class Parser extends DiagnosticEmitter {
/** Program being created. */ /** Program being created. */
program: Program; program: Program;
/** Log of source file names to be requested. */ /** Source file names to be requested next. */
backlog: string[] = new Array(); backlog: string[] = new Array();
/** Log of source file names already processed. */ /** Source file names already seen, that is processed or backlogged. */
seenlog: Set<string> = new Set(); seenlog: Set<string> = new Set();
/** Source file names already completely processed. */
donelog: Set<string> = new Set();
/** Optional handler to intercept comments while tokenizing. */ /** Optional handler to intercept comments while tokenizing. */
onComment: CommentHandler | null = null; onComment: CommentHandler | null = null;
@ -106,16 +108,13 @@ export class Parser extends DiagnosticEmitter {
path: string, path: string,
isEntry: bool isEntry: bool
): void { ): void {
var program = this.program;
// check if already parsed
var normalizedPath = normalizePath(path); var normalizedPath = normalizePath(path);
var internalPath = mangleInternalPath(normalizedPath); var internalPath = mangleInternalPath(normalizedPath);
var sources = program.sources;
for (let i = 0, k = sources.length; i < k; ++i) { // check if already processed
if (sources[i].internalPath == internalPath) return; if (this.donelog.has(internalPath)) return;
} this.donelog.add(internalPath); // do not parse again
this.seenlog.add(internalPath); this.seenlog.add(internalPath); // do not request again
// create the source element // create the source element
var source = new Source( var source = new Source(
@ -127,7 +126,8 @@ export class Parser extends DiagnosticEmitter {
? SourceKind.LIBRARY ? SourceKind.LIBRARY
: SourceKind.DEFAULT : SourceKind.DEFAULT
); );
sources.push(source); var program = this.program;
program.sources.push(source);
// mark the special builtins library file // mark the special builtins library file
if (source.normalizedPath == builtinsFile) { if (source.normalizedPath == builtinsFile) {
@ -350,6 +350,7 @@ export class Parser extends DiagnosticEmitter {
if (this.backlog.length) throw new Error("backlog is not empty"); if (this.backlog.length) throw new Error("backlog is not empty");
this.backlog = []; this.backlog = [];
this.seenlog.clear(); this.seenlog.clear();
this.donelog.clear();
return this.program; return this.program;
} }
@ -979,6 +980,8 @@ export class Parser extends DiagnosticEmitter {
return null; return null;
} }
private parseParametersThis: TypeNode | null = null;
parseParameters( parseParameters(
tn: Tokenizer, tn: Tokenizer,
isConstructor: bool = false isConstructor: bool = false
@ -990,9 +993,44 @@ export class Parser extends DiagnosticEmitter {
var seenRest: ParameterNode | null = null; var seenRest: ParameterNode | null = null;
var seenOptional = false; var seenOptional = false;
var reportedRest = false; var reportedRest = false;
var thisType: CommonTypeNode | null = null;
// check if there is a leading `this` parameter
this.parseParametersThis = null;
if (tn.skip(Token.THIS)) {
if (tn.skip(Token.COLON)) {
thisType = this.parseType(tn); // reports
if (!thisType) return null;
if (thisType.kind == NodeKind.TYPE) {
this.parseParametersThis = <TypeNode>thisType;
} else {
this.error(
DiagnosticCode.Operation_not_supported,
thisType.range
);
}
} else {
this.error(
DiagnosticCode._0_expected,
tn.range(), ":"
);
return null;
}
if (!tn.skip(Token.COMMA)) {
if (tn.skip(Token.CLOSEPAREN)) {
return parameters;
} else {
this.error(
DiagnosticCode._0_expected,
tn.range(), ")"
);
return null;
}
}
}
while (!tn.skip(Token.CLOSEPAREN)) { while (!tn.skip(Token.CLOSEPAREN)) {
let param = this.parseParameter(tn, isConstructor); let param = this.parseParameter(tn, isConstructor); // reports
if (!param) return null; if (!param) return null;
if (seenRest && !reportedRest) { if (seenRest && !reportedRest) {
this.error( this.error(
@ -1187,6 +1225,7 @@ export class Parser extends DiagnosticEmitter {
var parameters = this.parseParameters(tn); var parameters = this.parseParameters(tn);
if (!parameters) return null; if (!parameters) return null;
var thisType = this.parseParametersThis;
var isSetter = (flags & CommonFlags.SET) != 0; var isSetter = (flags & CommonFlags.SET) != 0;
if (isSetter) { if (isSetter) {
@ -1234,7 +1273,7 @@ export class Parser extends DiagnosticEmitter {
var signature = Node.createSignature( var signature = Node.createSignature(
parameters, parameters,
returnType, returnType,
null, thisType,
false, false,
tn.range(signatureStart, tn.pos) tn.range(signatureStart, tn.pos)
); );
@ -1349,7 +1388,7 @@ export class Parser extends DiagnosticEmitter {
var signature = Node.createSignature( var signature = Node.createSignature(
parameters, parameters,
returnType, returnType,
null, null, // TODO?
false, false,
tn.range(signatureStart, tn.pos) tn.range(signatureStart, tn.pos)
); );
@ -1653,6 +1692,7 @@ export class Parser extends DiagnosticEmitter {
let signatureStart = tn.tokenPos; let signatureStart = tn.tokenPos;
let parameters = this.parseParameters(tn, isConstructor); let parameters = this.parseParameters(tn, isConstructor);
if (!parameters) return null; if (!parameters) return null;
let thisType = this.parseParametersThis;
if (isConstructor) { if (isConstructor) {
for (let i = 0, k = parameters.length; i < k; ++i) { for (let i = 0, k = parameters.length; i < k; ++i) {
let parameter = parameters[i]; let parameter = parameters[i];
@ -1726,7 +1766,7 @@ export class Parser extends DiagnosticEmitter {
let signature = Node.createSignature( let signature = Node.createSignature(
parameters, parameters,
returnType, returnType,
null, thisType,
false, false,
tn.range(signatureStart, tn.pos) tn.range(signatureStart, tn.pos)
); );
@ -1907,7 +1947,7 @@ export class Parser extends DiagnosticEmitter {
} }
let ret = Node.createExportStatement(members, path, flags, tn.range(startPos, tn.pos)); let ret = Node.createExportStatement(members, path, flags, tn.range(startPos, tn.pos));
let internalPath = ret.internalPath; let internalPath = ret.internalPath;
if (internalPath != null && !this.seenlog.has(internalPath)) { if (internalPath !== null && !this.seenlog.has(internalPath)) {
this.backlog.push(internalPath); this.backlog.push(internalPath);
this.seenlog.add(internalPath); this.seenlog.add(internalPath);
} }

View File

@ -100,6 +100,7 @@ import {
getConstValueF64, getConstValueF64,
getConstValueI64Low getConstValueI64Low
} from "./module"; } from "./module";
import { CharCode } from "./util";
/** Path delimiter inserted between file system levels. */ /** Path delimiter inserted between file system levels. */
export const PATH_DELIMITER = "/"; export const PATH_DELIMITER = "/";
@ -166,26 +167,79 @@ export enum OperatorKind {
} }
function operatorKindFromString(str: string): OperatorKind { function operatorKindFromString(str: string): OperatorKind {
switch (str) { assert(str.length);
case "[]" : return OperatorKind.INDEXED_GET; switch (str.charCodeAt(0)) {
case "[]=": return OperatorKind.INDEXED_SET; case CharCode.OPENBRACKET: {
case "{}" : return OperatorKind.UNCHECKED_INDEXED_GET; switch (str) {
case "{}=": return OperatorKind.UNCHECKED_INDEXED_SET; case "[]" : return OperatorKind.INDEXED_GET;
case "+" : return OperatorKind.ADD; case "[]=": return OperatorKind.INDEXED_SET;
case "-" : return OperatorKind.SUB; }
case "*" : return OperatorKind.MUL; break;
case "/" : return OperatorKind.DIV; }
case "%" : return OperatorKind.REM; case CharCode.OPENBRACE: {
case "**" : return OperatorKind.POW; switch (str) {
case "&" : return OperatorKind.AND; case "{}" : return OperatorKind.UNCHECKED_INDEXED_GET;
case "|" : return OperatorKind.OR; case "{}=": return OperatorKind.UNCHECKED_INDEXED_SET;
case "^" : return OperatorKind.XOR; }
case "==" : return OperatorKind.EQ; break;
case "!=" : return OperatorKind.NE; }
case ">" : return OperatorKind.GT; case CharCode.PLUS: {
case ">=" : return OperatorKind.GE; if (str.length == 1) return OperatorKind.ADD;
case "<" : return OperatorKind.LT; break;
case "<=" : return OperatorKind.LE; }
case CharCode.MINUS: {
if (str.length == 1) return OperatorKind.SUB;
break;
}
case CharCode.ASTERISK: {
switch (str) {
case "*" : return OperatorKind.MUL;
case "**": return OperatorKind.POW;
}
break;
}
case CharCode.SLASH: {
if (str.length == 1) return OperatorKind.DIV;
break;
}
case CharCode.PERCENT: {
if (str.length == 1) return OperatorKind.REM;
break;
}
case CharCode.AMPERSAND: {
if (str.length == 1) return OperatorKind.AND;
break;
}
case CharCode.BAR: {
if (str.length == 1) return OperatorKind.OR;
break;
}
case CharCode.CARET: {
if (str.length == 1) return OperatorKind.XOR;
break;
}
case CharCode.EQUALS: {
if (str == "==") return OperatorKind.EQ;
break;
}
case CharCode.EXCLAMATION: {
if (str == "!=") return OperatorKind.NE;
break;
}
case CharCode.GREATERTHAN: {
switch (str) {
case ">" : return OperatorKind.GT;
case ">=": return OperatorKind.GE;
}
break;
}
case CharCode.LESSTHAN: {
switch (str) {
case "<" : return OperatorKind.LT;
case "<=": return OperatorKind.LE;
}
break;
}
} }
return OperatorKind.INVALID; return OperatorKind.INVALID;
} }
@ -1674,7 +1728,7 @@ export class Program extends DiagnosticEmitter {
); );
if (!thisType) return null; if (!thisType) return null;
} }
var parameterTypeNodes = node.parameterTypes; var parameterTypeNodes = node.parameters;
var numParameters = parameterTypeNodes.length; var numParameters = parameterTypeNodes.length;
var parameterTypes = new Array<Type>(numParameters); var parameterTypes = new Array<Type>(numParameters);
var parameterNames = new Array<string>(numParameters); var parameterNames = new Array<string>(numParameters);
@ -2664,7 +2718,7 @@ export class FunctionPrototype extends Element {
} }
// resolve signature node // resolve signature node
var signatureParameters = signatureNode.parameterTypes; var signatureParameters = signatureNode.parameters;
var signatureParameterCount = signatureParameters.length; var signatureParameterCount = signatureParameters.length;
var parameterTypes = new Array<Type>(signatureParameterCount); var parameterTypes = new Array<Type>(signatureParameterCount);
var parameterNames = new Array<string>(signatureParameterCount); var parameterNames = new Array<string>(signatureParameterCount);

View File

@ -173,7 +173,8 @@ export enum IdentifierHandling {
} }
export function tokenFromKeyword(text: string): Token { export function tokenFromKeyword(text: string): Token {
switch (text.length && text.charCodeAt(0)) { assert(text.length);
switch (text.charCodeAt(0)) {
case CharCode.a: { case CharCode.a: {
switch (text) { switch (text) {
case "abstract": return Token.ABSTRACT; case "abstract": return Token.ABSTRACT;

1
std/portable.d.ts vendored
View File

@ -316,6 +316,7 @@ declare class Symbol {
declare class Set<T> { declare class Set<T> {
constructor(entries?: T[]); constructor(entries?: T[]);
readonly size: i32;
has(value: T): bool; has(value: T): bool;
add(value: T): void; add(value: T): void;
delete(value: T): bool; delete(value: T): bool;

View File

@ -2,3 +2,5 @@ function simple(): void {}
function typeparams<T, V extends T>(a: V | null = null): void {} function typeparams<T, V extends T>(a: V | null = null): void {}
@decorator() @decorator()
function withdecorator(): void {} function withdecorator(): void {}
function withthis(this: i32): i32 { return this; }
function withthisp(this: i32, a: f32, b: f64): i32 { return this; }

View File

@ -2,3 +2,9 @@ function simple(): void {}
function typeparams<T, V extends T>(a: V | null = null): void {} function typeparams<T, V extends T>(a: V | null = null): void {}
@decorator() @decorator()
function withdecorator(): void {} function withdecorator(): void {}
function withthis(this: i32): i32 {
return this;
}
function withthisp(this: i32, a: f32, b: f64): i32 {
return this;
}