Implement asc in js for dist

This commit is contained in:
dcodeIO 2017-12-05 15:06:44 +01:00
parent df212653a8
commit 330752908a
12 changed files with 348 additions and 173 deletions

View File

@ -38,7 +38,7 @@ $> npm install
$> node bin\asc yourModule.ts
```
Building a browser bundle to `dist/assemblyscript.js` (requires [binaryen.js](https://github.com/AssemblyScript/binaryen.js)):
Building a browser bundle to `dist/assemblyscript.js` (still requires [binaryen.js](https://github.com/AssemblyScript/binaryen.js)):
```
$> npm run build

View File

@ -1,2 +1,137 @@
var fs = require("fs");
var path = require("path");
var minimist = require("minimist");
var assemblyscript;
var isDev = true;
try {
assemblyscript = require("../dist/assemblyscript.js");
require("source-map-support").install();
isDev = false;
} catch (e) {
require("ts-node").register({ project: require("path").join(__dirname, "..", "src") });
require("./asc.ts");
require("../src/glue/js");
assemblyscript = require("../src");
}
var conf = require("./asc.json");
var opts = {};
Object.keys(conf).forEach(key => {
var opt = conf[key];
if (opt.aliases)
(opts.alias || (opts.alias = {}))[key] = opt.aliases;
if (opt.default !== undefined)
(opts.default || (opts.default = {}))[key] = opt.default;
if (opt.type === "string")
(opts.string || (opts.string = [])).push(key);
else if (opt.type === "boolean")
(opts.boolean || (opts.boolean = [])).push(key);
});
var args = minimist(process.argv.slice(2), opts);
var version = require("../package.json").version;
if (isDev) version += "-dev";
if (args.version) {
console.log([
"Version " + version
].join("\n"));
process.exit(0);
}
if (args.help || args._.length < 1) {
var options = [];
Object.keys(conf).forEach(name => {
var option = conf[name];
var text = "";
if (option.aliases) {
option.aliases.forEach((alias, i) => {
if (i > 0)
text += ", ";
text += "-" + alias;
});
text += ", ";
}
text += "--" + name;
while (text.length < 20)
text += " ";
options.push(text + option.desc);
});
console.log([
"Version " + version,
"Syntax: asc [options] [file ...]",
"",
"Examples: asc hello.ts",
"",
"Options:"
].concat(options).join("\n"));
process.exit(args.help ? 0 : 1);
}
var entryPath = args._[0];
var entryText = fs.readFileSync(entryPath, { encoding: "utf8" });
var parser = assemblyscript.parseFile(entryText, entryPath);
var nextPath;
var nextText;
while ((nextPath = parser.nextFile()) != null) {
try {
nextText = fs.readFileSync(path.join(path.dirname(entryPath), nextPath + ".ts"), { encoding: "utf8" });
} catch (e) {
nextText = fs.readFileSync(path.join(path.dirname(entryPath), nextPath, "index.ts"), { encoding: "utf8" });
}
assemblyscript.parseFile(nextText, nextPath, parser);
}
var diagnostic;
var hasErrors = false;
while ((diagnostic = assemblyscript.nextDiagnostic(parser)) != null) {
console.error(assemblyscript.formatDiagnostic(diagnostic, process.stderr.isTTY, true));
if (assemblyscript.isError(diagnostic))
hasErrors = true;
}
if (hasErrors)
process.exit(1);
var module = assemblyscript.compile(parser);
hasErrors = false;
while ((diagnostic = assemblyscript.nextDiagnostic(parser)) != null) {
console.error(assemblyscript.formatDiagnostic(diagnostic, process.stderr.isTTY, true));
if (assemblyscript.isError(diagnostic))
hasErrors = true;
}
if (hasErrors) {
module.dispose();
process.exit(1);
}
if (args.validate)
if (!module.validate()) {
module.dispose();
process.exit(1);
}
if (args.optimize)
module.optimize();
var hasOutput = false;
if (args.outFile != null) {
fs.writeFileSync(args.outFile, module.toBinary());
hasOutput = true;
}
if (args.textFile != null) {
fs.writeFileSync(args.textFile, module.toText(), { encoding: "utf8" });
hasOutput = true;
}
if (!hasOutput)
module.print();
module.dispose();

View File

@ -1,126 +0,0 @@
import * as fs from "fs";
import * as path from "path";
import * as minimist from "minimist";
import "../src/glue/js";
import * as as from "../src";
var conf: { [key: string]: { desc: string, type: string, aliases: string[], default: any } } = require("./asc.json");
var opts: minimist.Opts = {};
Object.keys(conf).forEach(key => {
var opt = conf[key];
if (opt.aliases)
(opts.alias || (opts.alias = {}))[key] = opt.aliases;
if (opt.default !== undefined)
(opts.default || (opts.default = {}))[key] = opt.default;
if (opt.type === "string")
(<string[]>(opts.string || (opts.string = []))).push(key);
else if (opt.type === "boolean")
(<string[]>(opts.boolean || (opts.boolean = []))).push(key);
});
const args = minimist(process.argv.slice(2), opts);
const version = <string>require("../package.json")["version"];
if (args["version"]) {
console.log([
"Version " + version
].join("\n"));
process.exit(0);
}
if (args["help"] || args._.length < 1) {
let options: string[] = [];
Object.keys(conf).forEach(name => {
const option = conf[name];
let text = "";
if (option.aliases) {
option.aliases.forEach((alias, i) => {
if (i > 0)
text += ", ";
text += "-" + alias;
});
text += ", ";
}
text += "--" + name;
while (text.length < 20)
text += " ";
options.push(text + option.desc);
});
console.log([
"Version " + version,
"Syntax: asc [options] [file ...]",
"",
"Examples: asc hello.ts",
"",
"Options:"
].concat(options).join("\n"));
process.exit(args["help"] ? 0 : 1);
}
const entryPath = args._[0];
const entryText = fs.readFileSync(entryPath, { encoding: "utf8" });
const parser = as.parseFile(entryText, entryPath);
let nextPath: string | null;
let nextText: string;
while ((nextPath = parser.nextFile()) != null) {
try {
nextText = fs.readFileSync(path.join(path.dirname(entryPath), nextPath + ".ts"), { encoding: "utf8" });
} catch (e) {
nextText = fs.readFileSync(path.join(path.dirname(entryPath), nextPath, "index.ts"), { encoding: "utf8" });
}
as.parseFile(nextText, nextPath, parser);
}
let diagnostic: as.DiagnosticMessage | null;
let hasErrors: boolean = false;
while ((diagnostic = as.nextDiagnostic(parser)) != null) {
console.error(as.formatDiagnostic(diagnostic, process.stderr.isTTY, true));
if (as.isError(diagnostic))
hasErrors = true;
}
if (hasErrors)
process.exit(1);
const module = as.compile(parser);
hasErrors = false;
while ((diagnostic = as.nextDiagnostic(parser)) != null) {
console.error(as.formatDiagnostic(diagnostic, process.stderr.isTTY, true));
if (as.isError(diagnostic))
hasErrors = true;
}
if (hasErrors) {
module.dispose();
process.exit(1);
}
if (args["validate"])
if (!module.validate()) {
module.dispose();
process.exit(1);
}
if (args["optimize"])
module.optimize();
let hasOutput = false;
if (args["outFile"]) {
fs.writeFileSync(args["outFile"], module.toBinary());
hasOutput = true;
}
if (args["textFile"]) {
fs.writeFileSync(args["textFile"], module.toText(), { encoding: "utf8" });
hasOutput = true;
}
if (!hasOutput)
module.print();
module.dispose();

48
package-lock.json generated
View File

@ -1,5 +1,5 @@
{
"name": "@assemblyscript/next",
"name": "assemblyscript",
"version": "0.5.0",
"lockfileVersion": 1,
"requires": true,
@ -19,6 +19,11 @@
"integrity": "sha512-q3zfJvaTroV5BjAAR+peTHEGAAhGrPX0z2EzCzpt2mwFA+qzUn2nigJLqSekXRtdULKmT8am7zjvTMZSapIgHw==",
"dev": true
},
"@types/events": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-1.1.0.tgz",
"integrity": "sha512-y3bR98mzYOo0pAZuiLari+cQyiKk3UXRuT45h1RjhfeCzqkjaVsfZJNaxdgtk7/3tzOm1ozLTqEqMP3VbI48jw=="
},
"@types/glob": {
"version": "5.0.33",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.33.tgz",
@ -26,7 +31,7 @@
"dev": true,
"requires": {
"@types/minimatch": "3.0.1",
"@types/node": "8.0.53"
"@types/node": "8.0.54"
}
},
"@types/long": {
@ -44,12 +49,16 @@
"@types/minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY="
"integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=",
"dev": true
},
"@types/node": {
"version": "8.0.53",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.53.tgz",
"integrity": "sha512-54Dm6NwYeiSQmRB1BLXKr5GELi0wFapR1npi8bnZhEcu84d/yQKqnwwXQ56hZ0RUbTG6L5nqDZaN3dgByQXQRQ=="
"version": "8.0.54",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.54.tgz",
"integrity": "sha512-qetMdTv3Ytz9u9ESLdcYs45LPI0mczYZIbC184n7kY0jczOqPNQsabBfVCh+na3B2shAfvC459JqHV771A8Rxg==",
"requires": {
"@types/events": "1.1.0"
}
},
"acorn": {
"version": "4.0.13",
@ -1897,12 +1906,18 @@
"dev": true
},
"source-map-support": {
"version": "0.4.18",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
"integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
"dev": true,
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.0.tgz",
"integrity": "sha512-vUoN3I7fHQe0R/SJLKRdKYuEdRGogsviXFkHHo17AWaTGv17VLnxw+CFXvqy+y4ORZ3doWLQcxRYfwKrsd/H7Q==",
"requires": {
"source-map": "0.5.7"
"source-map": "0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
},
"spdx-correct": {
@ -2067,6 +2082,17 @@
"tsconfig": "6.0.0",
"v8flags": "3.0.0",
"yn": "2.0.0"
},
"dependencies": {
"source-map-support": {
"version": "0.4.18",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
"integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
"dev": true,
"requires": {
"source-map": "0.5.7"
}
}
}
},
"tsconfig": {

View File

@ -1,18 +1,27 @@
{
"name": "@assemblyscript/next",
"name": "assemblyscript",
"version": "0.5.0",
"author": "Daniel Wirtz <dcode+assemblyscript@dcode.io>",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/AssemblyScript/next.git"
},
"bugs": {
"url": "https://github.com/AssemblyScript/next/issues"
},
"dependencies": {
"@types/minimist": "^1.2.0",
"@types/node": "^8.0.53",
"@types/node": "^8.0.54",
"binaryen": "39.0.0-nightly.20171116",
"minimist": "^1.2.0"
"minimist": "^1.2.0",
"source-map-support": "^0.5.0"
},
"devDependencies": {
"@types/chalk": "^2.2.0",
"@types/diff": "^3.2.2",
"@types/glob": "^5.0.33",
"@types/long": "^3.0.32",
"@types/minimist": "^1.2.0",
"chalk": "^2.3.0",
"diff": "^3.4.0",
"glob": "^7.1.2",
@ -22,13 +31,27 @@
"typescript": "^2.6.2",
"webpack": "^3.10.0"
},
"main": "dist/assemblyscript.js",
"bin": {
"asc": "bin/asc.js"
},
"scripts": {
"build": "webpack",
"clean": "rm dist/assemblyscript.*",
"test:parser": "ts-node -P src tests/parser",
"test:compiler": "ts-node -P src tests/compiler",
"test": "npm run test:parser && npm run test:compiler"
}
},
"files": [
"assembly.d.ts",
"bin/asc.js",
"bin/asc.json",
"dist/assemblyscript.js",
"dist/assemblyscript.js.map",
"LICENSE",
"NOTICE",
"package.json",
"package-lock.json",
"README.md"
]
}

View File

@ -32,13 +32,16 @@ export function initialize(program: Program): void {
addFunction(program, "isNaN", true);
addFunction(program, "isFinite", true);
addFunction(program, "assert");
// addFunction(program, "fmod", false, true);
// addFunction(program, "pow", true, true);
}
/** Adds a built-in function to the specified program. */
function addFunction(program: Program, name: string, isGeneric: bool = false): void {
function addFunction(program: Program, name: string, isGeneric: bool = false, isImport: bool = false): void {
let prototype: FunctionPrototype = new FunctionPrototype(program, name, null, null);
prototype.isGeneric = isGeneric;
prototype.isBuiltIn = true;
prototype.isGeneric = isGeneric;
prototype.isImport = isImport;
program.elements.set(name, prototype);
}
@ -413,6 +416,9 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
compiler.module.createUnary(UnaryOp.EqzI32, arg0),
compiler.module.createUnreachable()
);
// case "fmod":
// case "pow":
}
return 0;
}

View File

@ -698,7 +698,12 @@ export class Compiler extends DiagnosticEmitter {
}
compileBlockStatement(statement: BlockStatement): ExpressionRef {
return this.module.createBlock(null, this.compileStatements(statement.statements), NativeType.None);
const statements: Statement[] = statement.statements;
if (statements.length == 0)
return this.module.createNop();
if (statements.length == 1)
return this.compileStatement(statements[0]);
return this.module.createBlock(null, this.compileStatements(statements), NativeType.None);
}
compileBreakStatement(statement: BreakStatement): ExpressionRef {
@ -962,7 +967,7 @@ export class Compiler extends DiagnosticEmitter {
throw new Error("unexpected expression kind");
}
if (conversionKind != ConversionKind.NONE) {
if (conversionKind != ConversionKind.NONE && this.currentType != contextualType) {
expr = this.convertExpression(expr, this.currentType, contextualType, conversionKind, expression);
this.currentType = contextualType;
}

View File

@ -8,14 +8,12 @@
(func $do/loopDo (; 0 ;) (type $iv) (param $0 i32)
(block $break$1.1
(loop $continue$1.1
(block
(set_local $0
(i32.sub
(get_local $0)
(i32.const 1)
)
)
)
(br_if $continue$1.1
(get_local $0)
)
@ -34,14 +32,12 @@
)
(block $break$1.2
(loop $continue$1.2
(block
(set_local $0
(i32.sub
(get_local $0)
(i32.const 1)
)
)
)
(br_if $continue$1.2
(get_local $0)
)

View File

@ -0,0 +1,37 @@
(module
(type $v (func))
(global $for/i (mut i32) (i32.const 0))
(memory $0 1)
(data (i32.const 4) "\08")
(export "memory" (memory $0))
(start $start)
(func $start (; 0 ;) (type $v)
(set_global $for/i
(i32.const 0)
)
(loop $continue$1.1
(if
(i32.lt_s
(get_global $for/i)
(i32.const 10)
)
(block
(set_global $for/i
(i32.add
(get_global $for/i)
(i32.const 1)
)
)
(br $continue$1.1)
)
)
)
(if
(i32.ne
(get_global $for/i)
(i32.const 10)
)
(unreachable)
)
)
)

6
tests/compiler/for.ts Normal file
View File

@ -0,0 +1,6 @@
let i: i32;
for (i = 0; i < 10; ++i) {
;
}
if (i != 10)
unreachable();

71
tests/compiler/for.wast Normal file
View File

@ -0,0 +1,71 @@
(module
(type $v (func))
(global $for/i (mut i32) (i32.const 0))
(memory $0 1)
(data (i32.const 4) "\08\00\00\00")
(export "memory" (memory $0))
(start $start)
(func $start (; 0 ;) (type $v)
(block $break$1.1
(set_global $for/i
(i32.const 0)
)
(loop $continue$1.1
(if
(i32.lt_s
(get_global $for/i)
(i32.const 10)
)
(block
(nop)
(set_global $for/i
(i32.add
(get_global $for/i)
(i32.const 1)
)
)
(br $continue$1.1)
)
)
)
)
(if
(i32.ne
(get_global $for/i)
(i32.const 10)
)
(unreachable)
)
)
)
(;
[program.elements]
clz
ctz
popcnt
rotl
rotr
abs
ceil
copysign
floor
max
min
nearest
sqrt
trunc
current_memory
grow_memory
unreachable
load
store
reinterpret
select
sizeof
isNaN
isFinite
assert
for/i
[program.exports]
;)

View File

@ -10,7 +10,6 @@
(loop $continue$1.1
(if
(get_local $0)
(block
(block
(set_local $0
(i32.sub
@ -18,7 +17,6 @@
(i32.const 1)
)
)
)
(br $continue$1.1)
)
)
@ -42,7 +40,6 @@
(loop $continue$1.2
(if
(get_local $0)
(block
(block
(set_local $0
(i32.sub
@ -50,7 +47,6 @@
(i32.const 1)
)
)
)
(br $continue$1.2)
)
)