@harmoniclabs/pebble 0.1.10 → 0.3.0

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.
Files changed (182) hide show
  1. package/dist/IR/CompilationCtx.d.ts +40 -0
  2. package/dist/IR/CompilationCtx.js +54 -0
  3. package/dist/IR/IRHash.d.ts +23 -2
  4. package/dist/IR/IRHash.js +10 -60
  5. package/dist/IR/IRNodes/IRConst.js +35 -4
  6. package/dist/IR/IRNodes/IRHoisted.d.ts +0 -1
  7. package/dist/IR/IRNodes/IRHoisted.js +4 -6
  8. package/dist/IR/IRNodes/IRLetted.d.ts +0 -1
  9. package/dist/IR/IRNodes/IRLetted.js +4 -6
  10. package/dist/IR/IRNodes/IRNative/IRNativeTag.d.ts +22 -2
  11. package/dist/IR/IRNodes/IRNative/IRNativeTag.js +26 -2
  12. package/dist/IR/IRNodes/IRNative/index.d.ts +16 -1
  13. package/dist/IR/IRNodes/IRNative/index.js +31 -2
  14. package/dist/IR/IRNodes/utils/hashVarSym.d.ts +0 -1
  15. package/dist/IR/IRNodes/utils/hashVarSym.js +27 -33
  16. package/dist/IR/toUPLC/CompilerOptions.d.ts +34 -7
  17. package/dist/IR/toUPLC/CompilerOptions.js +19 -10
  18. package/dist/IR/toUPLC/compileIRToUPLC.js +39 -3
  19. package/dist/IR/toUPLC/subRoutines/inlineSingleUseLetBindingsAndReturnRoot.d.ts +23 -0
  20. package/dist/IR/toUPLC/subRoutines/inlineSingleUseLetBindingsAndReturnRoot.js +263 -0
  21. package/dist/IR/toUPLC/subRoutines/introduceCaseForDualHeadTailAndReturnRoot.d.ts +35 -0
  22. package/dist/IR/toUPLC/subRoutines/introduceCaseForDualHeadTailAndReturnRoot.js +169 -0
  23. package/dist/IR/toUPLC/subRoutines/replaceHoistedWithLetted.d.ts +0 -1
  24. package/dist/IR/toUPLC/subRoutines/replaceHoistedWithLetted.js +6 -6
  25. package/dist/IR/toUPLC/subRoutines/replaceNatives/nativeToIR.d.ts +2 -3
  26. package/dist/IR/toUPLC/subRoutines/replaceNatives/nativeToIR.js +106 -65
  27. package/dist/IR/toUPLC/subRoutines/rewriteHeadTailInCaseConsAndReturnRoot.d.ts +30 -0
  28. package/dist/IR/toUPLC/subRoutines/rewriteHeadTailInCaseConsAndReturnRoot.js +95 -0
  29. package/dist/IR/toUPLC/subRoutines/rewriteNativesAppliedToConstantsAndReturnRoot.js +36 -5
  30. package/dist/IR/toUPLC/subRoutines/rewriteToCaseOverConstAndReturnRoot.d.ts +35 -0
  31. package/dist/IR/toUPLC/subRoutines/rewriteToCaseOverConstAndReturnRoot.js +169 -0
  32. package/dist/IR/tree_utils/_ir_caseList.d.ts +15 -0
  33. package/dist/IR/tree_utils/_ir_caseList.js +19 -0
  34. package/dist/IR/tree_utils/bytesToHex.d.ts +8 -0
  35. package/dist/IR/tree_utils/bytesToHex.js +69 -0
  36. package/dist/ast/nodes/expr/functions/FuncExpr.d.ts +16 -2
  37. package/dist/ast/nodes/expr/functions/FuncExpr.js +17 -0
  38. package/dist/ast/nodes/expr/litteral/LitteralExpr.d.ts +2 -1
  39. package/dist/ast/nodes/expr/litteral/LitteralExpr.js +2 -0
  40. package/dist/ast/nodes/expr/litteral/TemplateStrExpr.d.ts +30 -0
  41. package/dist/ast/nodes/expr/litteral/TemplateStrExpr.js +35 -0
  42. package/dist/ast/nodes/statements/ExportStmt.d.ts +3 -3
  43. package/dist/ast/nodes/statements/PebbleStmt.d.ts +4 -3
  44. package/dist/ast/nodes/statements/PebbleStmt.js +6 -2
  45. package/dist/ast/nodes/statements/TestParam.d.ts +18 -0
  46. package/dist/ast/nodes/statements/TestParam.js +18 -0
  47. package/dist/ast/nodes/statements/TestStmt.d.ts +5 -3
  48. package/dist/ast/nodes/statements/TestStmt.js +3 -1
  49. package/dist/ast/nodes/statements/UsingStmt.d.ts +32 -2
  50. package/dist/ast/nodes/statements/UsingStmt.js +39 -3
  51. package/dist/ast/nodes/statements/declarations/NamespaceDecl.d.ts +21 -0
  52. package/dist/ast/nodes/statements/declarations/NamespaceDecl.js +31 -0
  53. package/dist/ast/nodes/statements/declarations/StructDecl.d.ts +16 -2
  54. package/dist/ast/nodes/statements/declarations/StructDecl.js +15 -1
  55. package/dist/compiler/AstCompiler/AstCompiler.d.ts +27 -0
  56. package/dist/compiler/AstCompiler/AstCompiler.js +244 -7
  57. package/dist/compiler/AstCompiler/internal/_deriveContractBody/_deriveContractBody.js +16 -5
  58. package/dist/compiler/AstCompiler/internal/exprs/_compileCallExpr.js +97 -6
  59. package/dist/compiler/AstCompiler/internal/exprs/_compileCaseExpr.js +31 -0
  60. package/dist/compiler/AstCompiler/internal/exprs/_compileFuncExpr.js +12 -5
  61. package/dist/compiler/AstCompiler/internal/exprs/_compileIsExpr.js +12 -0
  62. package/dist/compiler/AstCompiler/internal/exprs/_compileLitteralExpr.js +59 -0
  63. package/dist/compiler/AstCompiler/internal/exprs/_compilePropAccessExpr.d.ts +2 -3
  64. package/dist/compiler/AstCompiler/internal/exprs/_compilePropAccessExpr.js +64 -0
  65. package/dist/compiler/AstCompiler/internal/exprs/_compileUnaryPrefixExpr.js +13 -1
  66. package/dist/compiler/AstCompiler/internal/exprs/_compileVarAccessExpr.js +2 -0
  67. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileAddExpr.js +18 -5
  68. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileEqualExpr.js +3 -1
  69. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileGreaterThanEqualExpr.js +2 -1
  70. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileGreaterThanExpr.js +2 -1
  71. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileLessThanEqualExpr.js +2 -1
  72. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileLessThanExpr.js +2 -1
  73. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileMultExpr.js +24 -6
  74. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileNotEqualExpr.js +2 -1
  75. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileSubExpr.js +16 -5
  76. package/dist/compiler/AstCompiler/internal/statements/_compileMatchStmt.js +33 -20
  77. package/dist/compiler/AstCompiler/internal/statements/_compileStatement.js +4 -1
  78. package/dist/compiler/AstCompiler/internal/statements/_compileTestStmt.d.ts +15 -1
  79. package/dist/compiler/AstCompiler/internal/statements/_compileTestStmt.js +70 -30
  80. package/dist/compiler/AstCompiler/internal/statements/_compileUsingAliasStmt.d.ts +11 -0
  81. package/dist/compiler/AstCompiler/internal/statements/_compileUsingAliasStmt.js +26 -0
  82. package/dist/compiler/AstCompiler/internal/statements/_compileUsingStmt.d.ts +9 -4
  83. package/dist/compiler/AstCompiler/internal/statements/_compileUsingStmt.js +51 -10
  84. package/dist/compiler/AstCompiler/internal/types/_compileDataEncodedConcreteType.js +21 -2
  85. package/dist/compiler/AstCompiler/internal/types/_compileSopEncodedConcreteType.js +17 -2
  86. package/dist/compiler/AstCompiler/scope/AstScope.d.ts +70 -1
  87. package/dist/compiler/AstCompiler/scope/AstScope.js +91 -0
  88. package/dist/compiler/AstCompiler/utils/getPropAccessReturnType.js +36 -1
  89. package/dist/compiler/AstCompiler/utils/monomorphizeGeneric.d.ts +36 -0
  90. package/dist/compiler/AstCompiler/utils/monomorphizeGeneric.js +123 -0
  91. package/dist/compiler/AstCompiler/utils/resolveNamespaceChain.d.ts +28 -0
  92. package/dist/compiler/AstCompiler/utils/resolveNamespaceChain.js +95 -0
  93. package/dist/compiler/AstCompiler/utils/resolveNamespacePath.d.ts +37 -0
  94. package/dist/compiler/AstCompiler/utils/resolveNamespacePath.js +93 -0
  95. package/dist/compiler/Compiler.d.ts +9 -1
  96. package/dist/compiler/Compiler.js +218 -30
  97. package/dist/compiler/TirCompiler/expressify/ExpressifyCtx.js +1 -1
  98. package/dist/compiler/TirCompiler/expressify/expressify.js +30 -2
  99. package/dist/compiler/TirCompiler/expressify/expressifyForStmt.d.ts +2 -1
  100. package/dist/compiler/TirCompiler/expressify/expressifyForStmt.js +45 -7
  101. package/dist/compiler/TirCompiler/expressify/expressifyVars.d.ts +0 -1
  102. package/dist/compiler/TirCompiler/expressify/expressifyVars.js +49 -15
  103. package/dist/compiler/test/TestResult.d.ts +38 -0
  104. package/dist/compiler/test/TestResult.js +6 -0
  105. package/dist/compiler/test/fuzz/PRNG.d.ts +26 -0
  106. package/dist/compiler/test/fuzz/PRNG.js +59 -0
  107. package/dist/compiler/tir/expressions/TirCaseExpr.d.ts +9 -0
  108. package/dist/compiler/tir/expressions/TirCaseExpr.js +144 -122
  109. package/dist/compiler/tir/expressions/TirElemAccessExpr.js +2 -2
  110. package/dist/compiler/tir/expressions/TirExpr.d.ts +2 -1
  111. package/dist/compiler/tir/expressions/TirExpr.js +2 -0
  112. package/dist/compiler/tir/expressions/TirFromDataExpr.js +102 -67
  113. package/dist/compiler/tir/expressions/TirIsExpr.js +14 -1
  114. package/dist/compiler/tir/expressions/TirNativeFunc.d.ts +18 -2
  115. package/dist/compiler/tir/expressions/TirNativeFunc.js +55 -118
  116. package/dist/compiler/tir/expressions/TirShowExpr.d.ts +52 -0
  117. package/dist/compiler/tir/expressions/TirShowExpr.js +199 -0
  118. package/dist/compiler/tir/expressions/TirToDataExpr.js +3 -0
  119. package/dist/compiler/tir/expressions/TirTraceExpr.js +11 -7
  120. package/dist/compiler/tir/expressions/TirTypeConversionExpr.js +10 -0
  121. package/dist/compiler/tir/expressions/TirVariableAccessExpr.d.ts +2 -3
  122. package/dist/compiler/tir/expressions/TirVariableAccessExpr.js +1 -4
  123. package/dist/compiler/tir/expressions/ToIRTermCtx.d.ts +20 -3
  124. package/dist/compiler/tir/expressions/ToIRTermCtx.js +48 -3
  125. package/dist/compiler/tir/expressions/binary/TirBinaryExpr.d.ts +2 -2
  126. package/dist/compiler/tir/expressions/binary/TirBinaryExpr.js +45 -8
  127. package/dist/compiler/tir/expressions/litteral/TirLitEnumMemberExpr.d.ts +19 -0
  128. package/dist/compiler/tir/expressions/litteral/TirLitEnumMemberExpr.js +24 -0
  129. package/dist/compiler/tir/expressions/litteral/TirLitteralExpr.d.ts +2 -1
  130. package/dist/compiler/tir/expressions/litteral/TirLitteralExpr.js +2 -0
  131. package/dist/compiler/tir/expressions/unary/TirUnaryMinus.js +4 -1
  132. package/dist/compiler/tir/program/TypedProgram.d.ts +101 -0
  133. package/dist/compiler/tir/program/TypedProgram.js +43 -0
  134. package/dist/compiler/tir/program/stdScope/populateBuiltinInterfaces.d.ts +17 -0
  135. package/dist/compiler/tir/program/stdScope/populateBuiltinInterfaces.js +70 -0
  136. package/dist/compiler/tir/program/stdScope/populateStdNamespace.d.ts +22 -0
  137. package/dist/compiler/tir/program/stdScope/populateStdNamespace.js +619 -0
  138. package/dist/compiler/tir/program/stdScope/prelude/preludeTypesSrc.js +35 -2
  139. package/dist/compiler/tir/program/stdScope/stdScope.d.ts +8 -0
  140. package/dist/compiler/tir/program/stdScope/stdScope.js +84 -41
  141. package/dist/compiler/tir/statements/TirStmt.js +0 -1
  142. package/dist/compiler/tir/statements/TirTestStmt.d.ts +46 -0
  143. package/dist/compiler/tir/statements/TirTestStmt.js +35 -0
  144. package/dist/compiler/tir/types/TirEnumType.d.ts +21 -0
  145. package/dist/compiler/tir/types/TirEnumType.js +36 -0
  146. package/dist/compiler/tir/types/TirNativeType/TirNativeType.d.ts +53 -2
  147. package/dist/compiler/tir/types/TirNativeType/TirNativeType.js +58 -1
  148. package/dist/compiler/tir/types/TirNativeType/native/array.d.ts +16 -0
  149. package/dist/compiler/tir/types/TirNativeType/native/array.js +38 -0
  150. package/dist/compiler/tir/types/TirNativeType/native/index.d.ts +2 -0
  151. package/dist/compiler/tir/types/TirNativeType/native/index.js +2 -0
  152. package/dist/compiler/tir/types/TirNativeType/native/value.d.ts +18 -0
  153. package/dist/compiler/tir/types/TirNativeType/native/value.js +17 -0
  154. package/dist/compiler/tir/types/TirStructType.js +6 -1
  155. package/dist/compiler/tir/types/TirType.d.ts +3 -2
  156. package/dist/compiler/tir/types/TirType.js +7 -2
  157. package/dist/compiler/tir/types/utils/canAssignTo.js +36 -1
  158. package/dist/compiler/tir/types/utils/canCastTo.js +14 -1
  159. package/dist/compiler/tir/types/utils/getDeconstructableType.d.ts +2 -1
  160. package/dist/compiler/tir/types/utils/getDeconstructableType.js +2 -0
  161. package/dist/compiler/tir/types/utils/inferTypeArgs.d.ts +19 -0
  162. package/dist/compiler/tir/types/utils/inferTypeArgs.js +83 -0
  163. package/dist/compiler/tir/types/utils/normalizeEnumToInt.d.ts +10 -0
  164. package/dist/compiler/tir/types/utils/normalizeEnumToInt.js +17 -0
  165. package/dist/compiler/tir/types/utils/substituteTypeParams.d.ts +9 -0
  166. package/dist/compiler/tir/types/utils/substituteTypeParams.js +67 -0
  167. package/dist/diagnostics/diagnosticMessages.generated.d.ts +10 -0
  168. package/dist/diagnostics/diagnosticMessages.generated.js +20 -0
  169. package/dist/index.d.ts +2 -0
  170. package/dist/index.js +2 -0
  171. package/dist/parser/Parser.d.ts +73 -3
  172. package/dist/parser/Parser.js +362 -46
  173. package/dist/tokenizer/Token.d.ts +106 -102
  174. package/dist/tokenizer/Token.js +111 -109
  175. package/dist/tokenizer/utils/tokenFromKeyword.js +11 -6
  176. package/dist/utils/semverSatisfies.d.ts +1 -0
  177. package/dist/utils/semverSatisfies.js +161 -0
  178. package/dist/version.generated.d.ts +1 -0
  179. package/dist/version.generated.js +2 -0
  180. package/package.json +5 -4
  181. package/dist/IR/tree_utils/_ir_lazyChooseList.d.ts +0 -3
  182. package/dist/IR/tree_utils/_ir_lazyChooseList.js +0 -7
@@ -21,13 +21,14 @@ import { LitThisExpr } from "../ast/nodes/expr/litteral/LitThisExpr.js";
21
21
  import { LitTrueExpr } from "../ast/nodes/expr/litteral/LitTrueExpr.js";
22
22
  import { ParentesizedExpr } from "../ast/nodes/expr/ParentesizedExpr.js";
23
23
  import { ArrowKind } from "../ast/nodes/expr/functions/ArrowKind.js";
24
- import { FuncExpr } from "../ast/nodes/expr/functions/FuncExpr.js";
24
+ import { FuncExpr, TypeParamDecl } from "../ast/nodes/expr/functions/FuncExpr.js";
25
25
  import { AstBooleanType, AstBytesType, AstListType, AstIntType, AstNativeOptionalType, AstVoidType, AstLinearMapType, AstFuncType } from "../ast/nodes/types/AstNativeTypeExpr.js";
26
26
  import { AstNamedTypeExpr } from "../ast/nodes/types/AstNamedTypeExpr.js";
27
27
  import { LitArrExpr } from "../ast/nodes/expr/litteral/LitArrExpr.js";
28
28
  import { LitNamedObjExpr } from "../ast/nodes/expr/litteral/LitNamedObjExpr.js";
29
29
  import { LitObjExpr } from "../ast/nodes/expr/litteral/LitObjExpr.js";
30
30
  import { LitStrExpr } from "../ast/nodes/expr/litteral/LitStrExpr.js";
31
+ import { TemplateStrExpr } from "../ast/nodes/expr/litteral/TemplateStrExpr.js";
31
32
  import { LitIntExpr } from "../ast/nodes/expr/litteral/LitIntExpr.js";
32
33
  import { LitHexBytesExpr } from "../ast/nodes/expr/litteral/LitHexBytesExpr.js";
33
34
  import { CallExpr } from "../ast/nodes/expr/functions/CallExpr.js";
@@ -44,6 +45,7 @@ import { FailStmt } from "../ast/nodes/statements/FailStmt.js";
44
45
  import { TraceStmt } from "../ast/nodes/statements/TraceStmt.js";
45
46
  import { AssertStmt } from "../ast/nodes/statements/AssertStmt.js";
46
47
  import { TestStmt } from "../ast/nodes/statements/TestStmt.js";
48
+ import { TestParam } from "../ast/nodes/statements/TestParam.js";
47
49
  import { MatchStmt, MatchStmtCase, MatchStmtElseCase } from "../ast/nodes/statements/MatchStmt.js";
48
50
  import { WhileStmt } from "../ast/nodes/statements/WhileStmt.js";
49
51
  import { CaseExpr, CaseExprMatcher, CaseWildcardMatcher } from "../ast/nodes/expr/CaseExpr.js";
@@ -65,7 +67,8 @@ import { makePropAccessExpr } from "../ast/nodes/expr/PropAccessExpr.js";
65
67
  import { makeBinaryExpr } from "../ast/nodes/expr/binary/BinaryExpr.js";
66
68
  import { isAssignmentStmt, makeAssignmentStmt } from "../ast/nodes/statements/AssignmentStmt.js";
67
69
  import { hoistStatementsInplace } from "./hoistStatementsInplace.js";
68
- import { UsingStmt, UsingStmtDeclaredConstructor } from "../ast/nodes/statements/UsingStmt.js";
70
+ import { UsingAliasStmt, UsingPath, UsingStmt, UsingStmtDeclaredConstructor } from "../ast/nodes/statements/UsingStmt.js";
71
+ import { NamespaceDecl, NamespaceMember } from "../ast/nodes/statements/declarations/NamespaceDecl.js";
69
72
  import { IncrStmt } from "../ast/nodes/statements/IncrStmt.js";
70
73
  import { DecrStmt } from "../ast/nodes/statements/DecrStmt.js";
71
74
  import { ExportStmt } from "../ast/nodes/statements/ExportStmt.js";
@@ -151,9 +154,15 @@ export class Parser extends DiagnosticEmitter {
151
154
  break;
152
155
  }
153
156
  case Token.Using: {
157
+ tn.next(); // skip `using`
154
158
  statement = this.parseUsingDecl();
155
159
  break;
156
160
  }
161
+ case Token.Namespace: {
162
+ tn.next(); // skip `namespace`
163
+ statement = this.parseNamespaceDecl(startPos);
164
+ break;
165
+ }
157
166
  case Token.Enum: {
158
167
  tn.next();
159
168
  statement = this.parseEnum(flags, startPos);
@@ -169,13 +178,19 @@ export class Parser extends DiagnosticEmitter {
169
178
  case Token.Data: {
170
179
  // `next()` skips `data` keyword
171
180
  tn.next();
181
+ let extraFlags = StructDeclAstFlags.onlyDataEncoding;
182
+ // accept `data untagged struct ...`
183
+ if (tn.peek() === Token.Untagged) {
184
+ tn.next();
185
+ extraFlags |= StructDeclAstFlags.untagged;
186
+ }
172
187
  // positions on (expected) `struct` keyword
173
188
  if (tn.peek() !== Token.Struct) {
174
189
  console.error(Token[tn.peek()]);
175
190
  return this.error(DiagnosticCode._0_expected, tn.range(), "struct");
176
191
  }
177
192
  tn.next(); // skip `struct`
178
- statement = this.parseStruct(StructDeclAstFlags.onlyDataEncoding, flags, startPos);
193
+ statement = this.parseStruct(extraFlags, flags, startPos);
179
194
  break;
180
195
  }
181
196
  case Token.Runtime: {
@@ -194,6 +209,22 @@ export class Parser extends DiagnosticEmitter {
194
209
  statement = this.parseStruct(StructDeclAstFlags.none, flags, startPos);
195
210
  break;
196
211
  }
212
+ case Token.Untagged: {
213
+ // `untagged` keyword forces listData encoding (single ctor).
214
+ // Accept: `untagged struct ...` or `untagged data struct ...`.
215
+ tn.next(); // skip `untagged`
216
+ let extraFlags = StructDeclAstFlags.untagged;
217
+ if (tn.peek() === Token.Data) {
218
+ tn.next(); // skip `data`
219
+ extraFlags |= StructDeclAstFlags.onlyDataEncoding;
220
+ }
221
+ if (tn.peek() !== Token.Struct) {
222
+ return this.error(DiagnosticCode._0_expected, tn.range(), "struct");
223
+ }
224
+ tn.next(); // skip `struct`
225
+ statement = this.parseStruct(extraFlags, flags, startPos);
226
+ break;
227
+ }
197
228
  case Token.Interface: {
198
229
  tn.next();
199
230
  statement = this.parseInterface(flags, startPos);
@@ -374,8 +405,19 @@ export class Parser extends DiagnosticEmitter {
374
405
  parseUsingDecl() {
375
406
  const tn = this.tn;
376
407
  const startPos = tn.tokenPos;
377
- if (!tn.skip(Token.OpenBrace))
378
- return this.error(DiagnosticCode._0_expected, tn.range(), "{");
408
+ // alias form: `using <ident> = <NamespacePath>;`
409
+ if (!tn.skip(Token.OpenBrace)) {
410
+ if (!tn.skipIdentifier())
411
+ return this.error(DiagnosticCode._0_expected, tn.range(), "{");
412
+ const alias = new Identifier(tn.readIdentifier(), tn.range());
413
+ if (!tn.skip(Token.Equals))
414
+ return this.error(DiagnosticCode._0_expected, tn.range(), "=");
415
+ const path = this.parseUsingPath();
416
+ if (!path)
417
+ return undefined;
418
+ return new UsingAliasStmt(alias, path, tn.range(startPos, tn.pos));
419
+ }
420
+ // destructure form: `using { a, b: c } = <rhs>;`
379
421
  const members = new Array();
380
422
  while (!tn.skip(Token.CloseBrace)) {
381
423
  const thisStartPos = tn.tokenPos;
@@ -397,10 +439,169 @@ export class Parser extends DiagnosticEmitter {
397
439
  }
398
440
  if (!tn.skip(Token.Equals))
399
441
  return this.error(DiagnosticCode._0_expected, tn.range(), "=");
400
- const structTypeExpr = this.parseTypeExpr();
401
- if (!structTypeExpr)
442
+ const rhs = this.parseUsingRhs();
443
+ if (!rhs)
402
444
  return undefined;
403
- return new UsingStmt(members, structTypeExpr, tn.range(startPos, tn.pos));
445
+ return new UsingStmt(members, rhs, tn.range(startPos, tn.pos));
446
+ }
447
+ /**
448
+ * parse a dotted chain of identifiers: `A`, `A.B`, `A.B.C`, ...
449
+ * used for namespace paths on the RHS of `using` statements.
450
+ */
451
+ parseUsingPath() {
452
+ const tn = this.tn;
453
+ const startPos = tn.tokenPos;
454
+ if (!tn.skipIdentifier())
455
+ return this.error(DiagnosticCode.Identifier_expected, tn.range());
456
+ const segments = [
457
+ new Identifier(tn.readIdentifier(), tn.range())
458
+ ];
459
+ while (tn.skip(Token.Dot)) {
460
+ if (!tn.skipIdentifier())
461
+ return this.error(DiagnosticCode.Identifier_expected, tn.range());
462
+ segments.push(new Identifier(tn.readIdentifier(), tn.range()));
463
+ }
464
+ return new UsingPath(segments, tn.range(startPos, tn.pos));
465
+ }
466
+ /**
467
+ * parse the RHS of `using { ... } = <rhs>;`:
468
+ * - if it begins with a native type keyword (or a generic struct
469
+ * with type args), it's parsed as `AstTypeExpr` (legacy
470
+ * struct-destructure behavior)
471
+ * - if it's a single identifier followed by `<`, it's also parsed as
472
+ * a generic type expression
473
+ * - otherwise, it's parsed as a dotted `UsingPath`
474
+ * (a namespace path; the compiler decides whether it's a struct
475
+ * type or a namespace based on what the head identifier resolves to)
476
+ */
477
+ parseUsingRhs() {
478
+ const tn = this.tn;
479
+ const next = tn.peek();
480
+ // native type keywords always go through parseTypeExpr
481
+ if (next === Token.Void
482
+ || next === Token.Boolean
483
+ || next === Token.Int
484
+ || next === Token.Bytes
485
+ || next === Token.Optional
486
+ || next === Token.List
487
+ || next === Token.LinearMap) {
488
+ const t = this.parseTypeExpr();
489
+ if (!t)
490
+ return undefined;
491
+ return t;
492
+ }
493
+ const path = this.parseUsingPath();
494
+ if (!path)
495
+ return undefined;
496
+ // single-segment path followed by `<...>` → generic struct type expression
497
+ if (path.segments.length === 1
498
+ && tn.peek() === Token.LessThan) {
499
+ tn.next(); // consume `<`
500
+ const tyArgs = [];
501
+ do {
502
+ const ty = this.parseTypeExpr();
503
+ if (!ty)
504
+ return undefined;
505
+ tyArgs.push(ty);
506
+ } while (tn.skip(Token.Comma));
507
+ if (!tn.skip(Token.GreaterThan))
508
+ return this.error(DiagnosticCode._0_expected, tn.range(), ">");
509
+ return new AstNamedTypeExpr(path.segments[0], tyArgs, tn.range(path.range.start, tn.pos));
510
+ }
511
+ return path;
512
+ }
513
+ /**
514
+ * parse a namespace body: `{ (private? <member-decl>)* }`
515
+ *
516
+ * called with `namespace` already consumed; `startPos` is the position
517
+ * of the `namespace` keyword.
518
+ */
519
+ parseNamespaceDecl(startPos) {
520
+ const tn = this.tn;
521
+ if (!tn.skipIdentifier())
522
+ return this.error(DiagnosticCode.Identifier_expected, tn.range());
523
+ const name = new Identifier(tn.readIdentifier(), tn.range());
524
+ if (!tn.skip(Token.OpenBrace))
525
+ return this.error(DiagnosticCode._0_expected, tn.range(), "{");
526
+ const members = [];
527
+ while (!tn.skip(Token.CloseBrace)) {
528
+ tn.skip(Token.Semicolon);
529
+ if (tn.skip(Token.CloseBrace))
530
+ break;
531
+ const memberStartPos = tn.tokenPos;
532
+ const isPrivate = tn.skip(Token.Private);
533
+ const member = this.parseNamespaceMember();
534
+ if (!member)
535
+ return undefined;
536
+ members.push(new NamespaceMember(isPrivate, member, tn.range(memberStartPos, tn.pos)));
537
+ tn.skip(Token.Semicolon);
538
+ }
539
+ return new NamespaceDecl(name, members, tn.range(startPos, tn.pos));
540
+ }
541
+ /**
542
+ * parse a single namespace body member. delegates to the relevant
543
+ * top-level-style parser based on the next token, but rejects
544
+ * declarations that aren't allowed inside a namespace body
545
+ * (no `export`, no `import`, no `using`, no `contract`, no `test`).
546
+ */
547
+ parseNamespaceMember() {
548
+ const tn = this.tn;
549
+ const startPos = tn.tokenPos;
550
+ const flags = CommonFlags.None;
551
+ const first = tn.peek();
552
+ switch (first) {
553
+ case Token.Namespace: {
554
+ tn.next();
555
+ return this.parseNamespaceDecl(startPos);
556
+ }
557
+ case Token.Function: {
558
+ tn.next();
559
+ return this.parseFuncDecl(flags, startPos);
560
+ }
561
+ case Token.Interface: {
562
+ tn.next();
563
+ return this.parseInterface(flags, startPos);
564
+ }
565
+ case Token.Var:
566
+ case Token.Let:
567
+ case Token.Const: {
568
+ tn.next();
569
+ return this.parseVarStmt(first === Token.Const ? CommonFlags.Const : CommonFlags.Let, startPos);
570
+ }
571
+ case Token.Enum: {
572
+ tn.next();
573
+ return this.parseEnum(flags, startPos);
574
+ }
575
+ case Token.Struct: {
576
+ tn.next();
577
+ return this.parseStruct(StructDeclAstFlags.none, flags, startPos);
578
+ }
579
+ case Token.Data: {
580
+ tn.next();
581
+ if (tn.peek() !== Token.Struct)
582
+ return this.error(DiagnosticCode._0_expected, tn.range(), "struct");
583
+ tn.next();
584
+ return this.parseStruct(StructDeclAstFlags.onlyDataEncoding, flags, startPos);
585
+ }
586
+ case Token.Runtime: {
587
+ tn.next();
588
+ if (tn.peek() !== Token.Struct)
589
+ return this.error(DiagnosticCode._0_expected, tn.range(), "struct");
590
+ tn.next();
591
+ return this.parseStruct(StructDeclAstFlags.onlySopEncoding, flags, startPos);
592
+ }
593
+ case Token.Type: {
594
+ tn.next();
595
+ const stmt = this.parseTypeStmt(flags, startPos);
596
+ if (!stmt)
597
+ return undefined;
598
+ if (!(stmt instanceof TypeAliasDecl))
599
+ return this.error(DiagnosticCode._0_expected, stmt.range, "type alias declaration");
600
+ return stmt;
601
+ }
602
+ default:
603
+ return this.error(DiagnosticCode._0_expected, tn.range(), "namespace member declaration");
604
+ }
404
605
  }
405
606
  parseTypeParameters() {
406
607
  const tn = this.tn;
@@ -419,6 +620,41 @@ export class Parser extends DiagnosticEmitter {
419
620
  }
420
621
  return typeParams;
421
622
  }
623
+ /**
624
+ * Parses a function's type-parameter list with optional `implements`
625
+ * interface constraints:
626
+ * `<T, U implements ToData, V implements Foo>`
627
+ *
628
+ * Returns `TypeParamDecl[]` so the compiler can read each param's
629
+ * optional constraint at template-registration time. Struct/interface
630
+ * decls keep using the simpler {@link parseTypeParameters} which
631
+ * returns bare `Identifier[]`.
632
+ */
633
+ parseFuncTypeParameters() {
634
+ const tn = this.tn;
635
+ // at '<': TypeParamDecl (',' TypeParamDecl)* '>'
636
+ const typeParams = new Array();
637
+ while (!tn.skip(Token.GreaterThan)) {
638
+ const startPos = tn.tokenPos;
639
+ if (!tn.skipIdentifier())
640
+ return this.error(DiagnosticCode.Identifier_expected, tn.range());
641
+ const name = new Identifier(tn.readIdentifier(), tn.range());
642
+ let constraint = undefined;
643
+ if (tn.skip(Token.Implements)) {
644
+ constraint = this.parseTypeExpr();
645
+ if (!constraint)
646
+ return undefined;
647
+ }
648
+ typeParams.push(new TypeParamDecl(name, constraint, tn.range(startPos, tn.pos)));
649
+ if (tn.skip(Token.Comma))
650
+ continue;
651
+ if (tn.skip(Token.GreaterThan))
652
+ break;
653
+ else
654
+ return this.error(DiagnosticCode._0_expected, tn.range(), ">");
655
+ }
656
+ return typeParams;
657
+ }
422
658
  parseTypeArguments() {
423
659
  const tn = this.tn;
424
660
  // at '<': TypeParameter (',' TypeParameter)* '>'
@@ -537,7 +773,11 @@ export class Parser extends DiagnosticEmitter {
537
773
  const body = this.parseBlockStmt();
538
774
  if (!body)
539
775
  return undefined;
540
- members.push(new InterfaceMethodImpl(methodName, typeParams ?? [], sig, body, tn.range(startPos, tn.pos)));
776
+ members.push(new InterfaceMethodImpl(methodName,
777
+ // InterfaceMethodImpl still uses bare Identifier[];
778
+ // strip any constraint clauses (method-decl constraints
779
+ // would be a separate feature).
780
+ typeParams?.map(p => p.name) ?? [], sig, body, tn.range(startPos, tn.pos)));
541
781
  }
542
782
  tn.skip(Token.Semicolon); // if any
543
783
  return new TypeImplementsStmt(typeId, interfaceType, members, tn.range());
@@ -666,7 +906,7 @@ export class Parser extends DiagnosticEmitter {
666
906
  [
667
907
  new StructConstrDecl(new Identifier(name.text, name.range), [], // fields
668
908
  range)
669
- ], structDeclFlags | StructDeclAstFlags.untaggedSingleConstructor, range.clone());
909
+ ], structDeclFlags | StructDeclAstFlags.shortcutSingleConstructor, range.clone());
670
910
  }
671
911
  let constrIdentifier = undefined;
672
912
  // in case of single constr shortcut
@@ -687,7 +927,7 @@ export class Parser extends DiagnosticEmitter {
687
927
  tn.skip(Token.Semicolon); // if any
688
928
  return new StructDecl(name, typeParams, [
689
929
  new StructConstrDecl(new Identifier(name.text, name.range), fields, tn.range(startPos, tn.pos))
690
- ], structDeclFlags | StructDeclAstFlags.untaggedSingleConstructor, tn.range(startPos, tn.pos));
930
+ ], structDeclFlags | StructDeclAstFlags.shortcutSingleConstructor, tn.range(startPos, tn.pos));
691
931
  }
692
932
  const constrFields = this.parseStructConstrFields(flags);
693
933
  if (!Array.isArray(constrFields))
@@ -747,7 +987,7 @@ export class Parser extends DiagnosticEmitter {
747
987
  let typeParams = undefined;
748
988
  if (tn.skip(Token.LessThan)) {
749
989
  sigStart = tn.tokenPos;
750
- typeParams = this.parseTypeParameters();
990
+ typeParams = this.parseFuncTypeParameters();
751
991
  if (!typeParams || typeParams.length === 0)
752
992
  return undefined;
753
993
  // flags |= CommonFlags.Generic;
@@ -776,15 +1016,11 @@ export class Parser extends DiagnosticEmitter {
776
1016
  const namedSig = this.parseNamedFuncSig(flags, startPos, defaultReturnType);
777
1017
  if (!namedSig)
778
1018
  return undefined;
779
- const [name, typeArgs, sig] = namedSig;
780
- const nParams = typeArgs?.length ?? 0;
781
- const typeParams = new Array(nParams);
782
- for (let i = 0; i < nParams; ++i) {
783
- const arg = typeArgs[i];
784
- if (!(arg instanceof AstNamedTypeExpr))
785
- return this.error(DiagnosticCode.Type_parameters_must_be_identifiers, arg.range);
786
- typeParams[i] = arg.name;
787
- }
1019
+ const [name, typeParamsRaw, sig] = namedSig;
1020
+ // `parseNamedFuncSig` returns `TypeParamDecl[]` (with optional
1021
+ // `implements` constraint per param) — `FuncExpr.typeParams` carries
1022
+ // them through to template registration.
1023
+ const typeParams = typeParamsRaw ?? [];
788
1024
  if (!tn.skip(Token.OpenBrace))
789
1025
  return this.error(DiagnosticCode.Function_implementation_is_missing_or_not_immediately_following_the_declaration, tn.range());
790
1026
  const body = this.parseBlockStmt();
@@ -792,7 +1028,7 @@ export class Parser extends DiagnosticEmitter {
792
1028
  return undefined;
793
1029
  const endPos = tn.pos;
794
1030
  tn.skip(Token.Semicolon); // if any
795
- const expr = new FuncExpr(name, flags, typeParams ?? [], sig, body, ArrowKind.None, tn.range(startPos, endPos));
1031
+ const expr = new FuncExpr(name, flags, typeParams, sig, body, ArrowKind.None, tn.range(startPos, endPos));
796
1032
  return new FuncDecl(expr);
797
1033
  }
798
1034
  parseEnum(flags, startPos) {
@@ -1113,11 +1349,15 @@ export class Parser extends DiagnosticEmitter {
1113
1349
  switch (token) {
1114
1350
  case Token.Void: return new AstVoidType(currRange);
1115
1351
  // case Token.True:
1116
- // case Token.False:
1352
+ // case Token.False:
1117
1353
  case Token.Boolean: return new AstBooleanType(currRange);
1118
1354
  case Token.Int: return new AstIntType(currRange);
1119
1355
  // case Token.Number: return new AstIntType( currRange )
1120
1356
  case Token.Bytes: return new AstBytesType(currRange);
1357
+ // `data` is registered in the prelude as a named type; expose it
1358
+ // as a plain `AstNamedTypeExpr` so it can be written in type
1359
+ // position (e.g. `function f(x: data): ...`).
1360
+ case Token.Data: return new AstNamedTypeExpr(new Identifier("data", currRange), [], currRange);
1121
1361
  case Token.Optional: {
1122
1362
  if (!tn.skip(Token.LessThan)) {
1123
1363
  canError && this.error(DiagnosticCode._0_expected, currRange, "Type argument for Optional");
@@ -1308,7 +1548,10 @@ export class Parser extends DiagnosticEmitter {
1308
1548
  if (tn.skipIdentifier(IdentifierHandling.Always)) {
1309
1549
  prop = new Identifier(tn.readIdentifier(), tn.range());
1310
1550
  expr = makePropAccessExpr(token, expr, prop, tn.range(startPos, tn.pos));
1311
- expr = this.tryParseCallExprOrReturnSame(expr);
1551
+ // pass `true` so we attempt `<TypeArgs>` parsing —
1552
+ // generic calls on dotted paths (e.g. `std.x.f<T>(a)`)
1553
+ // need this to consume the type arguments.
1554
+ expr = this.tryParseCallExprOrReturnSame(expr, true);
1312
1555
  break;
1313
1556
  }
1314
1557
  const state = tn.mark();
@@ -1578,9 +1821,7 @@ export class Parser extends DiagnosticEmitter {
1578
1821
  return new LitStrExpr(tn.readString(), tn.range(startPos, tn.pos));
1579
1822
  }
1580
1823
  case Token.StringTemplateLiteralQuote: {
1581
- this.error(DiagnosticCode.Not_implemented_0, tn.range(), "string template literals");
1582
- return undefined;
1583
- // return this.parseTemplateLiteral();
1824
+ return this.parseTemplateLiteral(startPos);
1584
1825
  }
1585
1826
  case Token.IntegerLiteral: {
1586
1827
  const value = tn.readInteger();
@@ -1666,17 +1907,14 @@ export class Parser extends DiagnosticEmitter {
1666
1907
  const expr = this.parseExpr(Precedence.Relational + 1);
1667
1908
  if (!expr)
1668
1909
  return undefined;
1669
- let noPatternCaseSeen = false;
1670
1910
  const cases = new Array();
1671
1911
  while (tn.skip(Token.Is)) {
1672
- if (noPatternCaseSeen)
1673
- return this.error(DiagnosticCode.This_case_will_never_be_evaluated_because_all_patterns_will_be_catched_before, tn.range());
1674
1912
  const startPos = tn.tokenPos;
1675
1913
  const matcher = this._parseVarDecl(CommonFlags.Const);
1676
1914
  if (!matcher)
1677
1915
  return undefined;
1678
- if (matcher instanceof SimpleVarDecl)
1679
- noPatternCaseSeen = true;
1916
+ // SimpleVarDecl patterns are validated by the AstCompiler, which
1917
+ // has type info (enum-member promotion vs invalid catch-all).
1680
1918
  if (matcher.initExpr || matcher.type)
1681
1919
  return this.error(DiagnosticCode.Patterns_may_not_have_initializers_or_explicit_types, matcher.initExpr ? matcher.initExpr.range : matcher.type.range);
1682
1920
  if (!tn.skip(Token.FatArrow))
@@ -2340,17 +2578,63 @@ export class Parser extends DiagnosticEmitter {
2340
2578
  }
2341
2579
  parseTestStatement() {
2342
2580
  const tn = this.tn;
2343
- // at 'test': string? BlockStmt
2344
- const startPost = tn.pos;
2345
- let testName = undefined;
2346
- if (tn.skip(Token.StringLiteral)) {
2347
- const value = tn.readString();
2348
- testName = new LitStrExpr(value, tn.range(startPost, tn.pos));
2349
- }
2350
- let body = this.parseBlockStmt(true);
2581
+ // at 'test': Identifier '(' TestParam (',' TestParam)* ')' '{' BlockStmt
2582
+ const startPos = tn.pos;
2583
+ if (!tn.skipIdentifier())
2584
+ return this.error(DiagnosticCode.Identifier_expected, tn.range());
2585
+ const testName = new Identifier(tn.readIdentifier(), tn.range());
2586
+ if (!tn.skip(Token.OpenParen))
2587
+ return this.error(DiagnosticCode._0_expected, tn.range(), "(");
2588
+ const params = this.parseTestParameters();
2589
+ if (!params)
2590
+ return undefined;
2591
+ if (!tn.skip(Token.OpenBrace))
2592
+ return this.error(DiagnosticCode.Tests_must_be_specified_in_a_block_statement, tn.range());
2593
+ let body = this.parseBlockStmt();
2351
2594
  if (!body)
2352
2595
  return this.error(DiagnosticCode.Tests_must_be_specified_in_a_block_statement, tn.range());
2353
- return new TestStmt(testName, body, tn.range(startPost, tn.pos));
2596
+ return new TestStmt(testName, params, body, tn.range(startPos, tn.pos));
2597
+ }
2598
+ /**
2599
+ * Parses the parameter list of a `test` declaration:
2600
+ * `( <id>: <type> ('via' <expr>)? (, <id>: <type> ('via' <expr>)? )* )?`
2601
+ *
2602
+ * Assumes the opening `(` has already been consumed by the caller.
2603
+ * Consumes the closing `)` on success.
2604
+ *
2605
+ * `via` is recognised here ONLY — function/method/contract parameter
2606
+ * parsing uses `parseParameters()` which never looks for `Token.Via`.
2607
+ */
2608
+ parseTestParameters() {
2609
+ const tn = this.tn;
2610
+ const params = [];
2611
+ if (tn.skip(Token.CloseParen))
2612
+ return params;
2613
+ while (true) {
2614
+ const paramStart = tn.pos;
2615
+ if (!tn.skipIdentifier())
2616
+ return this.error(DiagnosticCode.Identifier_expected, tn.range());
2617
+ const name = new Identifier(tn.readIdentifier(), tn.range());
2618
+ if (!tn.skip(Token.Colon))
2619
+ return this.error(DiagnosticCode._0_expected, tn.range(), ":");
2620
+ const type = this.parseTypeExpr();
2621
+ if (!type)
2622
+ return undefined;
2623
+ let viaExpr = undefined;
2624
+ if (tn.skip(Token.Via)) {
2625
+ const expr = this.parseExpr();
2626
+ if (!expr)
2627
+ return undefined;
2628
+ viaExpr = expr;
2629
+ }
2630
+ params.push(new TestParam(name, type, viaExpr, tn.range(paramStart, tn.pos)));
2631
+ if (tn.skip(Token.Comma))
2632
+ continue;
2633
+ if (tn.skip(Token.CloseParen))
2634
+ break;
2635
+ return this.error(DiagnosticCode._0_expected, tn.range(), ")");
2636
+ }
2637
+ return params;
2354
2638
  }
2355
2639
  parseMatchStatement() {
2356
2640
  const tn = this.tn;
@@ -2361,7 +2645,6 @@ export class Parser extends DiagnosticEmitter {
2361
2645
  return this.error(DiagnosticCode.Expression_expected, tn.range(startPos - 5, startPos));
2362
2646
  if (!tn.skip(Token.OpenBrace))
2363
2647
  return this.error(DiagnosticCode._0_expected, tn.range(), "{");
2364
- let noPatternCaseSeen = false;
2365
2648
  const cases = new Array();
2366
2649
  while (!tn.skip(Token.CloseBrace)
2367
2650
  && tn.peek() !== Token.Else) {
@@ -2372,10 +2655,8 @@ export class Parser extends DiagnosticEmitter {
2372
2655
  const pattern = this._parseVarDecl(CommonFlags.Const, true);
2373
2656
  if (!pattern)
2374
2657
  return this.error(DiagnosticCode.Pattern_expected, tn.range());
2375
- if (noPatternCaseSeen)
2376
- return this.error(DiagnosticCode.This_case_will_never_be_evaluated_because_all_patterns_will_be_catched_before, pattern.range);
2377
- if (pattern instanceof SimpleVarDecl)
2378
- noPatternCaseSeen = true;
2658
+ // SimpleVarDecl patterns are validated by the AstCompiler, which
2659
+ // has type info (enum-member promotion vs invalid catch-all).
2379
2660
  if (!tn.skip(Token.Colon))
2380
2661
  return this.error(DiagnosticCode._0_expected, tn.range(), ":");
2381
2662
  const statePreBody = tn.mark();
@@ -2416,6 +2697,41 @@ export class Parser extends DiagnosticEmitter {
2416
2697
  return this.error(DiagnosticCode.Expression_expected, tn.range());
2417
2698
  return new TraceStmt(expr, tn.range());
2418
2699
  }
2700
+ /**
2701
+ * Parse a backtick-delimited template literal:
2702
+ *
2703
+ * `text ${expr1} more text ${expr2} ...`
2704
+ *
2705
+ * Tokenizer state: on entry, the current token is
2706
+ * `Token.StringTemplateLiteralQuote`; the tokenizer is positioned at
2707
+ * the opening backtick. `readString()` (called with no arg) consumes
2708
+ * the backtick + the first fragment up to `${` or to the closing
2709
+ * backtick; if it stopped at `${` it sets `readingTemplateString = true`
2710
+ * and the parser must consume an expression + `}` and then call
2711
+ * `readString(CharCode.Backtick)` to read the next fragment.
2712
+ */
2713
+ parseTemplateLiteral(startPos) {
2714
+ const tn = this.tn;
2715
+ const parts = [];
2716
+ const exprs = [];
2717
+ // First fragment — readString advances past the opening backtick.
2718
+ let fragment = tn.readString();
2719
+ parts.push(fragment);
2720
+ while (tn.readingTemplateString) {
2721
+ // Just consumed `${`. Parse the interpolated expression.
2722
+ const interp = this.parseExpr();
2723
+ if (!interp)
2724
+ return this.error(DiagnosticCode.Expression_expected, tn.range());
2725
+ exprs.push(interp);
2726
+ if (!tn.skip(Token.CloseBrace))
2727
+ return this.error(DiagnosticCode._0_expected, tn.range(), "}");
2728
+ // Read the next fragment up to the next `${` or the closing
2729
+ // backtick. `readingTemplateString` is set inside readString.
2730
+ fragment = tn.readString(96 /* CharCode.Backtick */);
2731
+ parts.push(fragment);
2732
+ }
2733
+ return new TemplateStrExpr(parts, exprs, tn.range(startPos, tn.pos));
2734
+ }
2419
2735
  parseAssertStatement() {
2420
2736
  const tn = this.tn;
2421
2737
  const startPos = tn.tokenPos;