@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.
- package/dist/IR/IRNodes/IRConst.js +14 -3
- package/dist/IR/IRNodes/IRNative/index.js +5 -1
- package/dist/IR/toUPLC/CompilerOptions.d.ts +22 -7
- package/dist/IR/toUPLC/CompilerOptions.js +5 -1
- package/dist/IR/tree_utils/bytesToHex.d.ts +8 -0
- package/dist/IR/tree_utils/bytesToHex.js +69 -0
- package/dist/ast/nodes/expr/functions/FuncExpr.d.ts +16 -2
- package/dist/ast/nodes/expr/functions/FuncExpr.js +17 -0
- package/dist/ast/nodes/expr/litteral/LitteralExpr.d.ts +2 -1
- package/dist/ast/nodes/expr/litteral/LitteralExpr.js +2 -0
- package/dist/ast/nodes/expr/litteral/TemplateStrExpr.d.ts +30 -0
- package/dist/ast/nodes/expr/litteral/TemplateStrExpr.js +35 -0
- package/dist/ast/nodes/statements/ExportStmt.d.ts +3 -3
- package/dist/ast/nodes/statements/PebbleStmt.d.ts +4 -3
- package/dist/ast/nodes/statements/PebbleStmt.js +6 -2
- package/dist/ast/nodes/statements/TestParam.d.ts +18 -0
- package/dist/ast/nodes/statements/TestParam.js +18 -0
- package/dist/ast/nodes/statements/TestStmt.d.ts +5 -3
- package/dist/ast/nodes/statements/TestStmt.js +3 -1
- package/dist/ast/nodes/statements/UsingStmt.d.ts +32 -2
- package/dist/ast/nodes/statements/UsingStmt.js +39 -3
- package/dist/ast/nodes/statements/declarations/NamespaceDecl.d.ts +21 -0
- package/dist/ast/nodes/statements/declarations/NamespaceDecl.js +31 -0
- package/dist/compiler/AstCompiler/AstCompiler.d.ts +26 -0
- package/dist/compiler/AstCompiler/AstCompiler.js +203 -3
- package/dist/compiler/AstCompiler/internal/_deriveContractBody/_deriveContractBody.js +14 -4
- package/dist/compiler/AstCompiler/internal/exprs/_compileCallExpr.js +97 -6
- package/dist/compiler/AstCompiler/internal/exprs/_compileFuncExpr.js +12 -5
- package/dist/compiler/AstCompiler/internal/exprs/_compileLitteralExpr.js +59 -0
- package/dist/compiler/AstCompiler/internal/exprs/_compilePropAccessExpr.d.ts +2 -3
- package/dist/compiler/AstCompiler/internal/exprs/_compilePropAccessExpr.js +28 -0
- package/dist/compiler/AstCompiler/internal/exprs/_compileVarAccessExpr.js +2 -0
- package/dist/compiler/AstCompiler/internal/statements/_compileStatement.js +4 -1
- package/dist/compiler/AstCompiler/internal/statements/_compileTestStmt.d.ts +15 -1
- package/dist/compiler/AstCompiler/internal/statements/_compileTestStmt.js +70 -30
- package/dist/compiler/AstCompiler/internal/statements/_compileUsingAliasStmt.d.ts +11 -0
- package/dist/compiler/AstCompiler/internal/statements/_compileUsingAliasStmt.js +26 -0
- package/dist/compiler/AstCompiler/internal/statements/_compileUsingStmt.d.ts +9 -4
- package/dist/compiler/AstCompiler/internal/statements/_compileUsingStmt.js +51 -10
- package/dist/compiler/AstCompiler/internal/types/_compileDataEncodedConcreteType.js +21 -2
- package/dist/compiler/AstCompiler/internal/types/_compileSopEncodedConcreteType.js +17 -2
- package/dist/compiler/AstCompiler/scope/AstScope.d.ts +70 -1
- package/dist/compiler/AstCompiler/scope/AstScope.js +91 -0
- package/dist/compiler/AstCompiler/utils/getPropAccessReturnType.js +25 -1
- package/dist/compiler/AstCompiler/utils/monomorphizeGeneric.d.ts +36 -0
- package/dist/compiler/AstCompiler/utils/monomorphizeGeneric.js +123 -0
- package/dist/compiler/AstCompiler/utils/resolveNamespaceChain.d.ts +28 -0
- package/dist/compiler/AstCompiler/utils/resolveNamespaceChain.js +95 -0
- package/dist/compiler/AstCompiler/utils/resolveNamespacePath.d.ts +37 -0
- package/dist/compiler/AstCompiler/utils/resolveNamespacePath.js +93 -0
- package/dist/compiler/Compiler.d.ts +9 -1
- package/dist/compiler/Compiler.js +204 -9
- package/dist/compiler/TirCompiler/expressify/expressifyVars.js +26 -7
- package/dist/compiler/test/TestResult.d.ts +38 -0
- package/dist/compiler/test/TestResult.js +6 -0
- package/dist/compiler/test/fuzz/PRNG.d.ts +26 -0
- package/dist/compiler/test/fuzz/PRNG.js +59 -0
- package/dist/compiler/tir/expressions/TirExpr.d.ts +2 -1
- package/dist/compiler/tir/expressions/TirExpr.js +2 -0
- package/dist/compiler/tir/expressions/TirNativeFunc.d.ts +17 -0
- package/dist/compiler/tir/expressions/TirNativeFunc.js +53 -106
- package/dist/compiler/tir/expressions/TirShowExpr.d.ts +52 -0
- package/dist/compiler/tir/expressions/TirShowExpr.js +199 -0
- package/dist/compiler/tir/expressions/TirTraceExpr.js +11 -7
- package/dist/compiler/tir/program/TypedProgram.d.ts +101 -0
- package/dist/compiler/tir/program/TypedProgram.js +43 -0
- package/dist/compiler/tir/program/stdScope/populateBuiltinInterfaces.d.ts +17 -0
- package/dist/compiler/tir/program/stdScope/populateBuiltinInterfaces.js +70 -0
- package/dist/compiler/tir/program/stdScope/populateStdNamespace.d.ts +22 -0
- package/dist/compiler/tir/program/stdScope/populateStdNamespace.js +574 -0
- package/dist/compiler/tir/program/stdScope/stdScope.d.ts +1 -0
- package/dist/compiler/tir/program/stdScope/stdScope.js +1 -1
- package/dist/compiler/tir/statements/TirStmt.js +0 -1
- package/dist/compiler/tir/statements/TirTestStmt.d.ts +46 -0
- package/dist/compiler/tir/statements/TirTestStmt.js +35 -0
- package/dist/compiler/tir/types/TirNativeType/TirNativeType.d.ts +50 -1
- package/dist/compiler/tir/types/TirNativeType/TirNativeType.js +53 -1
- package/dist/compiler/tir/types/TirType.js +3 -1
- package/dist/compiler/tir/types/utils/canAssignTo.js +8 -1
- package/dist/compiler/tir/types/utils/inferTypeArgs.d.ts +19 -0
- package/dist/compiler/tir/types/utils/inferTypeArgs.js +79 -0
- package/dist/compiler/tir/types/utils/substituteTypeParams.d.ts +9 -0
- package/dist/compiler/tir/types/utils/substituteTypeParams.js +62 -0
- package/dist/diagnostics/diagnosticMessages.generated.d.ts +5 -0
- package/dist/diagnostics/diagnosticMessages.generated.js +10 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/parser/Parser.d.ts +73 -3
- package/dist/parser/Parser.js +333 -33
- package/dist/tokenizer/Token.d.ts +105 -102
- package/dist/tokenizer/Token.js +110 -109
- package/dist/tokenizer/utils/tokenFromKeyword.js +9 -6
- package/dist/utils/semverSatisfies.d.ts +1 -0
- package/dist/utils/semverSatisfies.js +161 -0
- package/dist/version.generated.d.ts +1 -0
- package/dist/version.generated.js +2 -0
- 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
|