@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
@@ -0,0 +1,619 @@
1
+ import { SourceRange } from "../../../../ast/Source/SourceRange.js";
2
+ import { _ir_apps } from "../../../../IR/IRNodes/IRApp.js";
3
+ import { IRCase } from "../../../../IR/IRNodes/IRCase.js";
4
+ import { IRFunc } from "../../../../IR/IRNodes/IRFunc.js";
5
+ import { IRNative } from "../../../../IR/IRNodes/IRNative/index.js";
6
+ import { IRNativeTag } from "../../../../IR/IRNodes/IRNative/IRNativeTag.js";
7
+ import { IRVar } from "../../../../IR/IRNodes/IRVar.js";
8
+ import { AstScope } from "../../../AstCompiler/scope/AstScope.js";
9
+ import { TirInlineClosedIR } from "../../expressions/TirInlineClosedIR.js";
10
+ import { TirBlsG1T, TirBlsG2T, TirMlResultT, TirUnConstrDataResultT, TirFuncT, } from "../../types/TirNativeType/index.js";
11
+ import { TirLinearMapT } from "../../types/TirNativeType/native/linearMap.js";
12
+ import { TirLinearMapEntryT } from "../../types/TirNativeType/native/linearMapEntry.js";
13
+ import { TirListT } from "../../types/TirNativeType/native/list.js";
14
+ import { TirArrayT } from "../../types/TirNativeType/native/array.js";
15
+ import { TirValueT } from "../../types/TirNativeType/native/value.js";
16
+ import { TirSopOptT } from "../../types/TirNativeType/native/Optional/sop.js";
17
+ import { TirTypeParam } from "../../types/TirTypeParam.js";
18
+ import { bool_t, bytes_t, data_t, int_t, string_t, void_t, valueLovelacesName, valueAmountOfName, valueMapLovelacesName, valueMapAmountOfName, valueInsertCoinName, valueUnionName, valueContainsName, valueScaleName, valueToDataName, getCredentialHashFuncName, } from "./stdScope.js";
19
+ /**
20
+ * Populate the top-level `std` namespace and its sub-namespaces:
21
+ *
22
+ * std
23
+ * ├── crypto
24
+ * │ ├── hashing & signatures (sha2_256, blake2b_256, verifyEd25519Signature, ...)
25
+ * │ └── bls12_381
26
+ * │ ├── types: G1, G2, MlResult
27
+ * │ └── g1Add, g1Neg, g2Add, ..., millerLoop, finalVerify
28
+ * └── builtins
29
+ * ├── types: RawConstr
30
+ * ├── arithmetic, byte-string, bitwise, data, string, trace, conversion ops
31
+ * └── (polymorphic intrinsics like mkCons<T> are registered as native
32
+ * generic templates and dispatched through the same monomorphizer
33
+ * as user generic functions — see `populateNativeGenericTemplates`)
34
+ *
35
+ * Identifiers like `std.crypto.sha2_256(b)` resolve through the existing
36
+ * namespace-chain walker; the function is registered on the program as a
37
+ * `TirInlineClosedIR` whose IR is the corresponding `IRNative` tag.
38
+ */
39
+ export function populateStdNamespace(program) {
40
+ // ------------------------------------------------------------------
41
+ // 0. Scopes for each namespace
42
+ // ------------------------------------------------------------------
43
+ const stdNsScope = new AstScope(program.preludeScope, program, {});
44
+ const cryptoNsScope = new AstScope(stdNsScope, program, {});
45
+ const blsNsScope = new AstScope(cryptoNsScope, program, {});
46
+ const builtinsNsScope = new AstScope(stdNsScope, program, {});
47
+ // ------------------------------------------------------------------
48
+ // 1. Native types exported by namespaces
49
+ // ------------------------------------------------------------------
50
+ // BLS types -- registered both on the program and exposed under
51
+ // `std.crypto.bls12_381`.
52
+ const g1_t = new TirBlsG1T();
53
+ const g2_t = new TirBlsG2T();
54
+ const ml_t = new TirMlResultT();
55
+ program.types.set(g1_t.toConcreteTirTypeName(), g1_t);
56
+ program.types.set(g2_t.toConcreteTirTypeName(), g2_t);
57
+ program.types.set(ml_t.toConcreteTirTypeName(), ml_t);
58
+ // BLS native types are exported ONLY through `std.crypto.bls12_381`.
59
+ // To use them in source code, the user either fully qualifies the name
60
+ // or brings them into local scope with
61
+ // `using { G1, G2, MlResult } = std.crypto.bls12_381;`
62
+ blsNsScope.defineUnambigousType("G1", g1_t.toConcreteTirTypeName(), false, new Map());
63
+ blsNsScope.defineUnambigousType("G2", g2_t.toConcreteTirTypeName(), false, new Map());
64
+ blsNsScope.defineUnambigousType("MlResult", ml_t.toConcreteTirTypeName(), false, new Map());
65
+ // RawConstr — the `unConstrData` return shape, exposed under
66
+ // `std.builtins`. Field access (`.index` / `.fields`) is handled in
67
+ // `_compileDotPropAccessExpr` and lowers to fst/sndPair.
68
+ const rawConstr_t = new TirUnConstrDataResultT();
69
+ program.types.set(rawConstr_t.toConcreteTirTypeName(), rawConstr_t);
70
+ builtinsNsScope.defineUnambigousType("RawConstr", rawConstr_t.toConcreteTirTypeName(), false, new Map());
71
+ program.preludeScope.defineUnambigousType("RawConstr", rawConstr_t.toConcreteTirTypeName(), false, new Map());
72
+ // ------------------------------------------------------------------
73
+ // 2. Helper: register a monomorphic builtin as a namespace member
74
+ // ------------------------------------------------------------------
75
+ function defineBuiltin(scope, astName, tag, funcType, namespacePath) {
76
+ const uniqueTirName = `__pebble__std__${namespacePath}__${astName}`;
77
+ program.functions.set(uniqueTirName, new TirInlineClosedIR(funcType, () => new IRNative(tag), SourceRange.unknown));
78
+ scope.functions.set(astName, uniqueTirName);
79
+ }
80
+ /**
81
+ * Resolve the dictionary IRTerm for `interfaceName.<first-method>` against
82
+ * a concrete type, at IR-codegen time (so user-impl function references
83
+ * can be looked up through the live `ToIRTermCtx`).
84
+ *
85
+ * Resolution order — Rust-trait-like:
86
+ * 1. **User-impl** (declared via `type Foo implements I { ... }`).
87
+ * The impl method lives in `t.methodsNamesPtr` (alias) or
88
+ * `t.methodNamesPtr` (struct). Reference it by name through
89
+ * `ctx.getVarAccessIR(tirFuncName)`.
90
+ * 2. **Built-in factory** (`program.builtinInterfaceImpls`) — for
91
+ * compiler-supplied impls like `ToData` on primitive / data-encoded
92
+ * types.
93
+ * 3. Otherwise: throw — the constraint is unsatisfied.
94
+ *
95
+ * Currently picks the FIRST method of the interface, since this turn's
96
+ * only constrained native template uses single-method interfaces (`ToData`).
97
+ * Multi-method interfaces would pass each method's IRTerm separately.
98
+ */
99
+ function resolveInterfaceImpl(ctx, concreteType, interfaceName) {
100
+ // Pick the (single) method name to resolve. We grab it from the
101
+ // built-in factory map if registered, else from the prelude's
102
+ // interface signature map.
103
+ const factories = program.builtinInterfaceImpls.get(interfaceName);
104
+ const interfaceMethods = program.preludeScope.resolveInterface(interfaceName);
105
+ const methodName = factories?.keys().next().value
106
+ ?? interfaceMethods?.keys().next().value;
107
+ if (!methodName) {
108
+ throw new Error(`resolveInterfaceImpl: interface '${interfaceName}' is not registered`);
109
+ }
110
+ // 1) user-impl path -- read methodNamesPtr / methodsNamesPtr off the
111
+ // concrete type (unwrap aliases as needed).
112
+ const userTirFuncName = _findUserImplMethodName(concreteType, methodName);
113
+ if (userTirFuncName) {
114
+ const ir = ctx.getVarAccessIR(userTirFuncName);
115
+ if (ir)
116
+ return ir;
117
+ // It's expected the function is in scope at the call site. If
118
+ // not (very unusual), fall through to the built-in factory.
119
+ }
120
+ // 2) built-in factory path
121
+ if (factories) {
122
+ const factory = factories.get(methodName);
123
+ const irTerm = factory?.(concreteType);
124
+ if (irTerm)
125
+ return irTerm;
126
+ }
127
+ throw new Error(`type '${concreteType.toString()}' does not implement '${interfaceName}'`);
128
+ }
129
+ /**
130
+ * Walk a TirType to find a matching method name on its method-pointer
131
+ * map. Looks through:
132
+ * - `TirAliasType.methodsNamesPtr`
133
+ * - `TirStructType.methodNamesPtr` (data + sop variants)
134
+ * Unwraps aliases recursively.
135
+ */
136
+ function _findUserImplMethodName(t, methodName) {
137
+ // dynamic require to avoid bootstrap-time load order issues
138
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
139
+ const { TirAliasType } = require("../../types/TirAliasType.js");
140
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
141
+ const { isTirStructType } = require("../../types/TirStructType.js");
142
+ // `TirAliasType` and `isTirStructType` come back as `any` from the
143
+ // dynamic require, so TypeScript cannot narrow `cur` by the guards
144
+ // alone — cast through the relevant shapes explicitly.
145
+ let cur = t;
146
+ while (cur) {
147
+ if (cur instanceof TirAliasType) {
148
+ const aliasCur = cur;
149
+ const found = aliasCur.methodsNamesPtr.get(methodName);
150
+ if (found)
151
+ return found;
152
+ cur = aliasCur.aliased;
153
+ continue;
154
+ }
155
+ if (isTirStructType(cur)) {
156
+ const structCur = cur;
157
+ const found = structCur.methodNamesPtr.get(methodName);
158
+ if (found)
159
+ return found;
160
+ return undefined;
161
+ }
162
+ return undefined;
163
+ }
164
+ return undefined;
165
+ }
166
+ // ------------------------------------------------------------------
167
+ // 3. std.crypto -- hashing & signature verification
168
+ // ------------------------------------------------------------------
169
+ const cryptoNs = "crypto";
170
+ const hash_sig = new TirFuncT([bytes_t], bytes_t);
171
+ defineBuiltin(cryptoNsScope, "sha2_256", IRNativeTag.sha2_256, hash_sig, cryptoNs);
172
+ defineBuiltin(cryptoNsScope, "sha3_256", IRNativeTag.sha3_256, hash_sig, cryptoNs);
173
+ defineBuiltin(cryptoNsScope, "blake2b_256", IRNativeTag.blake2b_256, hash_sig, cryptoNs);
174
+ defineBuiltin(cryptoNsScope, "blake2b_224", IRNativeTag.blake2b_224, hash_sig, cryptoNs);
175
+ defineBuiltin(cryptoNsScope, "keccak_256", IRNativeTag.keccak_256, hash_sig, cryptoNs);
176
+ defineBuiltin(cryptoNsScope, "ripemd_160", IRNativeTag.ripemd_160, hash_sig, cryptoNs);
177
+ const verifySig = new TirFuncT([bytes_t, bytes_t, bytes_t], bool_t);
178
+ defineBuiltin(cryptoNsScope, "verifyEd25519Signature", IRNativeTag.verifyEd25519Signature, verifySig, cryptoNs);
179
+ defineBuiltin(cryptoNsScope, "verifyEcdsaSecp256k1Signature", IRNativeTag.verifyEcdsaSecp256k1Signature, verifySig, cryptoNs);
180
+ defineBuiltin(cryptoNsScope, "verifySchnorrSecp256k1Signature", IRNativeTag.verifySchnorrSecp256k1Signature, verifySig, cryptoNs);
181
+ // ------------------------------------------------------------------
182
+ // 4. std.crypto.bls12_381 -- BLS12-381 ops
183
+ // ------------------------------------------------------------------
184
+ const blsNs = "crypto__bls12_381";
185
+ defineBuiltin(blsNsScope, "g1Add", IRNativeTag.bls12_381_G1_add, new TirFuncT([g1_t, g1_t], g1_t), blsNs);
186
+ defineBuiltin(blsNsScope, "g1Neg", IRNativeTag.bls12_381_G1_neg, new TirFuncT([g1_t], g1_t), blsNs);
187
+ defineBuiltin(blsNsScope, "g1ScalarMul", IRNativeTag.bls12_381_G1_scalarMul, new TirFuncT([int_t, g1_t], g1_t), blsNs);
188
+ defineBuiltin(blsNsScope, "g1Equal", IRNativeTag.bls12_381_G1_equal, new TirFuncT([g1_t, g1_t], bool_t), blsNs);
189
+ defineBuiltin(blsNsScope, "g1HashToGroup", IRNativeTag.bls12_381_G1_hashToGroup, new TirFuncT([bytes_t, bytes_t], g1_t), blsNs);
190
+ defineBuiltin(blsNsScope, "g1Compress", IRNativeTag.bls12_381_G1_compress, new TirFuncT([g1_t], bytes_t), blsNs);
191
+ defineBuiltin(blsNsScope, "g1Uncompress", IRNativeTag.bls12_381_G1_uncompress, new TirFuncT([bytes_t], g1_t), blsNs);
192
+ defineBuiltin(blsNsScope, "g2Add", IRNativeTag.bls12_381_G2_add, new TirFuncT([g2_t, g2_t], g2_t), blsNs);
193
+ defineBuiltin(blsNsScope, "g2Neg", IRNativeTag.bls12_381_G2_neg, new TirFuncT([g2_t], g2_t), blsNs);
194
+ defineBuiltin(blsNsScope, "g2ScalarMul", IRNativeTag.bls12_381_G2_scalarMul, new TirFuncT([int_t, g2_t], g2_t), blsNs);
195
+ defineBuiltin(blsNsScope, "g2Equal", IRNativeTag.bls12_381_G2_equal, new TirFuncT([g2_t, g2_t], bool_t), blsNs);
196
+ defineBuiltin(blsNsScope, "g2HashToGroup", IRNativeTag.bls12_381_G2_hashToGroup, new TirFuncT([bytes_t, bytes_t], g2_t), blsNs);
197
+ defineBuiltin(blsNsScope, "g2Compress", IRNativeTag.bls12_381_G2_compress, new TirFuncT([g2_t], bytes_t), blsNs);
198
+ defineBuiltin(blsNsScope, "g2Uncompress", IRNativeTag.bls12_381_G2_uncompress, new TirFuncT([bytes_t], g2_t), blsNs);
199
+ defineBuiltin(blsNsScope, "millerLoop", IRNativeTag.bls12_381_millerLoop, new TirFuncT([g1_t, g2_t], ml_t), blsNs);
200
+ defineBuiltin(blsNsScope, "mulMlResult", IRNativeTag.bls12_381_mulMlResult, new TirFuncT([ml_t, ml_t], ml_t), blsNs);
201
+ defineBuiltin(blsNsScope, "finalVerify", IRNativeTag.bls12_381_finalVerify, new TirFuncT([ml_t, ml_t], bool_t), blsNs);
202
+ // ------------------------------------------------------------------
203
+ // 5. std.builtins -- general (monomorphic) builtins
204
+ // ------------------------------------------------------------------
205
+ const blt = "builtins";
206
+ // arithmetic / comparison
207
+ const intIntInt = new TirFuncT([int_t, int_t], int_t);
208
+ const intIntBool = new TirFuncT([int_t, int_t], bool_t);
209
+ defineBuiltin(builtinsNsScope, "addInteger", IRNativeTag.addInteger, intIntInt, blt);
210
+ defineBuiltin(builtinsNsScope, "subtractInteger", IRNativeTag.subtractInteger, intIntInt, blt);
211
+ defineBuiltin(builtinsNsScope, "multiplyInteger", IRNativeTag.multiplyInteger, intIntInt, blt);
212
+ defineBuiltin(builtinsNsScope, "divideInteger", IRNativeTag.divideInteger, intIntInt, blt);
213
+ defineBuiltin(builtinsNsScope, "quotientInteger", IRNativeTag.quotientInteger, intIntInt, blt);
214
+ defineBuiltin(builtinsNsScope, "remainderInteger", IRNativeTag.remainderInteger, intIntInt, blt);
215
+ defineBuiltin(builtinsNsScope, "modInteger", IRNativeTag.modInteger, intIntInt, blt);
216
+ defineBuiltin(builtinsNsScope, "equalsInteger", IRNativeTag.equalsInteger, intIntBool, blt);
217
+ defineBuiltin(builtinsNsScope, "lessThanInteger", IRNativeTag.lessThanInteger, intIntBool, blt);
218
+ defineBuiltin(builtinsNsScope, "lessThanEqualInteger", IRNativeTag.lessThanEqualInteger, intIntBool, blt);
219
+ // bytes
220
+ const bbB = new TirFuncT([bytes_t, bytes_t], bytes_t);
221
+ const bbBool = new TirFuncT([bytes_t, bytes_t], bool_t);
222
+ defineBuiltin(builtinsNsScope, "appendByteString", IRNativeTag.appendByteString, bbB, blt);
223
+ defineBuiltin(builtinsNsScope, "consByteString", IRNativeTag.consByteString, new TirFuncT([int_t, bytes_t], bytes_t), blt);
224
+ defineBuiltin(builtinsNsScope, "sliceByteString", IRNativeTag.sliceByteString, new TirFuncT([int_t, int_t, bytes_t], bytes_t), blt);
225
+ defineBuiltin(builtinsNsScope, "lengthOfByteString", IRNativeTag.lengthOfByteString, new TirFuncT([bytes_t], int_t), blt);
226
+ defineBuiltin(builtinsNsScope, "indexByteString", IRNativeTag.indexByteString, new TirFuncT([bytes_t, int_t], int_t), blt);
227
+ defineBuiltin(builtinsNsScope, "equalsByteString", IRNativeTag.equalsByteString, bbBool, blt);
228
+ defineBuiltin(builtinsNsScope, "lessThanByteString", IRNativeTag.lessThanByteString, bbBool, blt);
229
+ defineBuiltin(builtinsNsScope, "lessThanEqualsByteString", IRNativeTag.lessThanEqualsByteString, bbBool, blt);
230
+ // bytes bitwise (v3)
231
+ const flagBbB = new TirFuncT([bool_t, bytes_t, bytes_t], bytes_t);
232
+ defineBuiltin(builtinsNsScope, "andByteString", IRNativeTag.andByteString, flagBbB, blt);
233
+ defineBuiltin(builtinsNsScope, "orByteString", IRNativeTag.orByteString, flagBbB, blt);
234
+ defineBuiltin(builtinsNsScope, "xorByteString", IRNativeTag.xorByteString, flagBbB, blt);
235
+ defineBuiltin(builtinsNsScope, "complementByteString", IRNativeTag.complementByteString, new TirFuncT([bytes_t], bytes_t), blt);
236
+ defineBuiltin(builtinsNsScope, "readBit", IRNativeTag.readBit, new TirFuncT([bytes_t, int_t], bool_t), blt);
237
+ // writeBits in our wrapper: (bytes, List<int> positions, bool value) -> bytes
238
+ defineBuiltin(builtinsNsScope, "writeBits", IRNativeTag.writeBits, new TirFuncT([bytes_t, new TirListT(int_t), bool_t], bytes_t), blt);
239
+ defineBuiltin(builtinsNsScope, "replicateByte", IRNativeTag.replicateByte, new TirFuncT([int_t, int_t], bytes_t), blt);
240
+ defineBuiltin(builtinsNsScope, "shiftByteString", IRNativeTag.shiftByteString, new TirFuncT([bytes_t, int_t], bytes_t), blt);
241
+ defineBuiltin(builtinsNsScope, "rotateByteString", IRNativeTag.rotateByteString, new TirFuncT([bytes_t, int_t], bytes_t), blt);
242
+ defineBuiltin(builtinsNsScope, "countSetBits", IRNativeTag.countSetBits, new TirFuncT([bytes_t], int_t), blt);
243
+ defineBuiltin(builtinsNsScope, "findFirstSetBit", IRNativeTag.findFirstSetBit, new TirFuncT([bytes_t], int_t), blt);
244
+ // int <-> bytes (v3)
245
+ defineBuiltin(builtinsNsScope, "integerToByteString", IRNativeTag.integerToByteString, new TirFuncT([bool_t, int_t, int_t], bytes_t), blt);
246
+ defineBuiltin(builtinsNsScope, "byteStringToInteger", IRNativeTag.byteStringToInteger, new TirFuncT([bool_t, bytes_t], int_t), blt);
247
+ // strings (v1)
248
+ const ssS = new TirFuncT([string_t, string_t], string_t);
249
+ const ssBool = new TirFuncT([string_t, string_t], bool_t);
250
+ defineBuiltin(builtinsNsScope, "appendString", IRNativeTag.appendString, ssS, blt);
251
+ defineBuiltin(builtinsNsScope, "equalsString", IRNativeTag.equalsString, ssBool, blt);
252
+ defineBuiltin(builtinsNsScope, "encodeUtf8", IRNativeTag.encodeUtf8, new TirFuncT([string_t], bytes_t), blt);
253
+ defineBuiltin(builtinsNsScope, "decodeUtf8", IRNativeTag.decodeUtf8, new TirFuncT([bytes_t], string_t), blt);
254
+ // data constructors
255
+ defineBuiltin(builtinsNsScope, "constrData", IRNativeTag.constrData, new TirFuncT([int_t, new TirListT(data_t)], data_t), blt);
256
+ defineBuiltin(builtinsNsScope, "mapData", IRNativeTag.mapData, new TirFuncT([new TirLinearMapT(data_t, data_t)], data_t), blt);
257
+ defineBuiltin(builtinsNsScope, "listData", IRNativeTag.listData, new TirFuncT([new TirListT(data_t)], data_t), blt);
258
+ defineBuiltin(builtinsNsScope, "iData", IRNativeTag.iData, new TirFuncT([int_t], data_t), blt);
259
+ defineBuiltin(builtinsNsScope, "bData", IRNativeTag.bData, new TirFuncT([bytes_t], data_t), blt);
260
+ defineBuiltin(builtinsNsScope, "mkNilData", IRNativeTag.mkNilData, new TirFuncT([], new TirListT(data_t)), blt);
261
+ // data destructors
262
+ defineBuiltin(builtinsNsScope, "unConstrData", IRNativeTag.unConstrData, new TirFuncT([data_t], rawConstr_t), blt);
263
+ defineBuiltin(builtinsNsScope, "unMapData", IRNativeTag.unMapData, new TirFuncT([data_t], new TirLinearMapT(data_t, data_t)), blt);
264
+ defineBuiltin(builtinsNsScope, "unListData", IRNativeTag.unListData, new TirFuncT([data_t], new TirListT(data_t)), blt);
265
+ defineBuiltin(builtinsNsScope, "unIData", IRNativeTag.unIData, new TirFuncT([data_t], int_t), blt);
266
+ defineBuiltin(builtinsNsScope, "unBData", IRNativeTag.unBData, new TirFuncT([data_t], bytes_t), blt);
267
+ // data misc
268
+ defineBuiltin(builtinsNsScope, "equalsData", IRNativeTag.equalsData, new TirFuncT([data_t, data_t], bool_t), blt);
269
+ defineBuiltin(builtinsNsScope, "serialiseData", IRNativeTag.serialiseData, new TirFuncT([data_t], bytes_t), blt);
270
+ // Chang2 / value & array builtins
271
+ const value_native_t = new TirValueT();
272
+ defineBuiltin(builtinsNsScope, "expModInteger", IRNativeTag.expModInteger, new TirFuncT([int_t, int_t, int_t], int_t), blt);
273
+ defineBuiltin(builtinsNsScope, "insertCoin", IRNativeTag.insertCoin, new TirFuncT([bytes_t, bytes_t, int_t, value_native_t], value_native_t), blt);
274
+ defineBuiltin(builtinsNsScope, "lookupCoin", IRNativeTag.lookupCoin, new TirFuncT([bytes_t, bytes_t, value_native_t], int_t), blt);
275
+ defineBuiltin(builtinsNsScope, "unionValue", IRNativeTag.unionValue, new TirFuncT([value_native_t, value_native_t], value_native_t), blt);
276
+ defineBuiltin(builtinsNsScope, "valueContains", IRNativeTag.valueContains, new TirFuncT([value_native_t, value_native_t], bool_t), blt);
277
+ defineBuiltin(builtinsNsScope, "valueData", IRNativeTag.valueData, new TirFuncT([value_native_t], data_t), blt);
278
+ defineBuiltin(builtinsNsScope, "unValueData", IRNativeTag.unValueData, new TirFuncT([data_t], value_native_t), blt);
279
+ defineBuiltin(builtinsNsScope, "scaleValue", IRNativeTag.scaleValue, new TirFuncT([int_t, value_native_t], value_native_t), blt);
280
+ // ------------------------------------------------------------------
281
+ // 5b. std.builtins -- polymorphic intrinsics via native generic templates
282
+ // ------------------------------------------------------------------
283
+ //
284
+ // These builtins are polymorphic over one or more type parameters. They
285
+ // are registered as `NativeGenericTemplate`s; call sites go through the
286
+ // same `monomorphizeGeneric` path as user-defined generic functions and
287
+ // each instantiation produces a fresh `TirInlineClosedIR`.
288
+ function defineGenericBuiltin(scope, astName, nTypeParams, buildSig, buildIr,
289
+ /**
290
+ * Distinguishing path segment so multiple namespaces can each have a
291
+ * `length` (etc.) without colliding in `program.genericTemplates`.
292
+ * Defaults to `"builtins"` for backward compatibility with the
293
+ * existing `std.builtins.*` polymorphic intrinsics.
294
+ */
295
+ namespacePath = "builtins") {
296
+ const canonicalTirName = `__pebble__std__${namespacePath}__${astName}`;
297
+ const typeParams = [];
298
+ for (let i = 0; i < nTypeParams; i++) {
299
+ // single-letter style names just for diagnostics
300
+ typeParams.push(new TirTypeParam(String.fromCharCode(0x41 + i)));
301
+ }
302
+ const placeholderTirArgs = typeParams.map(tp => tp);
303
+ const placeholderFuncType = buildSig(placeholderTirArgs);
304
+ // Use the canonicalTirName as the template-registry key so per-namespace
305
+ // entries with the same `astName` (`std.list.length` vs
306
+ // `std.linearMap.length`) don't shadow each other.
307
+ program.genericTemplates.set(canonicalTirName, {
308
+ kind: "native",
309
+ astFuncName: astName,
310
+ typeParams,
311
+ canonicalTirName,
312
+ placeholderFuncType,
313
+ // unconstrained native template
314
+ constraints: new Array(nTypeParams).fill(undefined),
315
+ instantiate: (typeArgs) => new TirInlineClosedIR(buildSig(typeArgs), () => buildIr(typeArgs), SourceRange.unknown),
316
+ });
317
+ scope.defineValue({
318
+ name: astName,
319
+ type: placeholderFuncType,
320
+ isConstant: true,
321
+ genericTemplateName: canonicalTirName,
322
+ });
323
+ scope.functions.set(astName, canonicalTirName);
324
+ }
325
+ // ------------------------------------------------------------------
326
+ // Constrained variant -- for native generic templates whose body needs
327
+ // per-type-param dictionary IR (e.g. `std.linearMap.prepend<K implements
328
+ // ToData, V implements ToData>` uses `_toDataUplcFunc` for K and V).
329
+ //
330
+ // `paramConstraints` is aligned by index with the type-param list;
331
+ // `undefined` for unconstrained slots.
332
+ //
333
+ // `buildIr` receives the concrete typeArgs along with the resolved
334
+ // dictionary `IRTerm` for each constrained param (same order, undefined
335
+ // for unconstrained). It returns the raw IR (already a closure over its
336
+ // call-time arguments).
337
+ // ------------------------------------------------------------------
338
+ function defineGenericBuiltinConstrained(scope, astName, nTypeParams, paramConstraints, buildSig, buildIr, namespacePath = "builtins") {
339
+ if (paramConstraints.length !== nTypeParams) {
340
+ throw new Error(`defineGenericBuiltinConstrained: paramConstraints.length ` +
341
+ `(${paramConstraints.length}) !== nTypeParams (${nTypeParams})`);
342
+ }
343
+ const canonicalTirName = `__pebble__std__${namespacePath}__${astName}`;
344
+ const typeParams = [];
345
+ for (let i = 0; i < nTypeParams; i++) {
346
+ typeParams.push(new TirTypeParam(String.fromCharCode(0x41 + i)));
347
+ }
348
+ const placeholderTirArgs = typeParams.map(tp => tp);
349
+ const placeholderFuncType = buildSig(placeholderTirArgs);
350
+ // Resolve constraints up-front. We look up each interface in the
351
+ // prelude scope so monomorphization can validate at call-time.
352
+ const constraints = paramConstraints.map(name => {
353
+ if (!name)
354
+ return undefined;
355
+ const methods = program.preludeScope.resolveInterface(name);
356
+ if (!methods) {
357
+ throw new Error(`defineGenericBuiltinConstrained: interface '${name}' ` +
358
+ `is not registered in the prelude. Register it via ` +
359
+ `populateBuiltinInterfaces before this call.`);
360
+ }
361
+ return { interfaceName: name, methods };
362
+ });
363
+ program.genericTemplates.set(canonicalTirName, {
364
+ kind: "native",
365
+ astFuncName: astName,
366
+ typeParams,
367
+ canonicalTirName,
368
+ placeholderFuncType,
369
+ constraints,
370
+ instantiate: (typeArgs) => {
371
+ // Dictionary resolution is deferred to `getIr` time so it
372
+ // can consult the live `ToIRTermCtx` — this is necessary
373
+ // when the impl is a top-level user function that must be
374
+ // looked up by name (e.g. `type Foo implements ToData {
375
+ // toData(self): data { ... } }` — the impl is a regular
376
+ // user function whose IR-level reference is `IRVar(symbol)`
377
+ // resolved through the codegen scope).
378
+ return new TirInlineClosedIR(buildSig(typeArgs), (ctx) => {
379
+ const dicts = typeArgs.map((t, i) => {
380
+ const c = paramConstraints[i];
381
+ if (!c)
382
+ return undefined;
383
+ return resolveInterfaceImpl(ctx, t, c);
384
+ });
385
+ return buildIr(typeArgs, dicts);
386
+ }, SourceRange.unknown);
387
+ },
388
+ });
389
+ scope.defineValue({
390
+ name: astName,
391
+ type: placeholderFuncType,
392
+ isConstant: true,
393
+ genericTemplateName: canonicalTirName,
394
+ });
395
+ scope.functions.set(astName, canonicalTirName);
396
+ }
397
+ // trace<T>( msg: bytes, x: T ): T
398
+ defineGenericBuiltin(builtinsNsScope, "trace", 1, ([T]) => new TirFuncT([bytes_t, T], T), () => new IRNative(IRNativeTag.trace));
399
+ // ifThenElse<T>( cond: bool, then: T, else: T ): T -- strict variant
400
+ defineGenericBuiltin(builtinsNsScope, "ifThenElse", 1, ([T]) => new TirFuncT([bool_t, T, T], T), () => new IRNative(IRNativeTag.strictIfThenElse));
401
+ // chooseUnit<T>( u: void, x: T ): T
402
+ defineGenericBuiltin(builtinsNsScope, "chooseUnit", 1, ([T]) => new TirFuncT([void_t, T], T), () => new IRNative(IRNativeTag.chooseUnit));
403
+ // mkCons<T>( head: T, tail: List<T> ): List<T>
404
+ defineGenericBuiltin(builtinsNsScope, "mkCons", 1, ([T]) => new TirFuncT([T, new TirListT(T)], new TirListT(T)), () => new IRNative(IRNativeTag.mkCons));
405
+ // headList<T>( xs: List<T> ): T
406
+ defineGenericBuiltin(builtinsNsScope, "headList", 1, ([T]) => new TirFuncT([new TirListT(T)], T), () => new IRNative(IRNativeTag.headList));
407
+ // tailList<T>( xs: List<T> ): List<T>
408
+ defineGenericBuiltin(builtinsNsScope, "tailList", 1, ([T]) => new TirFuncT([new TirListT(T)], new TirListT(T)), () => new IRNative(IRNativeTag.tailList));
409
+ // nullList<T>( xs: List<T> ): bool
410
+ defineGenericBuiltin(builtinsNsScope, "nullList", 1, ([T]) => new TirFuncT([new TirListT(T)], bool_t), () => new IRNative(IRNativeTag.nullList));
411
+ // chooseList<A,B>( xs: List<A>, caseNil: B, caseCons: B ): B
412
+ // Lowered to a UPLC `Case` on the list: the cons branch ignores h/t
413
+ // (matching the `chooseList` builtin contract — head/tail aren't bound).
414
+ defineGenericBuiltin(builtinsNsScope, "chooseList", 2, ([A, B]) => new TirFuncT([new TirListT(A), B, B], B), () => {
415
+ const xs = Symbol("xs");
416
+ const caseNil = Symbol("caseNil");
417
+ const caseCons = Symbol("caseCons");
418
+ const h = Symbol("_h");
419
+ const t = Symbol("_t");
420
+ return new IRFunc([xs, caseNil, caseCons], new IRCase(new IRVar(xs), [
421
+ new IRFunc([h, t], new IRVar(caseCons)),
422
+ new IRVar(caseNil)
423
+ ]));
424
+ });
425
+ // chooseData<T>( d: data, caseConstr: T, caseMap: T, caseList: T,
426
+ // caseIData: T, caseBData: T ): T
427
+ defineGenericBuiltin(builtinsNsScope, "chooseData", 1, ([T]) => new TirFuncT([data_t, T, T, T, T, T], T), () => new IRNative(IRNativeTag.chooseData));
428
+ // ------------------------------------------------------------------
429
+ // 6. Per-type native namespaces -- std.list, std.linearMap, std.bytes,
430
+ // std.int, std.boolean, std.data, std.value, std.credential, plus
431
+ // the top-level std.id<T> / std.equals<T>.
432
+ //
433
+ // These expose the compiler-internal "native" helpers (negative-tag
434
+ // IRNativeTag entries) as first-class values so users can pass them
435
+ // to higher-order code (`std.list.some(std.int.isZero, xs)`) — the
436
+ // motivation being partial application of operator-like functions
437
+ // which the operator forms (`>`, `+`, ...) do not allow.
438
+ //
439
+ // Method-call surface (e.g. `xs.map(f)`) is unchanged.
440
+ // ------------------------------------------------------------------
441
+ const listNsScope = new AstScope(stdNsScope, program, {});
442
+ const arrayNsScope = new AstScope(stdNsScope, program, {});
443
+ const linearMapNsScope = new AstScope(stdNsScope, program, {});
444
+ const bytesNsScope = new AstScope(stdNsScope, program, {});
445
+ const intNsScope = new AstScope(stdNsScope, program, {});
446
+ const boolNsScope = new AstScope(stdNsScope, program, {});
447
+ const dataNsScope = new AstScope(stdNsScope, program, {});
448
+ const valueNsScope = new AstScope(stdNsScope, program, {});
449
+ const valueMapNsScope = new AstScope(stdNsScope, program, {});
450
+ const credentialNsScope = new AstScope(stdNsScope, program, {});
451
+ // ---------- std.list (polymorphic) ----------
452
+ const listNs = "list";
453
+ defineGenericBuiltin(listNsScope, "length", 1, ([T]) => new TirFuncT([new TirListT(T)], int_t), () => new IRNative(IRNativeTag._length), listNs);
454
+ defineGenericBuiltin(listNsScope, "isEmpty", 1, ([T]) => new TirFuncT([new TirListT(T)], bool_t), () => new IRNative(IRNativeTag.nullList), listNs);
455
+ defineGenericBuiltin(listNsScope, "head", 1, ([T]) => new TirFuncT([new TirListT(T)], T), () => new IRNative(IRNativeTag.headList), listNs);
456
+ defineGenericBuiltin(listNsScope, "tail", 1, ([T]) => new TirFuncT([new TirListT(T)], new TirListT(T)), () => new IRNative(IRNativeTag.tailList), listNs);
457
+ defineGenericBuiltin(listNsScope, "prepend", 1, ([T]) => new TirFuncT([T, new TirListT(T)], new TirListT(T)), () => new IRNative(IRNativeTag.mkCons), listNs);
458
+ defineGenericBuiltin(listNsScope, "drop", 1, ([T]) => new TirFuncT([int_t, new TirListT(T)], new TirListT(T)), () => new IRNative(IRNativeTag.dropList), listNs);
459
+ defineGenericBuiltin(listNsScope, "foldr", 2, ([T, A]) => new TirFuncT([new TirFuncT([T, A], A), A, new TirListT(T)], A), () => new IRNative(IRNativeTag._foldr), listNs);
460
+ defineGenericBuiltin(listNsScope, "foldl", 2, ([T, A]) => new TirFuncT([new TirFuncT([A, T], A), A, new TirListT(T)], A), () => new IRNative(IRNativeTag._foldl), listNs);
461
+ defineGenericBuiltin(listNsScope, "filter", 1, ([T]) => new TirFuncT([new TirFuncT([T], bool_t), new TirListT(T)], new TirListT(T)), () => new IRNative(IRNativeTag._filter), listNs);
462
+ defineGenericBuiltin(listNsScope, "some", 1, ([T]) => new TirFuncT([new TirFuncT([T], bool_t), new TirListT(T)], bool_t), () => new IRNative(IRNativeTag._some), listNs);
463
+ defineGenericBuiltin(listNsScope, "every", 1, ([T]) => new TirFuncT([new TirFuncT([T], bool_t), new TirListT(T)], bool_t), () => new IRNative(IRNativeTag._every), listNs);
464
+ defineGenericBuiltin(listNsScope, "find", 1, ([T]) => new TirFuncT([new TirFuncT([T], bool_t), new TirListT(T)], new TirSopOptT(T)), () => new IRNative(IRNativeTag._findSopOptional), listNs);
465
+ defineGenericBuiltin(listNsScope, "equals", 1, ([T]) => new TirFuncT([new TirFuncT([T, T], bool_t), new TirListT(T), new TirListT(T)], bool_t), () => new IRNative(IRNativeTag._mkEqualsList), listNs);
466
+ // NOTE: `map` is intentionally not exposed here. _mkMapList requires a
467
+ // nil-of-return-type literal as its first argument which the method-form
468
+ // (`xs.map(f)`) constructs at the TIR level; reproducing that inside a
469
+ // closed-IR thunk would need TIR-level composition which our current
470
+ // namespace helpers don't provide. Users keep `xs.map(f)`.
471
+ // ---------- std.linearMap (polymorphic) ----------
472
+ const linearMapNs = "linearMap";
473
+ defineGenericBuiltin(linearMapNsScope, "length", 2, ([K, V]) => new TirFuncT([new TirLinearMapT(K, V)], int_t), () => new IRNative(IRNativeTag._length), linearMapNs);
474
+ defineGenericBuiltin(linearMapNsScope, "isEmpty", 2, ([K, V]) => new TirFuncT([new TirLinearMapT(K, V)], bool_t), () => new IRNative(IRNativeTag.nullList), linearMapNs);
475
+ defineGenericBuiltin(linearMapNsScope, "head", 2, ([K, V]) => new TirFuncT([new TirLinearMapT(K, V)], new TirLinearMapEntryT(K, V)), () => new IRNative(IRNativeTag.headList), linearMapNs);
476
+ defineGenericBuiltin(linearMapNsScope, "tail", 2, ([K, V]) => new TirFuncT([new TirLinearMapT(K, V)], new TirLinearMapT(K, V)), () => new IRNative(IRNativeTag.tailList), linearMapNs);
477
+ // lookup<K,V>(k: K, m: LinearMap<K,V>): Optional<V> -- mirrors
478
+ // expressifyVars.ts:676 (passes raw K; relies on ambient data-encoding).
479
+ defineGenericBuiltin(linearMapNsScope, "lookup", 2, ([K, V]) => new TirFuncT([K, new TirLinearMapT(K, V)], new TirSopOptT(V)), () => new IRNative(IRNativeTag._lookupLinearMap), linearMapNs);
480
+ // prepend<K implements ToData, V implements ToData>
481
+ // (k: K, v: V, m: LinearMap<K,V>): LinearMap<K,V>
482
+ //
483
+ // Uses dictionary-passing for the ToData constraint: at instantiation
484
+ // time the compiler resolves the right `toData_K` / `toData_V` impls
485
+ // (via `program.builtinInterfaceImpls["ToData"]["toData"]`) — for the
486
+ // built-in factory this is `_toDataUplcFunc(K)` / `_toDataUplcFunc(V)`.
487
+ // Those IR closures are inlined into the body alongside `mkPairData`
488
+ // and `mkCons`, mirroring `expressifyVars.ts:690`'s method-form lowering.
489
+ defineGenericBuiltinConstrained(linearMapNsScope, "prepend", 2, ["ToData", "ToData"], ([K, V]) => new TirFuncT([K, V, new TirLinearMapT(K, V)], new TirLinearMapT(K, V)), (_typeArgs, dicts) => {
490
+ // Synthesize: \k v m -> mkCons( mkPairData( toDataK(k), toDataV(v) ), m )
491
+ const kSym = Symbol("k");
492
+ const vSym = Symbol("v");
493
+ const mSym = Symbol("m");
494
+ const toDataK = dicts[0];
495
+ const toDataV = dicts[1];
496
+ return new IRFunc([kSym, vSym, mSym], _ir_apps(IRNative.mkCons, _ir_apps(IRNative.mkPairData, _ir_apps(toDataK, new IRVar(kSym)), _ir_apps(toDataV, new IRVar(vSym))), new IRVar(mSym)));
497
+ }, linearMapNs);
498
+ // ---------- std.bytes (monomorphic) ----------
499
+ defineBuiltin(bytesNsScope, "length", IRNativeTag.lengthOfByteString, new TirFuncT([bytes_t], int_t), "bytes");
500
+ defineBuiltin(bytesNsScope, "slice", IRNativeTag.sliceByteString, new TirFuncT([int_t, int_t, bytes_t], bytes_t), "bytes");
501
+ defineBuiltin(bytesNsScope, "prepend", IRNativeTag.consByteString, new TirFuncT([int_t, bytes_t], bytes_t), "bytes");
502
+ defineBuiltin(bytesNsScope, "concat", IRNativeTag.appendByteString, new TirFuncT([bytes_t, bytes_t], bytes_t), "bytes");
503
+ defineBuiltin(bytesNsScope, "indexAt", IRNativeTag.indexByteString, new TirFuncT([bytes_t, int_t], int_t), "bytes");
504
+ defineBuiltin(bytesNsScope, "equals", IRNativeTag.equalsByteString, new TirFuncT([bytes_t, bytes_t], bool_t), "bytes");
505
+ defineBuiltin(bytesNsScope, "lessThan", IRNativeTag.lessThanByteString, new TirFuncT([bytes_t, bytes_t], bool_t), "bytes");
506
+ defineBuiltin(bytesNsScope, "lessThanEquals", IRNativeTag.lessThanEqualsByteString, new TirFuncT([bytes_t, bytes_t], bool_t), "bytes");
507
+ defineBuiltin(bytesNsScope, "greaterThan", IRNativeTag._gtBS, new TirFuncT([bytes_t, bytes_t], bool_t), "bytes");
508
+ defineBuiltin(bytesNsScope, "greaterThanEquals", IRNativeTag._gtEqBS, new TirFuncT([bytes_t, bytes_t], bool_t), "bytes");
509
+ defineBuiltin(bytesNsScope, "toInt", IRNativeTag._bytesToIntBE, new TirFuncT([bytes_t], int_t), "bytes");
510
+ defineBuiltin(bytesNsScope, "fromInt", IRNativeTag._intToBytesBE, new TirFuncT([int_t], bytes_t), "bytes");
511
+ // ---------- std.int (monomorphic) ----------
512
+ defineBuiltin(intNsScope, "add", IRNativeTag.addInteger, new TirFuncT([int_t, int_t], int_t), "int");
513
+ defineBuiltin(intNsScope, "subtract", IRNativeTag.subtractInteger, new TirFuncT([int_t, int_t], int_t), "int");
514
+ defineBuiltin(intNsScope, "multiply", IRNativeTag.multiplyInteger, new TirFuncT([int_t, int_t], int_t), "int");
515
+ defineBuiltin(intNsScope, "divide", IRNativeTag.divideInteger, new TirFuncT([int_t, int_t], int_t), "int");
516
+ defineBuiltin(intNsScope, "quotient", IRNativeTag.quotientInteger, new TirFuncT([int_t, int_t], int_t), "int");
517
+ defineBuiltin(intNsScope, "remainder", IRNativeTag.remainderInteger, new TirFuncT([int_t, int_t], int_t), "int");
518
+ defineBuiltin(intNsScope, "mod", IRNativeTag.modInteger, new TirFuncT([int_t, int_t], int_t), "int");
519
+ defineBuiltin(intNsScope, "equals", IRNativeTag.equalsInteger, new TirFuncT([int_t, int_t], bool_t), "int");
520
+ defineBuiltin(intNsScope, "lessThan", IRNativeTag.lessThanInteger, new TirFuncT([int_t, int_t], bool_t), "int");
521
+ defineBuiltin(intNsScope, "lessThanEquals", IRNativeTag.lessThanEqualInteger, new TirFuncT([int_t, int_t], bool_t), "int");
522
+ defineBuiltin(intNsScope, "greaterThan", IRNativeTag._gtInt, new TirFuncT([int_t, int_t], bool_t), "int");
523
+ defineBuiltin(intNsScope, "greaterThanEquals", IRNativeTag._gtEqInt, new TirFuncT([int_t, int_t], bool_t), "int");
524
+ defineBuiltin(intNsScope, "negate", IRNativeTag._negateInt, new TirFuncT([int_t], int_t), "int");
525
+ defineBuiltin(intNsScope, "increment", IRNativeTag._increment, new TirFuncT([int_t], int_t), "int");
526
+ defineBuiltin(intNsScope, "decrement", IRNativeTag._decrement, new TirFuncT([int_t], int_t), "int");
527
+ defineBuiltin(intNsScope, "isZero", IRNativeTag._isZero, new TirFuncT([int_t], bool_t), "int");
528
+ defineBuiltin(intNsScope, "exponentiate", IRNativeTag._exponentiateInteger, new TirFuncT([int_t, int_t], int_t), "int");
529
+ defineBuiltin(intNsScope, "toBoolean", IRNativeTag._intToBool, new TirFuncT([int_t], bool_t), "int");
530
+ // ---------- std.boolean (monomorphic) ----------
531
+ defineBuiltin(boolNsScope, "not", IRNativeTag._not, new TirFuncT([bool_t], bool_t), "boolean");
532
+ defineBuiltin(boolNsScope, "strictAnd", IRNativeTag._strictAnd, new TirFuncT([bool_t, bool_t], bool_t), "boolean");
533
+ defineBuiltin(boolNsScope, "strictOr", IRNativeTag._strictOr, new TirFuncT([bool_t, bool_t], bool_t), "boolean");
534
+ defineBuiltin(boolNsScope, "equals", IRNativeTag._equalBoolean, new TirFuncT([bool_t, bool_t], bool_t), "boolean");
535
+ defineBuiltin(boolNsScope, "toInt", IRNativeTag._boolToInt, new TirFuncT([bool_t], int_t), "boolean");
536
+ // ---------- std.data (monomorphic) ----------
537
+ defineBuiltin(dataNsScope, "strToData", IRNativeTag._strToData, new TirFuncT([string_t], data_t), "data");
538
+ defineBuiltin(dataNsScope, "strFromData", IRNativeTag._strFromData, new TirFuncT([data_t], string_t), "data");
539
+ // ---------- std.value / std.credential ----------
540
+ // These reuse the prelude-registered `TirInlineClosedIR`s for
541
+ // `Value.amountOf`, `Value.lovelaces`, `Credential.hash`. We just point
542
+ // the namespace member at the existing program.functions entry.
543
+ function defineAliasFromProgram(scope, astName, existingTirFuncName) {
544
+ if (!program.functions.has(existingTirFuncName)) {
545
+ // Prelude didn't register the wrapper — shouldn't happen, but
546
+ // skip cleanly so a missing prelude entry doesn't break boot.
547
+ return;
548
+ }
549
+ scope.functions.set(astName, existingTirFuncName);
550
+ }
551
+ // std.value.* — methods on the native Value
552
+ defineAliasFromProgram(valueNsScope, "amountOf", valueAmountOfName);
553
+ defineAliasFromProgram(valueNsScope, "lovelaces", valueLovelacesName);
554
+ defineAliasFromProgram(valueNsScope, "insert", valueInsertCoinName);
555
+ defineAliasFromProgram(valueNsScope, "union", valueUnionName);
556
+ defineAliasFromProgram(valueNsScope, "contains", valueContainsName);
557
+ defineAliasFromProgram(valueNsScope, "scale", valueScaleName);
558
+ defineAliasFromProgram(valueNsScope, "toData", valueToDataName);
559
+ // std.valueMap.* — methods on the legacy AssocMap-of-AssocMap representation
560
+ defineAliasFromProgram(valueMapNsScope, "amountOf", valueMapAmountOfName);
561
+ defineAliasFromProgram(valueMapNsScope, "lovelaces", valueMapLovelacesName);
562
+ defineAliasFromProgram(credentialNsScope, "hash", getCredentialHashFuncName);
563
+ // ---------- std.array (polymorphic; native array) ----------
564
+ const arrayNs = "array";
565
+ defineGenericBuiltin(arrayNsScope, "length", 1, ([T]) => new TirFuncT([new TirArrayT(T)], int_t), () => new IRNative(IRNativeTag.lengthOfArray), arrayNs);
566
+ defineGenericBuiltin(arrayNsScope, "at", 1, ([T]) => new TirFuncT([new TirArrayT(T), int_t], T), () => new IRNative(IRNativeTag.indexArray), arrayNs);
567
+ defineGenericBuiltin(arrayNsScope, "fromList", 1, ([T]) => new TirFuncT([new TirListT(T)], new TirArrayT(T)), () => new IRNative(IRNativeTag.listToArray), arrayNs);
568
+ // ---------- top-level std.id<T> / std.equals<T> ----------
569
+ // id<T>(x: T): T -- the polymorphic identity. Useful as a default
570
+ // argument or "do-nothing" callback to higher-order code.
571
+ defineGenericBuiltin(stdNsScope, "id", 1, ([T]) => new TirFuncT([T], T), () => new IRNative(IRNativeTag._id), "top");
572
+ // equals<T>(a: T, b: T): bool -- compile-time-dispatched equality.
573
+ // The right IRNative is picked per instantiation (equalsInteger /
574
+ // equalsByteString / equalsData / etc.).
575
+ defineGenericBuiltin(stdNsScope, "equals", 1, ([T]) => new TirFuncT([T, T], bool_t), ([T]) => {
576
+ const tirKey = T.toConcreteTirTypeName();
577
+ switch (tirKey) {
578
+ case "int": return new IRNative(IRNativeTag.equalsInteger);
579
+ case "bytes": return new IRNative(IRNativeTag.equalsByteString);
580
+ case "boolean": return new IRNative(IRNativeTag._equalBoolean);
581
+ case "data": return new IRNative(IRNativeTag.equalsData);
582
+ default:
583
+ // Fall back to data equality — covers data-encoded
584
+ // structs, optionals, and most other Pebble types.
585
+ return new IRNative(IRNativeTag.equalsData);
586
+ }
587
+ }, "top");
588
+ // ------------------------------------------------------------------
589
+ // 7. Hook the namespaces together and attach `std` to the prelude
590
+ // ------------------------------------------------------------------
591
+ blsNsScope.readonly();
592
+ cryptoNsScope.defineNamespace({ name: "bls12_381", publicScope: blsNsScope });
593
+ cryptoNsScope.readonly();
594
+ builtinsNsScope.readonly();
595
+ listNsScope.readonly();
596
+ arrayNsScope.readonly();
597
+ linearMapNsScope.readonly();
598
+ bytesNsScope.readonly();
599
+ intNsScope.readonly();
600
+ boolNsScope.readonly();
601
+ dataNsScope.readonly();
602
+ valueNsScope.readonly();
603
+ valueMapNsScope.readonly();
604
+ credentialNsScope.readonly();
605
+ stdNsScope.defineNamespace({ name: "crypto", publicScope: cryptoNsScope });
606
+ stdNsScope.defineNamespace({ name: "builtins", publicScope: builtinsNsScope });
607
+ stdNsScope.defineNamespace({ name: "list", publicScope: listNsScope });
608
+ stdNsScope.defineNamespace({ name: "array", publicScope: arrayNsScope });
609
+ stdNsScope.defineNamespace({ name: "linearMap", publicScope: linearMapNsScope });
610
+ stdNsScope.defineNamespace({ name: "bytes", publicScope: bytesNsScope });
611
+ stdNsScope.defineNamespace({ name: "int", publicScope: intNsScope });
612
+ stdNsScope.defineNamespace({ name: "boolean", publicScope: boolNsScope });
613
+ stdNsScope.defineNamespace({ name: "data", publicScope: dataNsScope });
614
+ stdNsScope.defineNamespace({ name: "value", publicScope: valueNsScope });
615
+ stdNsScope.defineNamespace({ name: "valueMap", publicScope: valueMapNsScope });
616
+ stdNsScope.defineNamespace({ name: "credential", publicScope: credentialNsScope });
617
+ stdNsScope.readonly();
618
+ program.preludeScope.defineNamespace({ name: "std", publicScope: stdNsScope });
619
+ }