@harmoniclabs/pebble 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast/nodes/expr/IsExpr.d.ts +10 -1
- package/dist/ast/nodes/expr/IsExpr.js +9 -13
- package/dist/ast/nodes/expr/PebbleExpr.d.ts +2 -1
- package/dist/ast/nodes/expr/PebbleExpr.js +2 -1
- package/dist/ast/nodes/statements/declarations/ContractDecl.d.ts +3 -1
- package/dist/ast/nodes/statements/declarations/ContractDecl.js +3 -1
- package/dist/ast/nodes/statements/declarations/StateDecl.d.ts +12 -0
- package/dist/ast/nodes/statements/declarations/StateDecl.js +12 -0
- package/dist/compiler/AstCompiler/internal/_deriveContractBody/_deriveContractBody.js +154 -6
- package/dist/compiler/AstCompiler/internal/exprs/_compileCaseExpr.d.ts +1 -1
- package/dist/compiler/AstCompiler/internal/exprs/_compileCaseExpr.js +30 -4
- package/dist/compiler/AstCompiler/internal/exprs/_compileExpr.js +4 -1
- package/dist/compiler/AstCompiler/internal/exprs/_compileIsExpr.d.ts +5 -1
- package/dist/compiler/AstCompiler/internal/exprs/_compileIsExpr.js +20 -41
- package/dist/compiler/AstCompiler/internal/exprs/_compileTernaryExpr.js +7 -2
- package/dist/compiler/AstCompiler/internal/statements/_compileAssertStmt.js +4 -0
- package/dist/compiler/AstCompiler/internal/statements/_compileIfStmt.js +7 -2
- package/dist/compiler/AstCompiler/internal/statements/_compileMatchStmt.d.ts +1 -1
- package/dist/compiler/AstCompiler/internal/statements/_compileMatchStmt.js +17 -4
- package/dist/compiler/AstCompiler/scope/AstScope.d.ts +12 -0
- package/dist/compiler/AstCompiler/scope/AstScope.js +25 -2
- package/dist/compiler/AstCompiler/utils/extractIsNarrowings.d.ts +30 -0
- package/dist/compiler/AstCompiler/utils/extractIsNarrowings.js +110 -0
- package/dist/compiler/Compiler.js +7 -3
- package/dist/compiler/TirCompiler/expressify/expressifyVars.js +6 -0
- package/dist/compiler/tir/expressions/TirCallExpr.js +4 -0
- package/dist/compiler/tir/expressions/TirCaseExpr.js +38 -7
- package/dist/compiler/tir/expressions/TirExpr.d.ts +2 -1
- package/dist/compiler/tir/expressions/TirExpr.js +2 -1
- package/dist/compiler/tir/expressions/TirFuncExpr.js +4 -1
- package/dist/compiler/tir/expressions/TirIsExpr.d.ts +23 -0
- package/dist/compiler/tir/expressions/TirIsExpr.js +87 -0
- package/dist/compiler/tir/types/TirStructType.d.ts +33 -2
- package/dist/compiler/tir/types/TirStructType.js +69 -4
- package/dist/compiler/tir/types/utils/canAssignTo.js +14 -0
- package/dist/parser/Parser.d.ts +2 -0
- package/dist/parser/Parser.js +87 -22
- package/dist/tokenizer/Token.d.ts +79 -78
- package/dist/tokenizer/Token.js +79 -78
- package/dist/tokenizer/utils/tokenFromKeyword.js +7 -2
- package/dist/tokenizer/utils/tokenIsAlsoIdentifier.js +1 -0
- package/package.json +2 -1
|
@@ -17,13 +17,33 @@ export declare class TirDataStructType implements ITirStructType {
|
|
|
17
17
|
/** points to an array possibly shared with alternative encoding types */
|
|
18
18
|
readonly methodNamesPtr: Map<AstFuncName, TirFuncName>;
|
|
19
19
|
readonly untagged: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* indexes (in the ORIGINAL parent struct's constructors array) of the
|
|
22
|
+
* constructors still possible after flow-sensitive narrowing.
|
|
23
|
+
*
|
|
24
|
+
* `undefined` means "not narrowed" (full struct).
|
|
25
|
+
* If present, length matches `this.constructors.length` and entries
|
|
26
|
+
* correspond positionally to `this.constructors`.
|
|
27
|
+
*/
|
|
28
|
+
readonly narrowedFromParentCtorIdxs: number[] | undefined;
|
|
20
29
|
constructor(name: string, fileUid: string, constructors: TirStructConstr[],
|
|
21
30
|
/** points to an array possibly shared with alternative encoding types */
|
|
22
|
-
methodNamesPtr: Map<AstFuncName, TirFuncName>, untagged?: boolean);
|
|
31
|
+
methodNamesPtr: Map<AstFuncName, TirFuncName>, untagged?: boolean, narrowedFromParentCtorIdxs?: number[] | undefined);
|
|
23
32
|
hasDataEncoding(): boolean;
|
|
24
33
|
toTirTypeKey(): string;
|
|
25
34
|
toConcreteTirTypeName(): string;
|
|
26
35
|
isSingleConstr(): boolean;
|
|
36
|
+
isNarrowed(): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Original ctor index of `this.constructors[localIdx]` in the
|
|
39
|
+
* un-narrowed parent type. For un-narrowed types this is identity.
|
|
40
|
+
*/
|
|
41
|
+
parentCtorIdx(localIdx: number): number;
|
|
42
|
+
/**
|
|
43
|
+
* Returns a clone of this struct type narrowed to the constructors
|
|
44
|
+
* whose ORIGINAL parent indexes are listed in `parentIdxs`.
|
|
45
|
+
*/
|
|
46
|
+
narrowTo(parentIdxs: number[]): TirDataStructType;
|
|
27
47
|
toString(): string;
|
|
28
48
|
toAstName(): string;
|
|
29
49
|
protected _isConcrete: boolean | undefined;
|
|
@@ -37,13 +57,24 @@ export declare class TirSoPStructType implements ITirStructType {
|
|
|
37
57
|
readonly constructors: TirStructConstr[];
|
|
38
58
|
/** points to an array possibly shared with alternative encoding types */
|
|
39
59
|
readonly methodNamesPtr: Map<AstFuncName, TirFuncName>;
|
|
60
|
+
/**
|
|
61
|
+
* indexes (in the ORIGINAL parent struct's constructors array) of the
|
|
62
|
+
* constructors still possible after flow-sensitive narrowing.
|
|
63
|
+
*
|
|
64
|
+
* `undefined` means "not narrowed" (full struct).
|
|
65
|
+
* If present, length matches `this.constructors.length`.
|
|
66
|
+
*/
|
|
67
|
+
readonly narrowedFromParentCtorIdxs: number[] | undefined;
|
|
40
68
|
constructor(name: string, fileUid: string, constructors: TirStructConstr[],
|
|
41
69
|
/** points to an array possibly shared with alternative encoding types */
|
|
42
|
-
methodNamesPtr: Map<AstFuncName, TirFuncName
|
|
70
|
+
methodNamesPtr: Map<AstFuncName, TirFuncName>, narrowedFromParentCtorIdxs?: number[] | undefined);
|
|
43
71
|
hasDataEncoding(): boolean;
|
|
44
72
|
toTirTypeKey(): string;
|
|
45
73
|
toConcreteTirTypeName(): string;
|
|
46
74
|
isSingleConstr(): boolean;
|
|
75
|
+
isNarrowed(): boolean;
|
|
76
|
+
parentCtorIdx(localIdx: number): number;
|
|
77
|
+
narrowTo(parentIdxs: number[]): TirSoPStructType;
|
|
47
78
|
toString(): string;
|
|
48
79
|
toAstName(): string;
|
|
49
80
|
protected _isConcrete: boolean | undefined;
|
|
@@ -10,15 +10,25 @@ export class TirDataStructType {
|
|
|
10
10
|
constructors;
|
|
11
11
|
methodNamesPtr;
|
|
12
12
|
untagged;
|
|
13
|
+
/**
|
|
14
|
+
* indexes (in the ORIGINAL parent struct's constructors array) of the
|
|
15
|
+
* constructors still possible after flow-sensitive narrowing.
|
|
16
|
+
*
|
|
17
|
+
* `undefined` means "not narrowed" (full struct).
|
|
18
|
+
* If present, length matches `this.constructors.length` and entries
|
|
19
|
+
* correspond positionally to `this.constructors`.
|
|
20
|
+
*/
|
|
21
|
+
narrowedFromParentCtorIdxs;
|
|
13
22
|
constructor(name, fileUid, constructors,
|
|
14
23
|
/** points to an array possibly shared with alternative encoding types */
|
|
15
|
-
methodNamesPtr, untagged = false) {
|
|
24
|
+
methodNamesPtr, untagged = false, narrowedFromParentCtorIdxs = undefined) {
|
|
16
25
|
this.name = name;
|
|
17
26
|
this.fileUid = fileUid;
|
|
18
27
|
this.constructors = constructors;
|
|
19
28
|
this.methodNamesPtr = methodNamesPtr;
|
|
20
29
|
this.untagged = untagged;
|
|
21
30
|
this.untagged = false; // always false for now
|
|
31
|
+
this.narrowedFromParentCtorIdxs = narrowedFromParentCtorIdxs;
|
|
22
32
|
}
|
|
23
33
|
hasDataEncoding() { return true; }
|
|
24
34
|
toTirTypeKey() {
|
|
@@ -30,6 +40,33 @@ export class TirDataStructType {
|
|
|
30
40
|
isSingleConstr() {
|
|
31
41
|
return this.constructors.length === 1;
|
|
32
42
|
}
|
|
43
|
+
isNarrowed() {
|
|
44
|
+
return this.narrowedFromParentCtorIdxs !== undefined;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Original ctor index of `this.constructors[localIdx]` in the
|
|
48
|
+
* un-narrowed parent type. For un-narrowed types this is identity.
|
|
49
|
+
*/
|
|
50
|
+
parentCtorIdx(localIdx) {
|
|
51
|
+
return this.narrowedFromParentCtorIdxs?.[localIdx] ?? localIdx;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Returns a clone of this struct type narrowed to the constructors
|
|
55
|
+
* whose ORIGINAL parent indexes are listed in `parentIdxs`.
|
|
56
|
+
*/
|
|
57
|
+
narrowTo(parentIdxs) {
|
|
58
|
+
const baseIdxs = this.narrowedFromParentCtorIdxs ?? this.constructors.map((_, i) => i);
|
|
59
|
+
const filtered = [];
|
|
60
|
+
const filteredCtors = [];
|
|
61
|
+
for (let i = 0; i < this.constructors.length; i++) {
|
|
62
|
+
const parentIdx = baseIdxs[i];
|
|
63
|
+
if (parentIdxs.includes(parentIdx)) {
|
|
64
|
+
filtered.push(parentIdx);
|
|
65
|
+
filteredCtors.push(this.constructors[i]);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return new TirDataStructType(this.name, this.fileUid, filteredCtors, this.methodNamesPtr, this.untagged, filtered);
|
|
69
|
+
}
|
|
33
70
|
toString() {
|
|
34
71
|
return this.name;
|
|
35
72
|
}
|
|
@@ -43,7 +80,7 @@ export class TirDataStructType {
|
|
|
43
80
|
return this._isConcrete;
|
|
44
81
|
}
|
|
45
82
|
clone() {
|
|
46
|
-
const result = new TirDataStructType(this.name, this.fileUid, this.constructors.map(c => c.clone()), this.methodNamesPtr);
|
|
83
|
+
const result = new TirDataStructType(this.name, this.fileUid, this.constructors.map(c => c.clone()), this.methodNamesPtr, this.untagged, this.narrowedFromParentCtorIdxs ? [...this.narrowedFromParentCtorIdxs] : undefined);
|
|
47
84
|
result._isConcrete = this._isConcrete;
|
|
48
85
|
return result;
|
|
49
86
|
}
|
|
@@ -56,13 +93,22 @@ export class TirSoPStructType {
|
|
|
56
93
|
fileUid;
|
|
57
94
|
constructors;
|
|
58
95
|
methodNamesPtr;
|
|
96
|
+
/**
|
|
97
|
+
* indexes (in the ORIGINAL parent struct's constructors array) of the
|
|
98
|
+
* constructors still possible after flow-sensitive narrowing.
|
|
99
|
+
*
|
|
100
|
+
* `undefined` means "not narrowed" (full struct).
|
|
101
|
+
* If present, length matches `this.constructors.length`.
|
|
102
|
+
*/
|
|
103
|
+
narrowedFromParentCtorIdxs;
|
|
59
104
|
constructor(name, fileUid, constructors,
|
|
60
105
|
/** points to an array possibly shared with alternative encoding types */
|
|
61
|
-
methodNamesPtr) {
|
|
106
|
+
methodNamesPtr, narrowedFromParentCtorIdxs = undefined) {
|
|
62
107
|
this.name = name;
|
|
63
108
|
this.fileUid = fileUid;
|
|
64
109
|
this.constructors = constructors;
|
|
65
110
|
this.methodNamesPtr = methodNamesPtr;
|
|
111
|
+
this.narrowedFromParentCtorIdxs = narrowedFromParentCtorIdxs;
|
|
66
112
|
}
|
|
67
113
|
hasDataEncoding() { return false; }
|
|
68
114
|
toTirTypeKey() {
|
|
@@ -74,6 +120,25 @@ export class TirSoPStructType {
|
|
|
74
120
|
isSingleConstr() {
|
|
75
121
|
return this.constructors.length === 1;
|
|
76
122
|
}
|
|
123
|
+
isNarrowed() {
|
|
124
|
+
return this.narrowedFromParentCtorIdxs !== undefined;
|
|
125
|
+
}
|
|
126
|
+
parentCtorIdx(localIdx) {
|
|
127
|
+
return this.narrowedFromParentCtorIdxs?.[localIdx] ?? localIdx;
|
|
128
|
+
}
|
|
129
|
+
narrowTo(parentIdxs) {
|
|
130
|
+
const baseIdxs = this.narrowedFromParentCtorIdxs ?? this.constructors.map((_, i) => i);
|
|
131
|
+
const filtered = [];
|
|
132
|
+
const filteredCtors = [];
|
|
133
|
+
for (let i = 0; i < this.constructors.length; i++) {
|
|
134
|
+
const parentIdx = baseIdxs[i];
|
|
135
|
+
if (parentIdxs.includes(parentIdx)) {
|
|
136
|
+
filtered.push(parentIdx);
|
|
137
|
+
filteredCtors.push(this.constructors[i]);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return new TirSoPStructType(this.name, this.fileUid, filteredCtors, this.methodNamesPtr, filtered);
|
|
141
|
+
}
|
|
77
142
|
toString() {
|
|
78
143
|
return this.name;
|
|
79
144
|
}
|
|
@@ -87,7 +152,7 @@ export class TirSoPStructType {
|
|
|
87
152
|
return this._isConcrete;
|
|
88
153
|
}
|
|
89
154
|
clone() {
|
|
90
|
-
const result = new TirSoPStructType(this.name, this.fileUid, this.constructors.map(c => c.clone()), this.methodNamesPtr);
|
|
155
|
+
const result = new TirSoPStructType(this.name, this.fileUid, this.constructors.map(c => c.clone()), this.methodNamesPtr, this.narrowedFromParentCtorIdxs ? [...this.narrowedFromParentCtorIdxs] : undefined);
|
|
91
156
|
result._isConcrete = this._isConcrete;
|
|
92
157
|
return result;
|
|
93
158
|
}
|
|
@@ -240,6 +240,20 @@ function canAssignStruct(a, b, symbols) {
|
|
|
240
240
|
a = a.aliased;
|
|
241
241
|
while (b instanceof TirAliasType)
|
|
242
242
|
b = b.aliased;
|
|
243
|
+
// Same logical struct type? (same name + fileUid). When this holds,
|
|
244
|
+
// we use parent-ctor-idx based subset checks to handle narrowing.
|
|
245
|
+
const sameLogicalType = a.name === b.name
|
|
246
|
+
&& a.fileUid === b.fileUid;
|
|
247
|
+
if (sameLogicalType) {
|
|
248
|
+
const aIdxs = a.narrowedFromParentCtorIdxs ?? a.constructors.map((_, i) => i);
|
|
249
|
+
const bIdxs = b.narrowedFromParentCtorIdxs ?? b.constructors.map((_, i) => i);
|
|
250
|
+
// a is assignable to b iff a's parent-ctor set is a SUBSET of b's
|
|
251
|
+
for (const idx of aIdxs) {
|
|
252
|
+
if (!bIdxs.includes(idx))
|
|
253
|
+
return CanAssign.No;
|
|
254
|
+
}
|
|
255
|
+
return CanAssign.Yes;
|
|
256
|
+
}
|
|
243
257
|
const aCtors = a.constructors;
|
|
244
258
|
const bCtors = b.constructors;
|
|
245
259
|
if (aCtors.length !== bCtors.length)
|
package/dist/parser/Parser.d.ts
CHANGED
|
@@ -43,6 +43,7 @@ import { UsingStmt } from "../ast/nodes/statements/UsingStmt.js";
|
|
|
43
43
|
import { BodyStmt, TopLevelStmt } from "../ast/nodes/statements/PebbleStmt.js";
|
|
44
44
|
import { Precedence } from "./Precedence.js";
|
|
45
45
|
import { ContractDecl } from "../ast/nodes/statements/declarations/ContractDecl.js";
|
|
46
|
+
import { StateDecl } from "../ast/nodes/statements/declarations/StateDecl.js";
|
|
46
47
|
interface ParseStmtOpts {
|
|
47
48
|
isExport?: boolean;
|
|
48
49
|
topLevel?: boolean;
|
|
@@ -55,6 +56,7 @@ export declare class Parser extends DiagnosticEmitter {
|
|
|
55
56
|
parseSource(): DiagnosticMessage[];
|
|
56
57
|
parseTopLevelStatement(): TopLevelStmt | undefined;
|
|
57
58
|
parseContractDecl(startPos: number): ContractDecl | undefined;
|
|
59
|
+
parseStateDecl(startPos: number): StateDecl | undefined;
|
|
58
60
|
parseUsingDecl(): UsingStmt | undefined;
|
|
59
61
|
parseTypeParameters(): Identifier[] | undefined;
|
|
60
62
|
parseTypeArguments(): AstTypeExpr[] | undefined;
|
package/dist/parser/Parser.js
CHANGED
|
@@ -59,6 +59,7 @@ import { EnumDecl, EnumValueDecl } from "../ast/nodes/statements/declarations/En
|
|
|
59
59
|
import { TypeConversionExpr } from "../ast/nodes/expr/TypeConversionExpr.js";
|
|
60
60
|
import { NonNullExpr } from "../ast/nodes/expr/unary/NonNullExpr.js";
|
|
61
61
|
import { ElemAccessExpr } from "../ast/nodes/expr/ElemAccessExpr.js";
|
|
62
|
+
import { IsExpr } from "../ast/nodes/expr/IsExpr.js";
|
|
62
63
|
import { TernaryExpr } from "../ast/nodes/expr/TernaryExpr.js";
|
|
63
64
|
import { makePropAccessExpr } from "../ast/nodes/expr/PropAccessExpr.js";
|
|
64
65
|
import { makeBinaryExpr } from "../ast/nodes/expr/binary/BinaryExpr.js";
|
|
@@ -72,6 +73,7 @@ import { defaultSymbolForge } from "../compiler/internalVar.js";
|
|
|
72
73
|
import { Precedence, determinePrecedence } from "./Precedence.js";
|
|
73
74
|
import { LitFailExpr } from "../ast/nodes/expr/litteral/LitFailExpr.js";
|
|
74
75
|
import { ContractDecl } from "../ast/nodes/statements/declarations/ContractDecl.js";
|
|
76
|
+
import { StateDecl } from "../ast/nodes/statements/declarations/StateDecl.js";
|
|
75
77
|
import { LitContextExpr } from "../ast/nodes/expr/litteral/LitContextExpr.js";
|
|
76
78
|
import { tokenIsAlsoIdentifier } from "../tokenizer/utils/tokenIsAlsoIdentifier.js";
|
|
77
79
|
export class Parser extends DiagnosticEmitter {
|
|
@@ -247,12 +249,24 @@ export class Parser extends DiagnosticEmitter {
|
|
|
247
249
|
const withdrawMethods = [];
|
|
248
250
|
const proposeMethods = [];
|
|
249
251
|
const voteMethods = [];
|
|
252
|
+
const stateDecls = [];
|
|
250
253
|
while (!tn.skip(Token.CloseBrace)) {
|
|
251
254
|
tn.skip(Token.Semicolon); // if any
|
|
252
255
|
const thisStartPos = tn.tokenPos;
|
|
253
256
|
const prevState = tn.mark();
|
|
254
257
|
const nextToken = tn.next();
|
|
255
258
|
switch (nextToken) {
|
|
259
|
+
case Token.State:
|
|
260
|
+
{
|
|
261
|
+
const stateDecl = this.parseStateDecl(thisStartPos);
|
|
262
|
+
if (!stateDecl)
|
|
263
|
+
return undefined;
|
|
264
|
+
if (stateDecls.some(s => s.name.text === stateDecl.name.text))
|
|
265
|
+
return this.error(DiagnosticCode.Duplicate_identifier_0, stateDecl.name.range, stateDecl.name.text);
|
|
266
|
+
stateDecls.push(stateDecl);
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
break;
|
|
256
270
|
case Token.Param:
|
|
257
271
|
{
|
|
258
272
|
const varDecl = this._parseVarDecl(CommonFlags.Const);
|
|
@@ -300,7 +314,62 @@ export class Parser extends DiagnosticEmitter {
|
|
|
300
314
|
}
|
|
301
315
|
continue;
|
|
302
316
|
}
|
|
303
|
-
return new ContractDecl(contractName, params, spendMethods, mintMethods, certifyMethods, withdrawMethods, proposeMethods, voteMethods, tn.range(startPos, tn.pos));
|
|
317
|
+
return new ContractDecl(contractName, params, spendMethods, mintMethods, certifyMethods, withdrawMethods, proposeMethods, voteMethods, stateDecls, tn.range(startPos, tn.pos));
|
|
318
|
+
}
|
|
319
|
+
parseStateDecl(startPos) {
|
|
320
|
+
const tn = this.tn;
|
|
321
|
+
startPos = typeof startPos === "number" ? startPos : tn.tokenPos;
|
|
322
|
+
// at 'state': Identifier '{' ... '}'
|
|
323
|
+
if (!tn.skipIdentifier())
|
|
324
|
+
return this.error(DiagnosticCode.Identifier_expected, tn.range());
|
|
325
|
+
const name = new Identifier(tn.readIdentifier(), tn.range());
|
|
326
|
+
if (!tn.skip(Token.OpenBrace))
|
|
327
|
+
return this.error(DiagnosticCode._0_expected, tn.range(), "{");
|
|
328
|
+
const fields = [];
|
|
329
|
+
const spendMethods = [];
|
|
330
|
+
while (!tn.skip(Token.CloseBrace)) {
|
|
331
|
+
tn.skip(Token.Comma); // if any
|
|
332
|
+
tn.skip(Token.Semicolon); // if any
|
|
333
|
+
if (tn.skip(Token.CloseBrace))
|
|
334
|
+
break;
|
|
335
|
+
const memberStartPos = tn.tokenPos;
|
|
336
|
+
const prevState = tn.mark();
|
|
337
|
+
const nextToken = tn.next();
|
|
338
|
+
if (nextToken === Token.Spend) {
|
|
339
|
+
const funcDecl = this.parseFuncDecl(CommonFlags.None, memberStartPos, new AstVoidType(tn.range()));
|
|
340
|
+
if (!funcDecl)
|
|
341
|
+
return undefined;
|
|
342
|
+
if (!(funcDecl.expr.signature.returnType instanceof AstVoidType))
|
|
343
|
+
return this.error(DiagnosticCode.Contract_methods_must_return_void_or_fail, funcDecl.expr.signature.returnType?.range ?? funcDecl.expr.signature.range);
|
|
344
|
+
spendMethods.push(funcDecl);
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
if (nextToken === Token.Mint
|
|
348
|
+
|| nextToken === Token.Certify
|
|
349
|
+
|| nextToken === Token.Withdraw
|
|
350
|
+
|| nextToken === Token.Propose
|
|
351
|
+
|| nextToken === Token.Vote) {
|
|
352
|
+
return this.error(DiagnosticCode._0_expected, tn.range(), "spend method or field");
|
|
353
|
+
}
|
|
354
|
+
// not a method: parse as field declaration
|
|
355
|
+
tn.reset(prevState);
|
|
356
|
+
if (spendMethods.length > 0) {
|
|
357
|
+
// fields must come before spend methods
|
|
358
|
+
return this.error(DiagnosticCode._0_expected, tn.range(), "spend method");
|
|
359
|
+
}
|
|
360
|
+
const field = this._parseVarDecl(CommonFlags.Const);
|
|
361
|
+
if (!field)
|
|
362
|
+
return undefined;
|
|
363
|
+
if (!(field instanceof SimpleVarDecl))
|
|
364
|
+
return this.error(DiagnosticCode.Invalid_field_declaration, field.range);
|
|
365
|
+
if (!field.type)
|
|
366
|
+
return this.error(DiagnosticCode.Type_expected, field.range.atEnd());
|
|
367
|
+
if (field.initExpr)
|
|
368
|
+
return this.error(DiagnosticCode.Initialization_expressions_are_not_allowed_in_a_struct_declaration, SourceRange.join(field.type.range.atEnd(), field.initExpr.range));
|
|
369
|
+
fields.push(field);
|
|
370
|
+
}
|
|
371
|
+
tn.skip(Token.Semicolon); // if any
|
|
372
|
+
return new StateDecl(name, fields, spendMethods, tn.range(startPos, tn.pos));
|
|
304
373
|
}
|
|
305
374
|
parseUsingDecl() {
|
|
306
375
|
const tn = this.tn;
|
|
@@ -1171,28 +1240,15 @@ export class Parser extends DiagnosticEmitter {
|
|
|
1171
1240
|
expr = this.tryParseCallExprOrReturnSame(expr);
|
|
1172
1241
|
break;
|
|
1173
1242
|
}
|
|
1174
|
-
/*
|
|
1175
1243
|
case Token.Is: {
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
{
|
|
1180
|
-
this.error(
|
|
1181
|
-
DiagnosticCode.Identifier_expected,
|
|
1182
|
-
tn.range()
|
|
1183
|
-
);
|
|
1184
|
-
return undefined
|
|
1244
|
+
if (!tn.skipIdentifier()) {
|
|
1245
|
+
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
|
1246
|
+
return undefined;
|
|
1185
1247
|
}
|
|
1186
|
-
const
|
|
1187
|
-
tn.
|
|
1188
|
-
expr = new IsExpr(
|
|
1189
|
-
expr,
|
|
1190
|
-
ofType,
|
|
1191
|
-
tn.range( startPos, tn.pos )
|
|
1192
|
-
);
|
|
1248
|
+
const ofConstr = new Identifier(tn.readIdentifier(), tn.range());
|
|
1249
|
+
expr = new IsExpr(expr, ofConstr, tn.range(startPos, tn.pos));
|
|
1193
1250
|
break;
|
|
1194
1251
|
}
|
|
1195
|
-
//*/
|
|
1196
1252
|
case Token.OpenBracket: { // [ // accessing list element
|
|
1197
1253
|
const idxExpr = this.parseExpr();
|
|
1198
1254
|
if (!idxExpr)
|
|
@@ -1565,6 +1621,7 @@ export class Parser extends DiagnosticEmitter {
|
|
|
1565
1621
|
const expr = this.parseCaseExpr();
|
|
1566
1622
|
if (!expr)
|
|
1567
1623
|
return undefined;
|
|
1624
|
+
return expr;
|
|
1568
1625
|
}
|
|
1569
1626
|
case Token.Fail: {
|
|
1570
1627
|
return new LitFailExpr(tn.range());
|
|
@@ -1604,7 +1661,9 @@ export class Parser extends DiagnosticEmitter {
|
|
|
1604
1661
|
const tn = this.tn;
|
|
1605
1662
|
// at 'case': Expression ('is' VarDecl '=>' Expression)+ ('else' Expression)?
|
|
1606
1663
|
const startPos = tn.tokenPos;
|
|
1607
|
-
|
|
1664
|
+
// parse the matched expression at a precedence higher than `is`
|
|
1665
|
+
// so the case-level `is` is left unconsumed
|
|
1666
|
+
const expr = this.parseExpr(Precedence.Relational + 1);
|
|
1608
1667
|
if (!expr)
|
|
1609
1668
|
return undefined;
|
|
1610
1669
|
let noPatternCaseSeen = false;
|
|
@@ -1622,7 +1681,10 @@ export class Parser extends DiagnosticEmitter {
|
|
|
1622
1681
|
return this.error(DiagnosticCode.Patterns_may_not_have_initializers_or_explicit_types, matcher.initExpr ? matcher.initExpr.range : matcher.type.range);
|
|
1623
1682
|
if (!tn.skip(Token.FatArrow))
|
|
1624
1683
|
return this.error(DiagnosticCode._0_expected, tn.range(), "=>");
|
|
1625
|
-
|
|
1684
|
+
// parse body at precedence higher than `is` so the next case-arm's
|
|
1685
|
+
// `is` is left unconsumed (otherwise `is` would be greedily parsed
|
|
1686
|
+
// as the binary `is` operator inside the body)
|
|
1687
|
+
const body = this.parseExpr(Precedence.Relational + 1);
|
|
1626
1688
|
if (!body)
|
|
1627
1689
|
return undefined;
|
|
1628
1690
|
cases.push(new CaseExprMatcher(matcher, body, tn.range(startPos, tn.pos)));
|
|
@@ -1630,7 +1692,10 @@ export class Parser extends DiagnosticEmitter {
|
|
|
1630
1692
|
let wildcardCase = undefined;
|
|
1631
1693
|
if (tn.skip(Token.Else)) {
|
|
1632
1694
|
const wildcardStart = tn.tokenPos;
|
|
1633
|
-
|
|
1695
|
+
// parse body at precedence higher than `is` so the next case-arm's
|
|
1696
|
+
// `is` is left unconsumed (otherwise `is` would be greedily parsed
|
|
1697
|
+
// as the binary `is` operator inside the body)
|
|
1698
|
+
const body = this.parseExpr(Precedence.Relational + 1);
|
|
1634
1699
|
if (!body)
|
|
1635
1700
|
return undefined;
|
|
1636
1701
|
wildcardCase = new CaseWildcardMatcher(body, tn.range(wildcardStart));
|
|
@@ -45,126 +45,127 @@ export declare enum Token {
|
|
|
45
45
|
Contract = 42,
|
|
46
46
|
Param = 43,
|
|
47
47
|
Spend = 44,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
State = 45,
|
|
49
|
+
Mint = 46,
|
|
50
|
+
Certify = 47,
|
|
51
|
+
Withdraw = 48,
|
|
52
|
+
Propose = 49,
|
|
53
|
+
Vote = 50,
|
|
54
|
+
Context = 51,
|
|
54
55
|
/** `{` */
|
|
55
|
-
OpenBrace =
|
|
56
|
+
OpenBrace = 52,
|
|
56
57
|
/** `}` */
|
|
57
|
-
CloseBrace =
|
|
58
|
-
OpenParen =
|
|
59
|
-
CloseParen =
|
|
58
|
+
CloseBrace = 53,
|
|
59
|
+
OpenParen = 54,
|
|
60
|
+
CloseParen = 55,
|
|
60
61
|
/** `[` */
|
|
61
|
-
OpenBracket =
|
|
62
|
+
OpenBracket = 56,
|
|
62
63
|
/** `]` */
|
|
63
|
-
CloseBracket =
|
|
64
|
+
CloseBracket = 57,
|
|
64
65
|
/** `.` */
|
|
65
|
-
Dot =
|
|
66
|
+
Dot = 58,
|
|
66
67
|
/** `...` */
|
|
67
|
-
Dot_Dot_Dot =
|
|
68
|
+
Dot_Dot_Dot = 59,
|
|
68
69
|
/** `;` */
|
|
69
|
-
Semicolon =
|
|
70
|
+
Semicolon = 60,
|
|
70
71
|
/** `,` */
|
|
71
|
-
Comma =
|
|
72
|
+
Comma = 61,
|
|
72
73
|
/** `<` */
|
|
73
|
-
LessThan =
|
|
74
|
+
LessThan = 62,
|
|
74
75
|
/** `>` */
|
|
75
|
-
GreaterThan =
|
|
76
|
+
GreaterThan = 63,
|
|
76
77
|
/** `<=` */
|
|
77
|
-
LessThan_Equals =
|
|
78
|
+
LessThan_Equals = 64,
|
|
78
79
|
/** `>=` */
|
|
79
|
-
GreaterThan_Equals =
|
|
80
|
+
GreaterThan_Equals = 65,
|
|
80
81
|
/** `==` */
|
|
81
|
-
Equals_Equals =
|
|
82
|
+
Equals_Equals = 66,
|
|
82
83
|
/** `!=` */
|
|
83
|
-
Exclamation_Equals =
|
|
84
|
+
Exclamation_Equals = 67,
|
|
84
85
|
/** `===` */
|
|
85
|
-
Equals_Equals_Equals =
|
|
86
|
+
Equals_Equals_Equals = 68,
|
|
86
87
|
/** `!==` */
|
|
87
|
-
Exclamation_Equals_Equals =
|
|
88
|
+
Exclamation_Equals_Equals = 69,
|
|
88
89
|
/** `=>` */
|
|
89
|
-
FatArrow =
|
|
90
|
+
FatArrow = 70,
|
|
90
91
|
/** `+` */
|
|
91
|
-
Plus =
|
|
92
|
+
Plus = 71,
|
|
92
93
|
/** `-` */
|
|
93
|
-
Minus =
|
|
94
|
+
Minus = 72,
|
|
94
95
|
/** `**` */
|
|
95
|
-
Asterisk_Asterisk =
|
|
96
|
+
Asterisk_Asterisk = 73,
|
|
96
97
|
/** `*` */
|
|
97
|
-
Asterisk =
|
|
98
|
+
Asterisk = 74,
|
|
98
99
|
/** `/` */
|
|
99
|
-
Slash =
|
|
100
|
+
Slash = 75,
|
|
100
101
|
/** `%` */
|
|
101
|
-
Percent =
|
|
102
|
+
Percent = 76,
|
|
102
103
|
/** `++` */
|
|
103
|
-
Plus_Plus =
|
|
104
|
+
Plus_Plus = 77,
|
|
104
105
|
/** `--` */
|
|
105
|
-
Minus_Minus =
|
|
106
|
+
Minus_Minus = 78,
|
|
106
107
|
/** `<<` */
|
|
107
|
-
LessThan_LessThan =
|
|
108
|
+
LessThan_LessThan = 79,
|
|
108
109
|
/** `>>` */
|
|
109
|
-
GreaterThan_GreaterThan =
|
|
110
|
+
GreaterThan_GreaterThan = 80,
|
|
110
111
|
/** `>>>` */
|
|
111
|
-
GreaterThan_GreaterThan_GreaterThan =
|
|
112
|
+
GreaterThan_GreaterThan_GreaterThan = 81,
|
|
112
113
|
/** `+` */
|
|
113
|
-
Ampersand =
|
|
114
|
+
Ampersand = 82,
|
|
114
115
|
/** `|` */
|
|
115
|
-
Bar =
|
|
116
|
+
Bar = 83,
|
|
116
117
|
/** `^` */
|
|
117
|
-
Caret =
|
|
118
|
+
Caret = 84,
|
|
118
119
|
/** `!` */
|
|
119
|
-
Exclamation =
|
|
120
|
+
Exclamation = 85,
|
|
120
121
|
/** `~` */
|
|
121
|
-
Tilde =
|
|
122
|
+
Tilde = 86,
|
|
122
123
|
/** `&&` */
|
|
123
|
-
Ampersand_Ampersand =
|
|
124
|
+
Ampersand_Ampersand = 87,
|
|
124
125
|
/** `||` */
|
|
125
|
-
Bar_Bar =
|
|
126
|
+
Bar_Bar = 88,
|
|
126
127
|
/** `?` */
|
|
127
|
-
Question =
|
|
128
|
+
Question = 89,
|
|
128
129
|
/** `:` */
|
|
129
|
-
Colon =
|
|
130
|
+
Colon = 90,
|
|
130
131
|
/** `=` */
|
|
131
|
-
Equals =
|
|
132
|
-
Plus_Equals =
|
|
133
|
-
Minus_Equals =
|
|
134
|
-
Asterisk_Equals =
|
|
135
|
-
Asterisk_Asterisk_Equals =
|
|
136
|
-
Slash_Equals =
|
|
137
|
-
Percent_Equals =
|
|
138
|
-
LessThan_LessThan_Equals =
|
|
139
|
-
GreaterThan_GreaterThan_Equals =
|
|
140
|
-
GreaterThan_GreaterThan_GreaterThan_Equals =
|
|
141
|
-
Ampersand_Equals =
|
|
142
|
-
Bar_Equals =
|
|
143
|
-
Caret_Equals =
|
|
144
|
-
At =
|
|
132
|
+
Equals = 91,
|
|
133
|
+
Plus_Equals = 92,
|
|
134
|
+
Minus_Equals = 93,
|
|
135
|
+
Asterisk_Equals = 94,
|
|
136
|
+
Asterisk_Asterisk_Equals = 95,
|
|
137
|
+
Slash_Equals = 96,
|
|
138
|
+
Percent_Equals = 97,
|
|
139
|
+
LessThan_LessThan_Equals = 98,
|
|
140
|
+
GreaterThan_GreaterThan_Equals = 99,
|
|
141
|
+
GreaterThan_GreaterThan_GreaterThan_Equals = 100,
|
|
142
|
+
Ampersand_Equals = 101,
|
|
143
|
+
Bar_Equals = 102,
|
|
144
|
+
Caret_Equals = 103,
|
|
145
|
+
At = 104,
|
|
145
146
|
/** `??=` */
|
|
146
|
-
Question_Question_Equals =
|
|
147
|
+
Question_Question_Equals = 105,
|
|
147
148
|
/** `||=` */
|
|
148
|
-
Bar_Bar_Equals =
|
|
149
|
+
Bar_Bar_Equals = 106,
|
|
149
150
|
/** `&&=` */
|
|
150
|
-
Ampersand_Ampersand_Equals =
|
|
151
|
+
Ampersand_Ampersand_Equals = 107,
|
|
151
152
|
/** `??` */
|
|
152
|
-
Question_Question =
|
|
153
|
+
Question_Question = 108,
|
|
153
154
|
/** `?.` */
|
|
154
|
-
Question_Dot =
|
|
155
|
+
Question_Dot = 109,
|
|
155
156
|
/** `!.` */
|
|
156
|
-
Exclamation_Dot =
|
|
157
|
-
Data =
|
|
158
|
-
Bytes =
|
|
159
|
-
Optional =
|
|
160
|
-
List =
|
|
161
|
-
LinearMap =
|
|
162
|
-
Runtime =
|
|
163
|
-
Identifier =
|
|
164
|
-
StringLiteral =
|
|
165
|
-
HexBytesLiteral =
|
|
166
|
-
IntegerLiteral =
|
|
167
|
-
StringTemplateLiteralQuote =
|
|
168
|
-
Invalid =
|
|
169
|
-
EndOfFile =
|
|
157
|
+
Exclamation_Dot = 110,
|
|
158
|
+
Data = 111,
|
|
159
|
+
Bytes = 112,
|
|
160
|
+
Optional = 113,
|
|
161
|
+
List = 114,
|
|
162
|
+
LinearMap = 115,
|
|
163
|
+
Runtime = 116,
|
|
164
|
+
Identifier = 117,
|
|
165
|
+
StringLiteral = 118,
|
|
166
|
+
HexBytesLiteral = 119,
|
|
167
|
+
IntegerLiteral = 120,
|
|
168
|
+
StringTemplateLiteralQuote = 121,
|
|
169
|
+
Invalid = 122,
|
|
170
|
+
EndOfFile = 123
|
|
170
171
|
}
|