@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
@@ -2,6 +2,7 @@ import { DiagnosticCode } from "../../../../../diagnostics/diagnosticMessages.ge
2
2
  import { TirLessThanEqualExpr } from "../../../../tir/expressions/binary/TirBinaryExpr.js";
3
3
  import { TirAliasType } from "../../../../tir/types/TirAliasType.js";
4
4
  import { canAssignTo } from "../../../../tir/types/utils/canAssignTo.js";
5
+ import { normalizeEnumToInt } from "../../../../tir/types/utils/normalizeEnumToInt.js";
5
6
  import { int_t, bytes_t } from "../../../../tir/program/stdScope/stdScope.js";
6
7
  import { _compileExpr } from "../_compileExpr.js";
7
8
  export function _compileLessThanEqualExpr(ctx, expr, typeHint) {
@@ -11,7 +12,7 @@ export function _compileLessThanEqualExpr(ctx, expr, typeHint) {
11
12
  if (!canAssignTo(left.type, int_t)
12
13
  && !canAssignTo(left.type, bytes_t))
13
14
  return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.left.range, left.type.toString(), int_t.toString());
14
- let leftType = left.type;
15
+ let leftType = normalizeEnumToInt(left.type, int_t);
15
16
  while (leftType instanceof TirAliasType)
16
17
  leftType = leftType.aliased;
17
18
  const right = _compileExpr(ctx, expr.right, leftType);
@@ -2,6 +2,7 @@ import { DiagnosticCode } from "../../../../../diagnostics/diagnosticMessages.ge
2
2
  import { TirLessThanExpr } from "../../../../tir/expressions/binary/TirBinaryExpr.js";
3
3
  import { TirAliasType } from "../../../../tir/types/TirAliasType.js";
4
4
  import { canAssignTo } from "../../../../tir/types/utils/canAssignTo.js";
5
+ import { normalizeEnumToInt } from "../../../../tir/types/utils/normalizeEnumToInt.js";
5
6
  import { _compileExpr } from "../_compileExpr.js";
6
7
  export function _compileLessThanExpr(ctx, expr, typeHint) {
7
8
  const int_t = ctx.program.stdTypes.int;
@@ -12,7 +13,7 @@ export function _compileLessThanExpr(ctx, expr, typeHint) {
12
13
  if (!canAssignTo(left.type, int_t)
13
14
  && !canAssignTo(left.type, bytes_t))
14
15
  return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.left.range, left.type.toString(), int_t.toString());
15
- let leftType = left.type;
16
+ let leftType = normalizeEnumToInt(left.type, int_t);
16
17
  while (leftType instanceof TirAliasType)
17
18
  leftType = leftType.aliased;
18
19
  const right = _compileExpr(ctx, expr.right, leftType);
@@ -1,20 +1,38 @@
1
1
  import { DiagnosticCode } from "../../../../../diagnostics/diagnosticMessages.generated.js";
2
2
  import { TirMultExpr } from "../../../../tir/expressions/binary/TirBinaryExpr.js";
3
+ import { TirValueT } from "../../../../tir/types/TirNativeType/native/value.js";
3
4
  import { canAssignTo } from "../../../../tir/types/utils/canAssignTo.js";
5
+ import { getUnaliased } from "../../../../tir/types/utils/getUnaliased.js";
4
6
  import { _compileExpr } from "../_compileExpr.js";
5
7
  export function _compileMultExpr(ctx, expr, _typeHint) {
6
8
  const int_t = ctx.program.stdTypes.int;
7
- const left = _compileExpr(ctx, expr.left, int_t);
8
- if (!left)
9
+ // Probe both sides without hints so we can disambiguate
10
+ // (int * Value) / (Value * int) / (int * int).
11
+ const leftProbe = _compileExpr(ctx, expr.left, undefined);
12
+ if (!leftProbe)
9
13
  return undefined;
10
- if (!canAssignTo(left.type, int_t))
11
- return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.left.range, left.type.toString(), int_t.toString());
12
- const right = _compileExpr(ctx, expr.right, int_t);
14
+ const leftTy = getUnaliased(leftProbe.type);
15
+ if (leftTy instanceof TirValueT) {
16
+ const right = _compileExpr(ctx, expr.right, int_t);
17
+ if (!right)
18
+ return undefined;
19
+ if (!canAssignTo(right.type, int_t))
20
+ return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.right.range, right.type.toString(), int_t.toString());
21
+ return new TirMultExpr(leftProbe, right, expr.range);
22
+ }
23
+ if (!canAssignTo(leftProbe.type, int_t))
24
+ return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.left.range, leftProbe.type.toString(), int_t.toString());
25
+ // left is int — right may be int (regular product) or Value (scaleValue).
26
+ const right = _compileExpr(ctx, expr.right, undefined);
13
27
  if (!right)
14
28
  return undefined;
29
+ const rightTy = getUnaliased(right.type);
30
+ if (rightTy instanceof TirValueT) {
31
+ return new TirMultExpr(leftProbe, right, expr.range);
32
+ }
15
33
  if (!canAssignTo(right.type, int_t))
16
34
  return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.right.range, right.type.toString(), int_t.toString());
17
- return new TirMultExpr(left, right,
35
+ return new TirMultExpr(leftProbe, right,
18
36
  // implicit int type,
19
37
  expr.range);
20
38
  }
@@ -1,12 +1,13 @@
1
1
  import { DiagnosticCode } from "../../../../../diagnostics/diagnosticMessages.generated.js";
2
2
  import { TirNotEqualExpr } from "../../../../tir/expressions/binary/TirBinaryExpr.js";
3
3
  import { canAssignTo } from "../../../../tir/types/utils/canAssignTo.js";
4
+ import { normalizeEnumToInt } from "../../../../tir/types/utils/normalizeEnumToInt.js";
4
5
  import { _compileExpr } from "../_compileExpr.js";
5
6
  export function _compileNotEqualExpr(ctx, expr, typeHint) {
6
7
  const left = _compileExpr(ctx, expr.left, typeHint);
7
8
  if (!left)
8
9
  return undefined;
9
- const leftType = left.type;
10
+ const leftType = normalizeEnumToInt(left.type, ctx.program.stdTypes.int);
10
11
  const right = _compileExpr(ctx, expr.right, leftType);
11
12
  if (!right)
12
13
  return undefined;
@@ -1,20 +1,31 @@
1
1
  import { DiagnosticCode } from "../../../../../diagnostics/diagnosticMessages.generated.js";
2
2
  import { TirSubExpr } from "../../../../tir/expressions/binary/TirBinaryExpr.js";
3
+ import { TirValueT } from "../../../../tir/types/TirNativeType/native/value.js";
3
4
  import { canAssignTo } from "../../../../tir/types/utils/canAssignTo.js";
5
+ import { getUnaliased } from "../../../../tir/types/utils/getUnaliased.js";
4
6
  import { _compileExpr } from "../_compileExpr.js";
5
7
  export function _compileSubExpr(ctx, expr, _typeHint) {
6
8
  const int_t = ctx.program.stdTypes.int;
7
- const left = _compileExpr(ctx, expr.left, int_t);
8
- if (!left)
9
+ const leftProbe = _compileExpr(ctx, expr.left, undefined);
10
+ if (!leftProbe)
9
11
  return undefined;
10
- if (!canAssignTo(left.type, int_t))
11
- return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.left.range, left.type.toString(), int_t.toString());
12
+ const leftTy = getUnaliased(leftProbe.type);
13
+ if (leftTy instanceof TirValueT) {
14
+ const right = _compileExpr(ctx, expr.right, leftProbe.type);
15
+ if (!right)
16
+ return undefined;
17
+ if (!(getUnaliased(right.type) instanceof TirValueT))
18
+ return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.right.range, right.type.toString(), "Value");
19
+ return new TirSubExpr(leftProbe, right, expr.range);
20
+ }
21
+ if (!canAssignTo(leftProbe.type, int_t))
22
+ return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.left.range, leftProbe.type.toString(), int_t.toString());
12
23
  const right = _compileExpr(ctx, expr.right, int_t);
13
24
  if (!right)
14
25
  return undefined;
15
26
  if (!canAssignTo(right.type, int_t))
16
27
  return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.right.range, right.type.toString(), int_t.toString());
17
- return new TirSubExpr(left, right,
28
+ return new TirSubExpr(leftProbe, right,
18
29
  // implicit int type,
19
30
  expr.range);
20
31
  }
@@ -11,6 +11,7 @@ import { TirDataT } from "../../../tir/types/TirNativeType/native/data.js";
11
11
  import { TirDataOptT } from "../../../tir/types/TirNativeType/native/Optional/data.js";
12
12
  import { TirSopOptT } from "../../../tir/types/TirNativeType/native/Optional/sop.js";
13
13
  import { isTirStructType, TirDataStructType, TirSoPStructType } from "../../../tir/types/TirStructType.js";
14
+ import { TirEnumType } from "../../../tir/types/TirEnumType.js";
14
15
  import { getDeconstructableType } from "../../../tir/types/utils/getDeconstructableType.js";
15
16
  import { wrapManyStatements } from "../../utils/wrapManyStatementsOrReturnSame.js";
16
17
  import { _compileExpr } from "../exprs/_compileExpr.js";
@@ -32,11 +33,13 @@ export function _compileMatchStmt(ctx, stmt) {
32
33
  if (!deconstructableType)
33
34
  return ctx.error(DiagnosticCode.A_value_of_type_0_cannot_be_deconstructed, stmt.matchExpr.range, matchExprType.toString());
34
35
  // TODO: add support for all deconstructable types
35
- if (!isTirStructType(deconstructableType)) {
36
- return ctx.error(DiagnosticCode.Not_implemented_0, stmt.matchExpr.range, "only structs supported for now, sorry!");
36
+ if (!isTirStructType(deconstructableType) && !(deconstructableType instanceof TirEnumType)) {
37
+ return ctx.error(DiagnosticCode.Not_implemented_0, stmt.matchExpr.range, "only structs and enums supported for now, sorry!");
37
38
  }
38
- const ctors = deconstructableType.constructors;
39
- const ctorNames = ctors.map(c => c.name);
39
+ const ctorNames = deconstructableType instanceof TirEnumType
40
+ ? deconstructableType.members.slice()
41
+ : deconstructableType.constructors.map(c => c.name);
42
+ const totalCtors = ctorNames.length;
40
43
  const missingCtors = ctorNames.slice();
41
44
  if (stmt.cases.length === 0)
42
45
  return ctx.error(DiagnosticCode.A_match_statement_must_have_at_least_one_case, stmt.range);
@@ -70,7 +73,7 @@ export function _compileMatchStmt(ctx, stmt) {
70
73
  return undefined;
71
74
  wildcardCase = new TirMatchStmtWildcardCase(branchBody, matchCase.range);
72
75
  }
73
- if (!wildcardCase && cases.length < ctors.length) {
76
+ if (!wildcardCase && cases.length < totalCtors) {
74
77
  return ctx.error(DiagnosticCode.Match_cases_are_not_exhaustive, stmt.range);
75
78
  }
76
79
  return [new TirMatchStmt(matchExpr, cases, wildcardCase, stmt.range)];
@@ -82,23 +85,21 @@ export function _compileTirMatchStmtCase(ctx, matchCase, deconstructableType, co
82
85
  //*/
83
86
  const pattern = matchCase.pattern;
84
87
  if (pattern instanceof SimpleVarDecl) {
85
- /*
86
- if( pattern.name.text === "_" ) {
88
+ // bare-name pattern: only valid for enum scrutinees (`when Apple: ...`)
89
+ if (deconstructableType instanceof TirEnumType) {
90
+ const memberName = pattern.name.text;
91
+ const memberIdx = deconstructableType.indexOf(memberName);
92
+ if (memberIdx < 0)
93
+ return ctx.error(DiagnosticCode.Unknown_0_constructor_1, pattern.name.range, deconstructableType.toString(), memberName);
94
+ if (constrNamesAlreadySpecified.includes(memberName))
95
+ return ctx.error(DiagnosticCode.Constructor_0_was_already_specified, pattern.name.range, memberName);
96
+ constrNamesAlreadySpecified.push(memberName);
87
97
  const branchCtx = ctx.newBranchChildScope();
88
- const branchBody = wrapManyStatements(
89
- _compileStatement(
90
- branchCtx,
91
- matchCase.body
92
- ),
93
- matchCase.body.range
94
- );
95
- if( !branchBody ) return undefined;
96
- return new TirMatchStmtWildcardCase(
97
- branchBody,
98
- matchCase.range
99
- );
98
+ const branchBody = wrapManyStatements(_compileStatement(branchCtx, matchCase.body), matchCase.body.range);
99
+ if (!branchBody)
100
+ return undefined;
101
+ return new TirMatchStmtCase(new TirNamedDeconstructVarDecl(memberName, new Map(), undefined, deconstructableType, undefined, true, pattern.name.range, pattern.name.range), branchBody, matchCase.range);
100
102
  }
101
- //*/
102
103
  return ctx.error(DiagnosticCode.The_argument_of_a_match_statement_branch_must_be_deconstructed, matchCase.pattern.range);
103
104
  }
104
105
  else if (pattern instanceof NamedDeconstructVarDecl) {
@@ -107,6 +108,18 @@ export function _compileTirMatchStmtCase(ctx, matchCase, deconstructableType, co
107
108
  if (constrNamesAlreadySpecified.includes(deconstructedCtorName))
108
109
  return ctx.error(DiagnosticCode.Constructor_0_was_already_specified, deconstructedCtorIdentifier.range, deconstructedCtorName);
109
110
  constrNamesAlreadySpecified.push(deconstructedCtorName);
111
+ if (deconstructableType instanceof TirEnumType) {
112
+ const memberIdx = deconstructableType.indexOf(deconstructedCtorName);
113
+ if (memberIdx < 0)
114
+ return ctx.error(DiagnosticCode.Unknown_0_constructor_1, pattern.name.range, deconstructableType.toString(), deconstructedCtorName);
115
+ if (pattern.fields.size > 0 || pattern.rest)
116
+ return ctx.error(DiagnosticCode.Enum_member_pattern_cannot_have_fields, pattern.range);
117
+ const branchCtx = ctx.newBranchChildScope();
118
+ const branchBody = wrapManyStatements(_compileStatement(branchCtx, matchCase.body), matchCase.body.range);
119
+ if (!branchBody)
120
+ return undefined;
121
+ return new TirMatchStmtCase(new TirNamedDeconstructVarDecl(deconstructedCtorName, new Map(), undefined, deconstructableType, undefined, true, pattern.range, pattern.name.range), branchBody, matchCase.range);
122
+ }
110
123
  if (deconstructableType instanceof TirSoPStructType
111
124
  || deconstructableType instanceof TirDataStructType) {
112
125
  const localIdx = deconstructableType.constructors.findIndex(c => c.name === deconstructedCtorName);
@@ -12,7 +12,7 @@ import { ForStmt } from "../../../../ast/nodes/statements/ForStmt.js";
12
12
  import { IfStmt } from "../../../../ast/nodes/statements/IfStmt.js";
13
13
  import { MatchStmt } from "../../../../ast/nodes/statements/MatchStmt.js";
14
14
  import { ReturnStmt } from "../../../../ast/nodes/statements/ReturnStmt.js";
15
- import { UsingStmt } from "../../../../ast/nodes/statements/UsingStmt.js";
15
+ import { UsingAliasStmt, UsingStmt } from "../../../../ast/nodes/statements/UsingStmt.js";
16
16
  import { VarStmt } from "../../../../ast/nodes/statements/VarStmt.js";
17
17
  import { WhileStmt } from "../../../../ast/nodes/statements/WhileStmt.js";
18
18
  import { _compileAssertStmt } from "./_compileAssertStmt.js";
@@ -28,6 +28,7 @@ import { _compileIfStmt } from "./_compileIfStmt.js";
28
28
  import { _compileMatchStmt } from "./_compileMatchStmt.js";
29
29
  import { _compileReturnStmt } from "./_compileReturnStmt.js";
30
30
  import { _compileUsingStmt } from "./_compileUsingStmt.js";
31
+ import { _compileUsingAliasStmt } from "./_compileUsingAliasStmt.js";
31
32
  import { _compileVarStmt } from "./_compileVarStmt.js";
32
33
  import { _compileWhileStmt } from "./_compileWhileStmt.js";
33
34
  /**
@@ -74,6 +75,8 @@ export function _compileStatement(ctx, stmt) {
74
75
  // if( stmt instanceof ExprStmt ) return _compileExprStmt( ctx, stmt );
75
76
  if (stmt instanceof UsingStmt)
76
77
  return _compileUsingStmt(ctx, stmt);
78
+ if (stmt instanceof UsingAliasStmt)
79
+ return _compileUsingAliasStmt(ctx, stmt);
77
80
  const tsEnsureExhautstiveCheck = stmt;
78
81
  console.error(stmt);
79
82
  throw new Error("unreachable::AstCompiler::_compileStatement");
@@ -1 +1,15 @@
1
- export {};
1
+ import { TestStmt } from "../../../../ast/nodes/statements/TestStmt.js";
2
+ import { AstCompilationCtx } from "../../AstCompilationCtx.js";
3
+ /**
4
+ * Compiles a `test name( params? ) { body }` declaration.
5
+ *
6
+ * Synthesises a `function <tirFuncName>( params ): void { body }` and
7
+ * runs it through `_compileFuncExpr` so type-checking, scoping and
8
+ * later TIR-to-UPLC compilation work exactly like a user-defined function.
9
+ *
10
+ * Registers the resulting `TirFuncExpr` in `program.functions` and pushes
11
+ * a `TirTestStmt` referencing it onto `program.tests`.
12
+ *
13
+ * @returns `true` on success (test registered), `false` on failure (diagnostic emitted).
14
+ */
15
+ export declare function _compileTestStmt(ctx: AstCompilationCtx, stmt: TestStmt, srcUid: string, sourceFile: string): boolean;
@@ -1,32 +1,72 @@
1
- export {};
2
- /*
3
- export function _compileTestStmt(
4
- ctx: AstCompilationCtx,
5
- stmt: TestStmt
6
- ): [ TirTestStmt ] | undefined
7
- {
8
- if( ctx.functionCtx ) return ctx.error(
9
- DiagnosticCode.A_test_statement_can_only_be_used_outside_a_function,
10
- stmt.range
1
+ import { Identifier } from "../../../../ast/nodes/common/Identifier.js";
2
+ import { FuncExpr } from "../../../../ast/nodes/expr/functions/FuncExpr.js";
3
+ import { ArrowKind } from "../../../../ast/nodes/expr/functions/ArrowKind.js";
4
+ import { AstFuncType, AstVoidType } from "../../../../ast/nodes/types/AstNativeTypeExpr.js";
5
+ import { CommonFlags } from "../../../../common.js";
6
+ import { SimpleVarDecl } from "../../../../ast/nodes/statements/declarations/VarDecl/SimpleVarDecl.js";
7
+ import { PEBBLE_INTERNAL_IDENTIFIER_PREFIX } from "../../../internalVar.js";
8
+ import { TirTestStmt } from "../../../tir/statements/TirTestStmt.js";
9
+ import { _compileFuncExpr } from "../exprs/_compileFuncExpr.js";
10
+ import { TirIntT } from "../../../tir/types/TirNativeType/native/int.js";
11
+ import { TirBoolT } from "../../../tir/types/TirNativeType/native/bool.js";
12
+ import { getUnaliased } from "../../../tir/types/utils/getUnaliased.js";
13
+ /**
14
+ * Compiles a `test name( params? ) { body }` declaration.
15
+ *
16
+ * Synthesises a `function <tirFuncName>( params ): void { body }` and
17
+ * runs it through `_compileFuncExpr` so type-checking, scoping and
18
+ * later TIR-to-UPLC compilation work exactly like a user-defined function.
19
+ *
20
+ * Registers the resulting `TirFuncExpr` in `program.functions` and pushes
21
+ * a `TirTestStmt` referencing it onto `program.tests`.
22
+ *
23
+ * @returns `true` on success (test registered), `false` on failure (diagnostic emitted).
24
+ */
25
+ export function _compileTestStmt(ctx, stmt, srcUid, sourceFile) {
26
+ const program = ctx.program;
27
+ const astName = stmt.testName.text;
28
+ const tirFuncName = PEBBLE_INTERNAL_IDENTIFIER_PREFIX + "test_" + astName + "_" + srcUid;
29
+ // Lower each TestParam to a SimpleVarDecl for the synthesized FuncExpr.
30
+ // `viaExpr` is consumed later (fuzzer resolution); the wrapper function
31
+ // itself takes the same params a regular `function name( ... )` would.
32
+ const lowerParams = stmt.params.map(p => new SimpleVarDecl(p.name, p.type, undefined, // initExpr
33
+ CommonFlags.Const, p.range));
34
+ const sig = new AstFuncType(lowerParams, new AstVoidType(stmt.testName.range), stmt.range);
35
+ const astFuncExpr = new FuncExpr(new Identifier(tirFuncName, stmt.testName.range), CommonFlags.None, [], // typeParams
36
+ sig, stmt.body, ArrowKind.None, stmt.range);
37
+ const tirFuncExpr = _compileFuncExpr(ctx, astFuncExpr, undefined, // expectedFuncType
38
+ false // isMethod
11
39
  );
12
-
13
- let tirBody = wrapManyStatements(
14
- _compileStatement(
15
- ctx.newBranchChildScope(),
16
- stmt.body
17
- ),
18
- stmt.body.range
19
- );
20
- if( !tirBody ) return undefined;
21
- if(!( tirBody instanceof TirBlockStmt))
22
- {
23
- tirBody = new TirBlockStmt( [ tirBody ], stmt.body.range );
24
- }
25
-
26
- return [ new TirTestStmt(
27
- stmt.testName?.string,
28
- tirBody as TirBlockStmt,
29
- stmt.range
30
- ) ];
40
+ if (!tirFuncExpr)
41
+ return false;
42
+ program.functions.set(tirFuncName, tirFuncExpr);
43
+ // Resolve per-parameter fuzzer info. This walks both the source-level
44
+ // `TestParam` array (which carries any `via` expressions) and the
45
+ // resolved TIR param types (taken from the compiled function).
46
+ const fuzzerInfos = stmt.params.map((astParam, idx) => {
47
+ // Phase 1: `via` is parsed but execution of user-defined fuzzers
48
+ // is not wired up. Type-checking the expression is also deferred
49
+ // until the stdlib `std.test.fuzz` namespace ships.
50
+ if (astParam.viaExpr) {
51
+ return { kind: "via_not_implemented" };
52
+ }
53
+ const tirParamType = tirFuncExpr.params[idx]?.type;
54
+ if (!tirParamType) {
55
+ return {
56
+ kind: "unsupported",
57
+ reason: `parameter '${astParam.name.text}' has no resolved type`
58
+ };
59
+ }
60
+ const unaliased = getUnaliased(tirParamType);
61
+ if (unaliased instanceof TirIntT)
62
+ return { kind: "primitive", primitive: "int" };
63
+ if (unaliased instanceof TirBoolT)
64
+ return { kind: "primitive", primitive: "bool" };
65
+ return {
66
+ kind: "unsupported",
67
+ reason: `parameter '${astParam.name.text}' of type '${tirParamType.toString()}' has no default fuzzer; specify one with 'via <expr>' (note: user-defined fuzzers via 'via' are not yet executable)`
68
+ };
69
+ });
70
+ program.tests.push(new TirTestStmt(astName, tirFuncName, sourceFile, stmt.range, fuzzerInfos));
71
+ return true;
31
72
  }
32
- //*/
@@ -0,0 +1,11 @@
1
+ import { UsingAliasStmt } from "../../../../ast/nodes/statements/UsingStmt.js";
2
+ import { AstCompilationCtx } from "../../AstCompilationCtx.js";
3
+ /**
4
+ * `using <alias> = <NamespacePath>;`
5
+ *
6
+ * binds `<alias>` in the current scope as a namespace alias for the
7
+ * namespace at `<NamespacePath>`.
8
+ *
9
+ * compile-time only — no IR is emitted.
10
+ */
11
+ export declare function _compileUsingAliasStmt(ctx: AstCompilationCtx, stmt: UsingAliasStmt): [] | undefined;
@@ -0,0 +1,26 @@
1
+ import { DiagnosticCode } from "../../../../diagnostics/diagnosticMessages.generated.js";
2
+ import { resolveNamespacePath } from "../../utils/resolveNamespacePath.js";
3
+ /**
4
+ * `using <alias> = <NamespacePath>;`
5
+ *
6
+ * binds `<alias>` in the current scope as a namespace alias for the
7
+ * namespace at `<NamespacePath>`.
8
+ *
9
+ * compile-time only — no IR is emitted.
10
+ */
11
+ export function _compileUsingAliasStmt(ctx, stmt) {
12
+ const resolved = resolveNamespacePath(ctx, stmt.rhs);
13
+ if (!resolved) {
14
+ ctx.error(DiagnosticCode._0_is_not_a_namespace, stmt.rhs.range, stmt.rhs.segments[0].text);
15
+ return undefined;
16
+ }
17
+ const ok = ctx.scope.defineNamespace({
18
+ name: stmt.aliasName.text,
19
+ publicScope: resolved.namespace.publicScope
20
+ });
21
+ if (!ok) {
22
+ ctx.error(DiagnosticCode.Constructor_name_0_is_already_declared_in_this_scope, stmt.aliasName.range, stmt.aliasName.text);
23
+ return undefined;
24
+ }
25
+ return [];
26
+ }
@@ -1,11 +1,16 @@
1
1
  import { UsingStmt } from "../../../../ast/nodes/statements/UsingStmt.js";
2
2
  import { AstCompilationCtx } from "../../AstCompilationCtx.js";
3
3
  /**
4
- * `using` only introduces symbols in scope
4
+ * `using` only introduces symbols in scope.
5
5
  *
6
- * we don't represent `using` statements in the TIR
6
+ * we don't represent `using` statements in the TIR.
7
7
  *
8
- * @returns {[]} an empty array if successful compilation
8
+ * the RHS can be either:
9
+ * - a struct type expression (legacy behavior, brings constructors into scope)
10
+ * - a namespace path (new behavior, destructures the namespace's exported
11
+ * members into the current scope)
12
+ *
13
+ * @returns {[]} an empty array if compilation succeeded
9
14
  * @returns {undefined} `undefined` if compilation failed
10
- **/
15
+ */
11
16
  export declare function _compileUsingStmt(ctx: AstCompilationCtx, stmt: UsingStmt): [] | undefined;
@@ -1,27 +1,55 @@
1
+ import { UsingPath } from "../../../../ast/nodes/statements/UsingStmt.js";
1
2
  import { DiagnosticCode } from "../../../../diagnostics/diagnosticMessages.generated.js";
2
3
  import { getStructType } from "../../../tir/types/utils/canAssignTo.js";
4
+ import { bindNamespaceMember, resolveNamespacePath } from "../../utils/resolveNamespacePath.js";
3
5
  import { _compileDataEncodedConcreteType } from "../types/_compileDataEncodedConcreteType.js";
4
6
  import { _compileSopEncodedConcreteType } from "../types/_compileSopEncodedConcreteType.js";
7
+ import { AstNamedTypeExpr } from "../../../../ast/nodes/types/AstNamedTypeExpr.js";
5
8
  /**
6
- * `using` only introduces symbols in scope
9
+ * `using` only introduces symbols in scope.
7
10
  *
8
- * we don't represent `using` statements in the TIR
11
+ * we don't represent `using` statements in the TIR.
9
12
  *
10
- * @returns {[]} an empty array if successful compilation
13
+ * the RHS can be either:
14
+ * - a struct type expression (legacy behavior, brings constructors into scope)
15
+ * - a namespace path (new behavior, destructures the namespace's exported
16
+ * members into the current scope)
17
+ *
18
+ * @returns {[]} an empty array if compilation succeeded
11
19
  * @returns {undefined} `undefined` if compilation failed
12
- **/
20
+ */
13
21
  export function _compileUsingStmt(ctx, stmt) {
14
- stmt.constructorNames;
15
- stmt.structTypeExpr;
16
- stmt.range;
17
- const structOrAliasType = (_compileSopEncodedConcreteType(ctx, stmt.structTypeExpr)
18
- ?? _compileDataEncodedConcreteType(ctx, stmt.structTypeExpr));
22
+ const rhs = stmt.rhs;
23
+ if (rhs instanceof UsingPath) {
24
+ // namespace path. if the head is a namespace, destructure
25
+ // its public members; otherwise fall through to the struct path
26
+ // (this supports the single-identifier case where a name could
27
+ // be either a struct or a namespace).
28
+ const ns = resolveNamespacePath(ctx, rhs);
29
+ if (ns) {
30
+ return _compileUsingNamespaceDestructure(ctx, stmt, ns.namespace);
31
+ }
32
+ // single-segment fallback: treat as a struct type ref
33
+ if (rhs.segments.length === 1) {
34
+ const ident = rhs.segments[0];
35
+ const fakeTypeExpr = new AstNamedTypeExpr(ident, [], ident.range);
36
+ return _compileUsingStructDestructure(ctx, stmt, fakeTypeExpr);
37
+ }
38
+ ctx.error(DiagnosticCode._0_is_not_a_namespace, rhs.range, rhs.segments[0].text);
39
+ return undefined;
40
+ }
41
+ // RHS is an AstTypeExpr (existing struct-destructure code path)
42
+ return _compileUsingStructDestructure(ctx, stmt, rhs);
43
+ }
44
+ function _compileUsingStructDestructure(ctx, stmt, rhs) {
45
+ const structOrAliasType = (_compileSopEncodedConcreteType(ctx, rhs)
46
+ ?? _compileDataEncodedConcreteType(ctx, rhs));
19
47
  if (!structOrAliasType)
20
48
  return undefined;
21
49
  // un-alias
22
50
  const structType = getStructType(structOrAliasType);
23
51
  if (!structType || !structType.isConcrete())
24
- return ctx.error(DiagnosticCode.Type_0_does_not_have_constructors, stmt.structTypeExpr.range, structOrAliasType.toString());
52
+ return ctx.error(DiagnosticCode.Type_0_does_not_have_constructors, rhs.range, structOrAliasType.toString());
25
53
  const defCtorNames = structType.constructors.map(c => c.name);
26
54
  const sameStmtCtorNames = [];
27
55
  for (const stmtCtor of stmt.constructorNames) {
@@ -39,3 +67,16 @@ export function _compileUsingStmt(ctx, stmt) {
39
67
  }
40
68
  return [];
41
69
  }
70
+ function _compileUsingNamespaceDestructure(ctx, stmt, ns) {
71
+ const seen = new Set();
72
+ for (const decl of stmt.constructorNames) {
73
+ const name = decl.constructorName;
74
+ if (seen.has(name.text))
75
+ return ctx.error(DiagnosticCode.Constructor_0_was_already_specified, name.range, name.text);
76
+ seen.add(name.text);
77
+ const ok = bindNamespaceMember(ctx, ns, name, decl.renamedConstructorName, ctx.scope);
78
+ if (!ok)
79
+ return undefined;
80
+ }
81
+ return [];
82
+ }
@@ -46,11 +46,30 @@ export function _compileDataEncodedConcreteType(ctx, typeExpr, optionalsAsSop =
46
46
  return undefined; // no data encoding for function types
47
47
  if (typeExpr instanceof AstNamedTypeExpr) // struct, aliases and respective params
48
48
  {
49
+ // generic type parameters take precedence: `T` in a generic function
50
+ // body resolves directly to its TirTypeParam, leaving substitution
51
+ // to `monomorphizeGeneric` at call time.
52
+ const typeParam = ctx.scope.resolveTypeParam(typeExpr.name.text);
53
+ if (typeParam)
54
+ return typeParam;
49
55
  const possibleTirNames = ctx.scope.resolveType(typeExpr.name.text);
50
56
  if (!possibleTirNames)
51
57
  return ctx.error(DiagnosticCode._0_is_not_defined, typeExpr.name.range, typeExpr.name.text);
52
- if (possibleTirNames.isGeneric)
53
- throw new Error("not implemented: _compileDataEncodedConcreteType for generic types");
58
+ if (possibleTirNames.isGeneric) {
59
+ // Generic named type with explicit type-args, e.g. `List<int>` —
60
+ // compile each arg and apply the generic.
61
+ if (typeExpr.tyArgs.length === 0)
62
+ return ctx.error(DiagnosticCode._0_is_not_defined, typeExpr.name.range, typeExpr.name.text);
63
+ const compiledArgs = [];
64
+ for (const aExpr of typeExpr.tyArgs) {
65
+ const a = _compileDataEncodedConcreteType(ctx, aExpr, optionalsAsSop);
66
+ if (!a)
67
+ return undefined;
68
+ compiledArgs.push(a);
69
+ }
70
+ const applied = ctx.program.getAppliedGeneric(possibleTirNames.dataTirName ?? possibleTirNames.sopTirName, compiledArgs);
71
+ return applied;
72
+ }
54
73
  if (typeof possibleTirNames.dataTirName !== "string")
55
74
  return undefined;
56
75
  return ctx.program.types.get(possibleTirNames.dataTirName);
@@ -44,11 +44,26 @@ export function _compileSopEncodedConcreteType(ctx, typeExpr) {
44
44
  return undefined; // no data encoding for function types
45
45
  if (typeExpr instanceof AstNamedTypeExpr) // struct, aliases and respective params
46
46
  {
47
+ // generic type parameters take precedence over named-type lookup
48
+ const typeParam = ctx.scope.resolveTypeParam(typeExpr.name.text);
49
+ if (typeParam)
50
+ return typeParam;
47
51
  const possibleTirNames = ctx.scope.resolveType(typeExpr.name.text);
48
52
  if (!possibleTirNames)
49
53
  return ctx.error(DiagnosticCode._0_is_not_defined, typeExpr.name.range, typeExpr.name.text);
50
- if (possibleTirNames.isGeneric)
51
- throw new Error("not implemented: _compileSopEncodedConcreteType for generic types");
54
+ if (possibleTirNames.isGeneric) {
55
+ if (typeExpr.tyArgs.length === 0)
56
+ return ctx.error(DiagnosticCode._0_is_not_defined, typeExpr.name.range, typeExpr.name.text);
57
+ const compiledArgs = [];
58
+ for (const aExpr of typeExpr.tyArgs) {
59
+ const a = _compileSopEncodedConcreteType(ctx, aExpr);
60
+ if (!a)
61
+ return undefined;
62
+ compiledArgs.push(a);
63
+ }
64
+ const applied = ctx.program.getAppliedGeneric(possibleTirNames.sopTirName, compiledArgs);
65
+ return applied;
66
+ }
52
67
  if (typeof possibleTirNames.dataTirName !== "string")
53
68
  return undefined;
54
69
  return ctx.program.types.get(possibleTirNames.dataTirName);