Skip to content

Commit 859f9a5

Browse files
committed
Merge remote-tracking branch 'origin/master' into release
2 parents 9159028 + 51ba4a2 commit 859f9a5

22 files changed

+8822
-4103
lines changed

bin/asinit

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,26 @@ const fs = require("fs");
66
const path = require("path");
77
const colors = require("../cli/util/colors");
88
const version = require("../package.json").version;
9+
const options = require("../cli/util/options");
910

10-
if (process.argv.length != 3 || process.argv[2] == "--help" || process.argv[2] == "-h") printHelp();
11+
const asinitOptions = {
12+
"help": {
13+
"category": "General",
14+
"description": "Prints a help message.",
15+
"type": "b",
16+
"alias": "h"
17+
},
18+
"yes": {
19+
"category": "General",
20+
"description": "Answers all questions with their default option for non-interactive usage.",
21+
"type": "b",
22+
"alias": "y"
23+
}
24+
};
25+
26+
const cliOptions = options.parse(process.argv.slice(2), asinitOptions);
27+
28+
if (cliOptions.options.help || cliOptions.arguments.length === 0) printHelp();
1129

1230
function printHelp() {
1331
console.log([
@@ -19,12 +37,7 @@ function printHelp() {
1937
process.exit(0);
2038
}
2139

22-
const rl = require("readline").createInterface({
23-
input: process.stdin,
24-
output: process.stdout
25-
});
26-
27-
const projectDir = path.resolve(process.argv[2]);
40+
const projectDir = path.resolve(cliOptions.arguments[0]);
2841
const compilerDir = path.join(__dirname, "..");
2942
const compilerVersion = require(path.join(compilerDir, "package.json")).version;
3043
const assemblyDir = path.join(projectDir, "assembly");
@@ -75,7 +88,7 @@ console.log([
7588
""
7689
].join("\n"));
7790

78-
rl.question(colors.white("Do you want to proceed?") + " [Y/n] ", answer => {
91+
function createProject(answer) {
7992
if (!/^y?$/i.test(answer)) {
8093
process.exit(1);
8194
return;
@@ -132,8 +145,20 @@ rl.question(colors.white("Do you want to proceed?") + " [Y/n] ", answer => {
132145
"",
133146
"Have a nice day!"
134147
].join("\n"));
135-
rl.close();
136-
});
148+
}
149+
150+
if (cliOptions.options.yes) {
151+
createProject("y");
152+
} else {
153+
const rl = require("readline").createInterface({
154+
input: process.stdin,
155+
output: process.stdout
156+
});
157+
rl.question(colors.white("Do you want to proceed?") + " [Y/n] ", result => {
158+
rl.close();
159+
createProject(result);
160+
});
161+
}
137162

138163
function ensureProjectDirectory() {
139164
console.log("- Making sure that the project directory exists...");

src/ast.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ export abstract class Node {
685685

686686
static createEnumValueDeclaration(
687687
name: IdentifierExpression,
688-
value: Expression | null,
688+
initializer: Expression | null,
689689
flags: CommonFlags,
690690
range: Range
691691
): EnumValueDeclaration {
@@ -694,7 +694,7 @@ export abstract class Node {
694694
node.range = range;
695695
node.flags = flags;
696696
node.name = name;
697-
node.value = value;
697+
node.initializer = initializer;
698698
return node;
699699
}
700700

@@ -1848,8 +1848,6 @@ export class EnumDeclaration extends DeclarationStatement {
18481848

18491849
/** Represents a value of an `enum` declaration. */
18501850
export class EnumValueDeclaration extends VariableLikeDeclarationStatement {
1851-
/** Value expression. */
1852-
value: Expression | null;
18531851
}
18541852

18551853
/** Represents an `export import` statement of an interface. */

src/extra/ast.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,9 +1000,9 @@ export class ASTBuilder {
10001000

10011001
visitEnumValueDeclaration(node: EnumValueDeclaration): void {
10021002
this.visitIdentifierExpression(node.name);
1003-
if (node.value) {
1003+
if (node.initializer) {
10041004
this.sb.push(" = ");
1005-
this.visitNode(node.value);
1005+
this.visitNode(node.initializer);
10061006
}
10071007
}
10081008

src/parser.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ import {
1313
PATH_DELIMITER
1414
} from "./common";
1515

16-
import {
17-
Program
18-
} from "./program";
19-
2016
import {
2117
Tokenizer,
2218
Token,
@@ -28,7 +24,8 @@ import {
2824

2925
import {
3026
DiagnosticCode,
31-
DiagnosticEmitter
27+
DiagnosticEmitter,
28+
DiagnosticMessage
3229
} from "./diagnostics";
3330

3431
import {
@@ -95,8 +92,6 @@ import {
9592
/** Parser interface. */
9693
export class Parser extends DiagnosticEmitter {
9794

98-
/** Program being created. */
99-
program: Program;
10095
/** Source file names to be requested next. */
10196
backlog: string[] = new Array();
10297
/** Source file names already seen, that is processed or backlogged. */
@@ -109,11 +104,16 @@ export class Parser extends DiagnosticEmitter {
109104
currentSource: Source;
110105
/** Dependency map **/
111106
dependees: Map<string, Source> = new Map();
107+
/** An array of parsed sources. */
108+
sources: Source[];
112109

113110
/** Constructs a new parser. */
114-
constructor(program: Program) {
115-
super(program.diagnostics);
116-
this.program = program;
111+
constructor(
112+
diagnostics: DiagnosticMessage[] | null = null,
113+
sources: Source[] | null = null
114+
) {
115+
super(diagnostics);
116+
this.sources = sources ? sources : new Array<Source>();
117117
}
118118

119119
/** Parses a file and adds its definitions to the program. */
@@ -145,12 +145,12 @@ export class Parser extends DiagnosticEmitter {
145145
: SourceKind.LIBRARY
146146
: SourceKind.USER
147147
);
148-
var program = this.program;
149-
program.sources.push(source);
148+
149+
this.sources.push(source);
150150
this.currentSource = source;
151151

152152
// tokenize and parse
153-
var tn = new Tokenizer(source, program.diagnostics);
153+
var tn = new Tokenizer(source, this.diagnostics);
154154
tn.onComment = this.onComment;
155155
var statements = source.statements;
156156
while (!tn.skip(Token.ENDOFFILE)) {

src/program.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ export class Program extends DiagnosticEmitter {
537537
var nativeFile = new File(this, nativeSource);
538538
this.nativeFile = nativeFile;
539539
this.filesByName.set(nativeFile.internalName, nativeFile);
540-
this.parser = new Parser(this);
540+
this.parser = new Parser(this.diagnostics, this.sources);
541541
this.resolver = new Resolver(this);
542542
}
543543

@@ -2789,7 +2789,7 @@ export class EnumValue extends VariableLikeElement {
27892789

27902790
/** Gets the associated value node. */
27912791
get valueNode(): Expression | null {
2792-
return (<EnumValueDeclaration>this.declaration).value;
2792+
return (<EnumValueDeclaration>this.declaration).initializer;
27932793
}
27942794

27952795
/* @override */

std/assembly/array.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,64 @@ export class Array<T> {
493493
return <string>unreachable();
494494
}
495495

496+
flat(): T {
497+
if (!isArray<T>()) {
498+
ERROR("Cannot call flat() on Array<T> where T is not an Array.");
499+
}
500+
// Get the length and data start values
501+
var length = this.length_;
502+
var selfDataStart = this.dataStart;
503+
504+
// calculate the end size with an initial pass
505+
var size = 0;
506+
for (let i = 0; i < length; i++) {
507+
let child = load<usize>(selfDataStart + (i << alignof<T>()));
508+
size += child == 0 ? 0 : load<i32>(child, offsetof<T>("length_"));
509+
}
510+
511+
// calculate the byteLength of the resulting backing ArrayBuffer
512+
var byteLength = <usize>size << usize(alignof<valueof<T>>());
513+
var dataStart = __alloc(byteLength, idof<ArrayBuffer>());
514+
515+
// create the return value and initialize it
516+
var result = __alloc(offsetof<T>(), idof<T>());
517+
store<i32>(result, size, offsetof<T>("length_"));
518+
519+
// byteLength, dataStart, and buffer are all readonly
520+
store<i32>(result, byteLength, offsetof<T>("byteLength"));
521+
store<usize>(result, dataStart, offsetof<T>("dataStart"));
522+
store<usize>(result, __retain(dataStart), offsetof<T>("buffer"));
523+
524+
// set the elements
525+
var resultOffset: usize = 0;
526+
for (let i = 0; i < length; i++) { // for each child
527+
let child = load<usize>(selfDataStart + (<usize>i << alignof<T>()));
528+
529+
// ignore null arrays
530+
if (child == 0) continue;
531+
532+
// copy the underlying buffer data to the result buffer
533+
let childDataLength = load<i32>(child, offsetof<T>("byteLength"));
534+
memory.copy(
535+
dataStart + resultOffset,
536+
load<usize>(child, offsetof<T>("dataStart")),
537+
<usize>childDataLength
538+
);
539+
540+
// advance the result length
541+
resultOffset += childDataLength;
542+
}
543+
544+
// if the `valueof<T>` type is managed, we must call __retain() on each reference
545+
if (isManaged<valueof<T>>()) {
546+
for (let i = 0; i < size; i++) {
547+
__retain(load<usize>(dataStart + (<usize>i << usize(alignof<valueof<T>>()))));
548+
}
549+
}
550+
551+
return changetype<T>(result);
552+
}
553+
496554
toString(): string {
497555
return this.join();
498556
}

std/assembly/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,6 +1399,8 @@ declare class Array<T> {
13991399
sort(comparator?: (a: T, b: T) => i32): this;
14001400
join(separator?: string): string;
14011401
reverse(): T[];
1402+
/** Flattens an array of arrays. If any null entries exist in the array, they are ignored, unlike JavaScript's version of Array#flat(). */
1403+
flat(): valueof<T>[];
14021404
toString(): string;
14031405
}
14041406

0 commit comments

Comments
 (0)