Skip to content

Commit 1733927

Browse files
committed
fixed conflicts
1 parent a73141f commit 1733927

File tree

10 files changed

+10044
-1170
lines changed

10 files changed

+10044
-1170
lines changed

src/ast.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,16 @@ export abstract class Node {
372372
return new StringLiteralExpression(value, range);
373373
}
374374

375+
static createTemplateLiteralExpression(
376+
value: string,
377+
range: Range
378+
): StringLiteralExpression {
379+
var expr = new StringLiteralExpression();
380+
expr.range = range;
381+
expr.value = value;
382+
return expr;
383+
}
384+
375385
static createSuperExpression(
376386
range: Range
377387
): SuperExpression {
@@ -1089,7 +1099,8 @@ export enum LiteralKind {
10891099
STRING,
10901100
REGEXP,
10911101
ARRAY,
1092-
OBJECT
1102+
OBJECT,
1103+
TEMPLATE,
10931104
}
10941105

10951106
/** Base class of all literal expressions. */
@@ -1432,6 +1443,14 @@ export class StringLiteralExpression extends LiteralExpression {
14321443
}
14331444
}
14341445

1446+
/** Represents a string template literal expression. */
1447+
export class TemplateLiteralExpression extends LiteralExpression {
1448+
literalKind = LiteralKind.TEMPLATE;
1449+
1450+
/** String value without quotes. */
1451+
value: string;
1452+
}
1453+
14351454
/** Represents a `super` expression. */
14361455
export class SuperExpression extends IdentifierExpression {
14371456
constructor(

src/compiler.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ import {
174174
NamedTypeNode,
175175

176176
findDecorator,
177-
isTypeOmitted
177+
isTypeOmitted,
178+
TemplateLiteralExpression
178179
} from "./ast";
179180

180181
import {
@@ -8757,6 +8758,10 @@ export class Compiler extends DiagnosticEmitter {
87578758
assert(!implicitlyNegate);
87588759
return this.compileStringLiteral(<StringLiteralExpression>expression, constraints);
87598760
}
8761+
case LiteralKind.TEMPLATE: {
8762+
assert(!implicitlyNegate);
8763+
return this.compileTemplateLiteral(<TemplateLiteralExpression>expression, constraints);
8764+
}
87608765
case LiteralKind.OBJECT: {
87618766
assert(!implicitlyNegate);
87628767
return this.compileObjectLiteral(<ObjectLiteralExpression>expression, contextualType);
@@ -8775,7 +8780,13 @@ export class Compiler extends DiagnosticEmitter {
87758780
return module.unreachable();
87768781
}
87778782

8778-
private compileStringLiteral(
8783+
compileTemplateLiteral(arg0: TemplateLiteralExpression, constraints: Constraints): ExpressionRef {
8784+
const innerExpressions: ExpressionRef[] = [];
8785+
8786+
return 0;
8787+
}
8788+
8789+
compileStringLiteral(
87798790
expression: StringLiteralExpression,
87808791
constraints: Constraints
87818792
): ExpressionRef {

src/parser.ts

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929
} from "./diagnostics";
3030

3131
import {
32-
normalizePath
32+
normalizePath, CharCode
3333
} from "./util";
3434

3535
import {
@@ -367,7 +367,7 @@ export class Parser extends DiagnosticEmitter {
367367
statement = this.parseExport(tn, startPos, (flags & CommonFlags.DECLARE) != 0);
368368
}
369369

370-
// handle non-declaration statements
370+
// handle non-declaration statements
371371
} else {
372372
if (exportEnd) {
373373
this.error(
@@ -551,25 +551,25 @@ export class Parser extends DiagnosticEmitter {
551551
return null;
552552
}
553553

554-
// 'void'
554+
// 'void'
555555
} else if (token == Token.VOID) {
556556
type = Node.createNamedType(
557557
Node.createSimpleTypeName("void", tn.range()), [], false, tn.range(startPos, tn.pos)
558558
);
559559

560-
// 'this'
560+
// 'this'
561561
} else if (token == Token.THIS) {
562562
type = Node.createNamedType(
563563
Node.createSimpleTypeName("this", tn.range()), [], false, tn.range(startPos, tn.pos)
564564
);
565565

566-
// 'true'
566+
// 'true'
567567
} else if (token == Token.TRUE || token == Token.FALSE) {
568568
type = Node.createNamedType(
569569
Node.createSimpleTypeName("bool", tn.range()), [], false, tn.range(startPos, tn.pos)
570570
);
571571

572-
// 'null'
572+
// 'null'
573573
} else if (token == Token.NULL) {
574574
type = Node.createNamedType(
575575
Node.createSimpleTypeName("null", tn.range()), [], false, tn.range(startPos, tn.pos)
@@ -582,7 +582,7 @@ export class Parser extends DiagnosticEmitter {
582582
Node.createSimpleTypeName("string", tn.range()), [], false, tn.range(startPos, tn.pos)
583583
);
584584

585-
// Identifier
585+
// Identifier
586586
} else if (token == Token.IDENTIFIER) {
587587
let name = this.parseTypeName(tn);
588588
if (!name) return null;
@@ -664,7 +664,7 @@ export class Parser extends DiagnosticEmitter {
664664
}
665665
type = Node.createNamedType(
666666
Node.createSimpleTypeName("Array", bracketRange),
667-
[ type ],
667+
[type],
668668
nullable,
669669
tn.range(startPos, tn.pos)
670670
);
@@ -2244,7 +2244,7 @@ export class Parser extends DiagnosticEmitter {
22442244
name.range
22452245
);
22462246

2247-
// field: (':' Type)? ('=' Expression)? ';'?
2247+
// field: (':' Type)? ('=' Expression)? ';'?
22482248
} else {
22492249
if (flags & CommonFlags.ABSTRACT) {
22502250
this.error(
@@ -2501,7 +2501,7 @@ export class Parser extends DiagnosticEmitter {
25012501
let internalPath = assert(ret.internalPath);
25022502
let source = tn.source;
25032503
let exportPaths = source.exportPaths;
2504-
if (!exportPaths) source.exportPaths = [ internalPath ];
2504+
if (!exportPaths) source.exportPaths = [internalPath];
25052505
else if (!exportPaths.includes(internalPath)) exportPaths.push(internalPath);
25062506
if (!this.seenlog.has(internalPath)) {
25072507
this.dependees.set(internalPath, new Dependee(currentSource, path));
@@ -3239,7 +3239,7 @@ export class Parser extends DiagnosticEmitter {
32393239

32403240
var startPos = tn.tokenPos;
32413241
var statements: Statement[],
3242-
statement: Statement | null;
3242+
statement: Statement | null;
32433243

32443244
// 'case' Expression ':' Statement*
32453245

@@ -3797,7 +3797,11 @@ export class Parser extends DiagnosticEmitter {
37973797
return this.maybeParseCallExpression(tn, expr);
37983798
}
37993799
case Token.STRINGLITERAL: {
3800-
return Node.createStringLiteralExpression(tn.readString(), tn.range(startPos, tn.pos));
3800+
return this.parseStringLiteral(tn, startPos);
3801+
}
3802+
case Token.TEMPLATELITERAL: {
3803+
return this.parseTemplateLiteralExpression(tn);
3804+
// return Node.createTemplateLiteralExpression(tn.readString(), tn.range(startPos, tn.pos));
38013805
}
38023806
case Token.INTEGERLITERAL: {
38033807
return Node.createIntegerLiteralExpression(tn.readInteger(), tn.range(startPos, tn.pos));
@@ -3846,6 +3850,48 @@ export class Parser extends DiagnosticEmitter {
38463850
}
38473851
}
38483852
}
3853+
parseStringLiteral(tn: Tokenizer, startPos: i32, quote: i32 = -1): Expression {
3854+
return Node.createStringLiteralExpression(tn.readString(quote), tn.range(startPos, tn.pos));
3855+
}
3856+
3857+
parseTemplateLiteralExpression(tn: Tokenizer): Expression | null {
3858+
var startPos = tn.pos;
3859+
tn.inStringTemplate = true;
3860+
3861+
// at `(String*${ Expression }*String*)*`
3862+
const parts: Expression[] = [this.parseStringLiteral(tn, startPos)];
3863+
3864+
var token = tn.peek();
3865+
while (token == Token.DOLLAR) {
3866+
tn.skip(token);
3867+
tn.skip(Token.OPENBRACE);
3868+
let expr = this.parseExpressionStart(tn);
3869+
if (expr == null) return null;
3870+
parts.push(expr);
3871+
tn.skip(Token.CLOSEBRACE);
3872+
token = tn.next();
3873+
if (token == Token.TEMPLATELITERAL) {
3874+
break;
3875+
}
3876+
if (token == Token.DOLLAR) {
3877+
continue;
3878+
}
3879+
startPos = tn.pos;
3880+
parts.push(this.parseStringLiteral(tn, startPos, CharCode.BACKTICK));
3881+
token = tn.next();
3882+
}
3883+
if (token == Token.TEMPLATELITERAL) {
3884+
tn.advance();
3885+
tn.inStringTemplate = false;
3886+
}
3887+
if (parts.length == 1) {
3888+
return parts[0];
3889+
}
3890+
return parts.reduce((acc: Expression | null, expr: Expression) => {
3891+
if (acc == null) return expr;
3892+
return Node.createBinaryExpression(Token.PLUS, acc, expr, tn.range(startPos, tn.pos));
3893+
}, null);
3894+
}
38493895

38503896
tryParseTypeArgumentsBeforeArguments(
38513897
tn: Tokenizer
@@ -3866,7 +3912,7 @@ export class Parser extends DiagnosticEmitter {
38663912
tn.reset(state);
38673913
return null;
38683914
}
3869-
if (!typeArguments) typeArguments = [ type ];
3915+
if (!typeArguments) typeArguments = [type];
38703916
else typeArguments.push(type);
38713917
} while (tn.skip(Token.COMMA));
38723918
if (tn.skip(Token.GREATERTHAN)) {
@@ -4036,7 +4082,7 @@ export class Parser extends DiagnosticEmitter {
40364082
}
40374083
// CommaExpression
40384084
case Token.COMMA: {
4039-
let commaExprs: Expression[] = [ expr ];
4085+
let commaExprs: Expression[] = [expr];
40404086
do {
40414087
expr = this.parseExpression(tn, Precedence.COMMA + 1);
40424088
if (!expr) return null;

src/tokenizer.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,13 @@ export enum Token {
156156
BAR_EQUALS,
157157
CARET_EQUALS,
158158
AT,
159+
DOLLAR,
159160

160161
// literals
161162

162163
IDENTIFIER,
163164
STRINGLITERAL,
165+
TEMPLATELITERAL,
164166
INTEGERLITERAL,
165167
FLOATLITERAL,
166168

@@ -458,6 +460,7 @@ export class Tokenizer extends DiagnosticEmitter {
458460
nextTokenOnNewLine: bool = false;
459461

460462
onComment: CommentHandler | null = null;
463+
public inStringTemplate: bool = false;
461464

462465
/** Constructs a new tokenizer. */
463466
constructor(source: Source, diagnostics: DiagnosticMessage[] | null = null) {
@@ -553,7 +556,9 @@ export class Tokenizer extends DiagnosticEmitter {
553556
return Token.EXCLAMATION;
554557
}
555558
case CharCode.DOUBLEQUOTE:
556-
case CharCode.SINGLEQUOTE:
559+
case CharCode.SINGLEQUOTE: {
560+
return Token.STRINGLITERAL;
561+
}
557562
case CharCode.BACKTICK: { // TODO
558563
this.pos = pos;
559564
return Token.STRINGLITERAL; // expects a call to readString
@@ -904,6 +909,13 @@ export class Tokenizer extends DiagnosticEmitter {
904909
this.pos = pos + 1;
905910
return Token.AT;
906911
}
912+
case CharCode.DOLLAR: {
913+
if (this.inStringTemplate) {
914+
++this.pos;
915+
return Token.DOLLAR;
916+
}
917+
// fall through to identifier
918+
}
907919
default: {
908920
if (isIdentifierStart(c)) {
909921
if (isKeywordCharacter(c)) {
@@ -1014,6 +1026,11 @@ export class Tokenizer extends DiagnosticEmitter {
10141026
}
10151027
}
10161028

1029+
advance() {
1030+
this.nextToken = -1;
1031+
++this.pos;
1032+
}
1033+
10171034
mark(): State {
10181035
var state = reusableState;
10191036
if (state) {
@@ -1063,7 +1080,7 @@ export class Tokenizer extends DiagnosticEmitter {
10631080
return text.substring(start, pos);
10641081
}
10651082

1066-
readString(): string {
1083+
readString(quote: i32 = -1): string {
10671084
var text = this.source.text;
10681085
var end = this.end;
10691086
var pos = this.pos;
@@ -1128,6 +1145,7 @@ export class Tokenizer extends DiagnosticEmitter {
11281145
case CharCode.r: return "\r";
11291146
case CharCode.SINGLEQUOTE: return "'";
11301147
case CharCode.DOUBLEQUOTE: return "\"";
1148+
case CharCode.BACKTICK: return "`";
11311149
case CharCode.u: {
11321150
if (
11331151
this.pos < end &&

tests/compiler/std/string.optimized.wat

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@
454454
(global $std/string/str (mut i32) (i32.const 1040))
455455
(global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0))
456456
(global $~lib/rt/tlsf/collectLock (mut i32) (i32.const 0))
457+
(global $std/string/templateStr (mut i32) (i32.const 0))
457458
(global $~argumentsLength (mut i32) (i32.const 0))
458459
(global $~lib/util/string/__fixmulShift (mut i64) (i64.const 0))
459460
(global $~lib/util/number/_frc_plus (mut i64) (i64.const 0))
@@ -16468,13 +16469,13 @@
1646816469
call $~lib/rt/pure/__release
1646916470
local.get $51
1647016471
call $~lib/rt/pure/__release
16471-
local.get $52
16472+
local.get $55
1647216473
call $~lib/rt/pure/__release
1647316474
local.get $53
1647416475
call $~lib/rt/pure/__release
1647516476
local.get $54
1647616477
call $~lib/rt/pure/__release
16477-
local.get $55
16478+
local.get $51
1647816479
call $~lib/rt/pure/__release
1647916480
local.get $56
1648016481
call $~lib/rt/pure/__release
@@ -16610,6 +16611,8 @@
1661016611
call $~lib/rt/pure/__release
1661116612
local.get $123
1661216613
call $~lib/rt/pure/__release
16614+
local.get $122
16615+
call $~lib/rt/pure/__release
1661316616
local.get $124
1661416617
call $~lib/rt/pure/__release
1661516618
local.get $125

0 commit comments

Comments
 (0)