@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
@@ -1,6 +1,7 @@
1
1
  import { AstFuncType } from "../../../ast/nodes/types/AstNativeTypeExpr.js";
2
- import { TypedProgram } from "../../tir/program/TypedProgram.js";
2
+ import { TypedProgram, TypeParamConstraint } from "../../tir/program/TypedProgram.js";
3
3
  import { TirType } from "../../tir/types/TirType.js";
4
+ import { TirTypeParam } from "../../tir/types/TirTypeParam.js";
4
5
  export interface ScopeInfos {
5
6
  isFunctionDeclScope: boolean;
6
7
  isMethodScope: boolean;
@@ -32,6 +33,29 @@ export interface IVariableInfos {
32
33
  name: string;
33
34
  type: TirType;
34
35
  isConstant: boolean;
36
+ /**
37
+ * If set, this binding is a placeholder for a generic function template.
38
+ * The actual TIR function does not exist yet; it must be instantiated
39
+ * at the call site by `monomorphizeGeneric` using the template stored in
40
+ * `TypedProgram.genericTemplates` under this name.
41
+ *
42
+ * `type` for a generic placeholder is the *un-substituted* TirFuncT —
43
+ * i.e. it may contain `TirTypeParam` nodes for each declared type param.
44
+ */
45
+ genericTemplateName?: string;
46
+ }
47
+ /**
48
+ * A namespace is a compile-time only construct that groups
49
+ * symbols (values, types, functions, interfaces, and nested
50
+ * namespaces) under a single name.
51
+ *
52
+ * Members of the namespace marked with `private` are NOT included
53
+ * in `publicScope`; they only live in the namespace's body-compilation
54
+ * scope and are unreachable from outside.
55
+ */
56
+ export interface NamespaceSymbol {
57
+ name: string;
58
+ publicScope: AstScope;
35
59
  }
36
60
  export interface PossibleTirTypes {
37
61
  sopTirName: string;
@@ -81,6 +105,24 @@ export declare class AstScope {
81
105
  */
82
106
  readonly narrowings: Map<string, TirType>;
83
107
  readonly aviableConstructors: Map<string, IAvaiableConstructor>;
108
+ /**
109
+ * ast name -> namespace symbol
110
+ *
111
+ * namespaces are compile-time only; they do not emit IR
112
+ */
113
+ readonly namespaces: Map<string, NamespaceSymbol>;
114
+ /**
115
+ * Generic type parameters in scope, e.g. while compiling the signature
116
+ * (and later the body) of a generic function `function f<T>(...)`. These
117
+ * are NOT real types — they only mark positions that must be substituted
118
+ * by `monomorphizeGeneric` at each call site.
119
+ *
120
+ * When `_compileDataEncodedConcreteType` / `_compileSopEncodedConcreteType`
121
+ * encounter an `AstNamedTypeExpr` whose name is here, it returns the
122
+ * corresponding `TirTypeParam` directly instead of going through the
123
+ * regular `resolveType` path.
124
+ */
125
+ readonly typeParams: Map<string, TirTypeParam>;
84
126
  private _isReadonly;
85
127
  readonly infos: ScopeInfos;
86
128
  constructor(parent: AstScope | undefined, program: TypedProgram, infos: Partial<ScopeInfos>);
@@ -111,5 +153,32 @@ export declare class AstScope {
111
153
  */
112
154
  defineAviableConstructorIfValid(declaredName: string, originalName: string, structOrAliasType: TirType): boolean;
113
155
  inferStructTypeFromConstructorName(name: string): IAvaiableConstructor | undefined;
156
+ /** define a namespace in this scope; returns `false` if shadowed in current scope */
157
+ defineNamespace(ns: NamespaceSymbol): boolean;
158
+ /** resolve a namespace by walking the scope chain */
159
+ resolveNamespace(name: string): NamespaceSymbol | undefined;
160
+ /** define a generic type parameter in this scope; returns `false` if shadowed */
161
+ defineTypeParam(name: string, param: TirTypeParam): boolean;
162
+ /** resolve a generic type parameter by walking the scope chain */
163
+ resolveTypeParam(name: string): TirTypeParam | undefined;
164
+ /**
165
+ * Type-parameter constraints declared via `<T implements I>` syntax.
166
+ * Populated by `AstCompiler._registerGenericTemplate` for the function
167
+ * template's compilation scope. `resolveTypeParamConstraint` walks the
168
+ * parent chain like the other resolvers.
169
+ */
170
+ readonly typeParamConstraints: Map<string, TypeParamConstraint>;
171
+ defineTypeParamConstraint(name: string, constraint: TypeParamConstraint): boolean;
172
+ resolveTypeParamConstraint(name: string): TypeParamConstraint | undefined;
173
+ /**
174
+ * Walk the scope chain to resolve an interface by name. Returns the
175
+ * method-name -> AstFuncType signature map.
176
+ */
177
+ resolveInterface(name: string): Map<string, AstFuncType> | undefined;
178
+ /**
179
+ * `true` if `name` is bound in this scope (or any parent) under any kind.
180
+ * Used to detect shadowing across symbol categories when defining a new symbol.
181
+ */
182
+ hasAnySymbol(name: string): boolean;
114
183
  clone(): AstScope;
115
184
  }
@@ -59,6 +59,24 @@ export class AstScope {
59
59
  */
60
60
  narrowings = new Map();
61
61
  aviableConstructors = new Map();
62
+ /**
63
+ * ast name -> namespace symbol
64
+ *
65
+ * namespaces are compile-time only; they do not emit IR
66
+ */
67
+ namespaces = new Map();
68
+ /**
69
+ * Generic type parameters in scope, e.g. while compiling the signature
70
+ * (and later the body) of a generic function `function f<T>(...)`. These
71
+ * are NOT real types — they only mark positions that must be substituted
72
+ * by `monomorphizeGeneric` at each call site.
73
+ *
74
+ * When `_compileDataEncodedConcreteType` / `_compileSopEncodedConcreteType`
75
+ * encounter an `AstNamedTypeExpr` whose name is here, it returns the
76
+ * corresponding `TirTypeParam` directly instead of going through the
77
+ * regular `resolveType` path.
78
+ */
79
+ typeParams = new Map();
62
80
  _isReadonly = false;
63
81
  infos;
64
82
  constructor(parent, program, infos) {
@@ -202,6 +220,77 @@ export class AstScope {
202
220
  return (this.aviableConstructors.get(name)
203
221
  ?? this.parent?.inferStructTypeFromConstructorName(name));
204
222
  }
223
+ /** define a namespace in this scope; returns `false` if shadowed in current scope */
224
+ defineNamespace(ns) {
225
+ if (this._isReadonly)
226
+ return false;
227
+ if (invalidSymbolNames.has(ns.name))
228
+ return false;
229
+ if (this.namespaces.has(ns.name))
230
+ return false;
231
+ this.namespaces.set(ns.name, ns);
232
+ return true;
233
+ }
234
+ /** resolve a namespace by walking the scope chain */
235
+ resolveNamespace(name) {
236
+ return (this.namespaces.get(name)
237
+ ?? this.parent?.resolveNamespace(name));
238
+ }
239
+ /** define a generic type parameter in this scope; returns `false` if shadowed */
240
+ defineTypeParam(name, param) {
241
+ if (this._isReadonly)
242
+ return false;
243
+ if (this.typeParams.has(name))
244
+ return false;
245
+ this.typeParams.set(name, param);
246
+ return true;
247
+ }
248
+ /** resolve a generic type parameter by walking the scope chain */
249
+ resolveTypeParam(name) {
250
+ return (this.typeParams.get(name)
251
+ ?? this.parent?.resolveTypeParam(name));
252
+ }
253
+ /**
254
+ * Type-parameter constraints declared via `<T implements I>` syntax.
255
+ * Populated by `AstCompiler._registerGenericTemplate` for the function
256
+ * template's compilation scope. `resolveTypeParamConstraint` walks the
257
+ * parent chain like the other resolvers.
258
+ */
259
+ typeParamConstraints = new Map();
260
+ defineTypeParamConstraint(name, constraint) {
261
+ if (this._isReadonly)
262
+ return false;
263
+ if (this.typeParamConstraints.has(name))
264
+ return false;
265
+ this.typeParamConstraints.set(name, constraint);
266
+ return true;
267
+ }
268
+ resolveTypeParamConstraint(name) {
269
+ return (this.typeParamConstraints.get(name)
270
+ ?? this.parent?.resolveTypeParamConstraint(name));
271
+ }
272
+ /**
273
+ * Walk the scope chain to resolve an interface by name. Returns the
274
+ * method-name -> AstFuncType signature map.
275
+ */
276
+ resolveInterface(name) {
277
+ return (this.interfaces.get(name)
278
+ ?? this.parent?.resolveInterface(name));
279
+ }
280
+ /**
281
+ * `true` if `name` is bound in this scope (or any parent) under any kind.
282
+ * Used to detect shadowing across symbol categories when defining a new symbol.
283
+ */
284
+ hasAnySymbol(name) {
285
+ if (this.variables.has(name)
286
+ || this.types.has(name)
287
+ || this.functions.has(name)
288
+ || this.interfaces.has(name)
289
+ || this.namespaces.has(name)
290
+ || this.aviableConstructors.has(name))
291
+ return true;
292
+ return this.parent?.hasAnySymbol(name) ?? false;
293
+ }
205
294
  clone() {
206
295
  const cloned = new AstScope(this.parent, this.program, this.infos);
207
296
  for (const [key, value] of this.variables)
@@ -219,6 +308,8 @@ export class AstScope {
219
308
  });
220
309
  for (const [name, methods] of this.interfaces)
221
310
  cloned.interfaces.set(name, new Map(methods));
311
+ for (const [name, ns] of this.namespaces)
312
+ cloned.namespaces.set(name, ns);
222
313
  return cloned;
223
314
  }
224
315
  }
@@ -1,13 +1,16 @@
1
1
  import { TirAliasType } from "../../tir/types/TirAliasType.js";
2
2
  import { isTirStructType } from "../../tir/types/TirStructType.js";
3
+ import { TirEnumType } from "../../tir/types/TirEnumType.js";
3
4
  import { TirTypeParam } from "../../tir/types/TirTypeParam.js";
4
5
  import { int_t, bytes_t, bool_t, string_t } from "../../tir/program/stdScope/stdScope.js";
5
- import { TirUnConstrDataResultT, TirPairDataT } from "../../tir/types/TirNativeType/index.js";
6
+ import { TirBlsG1T, TirBlsG2T, TirMlResultT, TirUnConstrDataResultT, TirPairDataT } from "../../tir/types/TirNativeType/index.js";
6
7
  import { TirBoolT } from "../../tir/types/TirNativeType/native/bool.js";
7
8
  import { TirBytesT } from "../../tir/types/TirNativeType/native/bytes.js";
8
9
  import { TirDataT } from "../../tir/types/TirNativeType/native/data.js";
9
10
  import { TirFuncT } from "../../tir/types/TirNativeType/native/function.js";
10
11
  import { TirIntT } from "../../tir/types/TirNativeType/native/int.js";
12
+ import { TirArrayT } from "../../tir/types/TirNativeType/native/array.js";
13
+ import { TirValueT } from "../../tir/types/TirNativeType/native/value.js";
11
14
  import { TirLinearMapT } from "../../tir/types/TirNativeType/native/linearMap.js";
12
15
  import { TirLinearMapEntryT } from "../../tir/types/TirNativeType/native/linearMapEntry.js";
13
16
  import { TirListT } from "../../tir/types/TirNativeType/native/list.js";
@@ -27,6 +30,24 @@ export function getPropAccessReturnType(ctx, objType, propId) {
27
30
  objType = objType.aliased;
28
31
  }
29
32
  // if( objType instanceof TirAliasType ) return findPropInImpls( objType.impls, propName ) ?? getPropAccessReturnType( objType.aliased, propId );
33
+ // Universal `.show()` — every (built-in) type implementing the Show
34
+ // interface has signature `(): bytes`. Struct types fall through to
35
+ // `getStructPropAccessReturnType`, which checks user-declared
36
+ // `type X implements Show { ... }` impls first; if absent, the
37
+ // expressify-time fallback emits a TirShowExpr that auto-derives via
38
+ // `_showIR` (e.g. for data-encoded structs).
39
+ if (propName === "show") {
40
+ if (objType instanceof TirVoidT
41
+ || objType instanceof TirBoolT
42
+ || objType instanceof TirIntT
43
+ || objType instanceof TirBytesT
44
+ || objType instanceof TirStringT
45
+ || objType instanceof TirDataT
46
+ || objType instanceof TirListT
47
+ || objType instanceof TirLinearMapT
48
+ || isTirOptType(objType))
49
+ return new TirFuncT([], bytes_t);
50
+ }
30
51
  if (isTirStructType(objType))
31
52
  return getStructPropAccessReturnType(ctx, objType, propName);
32
53
  if (objType instanceof TirVoidT)
@@ -60,6 +81,20 @@ export function getPropAccessReturnType(ctx, objType, propId) {
60
81
  return undefined;
61
82
  if (objType instanceof TirPairDataT)
62
83
  return undefined;
84
+ if (objType instanceof TirBlsG1T)
85
+ return undefined;
86
+ if (objType instanceof TirBlsG2T)
87
+ return undefined;
88
+ if (objType instanceof TirMlResultT)
89
+ return undefined;
90
+ // Native Value / Array<T> — methods are reached through prelude/std
91
+ // aliases, not via direct prop-access on the native type.
92
+ if (objType instanceof TirValueT)
93
+ return undefined;
94
+ if (objType instanceof TirArrayT)
95
+ return undefined;
96
+ if (objType instanceof TirEnumType)
97
+ return undefined;
63
98
  const tsEnsureExhaustiveCheck = objType;
64
99
  console.error(objType);
65
100
  throw new Error("unreachable::getPropAccessReturnType");
@@ -0,0 +1,36 @@
1
+ import { SourceRange } from "../../../ast/Source/SourceRange.js";
2
+ import { GenericTemplate } from "../../tir/program/TypedProgram.js";
3
+ import { TirFuncT } from "../../tir/types/TirNativeType/native/function.js";
4
+ import { TirType } from "../../tir/types/TirType.js";
5
+ import { AstCompilationCtx } from "../AstCompilationCtx.js";
6
+ export interface MonomorphizationResult {
7
+ /** the canonical TIR function name registered in `program.functions` */
8
+ tirFuncName: string;
9
+ /** the substituted concrete TirFuncT (no remaining type params) */
10
+ concreteFuncType: TirFuncT;
11
+ }
12
+ /**
13
+ * Returns a deterministic instance key for memoization & function-table naming.
14
+ */
15
+ export declare function buildMonomorphizationKey(templateCanonicalName: string, typeArgs: TirType[]): string;
16
+ /**
17
+ * Instantiate a generic function template with the given concrete type
18
+ * arguments, producing (and caching) a fresh concrete TIR function.
19
+ *
20
+ * The strategy is "desugar to a concrete function during AST→TIR":
21
+ *
22
+ * 1. Build a child scope on the template's defining scope where each type
23
+ * parameter name resolves as a type alias for its concrete type. When the
24
+ * cloned FuncExpr is re-compiled, every `AstNamedTypeExpr` mentioning a
25
+ * type parameter resolves to its concrete TIR type.
26
+ * 2. Construct a fresh `FuncExpr` reusing the template's body & signature but
27
+ * with `typeParams = []` (so the "not implemented: generic functions"
28
+ * guard in `_compileFuncExpr` does not trip) and a unique instance name.
29
+ * 3. Compile via `_compileFuncExpr` and register the resulting `TirFuncExpr`
30
+ * in `program.functions` under the instance name.
31
+ *
32
+ * Results are memoized per `(template, type-args)` tuple — repeated calls
33
+ * with the same type arguments return the same instance and do not
34
+ * re-compile.
35
+ */
36
+ export declare function monomorphizeGeneric(ctx: AstCompilationCtx, template: GenericTemplate, typeArgs: TirType[], callRange: SourceRange): MonomorphizationResult | undefined;
@@ -0,0 +1,123 @@
1
+ import { FuncExpr } from "../../../ast/nodes/expr/functions/FuncExpr.js";
2
+ import { Identifier } from "../../../ast/nodes/common/Identifier.js";
3
+ import { ArrowKind } from "../../../ast/nodes/expr/functions/ArrowKind.js";
4
+ import { DiagnosticCode } from "../../../diagnostics/diagnosticMessages.generated.js";
5
+ import { substituteTypeParams } from "../../tir/types/utils/substituteTypeParams.js";
6
+ import { AstCompilationCtx } from "../AstCompilationCtx.js";
7
+ import { _compileFuncExpr } from "../internal/exprs/_compileFuncExpr.js";
8
+ /**
9
+ * Returns a deterministic instance key for memoization & function-table naming.
10
+ */
11
+ export function buildMonomorphizationKey(templateCanonicalName, typeArgs) {
12
+ return templateCanonicalName + "$$" + typeArgs.map(t => t.toConcreteTirTypeName()).join("$$");
13
+ }
14
+ /**
15
+ * Instantiate a generic function template with the given concrete type
16
+ * arguments, producing (and caching) a fresh concrete TIR function.
17
+ *
18
+ * The strategy is "desugar to a concrete function during AST→TIR":
19
+ *
20
+ * 1. Build a child scope on the template's defining scope where each type
21
+ * parameter name resolves as a type alias for its concrete type. When the
22
+ * cloned FuncExpr is re-compiled, every `AstNamedTypeExpr` mentioning a
23
+ * type parameter resolves to its concrete TIR type.
24
+ * 2. Construct a fresh `FuncExpr` reusing the template's body & signature but
25
+ * with `typeParams = []` (so the "not implemented: generic functions"
26
+ * guard in `_compileFuncExpr` does not trip) and a unique instance name.
27
+ * 3. Compile via `_compileFuncExpr` and register the resulting `TirFuncExpr`
28
+ * in `program.functions` under the instance name.
29
+ *
30
+ * Results are memoized per `(template, type-args)` tuple — repeated calls
31
+ * with the same type arguments return the same instance and do not
32
+ * re-compile.
33
+ */
34
+ export function monomorphizeGeneric(ctx, template, typeArgs, callRange) {
35
+ const program = ctx.program;
36
+ if (typeArgs.length !== template.typeParams.length) {
37
+ ctx.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, callRange, String(template.typeParams.length), String(typeArgs.length));
38
+ return undefined;
39
+ }
40
+ // Build the substitution env for substituteTypeParams
41
+ const subst = new Map();
42
+ for (let i = 0; i < template.typeParams.length; i++) {
43
+ subst.set(template.typeParams[i].symbol, typeArgs[i]);
44
+ }
45
+ // Compute concrete signature up-front (used by callers to type the call expr)
46
+ const concreteFuncType = substituteTypeParams(template.placeholderFuncType, subst);
47
+ // Memo key & cache hit
48
+ const instanceName = buildMonomorphizationKey(template.canonicalTirName, typeArgs);
49
+ const cached = program.monomorphizationCache.get(instanceName);
50
+ if (typeof cached === "string") {
51
+ return { tirFuncName: cached, concreteFuncType };
52
+ }
53
+ // Native template path: skip AST cloning entirely.
54
+ if (template.kind === "native") {
55
+ const tirFunc = template.instantiate(typeArgs);
56
+ program.functions.set(instanceName, tirFunc);
57
+ program.monomorphizationCache.set(instanceName, instanceName);
58
+ return { tirFuncName: instanceName, concreteFuncType };
59
+ }
60
+ // Cycle detection: polymorphic recursion (same template + same type args
61
+ // re-entering before the first compile finished) is impossible because
62
+ // recursion at the same type-args hits the memo cache below. Recursion at
63
+ // *different* type-args is allowed and produces a separate instance.
64
+ if (program.monomorphizationInFlight.has(instanceName)) {
65
+ // intentionally rare path; surface as a Not_implemented diagnostic
66
+ ctx.error(DiagnosticCode.Not_implemented_0, callRange, "mutually-recursive monomorphization for " + instanceName);
67
+ return undefined;
68
+ }
69
+ program.monomorphizationInFlight.add(instanceName);
70
+ // Pre-register memo so recursive same-args call resolves to the same name
71
+ program.monomorphizationCache.set(instanceName, instanceName);
72
+ try {
73
+ // Build child scope where each type-param name aliases its concrete type
74
+ const monoScope = template.definingScope.newChildScope({
75
+ ...template.definingScope.infos,
76
+ isFunctionDeclScope: false,
77
+ isMethodScope: false
78
+ });
79
+ for (let i = 0; i < template.typeParams.length; i++) {
80
+ const tparam = template.typeParams[i];
81
+ const concrete = typeArgs[i];
82
+ const concreteKey = concrete.toConcreteTirTypeName();
83
+ if (!program.types.has(concreteKey)) {
84
+ program.types.set(concreteKey, concrete);
85
+ }
86
+ monoScope.defineUnambigousType(tparam.name, concreteKey, concrete.hasDataEncoding(), new Map() // no methods on a bare type alias
87
+ );
88
+ }
89
+ // Register the instance in the parent (defining) scope under the
90
+ // instance name so the body's own recursive `id(...)` call (which
91
+ // resolves through the parent chain) sees a concrete value of the
92
+ // already-substituted type. Without this, recursive calls would
93
+ // re-trigger the generic placeholder path and infinite-loop the
94
+ // monomorphizer.
95
+ // Use the mono scope (not the defining scope) so the entry is local
96
+ // to this instantiation.
97
+ monoScope.defineValue({
98
+ name: instanceName,
99
+ type: concreteFuncType,
100
+ isConstant: true,
101
+ });
102
+ const cloneExpr = new FuncExpr(new Identifier(instanceName, template.astFuncExpr.name.range), template.astFuncExpr.flags, [], // intentionally empty: this clone is the monomorphized concrete fn
103
+ template.astFuncExpr.signature, template.astFuncExpr.body, template.astFuncExpr.arrowKind ?? ArrowKind.None, template.astFuncExpr.range);
104
+ // Pre-seed program.functions with the concrete signature so
105
+ // `_compileFuncExpr` picks it up via `program.functions.get(...).sig()`.
106
+ // We will replace this with the real TirFuncExpr after compile.
107
+ // (placeholder is not strictly required; _compileFuncExpr falls back to
108
+ // inferring from the signature if not present — leaving this out for
109
+ // simplicity)
110
+ const monoCtx = AstCompilationCtx.fromScope(program, monoScope);
111
+ const tirFuncExpr = _compileFuncExpr(monoCtx, cloneExpr, undefined, false // isMethod
112
+ );
113
+ if (!tirFuncExpr) {
114
+ program.monomorphizationCache.delete(instanceName);
115
+ return undefined;
116
+ }
117
+ program.functions.set(instanceName, tirFuncExpr);
118
+ return { tirFuncName: instanceName, concreteFuncType };
119
+ }
120
+ finally {
121
+ program.monomorphizationInFlight.delete(instanceName);
122
+ }
123
+ }
@@ -0,0 +1,28 @@
1
+ import { PebbleExpr } from "../../../ast/nodes/expr/PebbleExpr.js";
2
+ import { TirExpr } from "../../tir/expressions/TirExpr.js";
3
+ import { AstCompilationCtx } from "../AstCompilationCtx.js";
4
+ import { NamespaceSymbol } from "../scope/AstScope.js";
5
+ export type NamespaceChainResolution = {
6
+ kind: "namespace";
7
+ namespace: NamespaceSymbol;
8
+ } | {
9
+ kind: "value";
10
+ expr: TirExpr;
11
+ }
12
+ /** the chain points to a non-value (type / interface / nested ns
13
+ * used in non-expression position). callers should typically error. */
14
+ | {
15
+ kind: "incomplete";
16
+ } | undefined;
17
+ /**
18
+ * if `expr` is `Identifier` or a chain of `DotPropAccessExpr` ending in an
19
+ * `Identifier`, AND the head identifier resolves to a namespace in scope,
20
+ * walks the chain through namespace `publicScope`s and returns the resolved
21
+ * member. otherwise returns `undefined` so the caller can fall back to
22
+ * normal value/property-access compilation.
23
+ *
24
+ * the resolution does NOT emit diagnostics on plain "not a namespace"
25
+ * outcomes — those are silent failures so the caller can choose another
26
+ * resolution strategy.
27
+ */
28
+ export declare function tryResolveNamespaceChain(ctx: AstCompilationCtx, expr: PebbleExpr): NamespaceChainResolution;
@@ -0,0 +1,95 @@
1
+ import { Identifier } from "../../../ast/nodes/common/Identifier.js";
2
+ import { DotPropAccessExpr } from "../../../ast/nodes/expr/PropAccessExpr.js";
3
+ import { DiagnosticCode } from "../../../diagnostics/diagnosticMessages.generated.js";
4
+ import { TirVariableAccessExpr } from "../../tir/expressions/TirVariableAccessExpr.js";
5
+ /**
6
+ * if `expr` is `Identifier` or a chain of `DotPropAccessExpr` ending in an
7
+ * `Identifier`, AND the head identifier resolves to a namespace in scope,
8
+ * walks the chain through namespace `publicScope`s and returns the resolved
9
+ * member. otherwise returns `undefined` so the caller can fall back to
10
+ * normal value/property-access compilation.
11
+ *
12
+ * the resolution does NOT emit diagnostics on plain "not a namespace"
13
+ * outcomes — those are silent failures so the caller can choose another
14
+ * resolution strategy.
15
+ */
16
+ export function tryResolveNamespaceChain(ctx, expr) {
17
+ const segments = _collectChainSegments(expr);
18
+ if (!segments)
19
+ return undefined;
20
+ const head = ctx.scope.resolveNamespace(segments[0].text);
21
+ if (!head)
22
+ return undefined;
23
+ // head is a namespace; from here on, any failure emits a diagnostic
24
+ let current = head;
25
+ for (let i = 1; i < segments.length; i++) {
26
+ const seg = segments[i];
27
+ const name = seg.text;
28
+ const pub = current.publicScope;
29
+ const nested = pub.namespaces.get(name);
30
+ if (nested) {
31
+ current = nested;
32
+ continue;
33
+ }
34
+ const variable = pub.variables.get(name);
35
+ if (variable) {
36
+ // last segment must end here; if not, the chain is invalid
37
+ if (i !== segments.length - 1) {
38
+ ctx.error(DiagnosticCode.Property_0_does_not_exist_on_type_1, seg.range, segments[i + 1].text, variable.type.toString());
39
+ return { kind: "incomplete" };
40
+ }
41
+ return {
42
+ kind: "value",
43
+ expr: new TirVariableAccessExpr({ variableInfos: variable, isDefinedOutsideFuncScope: true }, seg.range)
44
+ };
45
+ }
46
+ const tirFuncName = pub.functions.get(name);
47
+ if (tirFuncName) {
48
+ if (i !== segments.length - 1) {
49
+ // function-typed member can't be further dotted
50
+ ctx.error(DiagnosticCode.Namespace_path_is_incomplete_expected_a_value_type_function_or_interface, seg.range);
51
+ return { kind: "incomplete" };
52
+ }
53
+ const funcExpr = pub.program.functions.get(tirFuncName);
54
+ if (!funcExpr) {
55
+ ctx.error(DiagnosticCode.Namespace_0_has_no_exported_member_1, seg.range, current.name, name);
56
+ return { kind: "incomplete" };
57
+ }
58
+ return {
59
+ kind: "value",
60
+ expr: new TirVariableAccessExpr({
61
+ variableInfos: {
62
+ isConstant: true,
63
+ name: tirFuncName,
64
+ type: funcExpr.type,
65
+ },
66
+ isDefinedOutsideFuncScope: true,
67
+ }, seg.range)
68
+ };
69
+ }
70
+ // not a namespace, not a value, not a function — likely a type or
71
+ // interface. either way it can't be used as a value here.
72
+ if (pub.types.has(name) || pub.interfaces.has(name)) {
73
+ ctx.error(DiagnosticCode.Namespace_path_is_incomplete_expected_a_value_type_function_or_interface, seg.range);
74
+ return { kind: "incomplete" };
75
+ }
76
+ ctx.error(DiagnosticCode.Namespace_0_has_no_exported_member_1, seg.range, current.name, name);
77
+ return { kind: "incomplete" };
78
+ }
79
+ // chain consumed entirely as namespaces (no leaf member)
80
+ return { kind: "namespace", namespace: current };
81
+ }
82
+ function _collectChainSegments(expr) {
83
+ if (expr instanceof Identifier)
84
+ return [expr];
85
+ if (expr instanceof DotPropAccessExpr) {
86
+ const inner = _collectChainSegments(expr.object);
87
+ if (!inner)
88
+ return undefined;
89
+ inner.push(expr.prop);
90
+ return inner;
91
+ }
92
+ // anything other than a plain dotted-identifier chain disqualifies
93
+ // namespace resolution.
94
+ return undefined;
95
+ }
@@ -0,0 +1,37 @@
1
+ import { Identifier } from "../../../ast/nodes/common/Identifier.js";
2
+ import { UsingPath } from "../../../ast/nodes/statements/UsingStmt.js";
3
+ import { AstScope, NamespaceSymbol } from "../scope/AstScope.js";
4
+ import { AstCompilationCtx } from "../AstCompilationCtx.js";
5
+ export interface ResolvedNamespacePath {
6
+ /** the namespace the path resolves to */
7
+ namespace: NamespaceSymbol;
8
+ /** the chain of resolved namespaces (one per segment of the path) */
9
+ chain: NamespaceSymbol[];
10
+ }
11
+ /**
12
+ * walks a dotted namespace path against the given scope.
13
+ *
14
+ * - returns the final `NamespaceSymbol` if every segment resolves to a namespace.
15
+ * - if the first segment is not a namespace, returns `undefined`
16
+ * (no diagnostic emitted; the caller can fall back to a different
17
+ * resolution strategy, e.g. struct lookup).
18
+ * - if a later segment is missing or is not a namespace, emits a
19
+ * diagnostic and returns `undefined`.
20
+ */
21
+ export declare function resolveNamespacePath(ctx: AstCompilationCtx, path: UsingPath): ResolvedNamespacePath | undefined;
22
+ /**
23
+ * looks up a member name in a namespace's public scope.
24
+ *
25
+ * the member can be any of:
26
+ * - a value (variable)
27
+ * - a function
28
+ * - a type
29
+ * - an interface
30
+ * - a nested namespace
31
+ *
32
+ * binds the resolved member into `target` (under either `originalName`
33
+ * or `aliasName` if provided). emits a diagnostic and returns `false`
34
+ * if no such member is exported, or if a conflicting binding already
35
+ * exists in `target`.
36
+ */
37
+ export declare function bindNamespaceMember(ctx: AstCompilationCtx, ns: NamespaceSymbol, originalName: Identifier, aliasName: Identifier | undefined, target: AstScope): boolean;