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