Skip to content

Commit b7dfb8f

Browse files
committed
feat: add support for named tuple types like [x: f64, y: f64]
1 parent 6c869a5 commit b7dfb8f

4 files changed

Lines changed: 34 additions & 5 deletions

File tree

src/ast.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,11 @@ export abstract class Node {
164164

165165
static createTupleType(
166166
elements: TypeNode[],
167+
elementNames: (IdentifierExpression | null)[] | null,
167168
isNullable: bool,
168169
range: Range
169170
): TupleTypeNode {
170-
return new TupleTypeNode(elements, isNullable, range);
171+
return new TupleTypeNode(elements, elementNames, isNullable, range);
171172
}
172173

173174
static createOmittedType(
@@ -948,6 +949,8 @@ export class TupleTypeNode extends TypeNode {
948949
constructor(
949950
/** Tuple elements. */
950951
public elements: TypeNode[],
952+
/** Tuple element names, if any. */
953+
public elementNames: (IdentifierExpression | null)[] | null,
951954
/** Whether nullable or not. */
952955
isNullable: bool,
953956
/** Source range. */

src/extra/ast.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,11 +463,22 @@ export class ASTBuilder {
463463
let sb = this.sb;
464464
sb.push("[");
465465
let elements = node.elements;
466+
let elementNames = node.elementNames;
466467
let numElements = elements.length;
467468
if (numElements) {
469+
let name = elementNames ? elementNames[0] : null;
470+
if (name) {
471+
this.visitIdentifierExpression(name);
472+
sb.push(": ");
473+
}
468474
this.visitTypeNode(elements[0]);
469475
for (let i = 1; i < numElements; ++i) {
470476
sb.push(", ");
477+
name = elementNames ? elementNames[i] : null;
478+
if (name) {
479+
this.visitIdentifierExpression(name);
480+
sb.push(": ");
481+
}
471482
this.visitTypeNode(elements[i]);
472483
}
473484
}

src/parser.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,11 +578,26 @@ export class Parser extends DiagnosticEmitter {
578578
// '[' Type (',' Type)* ']'
579579
} else if (token == Token.OpenBracket) {
580580
let elements: TypeNode[] = [];
581+
let elementNames: (IdentifierExpression | null)[] = [];
582+
let hasElementNames = false;
581583
if (!tn.skip(Token.CloseBracket)) {
582584
do {
585+
let elementName: IdentifierExpression | null = null;
586+
let state = tn.mark();
587+
if (tn.skip(Token.Identifier)) {
588+
let name = tn.readIdentifier();
589+
let nameRange = tn.range();
590+
if (tn.skip(Token.Colon)) {
591+
elementName = Node.createIdentifierExpression(name, nameRange);
592+
hasElementNames = true;
593+
} else {
594+
tn.reset(state);
595+
}
596+
}
583597
let element = this.parseType(tn, true, suppressErrors);
584598
if (!element) return null;
585599
elements.push(element);
600+
elementNames.push(elementName);
586601
} while (tn.skip(Token.Comma));
587602
if (!tn.skip(Token.CloseBracket)) {
588603
if (!suppressErrors) {
@@ -594,7 +609,7 @@ export class Parser extends DiagnosticEmitter {
594609
return null;
595610
}
596611
}
597-
type = Node.createTupleType(elements, false, tn.range(startPos, tn.pos));
612+
type = Node.createTupleType(elements, hasElementNames ? elementNames : null, false, tn.range(startPos, tn.pos));
598613

599614
// 'void'
600615
} else if (token == Token.Void) {

src/program.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,9 @@ export namespace OperatorKind {
390390
case Token.GreaterThan_GreaterThan_Equals: return OperatorKind.BitwiseShr;
391391
case Token.GreaterThan_GreaterThan_GreaterThan:
392392
case Token.GreaterThan_GreaterThan_GreaterThan_Equals: return OperatorKind.BitwiseShrU;
393-
case Token.Equals_Equals:
393+
case Token.Equals_Equals:
394394
case Token.Equals_Equals_Equals: return OperatorKind.Eq;
395-
case Token.Exclamation_Equals:
395+
case Token.Exclamation_Equals:
396396
case Token.Exclamation_Equals_Equals: return OperatorKind.Ne;
397397
case Token.GreaterThan: return OperatorKind.Gt;
398398
case Token.GreaterThan_Equals: return OperatorKind.Ge;
@@ -436,7 +436,7 @@ export class Program extends DiagnosticEmitter {
436436
diagnostics: DiagnosticMessage[] | null = null
437437
) {
438438
super(diagnostics);
439-
this.module = Module.create(options.stackSize > 0, options.sizeTypeRef);
439+
this.module = Module.create(options.stackSize > 0, options.sizeTypeRef);
440440
this.parser = new Parser(this.diagnostics, this.sources);
441441
this.resolver = new Resolver(this);
442442
let nativeFile = new File(this, Source.native);

0 commit comments

Comments
 (0)