mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 07:02:13 +00:00
Refactoring; Add tslint fwiw
This commit is contained in:
parent
d7c069b692
commit
4baff99125
117
package-lock.json
generated
117
package-lock.json
generated
@ -57,7 +57,8 @@
|
|||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "8.5.1",
|
"version": "8.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.1.tgz",
|
||||||
"integrity": "sha512-SrmAO+NhnsuG/6TychSl2VdxBZiw/d6V+8j+DFo8O3PwFi+QeYXWHhAw+b170aSc6zYab6/PjEWRZHIDN9mNUw=="
|
"integrity": "sha512-SrmAO+NhnsuG/6TychSl2VdxBZiw/d6V+8j+DFo8O3PwFi+QeYXWHhAw+b170aSc6zYab6/PjEWRZHIDN9mNUw==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/strip-bom": {
|
"@types/strip-bom": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
@ -202,6 +203,44 @@
|
|||||||
"integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
|
"integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"babel-code-frame": {
|
||||||
|
"version": "6.26.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||||
|
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"chalk": "1.1.3",
|
||||||
|
"esutils": "2.0.2",
|
||||||
|
"js-tokens": "3.0.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||||
|
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"chalk": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||||
|
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "2.2.1",
|
||||||
|
"escape-string-regexp": "1.0.5",
|
||||||
|
"has-ansi": "2.0.0",
|
||||||
|
"strip-ansi": "3.0.1",
|
||||||
|
"supports-color": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||||
@ -441,6 +480,12 @@
|
|||||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"commander": {
|
||||||
|
"version": "2.12.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
|
||||||
|
"integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
@ -742,6 +787,12 @@
|
|||||||
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
|
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"esutils": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
|
||||||
|
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"event-emitter": {
|
"event-emitter": {
|
||||||
"version": "0.3.5",
|
"version": "0.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
|
||||||
@ -920,6 +971,15 @@
|
|||||||
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
|
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"has-ansi": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"has-flag": {
|
"has-flag": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
|
||||||
@ -1138,6 +1198,12 @@
|
|||||||
"isarray": "1.0.0"
|
"isarray": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"js-tokens": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
|
||||||
|
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"json-loader": {
|
"json-loader": {
|
||||||
"version": "0.5.7",
|
"version": "0.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
|
||||||
@ -1593,6 +1659,12 @@
|
|||||||
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
|
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"path-parse": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"path-type": {
|
"path-type": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
|
||||||
@ -1829,6 +1901,15 @@
|
|||||||
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
|
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"resolve": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"path-parse": "1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"right-align": {
|
"right-align": {
|
||||||
"version": "0.1.3",
|
"version": "0.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
|
||||||
@ -2112,6 +2193,40 @@
|
|||||||
"strip-json-comments": "2.0.1"
|
"strip-json-comments": "2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.1.tgz",
|
||||||
|
"integrity": "sha1-aUavLR1lGnsYY7Ux1uWvpBqkTqw=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"tslint": {
|
||||||
|
"version": "5.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz",
|
||||||
|
"integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-code-frame": "6.26.0",
|
||||||
|
"builtin-modules": "1.1.1",
|
||||||
|
"chalk": "2.3.0",
|
||||||
|
"commander": "2.12.2",
|
||||||
|
"diff": "3.4.0",
|
||||||
|
"glob": "7.1.2",
|
||||||
|
"minimatch": "3.0.4",
|
||||||
|
"resolve": "1.5.0",
|
||||||
|
"semver": "5.4.1",
|
||||||
|
"tslib": "1.8.1",
|
||||||
|
"tsutils": "2.14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tsutils": {
|
||||||
|
"version": "2.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.14.0.tgz",
|
||||||
|
"integrity": "sha512-f6axSMV0RoUufiKiRQgmRlN1c+Ag+mDaZjcd6bHdvplT/zyhuMCGqw3pJS8s3+0x4EVkdoQajs9PchdDZlguvw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"tslib": "1.8.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tty-browserify": {
|
"tty-browserify": {
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"long": "^3.2.0",
|
"long": "^3.2.0",
|
||||||
"ts-loader": "^3.2.0",
|
"ts-loader": "^3.2.0",
|
||||||
"ts-node": "^4.0.2",
|
"ts-node": "^4.0.2",
|
||||||
|
"tslint": "^5.8.0",
|
||||||
"typescript": "^2.6.2",
|
"typescript": "^2.6.2",
|
||||||
"webpack": "^3.10.0"
|
"webpack": "^3.10.0"
|
||||||
},
|
},
|
||||||
@ -45,7 +46,8 @@
|
|||||||
"test:config:src": "tsc --noEmit -p src --diagnostics --listFiles",
|
"test:config:src": "tsc --noEmit -p src --diagnostics --listFiles",
|
||||||
"test:parser": "node tests/parser",
|
"test:parser": "node tests/parser",
|
||||||
"test:compiler": "node tests/compiler",
|
"test:compiler": "node tests/compiler",
|
||||||
"test": "npm run test:config --scripts-prepend-node-path && npm run test:parser --scripts-prepend-node-path && npm run test:compiler --scripts-prepend-node-path"
|
"test": "npm run test:config --scripts-prepend-node-path && npm run test:parser --scripts-prepend-node-path && npm run test:compiler --scripts-prepend-node-path",
|
||||||
|
"lint": "tslint --project src"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"bin/",
|
"bin/",
|
||||||
|
35
src/ast.ts
35
src/ast.ts
@ -1,8 +1,27 @@
|
|||||||
import { GETTER_PREFIX, SETTER_PREFIX, PATH_DELIMITER, PARENT_SUBST, STATIC_DELIMITER, INSTANCE_DELIMITER } from "./constants";
|
import {
|
||||||
import { Token, Tokenizer, operatorTokenToString, Range } from "./tokenizer";
|
PATH_DELIMITER,
|
||||||
import { CharCode } from "./util/charcode";
|
STATIC_DELIMITER,
|
||||||
import { I64 } from "./util/i64";
|
INSTANCE_DELIMITER
|
||||||
import { normalize as normalizePath, resolve as resolvePath } from "./util/path";
|
} from "./constants";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Token,
|
||||||
|
Tokenizer,
|
||||||
|
Range
|
||||||
|
} from "./tokenizer";
|
||||||
|
|
||||||
|
import{
|
||||||
|
CharCode
|
||||||
|
} from "./util/charcode";
|
||||||
|
|
||||||
|
import {
|
||||||
|
I64
|
||||||
|
} from "./util/i64";
|
||||||
|
|
||||||
|
import {
|
||||||
|
normalize as normalizePath,
|
||||||
|
resolve as resolvePath
|
||||||
|
} from "./util/path";
|
||||||
|
|
||||||
export { Range } from "./tokenizer";
|
export { Range } from "./tokenizer";
|
||||||
|
|
||||||
@ -489,7 +508,7 @@ export abstract class Node {
|
|||||||
(stmt.name = identifier).parent = stmt;
|
(stmt.name = identifier).parent = stmt;
|
||||||
for (i = 0, k = (stmt.typeParameters = typeParameters).length; i < k; ++i) typeParameters[i].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;
|
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.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.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.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;
|
if (stmt.decorators = decorators) for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i) (<Decorator[]>decorators)[i].parent = stmt;
|
||||||
@ -750,7 +769,7 @@ export class BinaryExpression extends Expression {
|
|||||||
serialize(sb: string[]): void {
|
serialize(sb: string[]): void {
|
||||||
this.left.serialize(sb);
|
this.left.serialize(sb);
|
||||||
sb.push(" ");
|
sb.push(" ");
|
||||||
sb.push(operatorTokenToString(this.operator));
|
sb.push(Token.operatorToString(this.operator));
|
||||||
sb.push(" ");
|
sb.push(" ");
|
||||||
this.right.serialize(sb);
|
this.right.serialize(sb);
|
||||||
}
|
}
|
||||||
@ -995,7 +1014,7 @@ export class UnaryPrefixExpression extends UnaryExpression {
|
|||||||
kind = NodeKind.UNARYPREFIX;
|
kind = NodeKind.UNARYPREFIX;
|
||||||
|
|
||||||
serialize(sb: string[]): void {
|
serialize(sb: string[]): void {
|
||||||
sb.push(operatorTokenToString(this.operator));
|
sb.push(Token.operatorToString(this.operator));
|
||||||
this.operand.serialize(sb);
|
this.operand.serialize(sb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,38 @@
|
|||||||
import { Compiler, Target, ConversionKind, typeToNativeType, typeToNativeOne, typeToNativeZero } from "./compiler";
|
import {
|
||||||
import { DiagnosticCode } from "./diagnostics";
|
Compiler,
|
||||||
import { Node, Expression, IdentifierExpression } from "./ast";
|
Target,
|
||||||
import { Type } from "./types";
|
ConversionKind
|
||||||
import { Module, ExpressionRef, UnaryOp, BinaryOp, HostOp, NativeType, FunctionTypeRef } from "./module";
|
} from "./compiler";
|
||||||
import { Program, ElementFlags, Element, Global, FunctionPrototype, Local } from "./program";
|
|
||||||
|
import {
|
||||||
|
DiagnosticCode
|
||||||
|
} from "./diagnostics";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Node,
|
||||||
|
Expression
|
||||||
|
} from "./ast";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Type
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Module,
|
||||||
|
UnaryOp,
|
||||||
|
BinaryOp,
|
||||||
|
HostOp,
|
||||||
|
NativeType,
|
||||||
|
ExpressionRef,
|
||||||
|
FunctionTypeRef
|
||||||
|
} from "./module";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Program,
|
||||||
|
Global,
|
||||||
|
FunctionPrototype,
|
||||||
|
Local
|
||||||
|
} from "./program";
|
||||||
|
|
||||||
/** Initializes the specified program with built-in functions. */
|
/** Initializes the specified program with built-in functions. */
|
||||||
export function initialize(program: Program): void {
|
export function initialize(program: Program): void {
|
||||||
@ -149,7 +178,7 @@ export function compileGetGlobal(compiler: Compiler, global: Global): Expression
|
|||||||
return compiler.module.createF64(Infinity);
|
return compiler.module.createF64(Infinity);
|
||||||
|
|
||||||
case "HEAP_BASE": // constant, but never inlined
|
case "HEAP_BASE": // constant, but never inlined
|
||||||
return compiler.module.createGetGlobal("HEAP_BASE", typeToNativeType(compiler.currentType = <Type>global.type));
|
return compiler.module.createGetGlobal("HEAP_BASE", (compiler.currentType = <Type>global.type).toNativeType());
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error("not implemented: " + global.internalName);
|
throw new Error("not implemented: " + global.internalName);
|
||||||
@ -539,7 +568,7 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty
|
|||||||
return module.createUnreachable();
|
return module.createUnreachable();
|
||||||
arg0 = compiler.compileExpression(operands[0], usizeType); // reports
|
arg0 = compiler.compileExpression(operands[0], usizeType); // reports
|
||||||
if ((compiler.currentType = typeArguments[0]) != Type.void)
|
if ((compiler.currentType = typeArguments[0]) != Type.void)
|
||||||
return module.createLoad(typeArguments[0].byteSize, typeArguments[0].isSignedInteger, arg0, typeToNativeType(typeArguments[0]));
|
return module.createLoad(typeArguments[0].byteSize, typeArguments[0].isSignedInteger, arg0, typeArguments[0].toNativeType());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "store": // store<T>(offset: usize, value: T) -> void
|
case "store": // store<T>(offset: usize, value: T) -> void
|
||||||
@ -550,7 +579,7 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty
|
|||||||
arg1 = compiler.compileExpression(operands[1], typeArguments[0]); // reports
|
arg1 = compiler.compileExpression(operands[1], typeArguments[0]); // reports
|
||||||
compiler.currentType = Type.void;
|
compiler.currentType = Type.void;
|
||||||
if (typeArguments[0] != Type.void)
|
if (typeArguments[0] != Type.void)
|
||||||
return module.createStore(typeArguments[0].byteSize, arg0, arg1, typeToNativeType(typeArguments[0]));
|
return module.createStore(typeArguments[0].byteSize, arg0, arg1, typeArguments[0].toNativeType());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "sizeof": // sizeof<T>() -> usize
|
case "sizeof": // sizeof<T>() -> usize
|
||||||
@ -685,7 +714,7 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty
|
|||||||
return module.createUnreachable();
|
return module.createUnreachable();
|
||||||
}
|
}
|
||||||
arg0 = compiler.compileExpression(operands[0], Type.i32); // reports
|
arg0 = compiler.compileExpression(operands[0], Type.i32); // reports
|
||||||
arg1 = operands.length > 1 ? compiler.compileExpression(operands[1], usizeType) : typeToNativeZero(module, usizeType); // TODO: string type
|
arg1 = operands.length > 1 ? compiler.compileExpression(operands[1], usizeType) : usizeType.toNativeZero(module); // TODO: string type
|
||||||
compiler.currentType = Type.void;
|
compiler.currentType = Type.void;
|
||||||
return compiler.options.noAssert
|
return compiler.options.noAssert
|
||||||
? module.createNop()
|
? module.createNop()
|
||||||
|
153
src/compiler.ts
153
src/compiler.ts
@ -1,8 +1,18 @@
|
|||||||
import { compileCall as compileBuiltinCall, compileGetGlobal as compileBuiltinGetGlobal, initialize } from "./builtins";
|
|
||||||
import { PATH_DELIMITER } from "./constants";
|
|
||||||
import { DiagnosticCode, DiagnosticEmitter } from "./diagnostics";
|
|
||||||
import {
|
import {
|
||||||
|
compileCall as compileBuiltinCall,
|
||||||
|
compileGetGlobal as compileBuiltinGetGlobal
|
||||||
|
} from "./builtins";
|
||||||
|
|
||||||
|
import {
|
||||||
|
PATH_DELIMITER
|
||||||
|
} from "./constants";
|
||||||
|
|
||||||
|
import {
|
||||||
|
DiagnosticCode,
|
||||||
|
DiagnosticEmitter
|
||||||
|
} from "./diagnostics";
|
||||||
|
|
||||||
|
import {
|
||||||
Module,
|
Module,
|
||||||
MemorySegment,
|
MemorySegment,
|
||||||
ExpressionRef,
|
ExpressionRef,
|
||||||
@ -12,15 +22,14 @@ import {
|
|||||||
FunctionTypeRef,
|
FunctionTypeRef,
|
||||||
FunctionRef,
|
FunctionRef,
|
||||||
ExpressionId
|
ExpressionId
|
||||||
|
|
||||||
} from "./module";
|
} from "./module";
|
||||||
import {
|
|
||||||
|
|
||||||
|
import {
|
||||||
Program,
|
Program,
|
||||||
ClassPrototype,
|
ClassPrototype,
|
||||||
Class, Element,
|
Class,
|
||||||
|
Element,
|
||||||
ElementKind,
|
ElementKind,
|
||||||
ElementFlags,
|
|
||||||
Enum,
|
Enum,
|
||||||
FunctionPrototype,
|
FunctionPrototype,
|
||||||
Function,
|
Function,
|
||||||
@ -29,17 +38,17 @@ import {
|
|||||||
Namespace,
|
Namespace,
|
||||||
Parameter,
|
Parameter,
|
||||||
EnumValue
|
EnumValue
|
||||||
|
|
||||||
} from "./program";
|
} from "./program";
|
||||||
import { Token } from "./tokenizer";
|
|
||||||
import {
|
|
||||||
|
|
||||||
|
import {
|
||||||
|
Token
|
||||||
|
} from "./tokenizer";
|
||||||
|
|
||||||
|
import {
|
||||||
Node,
|
Node,
|
||||||
NodeKind,
|
NodeKind,
|
||||||
TypeNode,
|
TypeNode,
|
||||||
TypeParameter,
|
|
||||||
Source,
|
Source,
|
||||||
|
|
||||||
// statements
|
// statements
|
||||||
BlockStatement,
|
BlockStatement,
|
||||||
BreakStatement,
|
BreakStatement,
|
||||||
@ -53,13 +62,11 @@ import {
|
|||||||
ExportMember,
|
ExportMember,
|
||||||
ExportStatement,
|
ExportStatement,
|
||||||
ExpressionStatement,
|
ExpressionStatement,
|
||||||
FieldDeclaration,
|
|
||||||
FunctionDeclaration,
|
FunctionDeclaration,
|
||||||
ForStatement,
|
ForStatement,
|
||||||
IfStatement,
|
IfStatement,
|
||||||
ImportStatement,
|
ImportStatement,
|
||||||
InterfaceDeclaration,
|
InterfaceDeclaration,
|
||||||
MethodDeclaration,
|
|
||||||
ModifierKind,
|
ModifierKind,
|
||||||
NamespaceDeclaration,
|
NamespaceDeclaration,
|
||||||
ReturnStatement,
|
ReturnStatement,
|
||||||
@ -72,9 +79,7 @@ import {
|
|||||||
VariableDeclaration,
|
VariableDeclaration,
|
||||||
VariableStatement,
|
VariableStatement,
|
||||||
WhileStatement,
|
WhileStatement,
|
||||||
|
|
||||||
// expressions
|
// expressions
|
||||||
ArrayLiteralExpression,
|
|
||||||
AssertionExpression,
|
AssertionExpression,
|
||||||
BinaryExpression,
|
BinaryExpression,
|
||||||
CallExpression,
|
CallExpression,
|
||||||
@ -92,19 +97,24 @@ import {
|
|||||||
StringLiteralExpression,
|
StringLiteralExpression,
|
||||||
UnaryPostfixExpression,
|
UnaryPostfixExpression,
|
||||||
UnaryPrefixExpression,
|
UnaryPrefixExpression,
|
||||||
|
|
||||||
// utility
|
// utility
|
||||||
hasModifier
|
hasModifier
|
||||||
|
|
||||||
} from "./ast";
|
} from "./ast";
|
||||||
import {
|
|
||||||
|
|
||||||
|
import {
|
||||||
Type,
|
Type,
|
||||||
TypeKind,
|
TypeKind,
|
||||||
|
typesToNativeTypes
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import { I64, U64 } from "./util/i64";
|
|
||||||
import { sb } from "./util/sb";
|
import {
|
||||||
|
I64,
|
||||||
|
U64
|
||||||
|
} from "./util/i64";
|
||||||
|
|
||||||
|
import {
|
||||||
|
sb
|
||||||
|
} from "./util/sb";
|
||||||
|
|
||||||
/** Compilation target. */
|
/** Compilation target. */
|
||||||
export enum Target {
|
export enum Target {
|
||||||
@ -331,7 +341,6 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
const declaration: VariableLikeDeclarationStatement | null = global.declaration;
|
const declaration: VariableLikeDeclarationStatement | null = global.declaration;
|
||||||
let type: Type | null = null;
|
|
||||||
let initExpr: ExpressionRef = 0;
|
let initExpr: ExpressionRef = 0;
|
||||||
|
|
||||||
if (!global.type) { // infer type
|
if (!global.type) { // infer type
|
||||||
@ -353,7 +362,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
throw new Error("declaration expected");
|
throw new Error("declaration expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
const nativeType: NativeType = typeToNativeType(global.type);
|
const nativeType: NativeType = global.type.toNativeType();
|
||||||
let initializeInStart: bool = false;
|
let initializeInStart: bool = false;
|
||||||
|
|
||||||
if (global.hasConstantValue) {
|
if (global.hasConstantValue) {
|
||||||
@ -386,13 +395,13 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
initializeInStart = true;
|
initializeInStart = true;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
initExpr = typeToNativeZero(this.module, global.type);
|
initExpr = global.type.toNativeZero(this.module);
|
||||||
} else
|
} else
|
||||||
throw new Error("declaration expected");
|
throw new Error("declaration expected");
|
||||||
|
|
||||||
const internalName: string = global.internalName;
|
const internalName: string = global.internalName;
|
||||||
if (initializeInStart) {
|
if (initializeInStart) {
|
||||||
this.module.addGlobal(internalName, nativeType, true, typeToNativeZero(this.module, global.type));
|
this.module.addGlobal(internalName, nativeType, true, global.type.toNativeZero(this.module));
|
||||||
const setExpr: ExpressionRef = this.module.createSetGlobal(internalName, initExpr);
|
const setExpr: ExpressionRef = this.module.createSetGlobal(internalName, initExpr);
|
||||||
if (!this.module.noEmit)
|
if (!this.module.noEmit)
|
||||||
this.startFunctionBody.push(setExpr);
|
this.startFunctionBody.push(setExpr);
|
||||||
@ -547,14 +556,14 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
// create the function type
|
// create the function type
|
||||||
let k: i32 = instance.parameters.length;
|
let k: i32 = instance.parameters.length;
|
||||||
const nativeResultType: NativeType = typeToNativeType(instance.returnType);
|
const nativeResultType: NativeType = instance.returnType.toNativeType();
|
||||||
const nativeParamTypes: NativeType[] = new Array(k);
|
const nativeParamTypes: NativeType[] = new Array(k);
|
||||||
const signatureNameParts: string[] = new Array(k + 1);
|
const signatureNameParts: string[] = new Array(k + 1);
|
||||||
for (let i: i32 = 0; i < k; ++i) {
|
for (let i: i32 = 0; i < k; ++i) {
|
||||||
nativeParamTypes[i] = typeToNativeType(instance.parameters[i].type);
|
nativeParamTypes[i] = instance.parameters[i].type.toNativeType();
|
||||||
signatureNameParts[i] = typeToSignatureNamePart(instance.parameters[i].type);
|
signatureNameParts[i] = instance.parameters[i].type.toSignatureName();
|
||||||
}
|
}
|
||||||
signatureNameParts[k] = typeToSignatureNamePart(instance.returnType);
|
signatureNameParts[k] = instance.returnType.toSignatureName();
|
||||||
let typeRef: FunctionTypeRef = this.module.getFunctionTypeBySignature(nativeResultType, nativeParamTypes);
|
let typeRef: FunctionTypeRef = this.module.getFunctionTypeBySignature(nativeResultType, nativeParamTypes);
|
||||||
if (!typeRef)
|
if (!typeRef)
|
||||||
typeRef = this.module.addFunctionType(signatureNameParts.join(""), nativeResultType, nativeParamTypes);
|
typeRef = this.module.addFunctionType(signatureNameParts.join(""), nativeResultType, nativeParamTypes);
|
||||||
@ -1101,10 +1110,10 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
precomputeExpressionRef(expr: ExpressionRef): ExpressionRef {
|
precomputeExpressionRef(expr: ExpressionRef): ExpressionRef {
|
||||||
const nativeType: NativeType = typeToNativeType(this.currentType);
|
const nativeType: NativeType = this.currentType.toNativeType();
|
||||||
let typeRef: FunctionTypeRef = this.module.getFunctionTypeBySignature(nativeType, []);
|
let typeRef: FunctionTypeRef = this.module.getFunctionTypeBySignature(nativeType, []);
|
||||||
if (!typeRef)
|
if (!typeRef)
|
||||||
typeRef = this.module.addFunctionType(typeToSignatureNamePart(this.currentType), nativeType, []);
|
typeRef = this.module.addFunctionType(this.currentType.toSignatureName(), nativeType, []);
|
||||||
const funcRef: FunctionRef = this.module.addFunction("__precompute", typeRef, [], expr);
|
const funcRef: FunctionRef = this.module.addFunction("__precompute", typeRef, [], expr);
|
||||||
this.module.runPasses([ "precompute" ], funcRef);
|
this.module.runPasses([ "precompute" ], funcRef);
|
||||||
const ret: ExpressionRef = _BinaryenFunctionGetBody(funcRef);
|
const ret: ExpressionRef = _BinaryenFunctionGetBody(funcRef);
|
||||||
@ -1564,7 +1573,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
? this.module.createBinary(BinaryOp.NeF32, condition, this.module.createF32(0))
|
? this.module.createBinary(BinaryOp.NeF32, condition, this.module.createF32(0))
|
||||||
: this.module.createTeeLocal(tempLocal.index, left),
|
: this.module.createTeeLocal(tempLocal.index, left),
|
||||||
right,
|
right,
|
||||||
this.module.createGetLocal(tempLocal.index, typeToNativeType(tempLocal.type))
|
this.module.createGetLocal(tempLocal.index, tempLocal.type.toNativeType())
|
||||||
);
|
);
|
||||||
|
|
||||||
case Token.BAR_BAR: // left || right
|
case Token.BAR_BAR: // left || right
|
||||||
@ -1596,7 +1605,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
: this.currentType == Type.f32
|
: this.currentType == Type.f32
|
||||||
? this.module.createBinary(BinaryOp.NeF32, condition, this.module.createF32(0))
|
? this.module.createBinary(BinaryOp.NeF32, condition, this.module.createF32(0))
|
||||||
: this.module.createTeeLocal(tempLocal.index, left),
|
: this.module.createTeeLocal(tempLocal.index, left),
|
||||||
this.module.createGetLocal(tempLocal.index, typeToNativeType(tempLocal.type)),
|
this.module.createGetLocal(tempLocal.index, tempLocal.type.toNativeType()),
|
||||||
right
|
right
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1665,7 +1674,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return this.module.createUnreachable();
|
return this.module.createUnreachable();
|
||||||
}
|
}
|
||||||
if (tee) {
|
if (tee) {
|
||||||
const globalNativeType: NativeType = typeToNativeType(<Type>(<Global>element).type);
|
const globalNativeType: NativeType = (<Type>(<Global>element).type).toNativeType();
|
||||||
return this.module.createBlock(null, [ // teeGlobal
|
return this.module.createBlock(null, [ // teeGlobal
|
||||||
this.module.createSetGlobal((<Global>element).internalName, valueWithCorrectType),
|
this.module.createSetGlobal((<Global>element).internalName, valueWithCorrectType),
|
||||||
this.module.createGetGlobal((<Global>element).internalName, globalNativeType)
|
this.module.createGetGlobal((<Global>element).internalName, globalNativeType)
|
||||||
@ -1724,7 +1733,6 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
/** Compiles a call to a function. If an instance method, `this` is the first element in `argumentExpressions`. */
|
/** Compiles a call to a function. If an instance method, `this` is the first element in `argumentExpressions`. */
|
||||||
compileCall(functionInstance: Function, argumentExpressions: Expression[], reportNode: Node): ExpressionRef {
|
compileCall(functionInstance: Function, argumentExpressions: Expression[], reportNode: Node): ExpressionRef {
|
||||||
const previousType: Type = this.currentType;
|
|
||||||
|
|
||||||
// validate and compile arguments
|
// validate and compile arguments
|
||||||
const parameters: Parameter[] = functionInstance.parameters;
|
const parameters: Parameter[] = functionInstance.parameters;
|
||||||
@ -1765,10 +1773,10 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
// imported function
|
// imported function
|
||||||
if (functionInstance.isDeclared)
|
if (functionInstance.isDeclared)
|
||||||
return this.module.createCallImport(functionInstance.internalName, operands, typeToNativeType(functionInstance.returnType));
|
return this.module.createCallImport(functionInstance.internalName, operands, functionInstance.returnType.toNativeType());
|
||||||
|
|
||||||
// internal function
|
// internal function
|
||||||
return this.module.createCall(functionInstance.internalName, operands, typeToNativeType(functionInstance.returnType));
|
return this.module.createCall(functionInstance.internalName, operands, functionInstance.returnType.toNativeType());
|
||||||
}
|
}
|
||||||
|
|
||||||
compileElementAccessExpression(expression: ElementAccessExpression, contextualType: Type): ExpressionRef {
|
compileElementAccessExpression(expression: ElementAccessExpression, contextualType: Type): ExpressionRef {
|
||||||
@ -1820,7 +1828,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
// local
|
// local
|
||||||
if (element.kind == ElementKind.LOCAL) {
|
if (element.kind == ElementKind.LOCAL) {
|
||||||
this.currentType = (<Local>element).type;
|
this.currentType = (<Local>element).type;
|
||||||
return this.module.createGetLocal((<Local>element).index, typeToNativeType(this.currentType));
|
return this.module.createGetLocal((<Local>element).index, this.currentType.toNativeType());
|
||||||
}
|
}
|
||||||
|
|
||||||
// global
|
// global
|
||||||
@ -1844,7 +1852,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
else
|
else
|
||||||
throw new Error("unexpected global type");
|
throw new Error("unexpected global type");
|
||||||
} else
|
} else
|
||||||
return this.module.createGetGlobal((<Global>element).internalName, typeToNativeType(this.currentType));
|
return this.module.createGetGlobal((<Global>element).internalName, this.currentType.toNativeType());
|
||||||
}
|
}
|
||||||
|
|
||||||
// field
|
// field
|
||||||
@ -1947,7 +1955,6 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
// look up the property within the target to obtain the actual element
|
// look up the property within the target to obtain the actual element
|
||||||
let element: Element | null;
|
let element: Element | null;
|
||||||
let expr: ExpressionRef;
|
|
||||||
switch (target.kind) {
|
switch (target.kind) {
|
||||||
|
|
||||||
case ElementKind.LOCAL:
|
case ElementKind.LOCAL:
|
||||||
@ -1996,7 +2003,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
switch (element.kind) {
|
switch (element.kind) {
|
||||||
|
|
||||||
case ElementKind.LOCAL:
|
case ElementKind.LOCAL:
|
||||||
return this.module.createGetLocal((<Local>element).index, typeToNativeType(this.currentType = (<Local>element).type));
|
return this.module.createGetLocal((<Local>element).index, (this.currentType = (<Local>element).type).toNativeType());
|
||||||
|
|
||||||
case ElementKind.GLOBAL:
|
case ElementKind.GLOBAL:
|
||||||
if (!this.compileGlobal(<Global>element))
|
if (!this.compileGlobal(<Global>element))
|
||||||
@ -2010,7 +2017,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
: this.currentType.isLongInteger
|
: this.currentType.isLongInteger
|
||||||
? this.module.createI64((<I64>(<Global>element).constantIntegerValue).lo, (<I64>(<Global>element).constantIntegerValue).hi)
|
? this.module.createI64((<I64>(<Global>element).constantIntegerValue).lo, (<I64>(<Global>element).constantIntegerValue).hi)
|
||||||
: this.module.createI32((<I64>(<Global>element).constantIntegerValue).lo);
|
: this.module.createI32((<I64>(<Global>element).constantIntegerValue).lo);
|
||||||
return this.module.createGetGlobal((<Global>element).internalName, typeToNativeType(this.currentType));
|
return this.module.createGetGlobal((<Global>element).internalName, this.currentType.toNativeType());
|
||||||
|
|
||||||
case ElementKind.FUNCTION: // getter
|
case ElementKind.FUNCTION: // getter
|
||||||
if (!(<Function>element).prototype.isGetter) {
|
if (!(<Function>element).prototype.isGetter) {
|
||||||
@ -2157,66 +2164,6 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
|
|
||||||
export function typeToNativeType(type: Type): NativeType {
|
|
||||||
return type.kind == TypeKind.F32
|
|
||||||
? NativeType.F32
|
|
||||||
: type.kind == TypeKind.F64
|
|
||||||
? NativeType.F64
|
|
||||||
: type.isLongInteger
|
|
||||||
? NativeType.I64
|
|
||||||
: type.isAnyInteger || type.kind == TypeKind.BOOL
|
|
||||||
? NativeType.I32
|
|
||||||
: NativeType.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function typesToNativeTypes(types: Type[]): NativeType[] {
|
|
||||||
const k: i32 = types.length;
|
|
||||||
const ret: NativeType[] = new Array(k);
|
|
||||||
for (let i: i32 = 0; i < k; ++i)
|
|
||||||
ret[i] = typeToNativeType(types[i]);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function typeToNativeZero(module: Module, type: Type): ExpressionRef {
|
|
||||||
return type.kind == TypeKind.F32
|
|
||||||
? module.createF32(0)
|
|
||||||
: type.kind == TypeKind.F64
|
|
||||||
? module.createF64(0)
|
|
||||||
: type.isLongInteger
|
|
||||||
? module.createI64(0, 0)
|
|
||||||
: module.createI32(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function typeToNativeOne(module: Module, type: Type): ExpressionRef {
|
|
||||||
return type.kind == TypeKind.F32
|
|
||||||
? module.createF32(1)
|
|
||||||
: type.kind == TypeKind.F64
|
|
||||||
? module.createF64(1)
|
|
||||||
: type.isLongInteger
|
|
||||||
? module.createI64(1, 0)
|
|
||||||
: module.createI32(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function typeToSignatureNamePart(type: Type): string {
|
|
||||||
return type.kind == TypeKind.VOID
|
|
||||||
? "v"
|
|
||||||
: type.kind == TypeKind.F32
|
|
||||||
? "f"
|
|
||||||
: type.kind == TypeKind.F64
|
|
||||||
? "F"
|
|
||||||
: type.isLongInteger
|
|
||||||
? "I"
|
|
||||||
: "i";
|
|
||||||
}
|
|
||||||
|
|
||||||
function typesToSignatureName(paramTypes: Type[], returnType: Type): string {
|
|
||||||
sb.length = 0;
|
|
||||||
for (let i: i32 = 0, k: i32 = paramTypes.length; i < k; ++i)
|
|
||||||
sb.push(typeToSignatureNamePart(paramTypes[i]));
|
|
||||||
sb.push(typeToSignatureNamePart(returnType));
|
|
||||||
return sb.join("");
|
|
||||||
}
|
|
||||||
|
|
||||||
function isModuleExport(element: Element, declaration: DeclarationStatement): bool {
|
function isModuleExport(element: Element, declaration: DeclarationStatement): bool {
|
||||||
if (!element.isExported)
|
if (!element.isExported)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
import {
|
import {
|
||||||
|
|
||||||
Module,
|
Module,
|
||||||
NativeType,
|
NativeType,
|
||||||
ExpressionId,
|
ExpressionId,
|
||||||
UnaryOp,
|
UnaryOp,
|
||||||
BinaryOp,
|
BinaryOp,
|
||||||
HostOp,
|
HostOp,
|
||||||
FunctionTypeRef,
|
|
||||||
FunctionRef,
|
FunctionRef,
|
||||||
ExpressionRef,
|
ExpressionRef,
|
||||||
Index,
|
Index,
|
||||||
|
|
||||||
readString
|
readString
|
||||||
|
|
||||||
} from "./module";
|
} from "./module";
|
||||||
import { I64 } from "./util/i64";
|
|
||||||
|
import {
|
||||||
|
I64
|
||||||
|
} from "./util/i64";
|
||||||
|
|
||||||
// TODO :-)
|
// TODO :-)
|
||||||
|
|
||||||
@ -40,7 +39,7 @@ export class Decompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
decompileFunction(func: FunctionRef): void {
|
decompileFunction(func: FunctionRef): void {
|
||||||
const name: string = readString(_BinaryenFunctionGetName(func)) || "$" + this.functionId.toString(10)
|
const name: string = readString(_BinaryenFunctionGetName(func)) || "$" + this.functionId.toString(10);
|
||||||
const body: ExpressionRef = _BinaryenFunctionGetBody(func);
|
const body: ExpressionRef = _BinaryenFunctionGetBody(func);
|
||||||
this.push("function ");
|
this.push("function ");
|
||||||
this.push(name);
|
this.push(name);
|
||||||
@ -560,7 +559,7 @@ export class Decompiler {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case BinaryOp.RotlI32:
|
case BinaryOp.RotlI32:
|
||||||
this.push("rotl<i32>(")
|
this.push("rotl<i32>(");
|
||||||
this.decompileExpression(_BinaryenBinaryGetLeft(expr));
|
this.decompileExpression(_BinaryenBinaryGetLeft(expr));
|
||||||
this.push(", ");
|
this.push(", ");
|
||||||
this.decompileExpression(_BinaryenBinaryGetRight(expr));
|
this.decompileExpression(_BinaryenBinaryGetRight(expr));
|
||||||
@ -568,7 +567,7 @@ export class Decompiler {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case BinaryOp.RotrI32:
|
case BinaryOp.RotrI32:
|
||||||
this.push("rotr<i32>(")
|
this.push("rotr<i32>(");
|
||||||
this.decompileExpression(_BinaryenBinaryGetLeft(expr));
|
this.decompileExpression(_BinaryenBinaryGetLeft(expr));
|
||||||
this.push(", ");
|
this.push(", ");
|
||||||
this.decompileExpression(_BinaryenBinaryGetRight(expr));
|
this.decompileExpression(_BinaryenBinaryGetRight(expr));
|
||||||
@ -821,7 +820,7 @@ export class Decompiler {
|
|||||||
|
|
||||||
case ExpressionId.AtomicWake:
|
case ExpressionId.AtomicWake:
|
||||||
}
|
}
|
||||||
throw new Error("not implemented: " + id);
|
throw new Error("not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
private push(text: string): void {
|
private push(text: string): void {
|
||||||
|
@ -1,9 +1,25 @@
|
|||||||
import { Range } from "./ast";
|
import {
|
||||||
import { DiagnosticCode, diagnosticCodeToString } from "./diagnosticMessages.generated";
|
Range
|
||||||
import { CharCode, isLineBreak } from "./util/charcode";
|
} from "./ast";
|
||||||
import { sb } from "./util/sb";
|
|
||||||
|
|
||||||
export { DiagnosticCode, diagnosticCodeToString } from "./diagnosticMessages.generated";
|
import {
|
||||||
|
DiagnosticCode,
|
||||||
|
diagnosticCodeToString
|
||||||
|
} from "./diagnosticMessages.generated";
|
||||||
|
|
||||||
|
import {
|
||||||
|
CharCode,
|
||||||
|
isLineBreak
|
||||||
|
} from "./util/charcode";
|
||||||
|
|
||||||
|
import {
|
||||||
|
sb
|
||||||
|
} from "./util/sb";
|
||||||
|
|
||||||
|
export {
|
||||||
|
DiagnosticCode,
|
||||||
|
diagnosticCodeToString
|
||||||
|
} from "./diagnosticMessages.generated";
|
||||||
|
|
||||||
export enum DiagnosticCategory {
|
export enum DiagnosticCategory {
|
||||||
INFO,
|
INFO,
|
||||||
@ -75,8 +91,8 @@ export class DiagnosticMessage {
|
|||||||
|
|
||||||
toString(): string {
|
toString(): string {
|
||||||
if (this.range)
|
if (this.range)
|
||||||
return diagnosticCategoryToString(this.category) + " " + this.code + ": \"" + this.message + "\" in " + this.range.source.path + " @ " + this.range.start + "," + this.range.end;
|
return diagnosticCategoryToString(this.category) + " " + this.code.toString(10) + ": \"" + this.message + "\" in " + this.range.source.path + " @ " + this.range.start.toString(10) + "," + this.range.end.toString(10);
|
||||||
return diagnosticCategoryToString(this.category) + " " + this.code + ": " + this.message;
|
return diagnosticCategoryToString(this.category) + " " + this.code.toString(10) + ": " + this.message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +100,7 @@ export function formatDiagnosticMessage(message: DiagnosticMessage, useColors: b
|
|||||||
// format context first (uses same string builder)
|
// format context first (uses same string builder)
|
||||||
let context: string = "";
|
let context: string = "";
|
||||||
if (message.range && showContext)
|
if (message.range && showContext)
|
||||||
context = formatDiagnosticContext(message.range, useColors)
|
context = formatDiagnosticContext(message.range, useColors);
|
||||||
|
|
||||||
// general information
|
// general information
|
||||||
sb.length = 0;
|
sb.length = 0;
|
||||||
|
33
src/index.ts
33
src/index.ts
@ -22,12 +22,33 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Module } from "./module";
|
import {
|
||||||
import { Compiler, Options, Target } from "./compiler";
|
Module
|
||||||
import { DiagnosticMessage, DiagnosticCategory, formatDiagnosticMessage } from "./diagnostics";
|
} from "./module";
|
||||||
import { Parser } from "./parser";
|
|
||||||
import { Program } from "./program";
|
import {
|
||||||
import { Decompiler } from "./decompiler";
|
Compiler,
|
||||||
|
Options,
|
||||||
|
Target
|
||||||
|
} from "./compiler";
|
||||||
|
|
||||||
|
import {
|
||||||
|
DiagnosticMessage,
|
||||||
|
DiagnosticCategory,
|
||||||
|
formatDiagnosticMessage
|
||||||
|
} from "./diagnostics";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Parser
|
||||||
|
} from "./parser";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Program
|
||||||
|
} from "./program";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Decompiler
|
||||||
|
} from "./decompiler";
|
||||||
|
|
||||||
/** Parses a single source file. If `parser` has been omitted a new one is created. */
|
/** Parses a single source file. If `parser` has been omitted a new one is created. */
|
||||||
export function parseFile(text: string, path: string, parser: Parser | null = null, isEntry: bool = false): Parser {
|
export function parseFile(text: string, path: string, parser: Parser | null = null, isEntry: bool = false): Parser {
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
import { Target } from "./compiler";
|
import {
|
||||||
import { I64, U64 } from "./util/i64";
|
Target
|
||||||
|
} from "./compiler";
|
||||||
|
|
||||||
|
import {
|
||||||
|
U64
|
||||||
|
} from "./util/i64";
|
||||||
|
|
||||||
export type ModuleRef = usize;
|
export type ModuleRef = usize;
|
||||||
export type FunctionTypeRef = usize;
|
export type FunctionTypeRef = usize;
|
||||||
@ -917,7 +922,7 @@ function allocU8Array(u8s: Uint8Array | null): usize {
|
|||||||
const ptr: usize = Heap.allocate((<Uint8Array>u8s).length);
|
const ptr: usize = Heap.allocate((<Uint8Array>u8s).length);
|
||||||
let idx: usize = ptr;
|
let idx: usize = ptr;
|
||||||
for (let i: i32 = 0, k: i32 = (<Uint8Array>u8s).length; i < k; ++i)
|
for (let i: i32 = 0, k: i32 = (<Uint8Array>u8s).length; i < k; ++i)
|
||||||
store<u8>(idx++, (<Uint8Array>u8s)[i])
|
store<u8>(idx++, (<Uint8Array>u8s)[i]);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,27 +7,36 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Program } from "./program";
|
|
||||||
import { Tokenizer, Token, Range } from "./tokenizer";
|
|
||||||
import { DiagnosticCode, DiagnosticEmitter } from "./diagnostics";
|
|
||||||
import { I64 } from "./util/i64";
|
|
||||||
import { normalize as normalizePath } from "./util/path";
|
|
||||||
import {
|
import {
|
||||||
|
Program
|
||||||
|
} from "./program";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Tokenizer,
|
||||||
|
Token,
|
||||||
|
Range
|
||||||
|
} from "./tokenizer";
|
||||||
|
|
||||||
|
import {
|
||||||
|
DiagnosticCode,
|
||||||
|
DiagnosticEmitter
|
||||||
|
} from "./diagnostics";
|
||||||
|
|
||||||
|
import {
|
||||||
|
normalize as normalizePath
|
||||||
|
} from "./util/path";
|
||||||
|
|
||||||
|
import {
|
||||||
Node,
|
Node,
|
||||||
NodeKind,
|
NodeKind,
|
||||||
Source,
|
Source,
|
||||||
|
|
||||||
// types
|
|
||||||
TypeNode,
|
TypeNode,
|
||||||
|
|
||||||
// expressions
|
// expressions
|
||||||
AssertionKind,
|
AssertionKind,
|
||||||
CallExpression,
|
CallExpression,
|
||||||
Expression,
|
Expression,
|
||||||
IdentifierExpression,
|
IdentifierExpression,
|
||||||
StringLiteralExpression,
|
StringLiteralExpression,
|
||||||
|
|
||||||
// statements
|
// statements
|
||||||
BlockStatement,
|
BlockStatement,
|
||||||
BreakStatement,
|
BreakStatement,
|
||||||
@ -64,12 +73,11 @@ import {
|
|||||||
VariableStatement,
|
VariableStatement,
|
||||||
VariableDeclaration,
|
VariableDeclaration,
|
||||||
WhileStatement,
|
WhileStatement,
|
||||||
|
// utility
|
||||||
addModifier,
|
addModifier,
|
||||||
getModifier,
|
getModifier,
|
||||||
hasModifier,
|
hasModifier,
|
||||||
setReusableModifiers
|
setReusableModifiers
|
||||||
|
|
||||||
} from "./ast";
|
} from "./ast";
|
||||||
|
|
||||||
/** Parser interface. */
|
/** Parser interface. */
|
||||||
@ -1402,7 +1410,7 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
|
|
||||||
let p: Precedence = determinePrecedenceStart(token);
|
let p: Precedence = determinePrecedenceStart(token);
|
||||||
if (p != Precedence.INVALID) {
|
if (p != Precedence.INVALID) {
|
||||||
let operand: Expression | null
|
let operand: Expression | null;
|
||||||
|
|
||||||
// TODO: SpreadExpression, YieldExpression (currently become unsupported UnaryPrefixExpressions)
|
// TODO: SpreadExpression, YieldExpression (currently become unsupported UnaryPrefixExpressions)
|
||||||
|
|
||||||
|
@ -1,29 +1,49 @@
|
|||||||
import { initialize as initializeBuiltins } from "./builtins";
|
|
||||||
import { Target, typeToNativeType } from "./compiler";
|
|
||||||
import { GETTER_PREFIX, SETTER_PREFIX, PATH_DELIMITER } from "./constants";
|
|
||||||
import { DiagnosticCode, DiagnosticMessage, DiagnosticEmitter } from "./diagnostics";
|
|
||||||
import { Type, typesToString } from "./types";
|
|
||||||
import { I64 } from "./util/i64";
|
|
||||||
import {
|
import {
|
||||||
|
initialize as initializeBuiltins
|
||||||
|
} from "./builtins";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Target
|
||||||
|
} from "./compiler";
|
||||||
|
|
||||||
|
import {
|
||||||
|
PATH_DELIMITER
|
||||||
|
} from "./constants";
|
||||||
|
|
||||||
|
import {
|
||||||
|
DiagnosticCode,
|
||||||
|
DiagnosticMessage,
|
||||||
|
DiagnosticEmitter
|
||||||
|
} from "./diagnostics";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Type,
|
||||||
|
typesToString
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
|
import {
|
||||||
|
I64
|
||||||
|
} from "./util/i64";
|
||||||
|
|
||||||
|
import {
|
||||||
ModifierKind,
|
ModifierKind,
|
||||||
Node,
|
Node,
|
||||||
NodeKind,
|
NodeKind,
|
||||||
Source,
|
Source,
|
||||||
Range,
|
Range,
|
||||||
|
|
||||||
TypeNode,
|
TypeNode,
|
||||||
|
TypeParameter,
|
||||||
|
Decorator,
|
||||||
|
|
||||||
Expression,
|
Expression,
|
||||||
IdentifierExpression,
|
IdentifierExpression,
|
||||||
LiteralExpression,
|
|
||||||
LiteralKind,
|
|
||||||
PropertyAccessExpression,
|
PropertyAccessExpression,
|
||||||
StringLiteralExpression,
|
StringLiteralExpression,
|
||||||
CallExpression,
|
CallExpression,
|
||||||
|
|
||||||
|
Statement,
|
||||||
ClassDeclaration,
|
ClassDeclaration,
|
||||||
DeclarationStatement,
|
DeclarationStatement,
|
||||||
Decorator,
|
|
||||||
EnumDeclaration,
|
EnumDeclaration,
|
||||||
EnumValueDeclaration,
|
EnumValueDeclaration,
|
||||||
ExportMember,
|
ExportMember,
|
||||||
@ -34,20 +54,18 @@ import {
|
|||||||
ImportStatement,
|
ImportStatement,
|
||||||
InterfaceDeclaration,
|
InterfaceDeclaration,
|
||||||
MethodDeclaration,
|
MethodDeclaration,
|
||||||
Modifier,
|
|
||||||
NamespaceDeclaration,
|
NamespaceDeclaration,
|
||||||
Statement,
|
|
||||||
TypeDeclaration,
|
TypeDeclaration,
|
||||||
TypeParameter,
|
|
||||||
VariableLikeDeclarationStatement,
|
VariableLikeDeclarationStatement,
|
||||||
VariableDeclaration,
|
VariableDeclaration,
|
||||||
VariableStatement,
|
VariableStatement,
|
||||||
|
|
||||||
hasModifier,
|
hasModifier
|
||||||
mangleInternalName
|
|
||||||
|
|
||||||
} from "./ast";
|
} from "./ast";
|
||||||
import { NativeType } from "./module";
|
|
||||||
|
import {
|
||||||
|
NativeType
|
||||||
|
} from "./module";
|
||||||
|
|
||||||
class QueuedExport {
|
class QueuedExport {
|
||||||
isReExport: bool;
|
isReExport: bool;
|
||||||
@ -845,7 +863,7 @@ export class Program extends DiagnosticEmitter {
|
|||||||
return this.resolveElement((<CallExpression>expression).expression, contextualFunction);
|
return this.resolveElement((<CallExpression>expression).expression, contextualFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error("not implemented: " + expression.kind);
|
throw new Error("not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1229,9 +1247,9 @@ export class FunctionPrototype extends Element {
|
|||||||
k = declaration.parameters.length;
|
k = declaration.parameters.length;
|
||||||
const parameters: Parameter[] = new Array(k);
|
const parameters: Parameter[] = new Array(k);
|
||||||
const parameterTypes: Type[] = new Array(k);
|
const parameterTypes: Type[] = new Array(k);
|
||||||
for (let i = 0; i < k; ++i) {
|
let typeNode: TypeNode | null ;
|
||||||
const typeNode: TypeNode | null = declaration.parameters[i].type;
|
for (i = 0; i < k; ++i) {
|
||||||
if (typeNode) {
|
if (typeNode = declaration.parameters[i].type) {
|
||||||
const type: Type | null = this.program.resolveType(<TypeNode>typeNode, contextualTypeArguments, true); // reports
|
const type: Type | null = this.program.resolveType(<TypeNode>typeNode, contextualTypeArguments, true); // reports
|
||||||
if (type) {
|
if (type) {
|
||||||
parameters[i] = new Parameter(declaration.parameters[i].name.name, type);
|
parameters[i] = new Parameter(declaration.parameters[i].name.name, type);
|
||||||
@ -1243,9 +1261,8 @@ export class FunctionPrototype extends Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// resolve return type
|
// resolve return type
|
||||||
const typeNode: TypeNode | null = declaration.returnType;
|
|
||||||
let returnType: Type;
|
let returnType: Type;
|
||||||
if (typeNode) {
|
if (typeNode = declaration.returnType) {
|
||||||
const type: Type | null = this.program.resolveType(<TypeNode>typeNode, contextualTypeArguments, true); // reports
|
const type: Type | null = this.program.resolveType(<TypeNode>typeNode, contextualTypeArguments, true); // reports
|
||||||
if (type)
|
if (type)
|
||||||
returnType = <Type>type;
|
returnType = <Type>type;
|
||||||
@ -1265,7 +1282,7 @@ export class FunctionPrototype extends Element {
|
|||||||
resolveInclTypeArguments(typeArgumentNodes: TypeNode[] | null, contextualTypeArguments: Map<string,Type> | null, alternativeReportNode: Node | null): Function | null {
|
resolveInclTypeArguments(typeArgumentNodes: TypeNode[] | null, contextualTypeArguments: Map<string,Type> | null, alternativeReportNode: Node | null): Function | null {
|
||||||
let resolvedTypeArguments: Type[] | null;
|
let resolvedTypeArguments: Type[] | null;
|
||||||
if (this.isGeneric) {
|
if (this.isGeneric) {
|
||||||
assert(typeArgumentNodes != null && typeArgumentNodes.length != 0, "" + this);
|
assert(typeArgumentNodes != null && typeArgumentNodes.length != 0);
|
||||||
if (!this.declaration)
|
if (!this.declaration)
|
||||||
throw new Error("missing declaration");
|
throw new Error("missing declaration");
|
||||||
resolvedTypeArguments = this.program.resolveTypeArguments(this.declaration.typeParameters, typeArgumentNodes, contextualTypeArguments, alternativeReportNode);
|
resolvedTypeArguments = this.program.resolveTypeArguments(this.declaration.typeParameters, typeArgumentNodes, contextualTypeArguments, alternativeReportNode);
|
||||||
@ -1357,7 +1374,7 @@ export class Function extends Element {
|
|||||||
/** Gets a free temporary local of the specified type. */
|
/** Gets a free temporary local of the specified type. */
|
||||||
getTempLocal(type: Type): Local {
|
getTempLocal(type: Type): Local {
|
||||||
let temps: Local[] | null;
|
let temps: Local[] | null;
|
||||||
switch (typeToNativeType(type)) {
|
switch (type.toNativeType()) {
|
||||||
case NativeType.I32: temps = this.tempI32s; break;
|
case NativeType.I32: temps = this.tempI32s; break;
|
||||||
case NativeType.I64: temps = this.tempI64s; break;
|
case NativeType.I64: temps = this.tempI64s; break;
|
||||||
case NativeType.F32: temps = this.tempF32s; break;
|
case NativeType.F32: temps = this.tempF32s; break;
|
||||||
@ -1372,7 +1389,7 @@ export class Function extends Element {
|
|||||||
/** Frees the temporary local for reuse. */
|
/** Frees the temporary local for reuse. */
|
||||||
freeTempLocal(local: Local): void {
|
freeTempLocal(local: Local): void {
|
||||||
let temps: Local[];
|
let temps: Local[];
|
||||||
switch (typeToNativeType(local.type)) {
|
switch (local.type.toNativeType()) {
|
||||||
case NativeType.I32: temps = this.tempI32s || (this.tempI32s = []); break;
|
case NativeType.I32: temps = this.tempI32s || (this.tempI32s = []); break;
|
||||||
case NativeType.I64: temps = this.tempI64s || (this.tempI64s = []); break;
|
case NativeType.I64: temps = this.tempI64s || (this.tempI64s = []); break;
|
||||||
case NativeType.F32: temps = this.tempF32s || (this.tempF32s = []); break;
|
case NativeType.F32: temps = this.tempF32s || (this.tempF32s = []); break;
|
||||||
@ -1385,7 +1402,7 @@ export class Function extends Element {
|
|||||||
/** Gets and immediately frees a temporary local of the specified type. */
|
/** Gets and immediately frees a temporary local of the specified type. */
|
||||||
getAndFreeTempLocal(type: Type): Local {
|
getAndFreeTempLocal(type: Type): Local {
|
||||||
let temps: Local[];
|
let temps: Local[];
|
||||||
switch (typeToNativeType(type)) {
|
switch (type.toNativeType()) {
|
||||||
case NativeType.I32: temps = this.tempI32s || (this.tempI32s = []); break;
|
case NativeType.I32: temps = this.tempI32s || (this.tempI32s = []); break;
|
||||||
case NativeType.I64: temps = this.tempI64s || (this.tempI64s = []); break;
|
case NativeType.I64: temps = this.tempI64s || (this.tempI64s = []); break;
|
||||||
case NativeType.F32: temps = this.tempF32s || (this.tempF32s = []); break;
|
case NativeType.F32: temps = this.tempF32s || (this.tempF32s = []); break;
|
||||||
@ -1416,7 +1433,7 @@ export class Function extends Element {
|
|||||||
assert(length > 0);
|
assert(length > 0);
|
||||||
(<i32[]>this.breakStack).pop();
|
(<i32[]>this.breakStack).pop();
|
||||||
if (length > 1) {
|
if (length > 1) {
|
||||||
this.breakContext = (<i32[]>this.breakStack)[length - 2].toString(10)
|
this.breakContext = (<i32[]>this.breakStack)[length - 2].toString(10);
|
||||||
} else {
|
} else {
|
||||||
this.breakContext = null;
|
this.breakContext = null;
|
||||||
this.breakStack = null;
|
this.breakStack = null;
|
||||||
@ -1461,7 +1478,7 @@ export class FieldPrototype extends Element {
|
|||||||
case ModifierKind.PROTECTED:
|
case ModifierKind.PROTECTED:
|
||||||
case ModifierKind.PUBLIC:
|
case ModifierKind.PUBLIC:
|
||||||
case ModifierKind.STATIC: break; // already handled
|
case ModifierKind.STATIC: break; // already handled
|
||||||
default: throw new Error("unexpected modifier: " + this.declaration.modifiers[i]);
|
default: assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
307
src/tokenizer.ts
307
src/tokenizer.ts
@ -19,10 +19,30 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { DiagnosticCode, DiagnosticMessage, DiagnosticEmitter, formatDiagnosticMessage } from "./diagnostics";
|
import {
|
||||||
import { Source } from "./ast";
|
DiagnosticCode,
|
||||||
import { CharCode, isLineBreak, isWhiteSpace, isIdentifierStart, isIdentifierPart, isDecimalDigit, isOctalDigit, isKeywordCharacter } from "./util/charcode";
|
DiagnosticMessage,
|
||||||
import { I64 } from "./util/i64";
|
DiagnosticEmitter
|
||||||
|
} from "./diagnostics";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Source
|
||||||
|
} from "./ast";
|
||||||
|
|
||||||
|
import {
|
||||||
|
CharCode,
|
||||||
|
isLineBreak,
|
||||||
|
isWhiteSpace,
|
||||||
|
isIdentifierStart,
|
||||||
|
isIdentifierPart,
|
||||||
|
isDecimalDigit,
|
||||||
|
isOctalDigit,
|
||||||
|
isKeywordCharacter
|
||||||
|
} from "./util/charcode";
|
||||||
|
|
||||||
|
import {
|
||||||
|
I64
|
||||||
|
} from "./util/i64";
|
||||||
|
|
||||||
/** Named token types. */
|
/** Named token types. */
|
||||||
export enum Token {
|
export enum Token {
|
||||||
@ -162,145 +182,148 @@ export enum Token {
|
|||||||
ENDOFFILE
|
ENDOFFILE
|
||||||
}
|
}
|
||||||
|
|
||||||
function textToKeywordToken(text: string): Token {
|
export namespace Token {
|
||||||
switch (text) {
|
|
||||||
case "abstract": return Token.ABSTRACT;
|
|
||||||
case "as": return Token.AS;
|
|
||||||
case "async": return Token.ASYNC;
|
|
||||||
case "await": return Token.AWAIT;
|
|
||||||
case "break": return Token.BREAK;
|
|
||||||
case "case": return Token.CASE;
|
|
||||||
case "catch": return Token.CATCH;
|
|
||||||
case "class": return Token.CLASS;
|
|
||||||
case "continue": return Token.CONTINUE;
|
|
||||||
case "const": return Token.CONST;
|
|
||||||
case "constructor": return Token.CONSTRUCTOR;
|
|
||||||
case "debugger": return Token.DEBUGGER;
|
|
||||||
case "declare": return Token.DECLARE;
|
|
||||||
case "default": return Token.DEFAULT;
|
|
||||||
case "delete": return Token.DELETE;
|
|
||||||
case "do": return Token.DO;
|
|
||||||
case "else": return Token.ELSE;
|
|
||||||
case "enum": return Token.ENUM;
|
|
||||||
case "export": return Token.EXPORT;
|
|
||||||
case "extends": return Token.EXTENDS;
|
|
||||||
case "false": return Token.FALSE;
|
|
||||||
case "finally": return Token.FINALLY;
|
|
||||||
case "for": return Token.FOR;
|
|
||||||
case "from": return Token.FROM;
|
|
||||||
case "function": return Token.FUNCTION;
|
|
||||||
case "get": return Token.GET;
|
|
||||||
case "if": return Token.IF;
|
|
||||||
case "implements": return Token.IMPLEMENTS;
|
|
||||||
case "import": return Token.IMPORT;
|
|
||||||
case "in": return Token.IN;
|
|
||||||
case "instanceof": return Token.INSTANCEOF;
|
|
||||||
case "interface": return Token.INTERFACE;
|
|
||||||
case "is": return Token.IS;
|
|
||||||
case "keyof": return Token.KEYOF;
|
|
||||||
case "let": return Token.LET;
|
|
||||||
case "module": return Token.MODULE;
|
|
||||||
case "namespace": return Token.NAMESPACE;
|
|
||||||
case "new": return Token.NEW;
|
|
||||||
case "null": return Token.NULL;
|
|
||||||
case "of": return Token.OF;
|
|
||||||
case "package": return Token.PACKAGE;
|
|
||||||
case "private": return Token.PRIVATE;
|
|
||||||
case "protected": return Token.PROTECTED;
|
|
||||||
case "public": return Token.PUBLIC;
|
|
||||||
case "readonly": return Token.READONLY;
|
|
||||||
case "return": return Token.RETURN;
|
|
||||||
case "set": return Token.SET;
|
|
||||||
case "static": return Token.STATIC;
|
|
||||||
case "super": return Token.SUPER;
|
|
||||||
case "switch": return Token.SWITCH;
|
|
||||||
case "this": return Token.THIS;
|
|
||||||
case "throw": return Token.THROW;
|
|
||||||
case "true": return Token.TRUE;
|
|
||||||
case "try": return Token.TRY;
|
|
||||||
case "type": return Token.TYPE;
|
|
||||||
case "typeof": return Token.TYPEOF;
|
|
||||||
case "var": return Token.VAR;
|
|
||||||
case "void": return Token.VOID;
|
|
||||||
case "while": return Token.WHILE;
|
|
||||||
case "with": return Token.WITH;
|
|
||||||
case "yield": return Token.YIELD;
|
|
||||||
default: return Token.INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function operatorTokenToString(token: Token): string {
|
export function fromKeyword(text: string): Token {
|
||||||
switch (token) {
|
switch (text) {
|
||||||
case Token.DELETE: return "delete";
|
case "abstract": return Token.ABSTRACT;
|
||||||
case Token.IN: return "in";
|
case "as": return Token.AS;
|
||||||
case Token.INSTANCEOF: return "instanceof";
|
case "async": return Token.ASYNC;
|
||||||
case Token.NEW: return "new";
|
case "await": return Token.AWAIT;
|
||||||
case Token.TYPEOF: return "typeof";
|
case "break": return Token.BREAK;
|
||||||
case Token.VOID: return "void";
|
case "case": return Token.CASE;
|
||||||
case Token.YIELD: return "yield";
|
case "catch": return Token.CATCH;
|
||||||
case Token.DOT_DOT_DOT: return "...";
|
case "class": return Token.CLASS;
|
||||||
case Token.COMMA: return ",";
|
case "continue": return Token.CONTINUE;
|
||||||
case Token.LESSTHAN: return "<";
|
case "const": return Token.CONST;
|
||||||
case Token.GREATERTHAN: return ">";
|
case "constructor": return Token.CONSTRUCTOR;
|
||||||
case Token.LESSTHAN_EQUALS: return "<=";
|
case "debugger": return Token.DEBUGGER;
|
||||||
case Token.GREATERTHAN_EQUALS: return ">=";
|
case "declare": return Token.DECLARE;
|
||||||
case Token.EQUALS_EQUALS: return "==";
|
case "default": return Token.DEFAULT;
|
||||||
case Token.EXCLAMATION_EQUALS: return "!=";
|
case "delete": return Token.DELETE;
|
||||||
case Token.EQUALS_EQUALS_EQUALS: return "===";
|
case "do": return Token.DO;
|
||||||
case Token.EXCLAMATION_EQUALS_EQUALS: return "!==";
|
case "else": return Token.ELSE;
|
||||||
case Token.PLUS: return "+";
|
case "enum": return Token.ENUM;
|
||||||
case Token.MINUS: return "-";
|
case "export": return Token.EXPORT;
|
||||||
case Token.ASTERISK_ASTERISK: return "**";
|
case "extends": return Token.EXTENDS;
|
||||||
case Token.ASTERISK: return "*";
|
case "false": return Token.FALSE;
|
||||||
case Token.SLASH: return "/";
|
case "finally": return Token.FINALLY;
|
||||||
case Token.PERCENT: return "%";
|
case "for": return Token.FOR;
|
||||||
case Token.PLUS_PLUS: return "++";
|
case "from": return Token.FROM;
|
||||||
case Token.MINUS_MINUS: return "--";
|
case "function": return Token.FUNCTION;
|
||||||
case Token.LESSTHAN_LESSTHAN: return "<<";
|
case "get": return Token.GET;
|
||||||
case Token.GREATERTHAN_GREATERTHAN: return ">>";
|
case "if": return Token.IF;
|
||||||
case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN: return ">>>";
|
case "implements": return Token.IMPLEMENTS;
|
||||||
case Token.AMPERSAND: return "&";
|
case "import": return Token.IMPORT;
|
||||||
case Token.BAR: return "|";
|
case "in": return Token.IN;
|
||||||
case Token.CARET: return "^";
|
case "instanceof": return Token.INSTANCEOF;
|
||||||
case Token.EXCLAMATION: return "!";
|
case "interface": return Token.INTERFACE;
|
||||||
case Token.TILDE: return "~";
|
case "is": return Token.IS;
|
||||||
case Token.AMPERSAND_AMPERSAND: return "&&";
|
case "keyof": return Token.KEYOF;
|
||||||
case Token.BAR_BAR: return "||";
|
case "let": return Token.LET;
|
||||||
case Token.EQUALS: return "=";
|
case "module": return Token.MODULE;
|
||||||
case Token.PLUS_EQUALS: return "+=";
|
case "namespace": return Token.NAMESPACE;
|
||||||
case Token.MINUS_EQUALS: return "-=";
|
case "new": return Token.NEW;
|
||||||
case Token.ASTERISK_EQUALS: return "*=";
|
case "null": return Token.NULL;
|
||||||
case Token.ASTERISK_ASTERISK_EQUALS: return "**=";
|
case "of": return Token.OF;
|
||||||
case Token.SLASH_EQUALS: return "/=";
|
case "package": return Token.PACKAGE;
|
||||||
case Token.PERCENT_EQUALS: return "%=";
|
case "private": return Token.PRIVATE;
|
||||||
case Token.LESSTHAN_LESSTHAN_EQUALS: return "<<=";
|
case "protected": return Token.PROTECTED;
|
||||||
case Token.GREATERTHAN_GREATERTHAN_EQUALS: return ">>=";
|
case "public": return Token.PUBLIC;
|
||||||
case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN_EQUALS: return ">>>=";
|
case "readonly": return Token.READONLY;
|
||||||
case Token.AMPERSAND_EQUALS: return "&=";
|
case "return": return Token.RETURN;
|
||||||
case Token.BAR_EQUALS: return "|=";
|
case "set": return Token.SET;
|
||||||
case Token.CARET_EQUALS: return "^=";
|
case "static": return Token.STATIC;
|
||||||
default: assert(false); return "";
|
case "super": return Token.SUPER;
|
||||||
|
case "switch": return Token.SWITCH;
|
||||||
|
case "this": return Token.THIS;
|
||||||
|
case "throw": return Token.THROW;
|
||||||
|
case "true": return Token.TRUE;
|
||||||
|
case "try": return Token.TRY;
|
||||||
|
case "type": return Token.TYPE;
|
||||||
|
case "typeof": return Token.TYPEOF;
|
||||||
|
case "var": return Token.VAR;
|
||||||
|
case "void": return Token.VOID;
|
||||||
|
case "while": return Token.WHILE;
|
||||||
|
case "with": return Token.WITH;
|
||||||
|
case "yield": return Token.YIELD;
|
||||||
|
default: return Token.INVALID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function isPossibleIdentifier(token: Token): bool {
|
export function operatorToString(token: Token): string {
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case Token.ABSTRACT:
|
case Token.DELETE: return "delete";
|
||||||
case Token.AS:
|
case Token.IN: return "in";
|
||||||
case Token.CONSTRUCTOR:
|
case Token.INSTANCEOF: return "instanceof";
|
||||||
case Token.DECLARE:
|
case Token.NEW: return "new";
|
||||||
case Token.FROM:
|
case Token.TYPEOF: return "typeof";
|
||||||
case Token.GET:
|
case Token.VOID: return "void";
|
||||||
case Token.IS:
|
case Token.YIELD: return "yield";
|
||||||
case Token.KEYOF:
|
case Token.DOT_DOT_DOT: return "...";
|
||||||
case Token.MODULE:
|
case Token.COMMA: return ",";
|
||||||
case Token.NAMESPACE:
|
case Token.LESSTHAN: return "<";
|
||||||
case Token.READONLY:
|
case Token.GREATERTHAN: return ">";
|
||||||
case Token.SET:
|
case Token.LESSTHAN_EQUALS: return "<=";
|
||||||
case Token.TYPE:
|
case Token.GREATERTHAN_EQUALS: return ">=";
|
||||||
return true;
|
case Token.EQUALS_EQUALS: return "==";
|
||||||
default:
|
case Token.EXCLAMATION_EQUALS: return "!=";
|
||||||
return false;
|
case Token.EQUALS_EQUALS_EQUALS: return "===";
|
||||||
|
case Token.EXCLAMATION_EQUALS_EQUALS: return "!==";
|
||||||
|
case Token.PLUS: return "+";
|
||||||
|
case Token.MINUS: return "-";
|
||||||
|
case Token.ASTERISK_ASTERISK: return "**";
|
||||||
|
case Token.ASTERISK: return "*";
|
||||||
|
case Token.SLASH: return "/";
|
||||||
|
case Token.PERCENT: return "%";
|
||||||
|
case Token.PLUS_PLUS: return "++";
|
||||||
|
case Token.MINUS_MINUS: return "--";
|
||||||
|
case Token.LESSTHAN_LESSTHAN: return "<<";
|
||||||
|
case Token.GREATERTHAN_GREATERTHAN: return ">>";
|
||||||
|
case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN: return ">>>";
|
||||||
|
case Token.AMPERSAND: return "&";
|
||||||
|
case Token.BAR: return "|";
|
||||||
|
case Token.CARET: return "^";
|
||||||
|
case Token.EXCLAMATION: return "!";
|
||||||
|
case Token.TILDE: return "~";
|
||||||
|
case Token.AMPERSAND_AMPERSAND: return "&&";
|
||||||
|
case Token.BAR_BAR: return "||";
|
||||||
|
case Token.EQUALS: return "=";
|
||||||
|
case Token.PLUS_EQUALS: return "+=";
|
||||||
|
case Token.MINUS_EQUALS: return "-=";
|
||||||
|
case Token.ASTERISK_EQUALS: return "*=";
|
||||||
|
case Token.ASTERISK_ASTERISK_EQUALS: return "**=";
|
||||||
|
case Token.SLASH_EQUALS: return "/=";
|
||||||
|
case Token.PERCENT_EQUALS: return "%=";
|
||||||
|
case Token.LESSTHAN_LESSTHAN_EQUALS: return "<<=";
|
||||||
|
case Token.GREATERTHAN_GREATERTHAN_EQUALS: return ">>=";
|
||||||
|
case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN_EQUALS: return ">>>=";
|
||||||
|
case Token.AMPERSAND_EQUALS: return "&=";
|
||||||
|
case Token.BAR_EQUALS: return "|=";
|
||||||
|
case Token.CARET_EQUALS: return "^=";
|
||||||
|
default: assert(false); return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isAlsoIdentifier(token: Token): bool {
|
||||||
|
switch (token) {
|
||||||
|
case Token.ABSTRACT:
|
||||||
|
case Token.AS:
|
||||||
|
case Token.CONSTRUCTOR:
|
||||||
|
case Token.DECLARE:
|
||||||
|
case Token.FROM:
|
||||||
|
case Token.GET:
|
||||||
|
case Token.IS:
|
||||||
|
case Token.KEYOF:
|
||||||
|
case Token.MODULE:
|
||||||
|
case Token.NAMESPACE:
|
||||||
|
case Token.READONLY:
|
||||||
|
case Token.SET:
|
||||||
|
case Token.TYPE:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,8 +698,8 @@ export class Tokenizer extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const keywordText: string = text.substring(posBefore, this.pos);
|
const keywordText: string = text.substring(posBefore, this.pos);
|
||||||
const keywordToken: Token = textToKeywordToken(keywordText);
|
const keywordToken: Token = Token.fromKeyword(keywordText);
|
||||||
if (keywordToken != Token.INVALID && !(preferIdentifier && isPossibleIdentifier(keywordToken)))
|
if (keywordToken != Token.INVALID && !(preferIdentifier && Token.isAlsoIdentifier(keywordToken)))
|
||||||
return keywordToken;
|
return keywordToken;
|
||||||
this.pos = posBefore;
|
this.pos = posBefore;
|
||||||
}
|
}
|
||||||
|
65
src/types.ts
65
src/types.ts
@ -1,5 +1,15 @@
|
|||||||
import { Class, Function } from "./program";
|
import {
|
||||||
import { sb } from "./util/sb";
|
Class,
|
||||||
|
Function
|
||||||
|
} from "./program";
|
||||||
|
|
||||||
|
import {
|
||||||
|
sb
|
||||||
|
} from "./util/sb";
|
||||||
|
|
||||||
|
import {
|
||||||
|
NativeType, ExpressionRef, Module
|
||||||
|
} from "./module";
|
||||||
|
|
||||||
/** Indicates the kind of a type. */
|
/** Indicates the kind of a type. */
|
||||||
export const enum TypeKind {
|
export const enum TypeKind {
|
||||||
@ -123,6 +133,48 @@ export class Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Binaryen specific
|
||||||
|
|
||||||
|
/** Converts this type to its respective native type. */
|
||||||
|
toNativeType(): NativeType {
|
||||||
|
return this.kind == TypeKind.F32
|
||||||
|
? NativeType.F32
|
||||||
|
: this.kind == TypeKind.F64
|
||||||
|
? NativeType.F64
|
||||||
|
: this.isLongInteger
|
||||||
|
? NativeType.I64
|
||||||
|
: this.isAnyInteger || this.kind == TypeKind.BOOL
|
||||||
|
? NativeType.I32
|
||||||
|
: NativeType.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Converts this type to its native `0` value. */
|
||||||
|
toNativeZero(module: Module): ExpressionRef {
|
||||||
|
return this.kind == TypeKind.F32 ? module.createF32(0)
|
||||||
|
: this.kind == TypeKind.F64 ? module.createF64(0)
|
||||||
|
: this.isLongInteger ? module.createI64(0, 0)
|
||||||
|
: module.createI32(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Converts this type to its native `1` value. */
|
||||||
|
toNativeOne(module: Module): ExpressionRef {
|
||||||
|
return this.kind == TypeKind.F32 ? module.createF32(1)
|
||||||
|
: this.kind == TypeKind.F64 ? module.createF64(1)
|
||||||
|
: this.isLongInteger ? module.createI64(1, 0)
|
||||||
|
: module.createI32(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Converts this type to its signature name. */
|
||||||
|
toSignatureName(): string {
|
||||||
|
return this.kind == TypeKind.VOID ? "v"
|
||||||
|
: this.kind == TypeKind.F32 ? "f"
|
||||||
|
: this.kind == TypeKind.F64 ? "F"
|
||||||
|
: this.isLongInteger ? "I"
|
||||||
|
: "i";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Types
|
||||||
|
|
||||||
/** An 8-bit signed integer. */
|
/** An 8-bit signed integer. */
|
||||||
static readonly i8: Type = new Type(TypeKind.I8, 8);
|
static readonly i8: Type = new Type(TypeKind.I8, 8);
|
||||||
/** A 16-bit signed integer. */
|
/** A 16-bit signed integer. */
|
||||||
@ -157,6 +209,15 @@ export class Type {
|
|||||||
static readonly void: Type = new Type(TypeKind.VOID, 0);
|
static readonly void: Type = new Type(TypeKind.VOID, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Converts an array of types to an array of native types. */
|
||||||
|
export function typesToNativeTypes(types: Type[]): NativeType[] {
|
||||||
|
const k: i32 = types.length;
|
||||||
|
const ret: NativeType[] = new Array(k);
|
||||||
|
for (let i: i32 = 0; i < k; ++i)
|
||||||
|
ret[i] = types[i].toNativeType();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/** Converts an array of types to its combined string representation. Usually type arguments. */
|
/** Converts an array of types to its combined string representation. Usually type arguments. */
|
||||||
export function typesToString(types: Type[], prefix: string = "<", postfix: string = ">"): string {
|
export function typesToString(types: Type[], prefix: string = "<", postfix: string = ">"): string {
|
||||||
const k: i32 = types.length;
|
const k: i32 = types.length;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { CharCode } from "./charcode";
|
import {
|
||||||
|
CharCode
|
||||||
|
} from "./charcode";
|
||||||
|
|
||||||
/** Normalizes the specified path, removing interior placeholders. Expects a posix-formatted string / not Windows compatible. */
|
/** Normalizes the specified path, removing interior placeholders. Expects a posix-formatted string / not Windows compatible. */
|
||||||
export function normalize(path: string, trimExtension: bool = false, separator: CharCode = CharCode.SLASH): string {
|
export function normalize(path: string, trimExtension: bool = false, separator: CharCode = CharCode.SLASH): string {
|
||||||
|
50
tslint.json
Normal file
50
tslint.json
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"defaultSeverity": "warning",
|
||||||
|
"rules": {
|
||||||
|
"adjacent-overload-signatures": true,
|
||||||
|
"ban-types": [ true, ["Object"], ["any"], ["undefined"], ["never"] ],
|
||||||
|
"deprecation": true,
|
||||||
|
"encoding": true,
|
||||||
|
"eofline": true,
|
||||||
|
"indent": [true, "spaces", 2],
|
||||||
|
"label-position": true,
|
||||||
|
"member-access": [ true, "no-public" ],
|
||||||
|
"new-parens": true,
|
||||||
|
"no-any": true,
|
||||||
|
"no-arg": true,
|
||||||
|
"no-consecutive-blank-lines": true,
|
||||||
|
"no-debugger": true,
|
||||||
|
"no-default-export": true,
|
||||||
|
"no-duplicate-imports": true,
|
||||||
|
"no-duplicate-super": true,
|
||||||
|
"no-duplicate-switch-case": true,
|
||||||
|
"no-duplicate-variable": true,
|
||||||
|
"no-eval": true,
|
||||||
|
"no-inferred-empty-object-type": true,
|
||||||
|
"no-internal-module": true,
|
||||||
|
"no-invalid-template-strings": true,
|
||||||
|
"no-invalid-this": true,
|
||||||
|
"no-irregular-whitespace": true,
|
||||||
|
"no-mergeable-namespace": true,
|
||||||
|
"no-misused-new": true,
|
||||||
|
"no-object-literal-type-assertion": true,
|
||||||
|
"no-parameter-properties": true,
|
||||||
|
"no-require-imports": true,
|
||||||
|
"no-shadowed-variable": true,
|
||||||
|
"no-sparse-arrays": true,
|
||||||
|
"no-string-literal": true,
|
||||||
|
"no-string-throw": true,
|
||||||
|
"no-this-assignment": true,
|
||||||
|
"no-trailing-whitespace": true,
|
||||||
|
"no-unbound-method": true,
|
||||||
|
"no-unsafe-any": true,
|
||||||
|
"no-unused-variable": true,
|
||||||
|
"no-void-expression": true,
|
||||||
|
"object-literal-shorthand": [true, "never"],
|
||||||
|
"prefer-method-signature": true,
|
||||||
|
"quotemark": [true, "double"],
|
||||||
|
"radix": true,
|
||||||
|
"restrict-plus-operands": true,
|
||||||
|
"semicolon": [true, "always"]
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user