Skip to content

Commit 06198a3

Browse files
committed
Rename lib prefix to '~lib' (parens aren't valid); Add built-in alignof<T>; Prepare for ArrayBufferView
1 parent 3b50720 commit 06198a3

Some content is hidden

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

51 files changed

+2281
-2204
lines changed

bin/asc.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ exports.compileString = (source, extraArgs={}) => new Promise((resolve, reject)
9393
const libDir = path.join(__dirname, "../std", "assembly");
9494
const libFiles = require("glob").sync("**/*.ts", { cwd: libDir });
9595
libFiles.forEach(file =>
96-
exports.libraryFiles["(lib)/" + file.replace(/\.ts$/, "")] = readFileNode(path.join(libDir, file), { encoding: "utf8" })
96+
exports.libraryFiles["~lib/" + file.replace(/\.ts$/, "")] = readFileNode(path.join(libDir, file), { encoding: "utf8" })
9797
);
9898
}
9999

@@ -265,7 +265,7 @@ exports.main = function main(argv, options, callback) {
265265
}
266266
}
267267

268-
// Otherwise try nextFile.ts, nextFile/index.ts, (lib)/nextFile.ts
268+
// Otherwise try nextFile.ts, nextFile/index.ts, ~lib/nextFile.ts
269269
} else {
270270
sourceText = readFile(path.join(baseDir, sourcePath + ".ts"));
271271
if (sourceText !== null) {

dist/asc.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/asc.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ast.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ export abstract class Node {
534534
identifier: IdentifierExpression,
535535
typeParameters: TypeParameterNode[],
536536
extendsType: TypeNode | null, // can't be a function
537-
implementsTypes: TypeNode[], // can't be a function
537+
implementsTypes: TypeNode[] | null, // can't be functions
538538
members: DeclarationStatement[],
539539
decorators: DecoratorNode[] | null,
540540
flags: CommonFlags,
@@ -546,7 +546,7 @@ export abstract class Node {
546546
stmt.name = identifier; identifier.parent = stmt;
547547
stmt.typeParameters = typeParameters; setParent(typeParameters, stmt);
548548
stmt.extendsType = extendsType; if (extendsType) extendsType.parent = stmt;
549-
stmt.implementsTypes = implementsTypes; setParent(implementsTypes, stmt);
549+
stmt.implementsTypes = implementsTypes; if (implementsTypes) setParent(implementsTypes, stmt);
550550
stmt.members = members; setParent(members, stmt);
551551
stmt.decorators = decorators; if (decorators) setParent(decorators, stmt);
552552
return stmt;
@@ -756,17 +756,21 @@ export abstract class Node {
756756

757757
static createInterfaceDeclaration(
758758
name: IdentifierExpression,
759+
typeParameters: TypeParameterNode[],
759760
extendsType: TypeNode | null, // can't be a function
760761
members: DeclarationStatement[],
762+
decorators: DecoratorNode[] | null,
761763
flags: CommonFlags,
762764
range: Range
763765
): InterfaceDeclaration {
764766
var stmt = new InterfaceDeclaration();
765767
stmt.range = range;
766768
stmt.flags = flags;
767769
stmt.name = name; name.parent = stmt;
770+
stmt.typeParameters = typeParameters; if (typeParameters) setParent(typeParameters, stmt);
768771
stmt.extendsType = extendsType; if (extendsType) extendsType.parent = stmt;
769772
stmt.members = members; setParent(members, stmt);
773+
stmt.decorators = decorators; if (decorators) setParent(decorators, stmt);
770774
return stmt;
771775
}
772776

@@ -1487,10 +1491,10 @@ export class ClassDeclaration extends DeclarationStatement {
14871491

14881492
/** Accepted type parameters. */
14891493
typeParameters: TypeParameterNode[];
1490-
/** Base class type being extended. */
1494+
/** Base class type being extended, if any. */
14911495
extendsType: TypeNode | null; // can't be a function
1492-
/** Interface types being implemented. */
1493-
implementsTypes: TypeNode[]; // can't be a function
1496+
/** Interface types being implemented, if any. */
1497+
implementsTypes: TypeNode[] | null; // can't be functions
14941498
/** Class member declarations. */
14951499
members: DeclarationStatement[];
14961500

src/builtins.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,6 +1790,55 @@ export function compileCall(
17901790
}
17911791
return ret;
17921792
}
1793+
case "alignof": { // alignof<T!>() -> usize
1794+
compiler.currentType = compiler.options.usizeType;
1795+
if (operands.length != 0) {
1796+
if (!(typeArguments && typeArguments.length == 1)) {
1797+
compiler.error(
1798+
DiagnosticCode.Expected_0_type_arguments_but_got_1,
1799+
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
1800+
);
1801+
}
1802+
compiler.error(
1803+
DiagnosticCode.Expected_0_arguments_but_got_1,
1804+
reportNode.range, "0", operands.length.toString(10)
1805+
);
1806+
return module.createUnreachable();
1807+
}
1808+
if (!(typeArguments && typeArguments.length == 1)) {
1809+
compiler.error(
1810+
DiagnosticCode.Expected_0_type_arguments_but_got_1,
1811+
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
1812+
);
1813+
}
1814+
let byteSize = (<Type[]>typeArguments)[0].byteSize;
1815+
let alignLog2: i32;
1816+
switch (byteSize) {
1817+
case 1: { alignLog2 = 0; break; }
1818+
case 2: { alignLog2 = 1; break; }
1819+
case 4: { alignLog2 = 2; break; }
1820+
case 8: { alignLog2 = 3; break; }
1821+
default: { assert(false); return module.createUnreachable(); }
1822+
}
1823+
if (compiler.options.isWasm64) {
1824+
// implicitly wrap if contextual type is a 32-bit integer
1825+
if (contextualType.is(TypeFlags.INTEGER) && contextualType.size <= 32) {
1826+
compiler.currentType = Type.u32;
1827+
ret = module.createI32(alignLog2);
1828+
} else {
1829+
ret = module.createI64(alignLog2, 0);
1830+
}
1831+
} else {
1832+
// implicitly extend if contextual type is a 64-bit integer
1833+
if (contextualType.is(TypeFlags.INTEGER) && contextualType.size == 64) {
1834+
compiler.currentType = Type.u64;
1835+
ret = module.createI64(alignLog2, 0);
1836+
} else {
1837+
ret = module.createI32(alignLog2);
1838+
}
1839+
}
1840+
return ret;
1841+
}
17931842
case "offsetof": { // offsetof<T!>(fieldName?: string) -> usize
17941843
compiler.currentType = compiler.options.usizeType;
17951844
if (operands.length > 1) {

src/compiler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ export class Compiler extends DiagnosticEmitter {
367367
}
368368
}
369369

370-
// try (lib)/file.ts
370+
// try ~lib/file.ts
371371
expected = LIBRARY_PREFIX + normalizedPathWithoutExtension + ".ts";
372372
for (let i = 0, k = sources.length; i < k; ++i) {
373373
let source = sources[i];

src/diagnosticMessages.generated.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export enum DiagnosticCode {
6464
Declaration_expected = 1146,
6565
_const_declarations_must_be_initialized = 1155,
6666
Unterminated_regular_expression_literal = 1161,
67+
Interface_declaration_cannot_have_implements_clause = 1176,
6768
Binary_digit_expected = 1177,
6869
Octal_digit_expected = 1178,
6970
An_implementation_cannot_be_declared_in_ambient_contexts = 1183,
@@ -169,6 +170,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
169170
case 1146: return "Declaration expected.";
170171
case 1155: return "'const' declarations must be initialized.";
171172
case 1161: return "Unterminated regular expression literal.";
173+
case 1176: return "Interface declaration cannot have 'implements' clause.";
172174
case 1177: return "Binary digit expected.";
173175
case 1178: return "Octal digit expected.";
174176
case 1183: return "An implementation cannot be declared in ambient contexts.";

src/diagnosticMessages.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"Declaration expected.": 1146,
5858
"'const' declarations must be initialized.": 1155,
5959
"Unterminated regular expression literal.": 1161,
60+
"Interface declaration cannot have 'implements' clause.": 1176,
6061
"Binary digit expected.": 1177,
6162
"Octal digit expected.": 1178,
6263
"An implementation cannot be declared in ambient contexts.": 1183,

src/extra/ast.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -784,13 +784,15 @@ export class ASTBuilder {
784784
this.visitTypeNode(extendsType);
785785
}
786786
var implementsTypes = node.implementsTypes;
787-
var numImplementsTypes = implementsTypes.length;
788-
if (numImplementsTypes) {
789-
sb.push(" implements ");
790-
this.visitTypeNode(implementsTypes[0]);
791-
for (let i = 1; i < numImplementsTypes; ++i) {
792-
sb.push(", ");
793-
this.visitTypeNode(implementsTypes[i]);
787+
if (implementsTypes) {
788+
let numImplementsTypes = implementsTypes.length;
789+
if (numImplementsTypes) {
790+
sb.push(" implements ");
791+
this.visitTypeNode(implementsTypes[0]);
792+
for (let i = 1; i < numImplementsTypes; ++i) {
793+
sb.push(", ");
794+
this.visitTypeNode(implementsTypes[i]);
795+
}
794796
}
795797
}
796798
var members = node.members;
@@ -1123,6 +1125,7 @@ export class ASTBuilder {
11231125
sb.push(" extends ");
11241126
this.visitTypeNode(extendsType);
11251127
}
1128+
// must not have implementsTypes
11261129
sb.push(" {\n");
11271130
var indentLevel = ++this.indentLevel;
11281131
var members = node.members;

src/parser.ts

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,10 @@ export class Parser extends DiagnosticEmitter {
262262
}
263263
// fall through
264264
}
265-
case Token.CLASS: {
265+
case Token.CLASS:
266+
case Token.INTERFACE: {
266267
tn.next();
267-
statement = this.parseClass(tn, flags, decorators, startPos);
268+
statement = this.parseClassOrInterface(tn, flags, decorators, startPos);
268269
decorators = null;
269270
break;
270271
}
@@ -1381,20 +1382,22 @@ export class Parser extends DiagnosticEmitter {
13811382
return Node.createFunctionExpression(declaration);
13821383
}
13831384

1384-
parseClass(
1385+
parseClassOrInterface(
13851386
tn: Tokenizer,
13861387
flags: CommonFlags,
13871388
decorators: DecoratorNode[] | null,
13881389
startPos: i32
13891390
): ClassDeclaration | null {
13901391

1391-
// at 'class':
1392+
// at ('class' | 'interface'):
13921393
// Identifier
13931394
// ('<' TypeParameters)?
13941395
// ('extends' Type)?
13951396
// ('implements' Type (',' Type)*)?
13961397
// '{' ClassMember* '}'
13971398

1399+
var isInterface = tn.token == Token.INTERFACE;
1400+
13981401
if (!tn.skip(Token.IDENTIFIER)) {
13991402
this.error(
14001403
DiagnosticCode.Identifier_expected,
@@ -1431,12 +1434,21 @@ export class Parser extends DiagnosticEmitter {
14311434
extendsType = <TypeNode>t;
14321435
}
14331436

1434-
var implementsTypes = new Array<TypeNode>();
1437+
var implementsTypes: TypeNode[] | null = null;
14351438
if (tn.skip(Token.IMPLEMENTS)) {
1439+
if (isInterface) {
1440+
this.error(
1441+
DiagnosticCode.Interface_declaration_cannot_have_implements_clause,
1442+
tn.range()
1443+
); // recoverable
1444+
}
14361445
do {
14371446
let type = this.parseType(tn);
14381447
if (!type) return null;
1439-
implementsTypes.push(<TypeNode>type);
1448+
if (!isInterface) {
1449+
if (!implementsTypes) implementsTypes = [];
1450+
implementsTypes.push(<TypeNode>type);
1451+
}
14401452
} while (tn.skip(Token.COMMA));
14411453
}
14421454

@@ -1449,16 +1461,30 @@ export class Parser extends DiagnosticEmitter {
14491461
}
14501462

14511463
var members = new Array<DeclarationStatement>();
1452-
var declaration = Node.createClassDeclaration(
1453-
identifier,
1454-
typeParameters,
1455-
extendsType,
1456-
implementsTypes,
1457-
members,
1458-
decorators,
1459-
flags,
1460-
tn.range(startPos, tn.pos)
1461-
);
1464+
var declaration: ClassDeclaration;
1465+
if (isInterface) {
1466+
assert(!implementsTypes);
1467+
declaration = Node.createInterfaceDeclaration(
1468+
identifier,
1469+
typeParameters,
1470+
extendsType,
1471+
members,
1472+
decorators,
1473+
flags,
1474+
tn.range(startPos, tn.pos)
1475+
);
1476+
} else {
1477+
declaration = Node.createClassDeclaration(
1478+
identifier,
1479+
typeParameters,
1480+
extendsType,
1481+
implementsTypes,
1482+
members,
1483+
decorators,
1484+
flags,
1485+
tn.range(startPos, tn.pos)
1486+
);
1487+
}
14621488
if (!tn.skip(Token.CLOSEBRACE)) {
14631489
do {
14641490
let member = this.parseClassMember(tn, declaration);

src/program.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export const INSTANCE_DELIMITER = "#";
8585
/** Delimiter used between class and namespace names and static members. */
8686
export const STATIC_DELIMITER = ".";
8787
/** Substitution used to indicate a library directory. */
88-
export const LIBRARY_SUBST = "(lib)";
88+
export const LIBRARY_SUBST = "~lib";
8989
/** Library directory prefix. */
9090
export const LIBRARY_PREFIX = LIBRARY_SUBST + PATH_DELIMITER;
9191

@@ -417,23 +417,25 @@ export class Program extends DiagnosticEmitter {
417417
this.elementsLookup.set(internalName, prototype);
418418

419419
var implementsTypes = declaration.implementsTypes;
420-
var numImplementsTypes = implementsTypes.length;
421-
if (prototype.is(CommonFlags.UNMANAGED)) {
422-
if (implementsTypes && numImplementsTypes) {
423-
this.error(
424-
DiagnosticCode.Structs_cannot_implement_interfaces,
425-
Range.join(
426-
declaration.name.range,
427-
implementsTypes[numImplementsTypes - 1].range
428-
)
429-
);
430-
}
431-
} else if (numImplementsTypes) {
432-
for (let i = 0; i < numImplementsTypes; ++i) {
433-
this.error(
434-
DiagnosticCode.Operation_not_supported,
435-
implementsTypes[i].range
436-
);
420+
if (implementsTypes) {
421+
let numImplementsTypes = implementsTypes.length;
422+
if (prototype.is(CommonFlags.UNMANAGED)) {
423+
if (implementsTypes && numImplementsTypes) {
424+
this.error(
425+
DiagnosticCode.Structs_cannot_implement_interfaces,
426+
Range.join(
427+
declaration.name.range,
428+
implementsTypes[numImplementsTypes - 1].range
429+
)
430+
);
431+
}
432+
} else if (numImplementsTypes) {
433+
for (let i = 0; i < numImplementsTypes; ++i) {
434+
this.error(
435+
DiagnosticCode.Operation_not_supported,
436+
implementsTypes[i].range
437+
);
438+
}
437439
}
438440
}
439441

std/assembly.d.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,10 @@ declare const NaN: f32 | f64;
223223
declare const Infinity: f32 | f64;
224224
/** Heap base offset. */
225225
declare const HEAP_BASE: usize;
226-
/** Determines the byte size of the specified core or class type. Compiles to a constant. */
226+
/** Determines the byte size of the specified underlying core type. Compiles to a constant. */
227227
declare function sizeof<T>(): usize;
228+
/** Determines the alignment (log2) of the specified underlying core type. Compiles to a constant. */
229+
declare function alignof<T>(): usize;
228230
/** Determines the offset of the specified field within the given class type. Returns the class type's end offset if field name has been omitted. Compiles to a constant. */
229231
declare function offsetof<T>(fieldName?: string): usize;
230232
/** Changes the type of any value of `usize` kind to another one of `usize` kind. Useful for casting class instances to their pointer values and vice-versa. Beware that this is unsafe.*/
@@ -270,6 +272,17 @@ declare class ArrayBuffer {
270272
slice(begin?: i32, end?: i32): ArrayBuffer;
271273
}
272274

275+
/** Interface for a typed view on an array buffer. */
276+
declare interface ArrayBufferView<T> {
277+
[key: number]: T;
278+
/** The {@link ArrayBuffer} referenced by this view. */
279+
readonly buffer: ArrayBuffer;
280+
/** The offset in bytes from the start of the referenced {@link ArrayBuffer}. */
281+
readonly byteOffset: i32;
282+
/** The length in bytes from the start of the referenced {@link ArrayBuffer}. */
283+
readonly byteLength: i32;
284+
}
285+
273286
/** Class representing a sequence of values of type `T`. */
274287
declare class Array<T> {
275288
[key: number]: T;

0 commit comments

Comments
 (0)