Skip to content

Commit 85a9fb1

Browse files
committed
Stdlib preparations
1 parent 4b3cc98 commit 85a9fb1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+834
-137
lines changed

bin/asc.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
var fs = require("fs");
22
var path = require("path");
33
var minimist = require("minimist");
4+
var glob = require("glob");
45

56
var assemblyscript;
67
var isDev = true;
@@ -88,6 +89,17 @@ function checkDiagnostics(parser) {
8889
process.exit(1);
8990
}
9091

92+
// Include standard library
93+
if (!args.noLib) {
94+
var stdlibDir = path.join(__dirname + "..", "std", "assembly");
95+
glob.sync("*.ts", { cwd: stdlibDir }).forEach(file => {
96+
var nextPath = "std/" + file;
97+
var nextText = fs.readFileSync(path.join(stdlibDir, file), { encoding: "utf8" });
98+
parser = assemblyscript.parseFile(nextText, nextPath, parser, false);
99+
});
100+
}
101+
102+
// Include entry files
91103
args._.forEach(filename => {
92104
var entryPath = filename.replace(/\\/g, "/").replace(/(\.ts|\/)$/, "");
93105
var entryDir = path.dirname(entryPath);
@@ -105,11 +117,12 @@ args._.forEach(filename => {
105117
}
106118
}
107119

108-
parser = assemblyscript.parseFile(entryText, entryPath, parser, true);
109-
110120
var nextPath;
111121
var nextText;
112122

123+
// Load entry text
124+
parser = assemblyscript.parseFile(entryText, entryPath, parser, true);
125+
113126
while ((nextPath = parser.nextFile()) != null) {
114127
try {
115128
nextText = fs.readFileSync(nextPath + ".ts", { encoding: "utf8" });

bin/asc.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@
4747
"desc": "Disables assertions.",
4848
"type": "boolean"
4949
},
50+
"noLib": {
51+
"desc": "Does not include the standard library.",
52+
"type": "boolean"
53+
},
5054
"trapMode": {
5155
"desc": [
5256
"Sets the trap mode to use.",

package-lock.json

Lines changed: 6 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"dependencies": {
1414
"@types/node": "^8.0.58",
1515
"binaryen": "40.0.0-nightly.20171209",
16+
"glob": "^7.1.2",
1617
"minimist": "^1.2.0",
1718
"source-map-support": "^0.5.0"
1819
},
@@ -24,7 +25,6 @@
2425
"@types/minimist": "^1.2.0",
2526
"chalk": "^2.3.0",
2627
"diff": "^3.4.0",
27-
"glob": "^7.1.2",
2828
"long": "^3.2.0",
2929
"ts-loader": "^3.2.0",
3030
"ts-node": "^3.3.0",

src/ast.ts

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export enum NodeKind {
109109
SUPER,
110110
THIS,
111111
TRUE,
112+
CONSTRUCTOR,
112113
UNARYPOSTFIX,
113114
UNARYPREFIX,
114115

@@ -240,6 +241,12 @@ export abstract class Expression extends Node {
240241
return expr;
241242
}
242243

244+
static createConstructor(range: Range): ConstructorExpression {
245+
const expr: ConstructorExpression = new ConstructorExpression();
246+
expr.range = range;
247+
return expr;
248+
}
249+
243250
static createElementAccess(expression: Expression, element: Expression, range: Range): ElementAccessExpression {
244251
const expr: ElementAccessExpression = new ElementAccessExpression();
245252
expr.range = range;
@@ -357,6 +364,16 @@ export abstract class Expression extends Node {
357364
}
358365
}
359366

367+
export class IdentifierExpression extends Expression {
368+
369+
kind = NodeKind.IDENTIFIER;
370+
name: string;
371+
372+
serialize(sb: string[]): void {
373+
sb.push(this.name);
374+
}
375+
}
376+
360377
export const enum LiteralKind {
361378
FLOAT,
362379
INTEGER,
@@ -459,6 +476,11 @@ export class CallExpression extends Expression {
459476
}
460477
}
461478

479+
export class ConstructorExpression extends IdentifierExpression {
480+
kind = NodeKind.CONSTRUCTOR;
481+
name = "this";
482+
}
483+
462484
export class ElementAccessExpression extends Expression {
463485

464486
kind = NodeKind.ELEMENTACCESS;
@@ -483,16 +505,6 @@ export class FloatLiteralExpression extends LiteralExpression {
483505
}
484506
}
485507

486-
export class IdentifierExpression extends Expression {
487-
488-
kind = NodeKind.IDENTIFIER;
489-
name: string;
490-
491-
serialize(sb: string[]): void {
492-
sb.push(this.name);
493-
}
494-
}
495-
496508
export class IntegerLiteralExpression extends LiteralExpression {
497509

498510
literalKind = LiteralKind.INTEGER;
@@ -641,8 +653,9 @@ export enum ModifierKind {
641653
PUBLIC,
642654
PRIVATE,
643655
PROTECTED,
656+
READONLY,
644657
GET,
645-
SET
658+
SET,
646659
}
647660

648661
export abstract class Statement extends Node {
@@ -1052,7 +1065,7 @@ export class ClassDeclaration extends DeclarationStatement {
10521065
if (this._cachedInternalName !== null)
10531066
return this._cachedInternalName;
10541067
const globalDecorator: Decorator | null = this.decorators ? getDecoratorByName("global", this.decorators) : null;
1055-
if (globalDecorator && globalDecorator.expression.kind == NodeKind.IDENTIFIER && (<IdentifierExpression>globalDecorator.expression).name == "global")
1068+
if (globalDecorator)
10561069
return this._cachedInternalName = this.identifier.name;
10571070
else
10581071
return this._cachedInternalName = mangleInternalName(this);
@@ -1589,9 +1602,10 @@ export class Modifier extends Node {
15891602
case ModifierKind.PRIVATE: sb.push("private"); break;
15901603
case ModifierKind.PROTECTED: sb.push("protected"); break;
15911604
case ModifierKind.PUBLIC: sb.push("public"); break;
1605+
case ModifierKind.READONLY: sb.push("readonly"); break;
15921606
case ModifierKind.SET: sb.push("set"); break;
15931607
case ModifierKind.STATIC: sb.push("static"); break;
1594-
default: sb.push("INVALID"); break;
1608+
default: throw new Error("unexpected modifier kind");
15951609
}
15961610
}
15971611
}
@@ -1772,16 +1786,21 @@ export function hasModifier(kind: ModifierKind, modifiers: Modifier[] | null): b
17721786
return false;
17731787
}
17741788

1775-
export function getDecoratorByName(name: string, decorators: Decorator[]): Decorator | null {
1776-
for (let i: i32 = 0, k: i32 = decorators.length; i < k; ++i) {
1777-
const decorator: Decorator = decorators[i];
1778-
const expression: Expression = decorator.expression;
1779-
if (expression.kind == NodeKind.IDENTIFIER && (<IdentifierExpression>expression).name == name)
1780-
return decorator;
1781-
}
1789+
function getDecoratorByName(name: string, decorators: Decorator[] | null): Decorator | null {
1790+
if (decorators)
1791+
for (let i: i32 = 0, k: i32 = decorators.length; i < k; ++i) {
1792+
const decorator: Decorator = decorators[i];
1793+
const expression: Expression = decorator.expression;
1794+
if (expression.kind == NodeKind.IDENTIFIER && (<IdentifierExpression>expression).name == name)
1795+
return decorator;
1796+
}
17821797
return null;
17831798
}
17841799

1800+
export function hasDecorator(name: string, decorators: Decorator[] | null): bool {
1801+
return getDecoratorByName(name, decorators) != null;
1802+
}
1803+
17851804
export function serialize(node: Node, indent: i32 = 0): string {
17861805
const sb: string[] = new Array(); // shared builder could grow too much
17871806
node.serialize(sb);

src/builtins.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Compiler, Target, ConversionKind, typeToNativeType, typeToNativeOne, typeToNativeZero } from "./compiler";
22
import { DiagnosticCode } from "./diagnostics";
3-
import { Node, Expression } from "./ast";
3+
import { Node, Expression, IdentifierExpression } from "./ast";
44
import { Type } from "./types";
55
import { Module, ExpressionRef, UnaryOp, BinaryOp, HostOp, NativeType, FunctionTypeRef } from "./module";
66
import { Program, ElementFlags, Element, Global, FunctionPrototype, Local } from "./program";
@@ -9,6 +9,9 @@ import { Program, ElementFlags, Element, Global, FunctionPrototype, Local } from
99
export function initialize(program: Program): void {
1010

1111
// math
12+
addConstant(program, "NaN", Type.f64);
13+
addConstant(program, "Infinity", Type.f64);
14+
1215
addFunction(program, "isNaN", true);
1316
addFunction(program, "isFinite", true);
1417
addFunction(program, "clz", true);
@@ -96,12 +99,24 @@ export function initialize(program: Program): void {
9699
if (program.target == Target.WASM64) {
97100
program.elements.set("isize", <Element>program.elements.get("i64"));
98101
program.elements.set("usize", <Element>program.elements.get("u64"));
102+
addConstant(program, "HEAP_START", Type.usize64);
99103
} else {
100104
program.elements.set("isize", <Element>program.elements.get("i32"));
101105
program.elements.set("usize", <Element>program.elements.get("u32"));
106+
addConstant(program, "HEAP_START", Type.usize32);
102107
}
103108
}
104109

110+
/** Adds a built-in global to the specified program. */
111+
function addConstant(program: Program, name: string, type: Type): Global {
112+
const global: Global = new Global(program, name, null, null);
113+
global.isBuiltIn = true;
114+
global.isConstant = true;
115+
global.type = type;
116+
program.elements.set(name, global);
117+
return global;
118+
}
119+
105120
/** Adds a built-in function to the specified program. */
106121
function addFunction(program: Program, name: string, isGeneric: bool = false): FunctionPrototype {
107122
let prototype: FunctionPrototype = new FunctionPrototype(program, name, name, null, null);
@@ -111,6 +126,29 @@ function addFunction(program: Program, name: string, isGeneric: bool = false): F
111126
return prototype;
112127
}
113128

129+
export function compileGetGlobal(compiler: Compiler, global: Global): ExpressionRef {
130+
switch (global.internalName) {
131+
132+
case "NaN":
133+
if (compiler.currentType == Type.f32)
134+
return compiler.module.createF32(NaN);
135+
compiler.currentType = Type.f64;
136+
return compiler.module.createF64(NaN);
137+
138+
case "Infinity":
139+
if (compiler.currentType == Type.f32)
140+
return compiler.module.createF32(Infinity);
141+
compiler.currentType = Type.f64;
142+
return compiler.module.createF64(Infinity);
143+
144+
case "HEAP_START": // never inlined
145+
return compiler.module.createGetGlobal("HEAP_START", typeToNativeType(<Type>global.type));
146+
147+
default:
148+
throw new Error("not implemented: " + global.internalName);
149+
}
150+
}
151+
114152
/** Compiles a call to a built-in function. */
115153
export function compileCall(compiler: Compiler, prototype: FunctionPrototype, typeArguments: Type[], operands: Expression[], reportNode: Node): ExpressionRef {
116154
const module: Module = compiler.module;

0 commit comments

Comments
 (0)