@harmoniclabs/pebble 0.1.10 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/IR/CompilationCtx.d.ts +40 -0
- package/dist/IR/CompilationCtx.js +54 -0
- package/dist/IR/IRHash.d.ts +23 -2
- package/dist/IR/IRHash.js +10 -60
- package/dist/IR/IRNodes/IRConst.js +35 -4
- package/dist/IR/IRNodes/IRHoisted.d.ts +0 -1
- package/dist/IR/IRNodes/IRHoisted.js +4 -6
- package/dist/IR/IRNodes/IRLetted.d.ts +0 -1
- package/dist/IR/IRNodes/IRLetted.js +4 -6
- package/dist/IR/IRNodes/IRNative/IRNativeTag.d.ts +22 -2
- package/dist/IR/IRNodes/IRNative/IRNativeTag.js +26 -2
- package/dist/IR/IRNodes/IRNative/index.d.ts +16 -1
- package/dist/IR/IRNodes/IRNative/index.js +31 -2
- package/dist/IR/IRNodes/utils/hashVarSym.d.ts +0 -1
- package/dist/IR/IRNodes/utils/hashVarSym.js +27 -33
- package/dist/IR/toUPLC/CompilerOptions.d.ts +34 -7
- package/dist/IR/toUPLC/CompilerOptions.js +19 -10
- package/dist/IR/toUPLC/compileIRToUPLC.js +39 -3
- package/dist/IR/toUPLC/subRoutines/inlineSingleUseLetBindingsAndReturnRoot.d.ts +23 -0
- package/dist/IR/toUPLC/subRoutines/inlineSingleUseLetBindingsAndReturnRoot.js +263 -0
- package/dist/IR/toUPLC/subRoutines/introduceCaseForDualHeadTailAndReturnRoot.d.ts +35 -0
- package/dist/IR/toUPLC/subRoutines/introduceCaseForDualHeadTailAndReturnRoot.js +169 -0
- package/dist/IR/toUPLC/subRoutines/replaceHoistedWithLetted.d.ts +0 -1
- package/dist/IR/toUPLC/subRoutines/replaceHoistedWithLetted.js +6 -6
- package/dist/IR/toUPLC/subRoutines/replaceNatives/nativeToIR.d.ts +2 -3
- package/dist/IR/toUPLC/subRoutines/replaceNatives/nativeToIR.js +106 -65
- package/dist/IR/toUPLC/subRoutines/rewriteHeadTailInCaseConsAndReturnRoot.d.ts +30 -0
- package/dist/IR/toUPLC/subRoutines/rewriteHeadTailInCaseConsAndReturnRoot.js +95 -0
- package/dist/IR/toUPLC/subRoutines/rewriteNativesAppliedToConstantsAndReturnRoot.js +36 -5
- package/dist/IR/toUPLC/subRoutines/rewriteToCaseOverConstAndReturnRoot.d.ts +35 -0
- package/dist/IR/toUPLC/subRoutines/rewriteToCaseOverConstAndReturnRoot.js +169 -0
- package/dist/IR/tree_utils/_ir_caseList.d.ts +15 -0
- package/dist/IR/tree_utils/_ir_caseList.js +19 -0
- 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/ast/nodes/statements/declarations/StructDecl.d.ts +16 -2
- package/dist/ast/nodes/statements/declarations/StructDecl.js +15 -1
- package/dist/compiler/AstCompiler/AstCompiler.d.ts +27 -0
- package/dist/compiler/AstCompiler/AstCompiler.js +244 -7
- package/dist/compiler/AstCompiler/internal/_deriveContractBody/_deriveContractBody.js +16 -5
- package/dist/compiler/AstCompiler/internal/exprs/_compileCallExpr.js +97 -6
- package/dist/compiler/AstCompiler/internal/exprs/_compileCaseExpr.js +31 -0
- package/dist/compiler/AstCompiler/internal/exprs/_compileFuncExpr.js +12 -5
- package/dist/compiler/AstCompiler/internal/exprs/_compileIsExpr.js +12 -0
- 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 +64 -0
- package/dist/compiler/AstCompiler/internal/exprs/_compileUnaryPrefixExpr.js +13 -1
- package/dist/compiler/AstCompiler/internal/exprs/_compileVarAccessExpr.js +2 -0
- package/dist/compiler/AstCompiler/internal/exprs/binary/_compileAddExpr.js +18 -5
- package/dist/compiler/AstCompiler/internal/exprs/binary/_compileEqualExpr.js +3 -1
- package/dist/compiler/AstCompiler/internal/exprs/binary/_compileGreaterThanEqualExpr.js +2 -1
- package/dist/compiler/AstCompiler/internal/exprs/binary/_compileGreaterThanExpr.js +2 -1
- package/dist/compiler/AstCompiler/internal/exprs/binary/_compileLessThanEqualExpr.js +2 -1
- package/dist/compiler/AstCompiler/internal/exprs/binary/_compileLessThanExpr.js +2 -1
- package/dist/compiler/AstCompiler/internal/exprs/binary/_compileMultExpr.js +24 -6
- package/dist/compiler/AstCompiler/internal/exprs/binary/_compileNotEqualExpr.js +2 -1
- package/dist/compiler/AstCompiler/internal/exprs/binary/_compileSubExpr.js +16 -5
- package/dist/compiler/AstCompiler/internal/statements/_compileMatchStmt.js +33 -20
- 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 +36 -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 +218 -30
- package/dist/compiler/TirCompiler/expressify/ExpressifyCtx.js +1 -1
- package/dist/compiler/TirCompiler/expressify/expressify.js +30 -2
- package/dist/compiler/TirCompiler/expressify/expressifyForStmt.d.ts +2 -1
- package/dist/compiler/TirCompiler/expressify/expressifyForStmt.js +45 -7
- package/dist/compiler/TirCompiler/expressify/expressifyVars.d.ts +0 -1
- package/dist/compiler/TirCompiler/expressify/expressifyVars.js +49 -15
- 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/TirCaseExpr.d.ts +9 -0
- package/dist/compiler/tir/expressions/TirCaseExpr.js +144 -122
- package/dist/compiler/tir/expressions/TirElemAccessExpr.js +2 -2
- package/dist/compiler/tir/expressions/TirExpr.d.ts +2 -1
- package/dist/compiler/tir/expressions/TirExpr.js +2 -0
- package/dist/compiler/tir/expressions/TirFromDataExpr.js +102 -67
- package/dist/compiler/tir/expressions/TirIsExpr.js +14 -1
- package/dist/compiler/tir/expressions/TirNativeFunc.d.ts +18 -2
- package/dist/compiler/tir/expressions/TirNativeFunc.js +55 -118
- package/dist/compiler/tir/expressions/TirShowExpr.d.ts +52 -0
- package/dist/compiler/tir/expressions/TirShowExpr.js +199 -0
- package/dist/compiler/tir/expressions/TirToDataExpr.js +3 -0
- package/dist/compiler/tir/expressions/TirTraceExpr.js +11 -7
- package/dist/compiler/tir/expressions/TirTypeConversionExpr.js +10 -0
- package/dist/compiler/tir/expressions/TirVariableAccessExpr.d.ts +2 -3
- package/dist/compiler/tir/expressions/TirVariableAccessExpr.js +1 -4
- package/dist/compiler/tir/expressions/ToIRTermCtx.d.ts +20 -3
- package/dist/compiler/tir/expressions/ToIRTermCtx.js +48 -3
- package/dist/compiler/tir/expressions/binary/TirBinaryExpr.d.ts +2 -2
- package/dist/compiler/tir/expressions/binary/TirBinaryExpr.js +45 -8
- package/dist/compiler/tir/expressions/litteral/TirLitEnumMemberExpr.d.ts +19 -0
- package/dist/compiler/tir/expressions/litteral/TirLitEnumMemberExpr.js +24 -0
- package/dist/compiler/tir/expressions/litteral/TirLitteralExpr.d.ts +2 -1
- package/dist/compiler/tir/expressions/litteral/TirLitteralExpr.js +2 -0
- package/dist/compiler/tir/expressions/unary/TirUnaryMinus.js +4 -1
- 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 +619 -0
- package/dist/compiler/tir/program/stdScope/prelude/preludeTypesSrc.js +35 -2
- package/dist/compiler/tir/program/stdScope/stdScope.d.ts +8 -0
- package/dist/compiler/tir/program/stdScope/stdScope.js +84 -41
- 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/TirEnumType.d.ts +21 -0
- package/dist/compiler/tir/types/TirEnumType.js +36 -0
- package/dist/compiler/tir/types/TirNativeType/TirNativeType.d.ts +53 -2
- package/dist/compiler/tir/types/TirNativeType/TirNativeType.js +58 -1
- package/dist/compiler/tir/types/TirNativeType/native/array.d.ts +16 -0
- package/dist/compiler/tir/types/TirNativeType/native/array.js +38 -0
- package/dist/compiler/tir/types/TirNativeType/native/index.d.ts +2 -0
- package/dist/compiler/tir/types/TirNativeType/native/index.js +2 -0
- package/dist/compiler/tir/types/TirNativeType/native/value.d.ts +18 -0
- package/dist/compiler/tir/types/TirNativeType/native/value.js +17 -0
- package/dist/compiler/tir/types/TirStructType.js +6 -1
- package/dist/compiler/tir/types/TirType.d.ts +3 -2
- package/dist/compiler/tir/types/TirType.js +7 -2
- package/dist/compiler/tir/types/utils/canAssignTo.js +36 -1
- package/dist/compiler/tir/types/utils/canCastTo.js +14 -1
- package/dist/compiler/tir/types/utils/getDeconstructableType.d.ts +2 -1
- package/dist/compiler/tir/types/utils/getDeconstructableType.js +2 -0
- package/dist/compiler/tir/types/utils/inferTypeArgs.d.ts +19 -0
- package/dist/compiler/tir/types/utils/inferTypeArgs.js +83 -0
- package/dist/compiler/tir/types/utils/normalizeEnumToInt.d.ts +10 -0
- package/dist/compiler/tir/types/utils/normalizeEnumToInt.js +17 -0
- package/dist/compiler/tir/types/utils/substituteTypeParams.d.ts +9 -0
- package/dist/compiler/tir/types/utils/substituteTypeParams.js +67 -0
- package/dist/diagnostics/diagnosticMessages.generated.d.ts +10 -0
- package/dist/diagnostics/diagnosticMessages.generated.js +20 -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 +362 -46
- package/dist/tokenizer/Token.d.ts +106 -102
- package/dist/tokenizer/Token.js +111 -109
- package/dist/tokenizer/utils/tokenFromKeyword.js +11 -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 +5 -4
- package/dist/IR/tree_utils/_ir_lazyChooseList.d.ts +0 -3
- package/dist/IR/tree_utils/_ir_lazyChooseList.js +0 -7
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TirBoolT, TirIntT } from "../../../compiler/tir/types/TirNativeType/index.js";
|
|
2
2
|
import { equalIrHash } from "../../IRHash.js";
|
|
3
3
|
import { _ir_apps } from "../../IRNodes/IRApp.js";
|
|
4
|
+
import { IRCase } from "../../IRNodes/IRCase.js";
|
|
4
5
|
import { IRConst } from "../../IRNodes/IRConst.js";
|
|
5
6
|
import { IRFunc } from "../../IRNodes/IRFunc.js";
|
|
6
7
|
import { IRHoisted } from "../../IRNodes/IRHoisted.js";
|
|
@@ -125,8 +126,14 @@ export function rewriteNativesAppliedToConstantsAndReturnRoot(term) {
|
|
|
125
126
|
if (isListLength(eqZeroArgFunc)
|
|
126
127
|
&& eqZeroArgArgs.length === 1) {
|
|
127
128
|
const listTerm = eqZeroArgArgs[0];
|
|
128
|
-
//
|
|
129
|
-
|
|
129
|
+
// if( list.length() === 0 ) thenArg else elseArg
|
|
130
|
+
// → case list of cons _h _t -> elseArg ; nil -> thenArg
|
|
131
|
+
const dh = Symbol("_h");
|
|
132
|
+
const dt = Symbol("_t");
|
|
133
|
+
const newTerm = new IRCase(listTerm, [
|
|
134
|
+
new IRFunc([dh, dt], elseArg),
|
|
135
|
+
thenArg
|
|
136
|
+
]);
|
|
130
137
|
modifyTermAndPushToReprocess(current, newTerm);
|
|
131
138
|
continue;
|
|
132
139
|
}
|
|
@@ -137,8 +144,14 @@ export function rewriteNativesAppliedToConstantsAndReturnRoot(term) {
|
|
|
137
144
|
else if (isNullList(condFunc)
|
|
138
145
|
&& condArgs.length === 1) {
|
|
139
146
|
const listTerm = condArgs[0];
|
|
140
|
-
//
|
|
141
|
-
|
|
147
|
+
// if( nullList(list) ) thenArg else elseArg
|
|
148
|
+
// → case list of cons _h _t -> elseArg ; nil -> thenArg
|
|
149
|
+
const dh = Symbol("_h");
|
|
150
|
+
const dt = Symbol("_t");
|
|
151
|
+
const newTerm = new IRCase(listTerm, [
|
|
152
|
+
new IRFunc([dh, dt], elseArg),
|
|
153
|
+
thenArg
|
|
154
|
+
]);
|
|
142
155
|
modifyTermAndPushToReprocess(current, newTerm);
|
|
143
156
|
continue;
|
|
144
157
|
} // if( x.isEmpty() )
|
|
@@ -227,6 +240,24 @@ export function rewriteNativesAppliedToConstantsAndReturnRoot(term) {
|
|
|
227
240
|
continue;
|
|
228
241
|
}
|
|
229
242
|
}
|
|
243
|
+
else if (tag === IRNativeTag.strictChooseList
|
|
244
|
+
&& restArgs.length === 2) {
|
|
245
|
+
// strictChooseList list caseNil caseCons
|
|
246
|
+
// → case list of (λ_h _t → caseCons) | caseNil
|
|
247
|
+
// IRCase branches are naturally lazy, so wrapping caseNil/
|
|
248
|
+
// caseCons in delay/force is unnecessary at the call site.
|
|
249
|
+
const listTerm = fstArg;
|
|
250
|
+
const caseNil = restArgs[0];
|
|
251
|
+
const caseCons = restArgs[1];
|
|
252
|
+
const dh = Symbol("_h");
|
|
253
|
+
const dt = Symbol("_t");
|
|
254
|
+
const newTerm = new IRCase(listTerm, [
|
|
255
|
+
new IRFunc([dh, dt], caseCons),
|
|
256
|
+
caseNil
|
|
257
|
+
]);
|
|
258
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
230
261
|
}
|
|
231
262
|
// only optimizations if first argument is constant after this point
|
|
232
263
|
if (!(fstArg instanceof IRConst)) {
|
|
@@ -254,7 +285,7 @@ function isDropList(term) {
|
|
|
254
285
|
term = term.value;
|
|
255
286
|
}
|
|
256
287
|
return (term instanceof IRNative
|
|
257
|
-
&& term.tag === IRNativeTag.
|
|
288
|
+
&& term.tag === IRNativeTag.dropList);
|
|
258
289
|
}
|
|
259
290
|
function isId(term) {
|
|
260
291
|
while (term instanceof IRHoisted
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Case-over-Const lowering pass.
|
|
3
|
+
*
|
|
4
|
+
* The UPLC `Case` term accepts a constant scrutinee and reinterprets it
|
|
5
|
+
* as a tag-untagged constructor (bool → 0/1, int N → N, unit → 0,
|
|
6
|
+
* pair → constr 0 [fst, snd], list → constr 1 [] for `[]` or
|
|
7
|
+
* constr 0 [head, tail] for cons).
|
|
8
|
+
*
|
|
9
|
+
* This pass replaces canonical `strictIfThenElse(cond, then, else)`
|
|
10
|
+
* sequences with the equivalent `IRCase(cond, [else, then])` form. The
|
|
11
|
+
* machine resolves bool=false → constr 0, bool=true → constr 1.
|
|
12
|
+
* This subsumes the strict boolean helpers (`_not`, `_strictAnd`,
|
|
13
|
+
* `_strictOr`) whose hoisted bodies are themselves `strictIfThenElse`
|
|
14
|
+
* triple-apps — they get lowered inside their hoisted definitions.
|
|
15
|
+
*
|
|
16
|
+
* It also replaces the LAZY pattern emitted by `_ir_lazyIfThenElse`:
|
|
17
|
+
*
|
|
18
|
+
* IRForced( strictIfThenElse cond (delay t) (delay e) )
|
|
19
|
+
*
|
|
20
|
+
* — which is how `&&`, `||` and pebble `if/else` are encoded today —
|
|
21
|
+
* with `IRCase(cond, [e, t])`. Branches under `Case` are naturally
|
|
22
|
+
* lazy, so the surrounding `force`/`delay` indirection is dropped.
|
|
23
|
+
*
|
|
24
|
+
* It also prunes trailing IRError continuations: a missing branch is
|
|
25
|
+
* semantically equivalent to an evaluation-failure branch, so dropping a
|
|
26
|
+
* trailing `IRError` reduces script size while preserving meaning.
|
|
27
|
+
*
|
|
28
|
+
* NOTE: `getApplicationTerms` sees through both raw `IRApp` chains AND
|
|
29
|
+
* the case-constr-app encoding produced earlier in `performUplc…`
|
|
30
|
+
* (i.e. `IRCase(IRConstr(0, [args]), [func])`). We therefore check the
|
|
31
|
+
* app-pattern *before* the IRCase trailing-error pruning so that a case
|
|
32
|
+
* that's really a function call gets unwrapped first.
|
|
33
|
+
*/
|
|
34
|
+
import { IRTerm } from "../../IRTerm.js";
|
|
35
|
+
export declare function rewriteToCaseOverConstAndReturnRoot(term: IRTerm): IRTerm;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Case-over-Const lowering pass.
|
|
3
|
+
*
|
|
4
|
+
* The UPLC `Case` term accepts a constant scrutinee and reinterprets it
|
|
5
|
+
* as a tag-untagged constructor (bool → 0/1, int N → N, unit → 0,
|
|
6
|
+
* pair → constr 0 [fst, snd], list → constr 1 [] for `[]` or
|
|
7
|
+
* constr 0 [head, tail] for cons).
|
|
8
|
+
*
|
|
9
|
+
* This pass replaces canonical `strictIfThenElse(cond, then, else)`
|
|
10
|
+
* sequences with the equivalent `IRCase(cond, [else, then])` form. The
|
|
11
|
+
* machine resolves bool=false → constr 0, bool=true → constr 1.
|
|
12
|
+
* This subsumes the strict boolean helpers (`_not`, `_strictAnd`,
|
|
13
|
+
* `_strictOr`) whose hoisted bodies are themselves `strictIfThenElse`
|
|
14
|
+
* triple-apps — they get lowered inside their hoisted definitions.
|
|
15
|
+
*
|
|
16
|
+
* It also replaces the LAZY pattern emitted by `_ir_lazyIfThenElse`:
|
|
17
|
+
*
|
|
18
|
+
* IRForced( strictIfThenElse cond (delay t) (delay e) )
|
|
19
|
+
*
|
|
20
|
+
* — which is how `&&`, `||` and pebble `if/else` are encoded today —
|
|
21
|
+
* with `IRCase(cond, [e, t])`. Branches under `Case` are naturally
|
|
22
|
+
* lazy, so the surrounding `force`/`delay` indirection is dropped.
|
|
23
|
+
*
|
|
24
|
+
* It also prunes trailing IRError continuations: a missing branch is
|
|
25
|
+
* semantically equivalent to an evaluation-failure branch, so dropping a
|
|
26
|
+
* trailing `IRError` reduces script size while preserving meaning.
|
|
27
|
+
*
|
|
28
|
+
* NOTE: `getApplicationTerms` sees through both raw `IRApp` chains AND
|
|
29
|
+
* the case-constr-app encoding produced earlier in `performUplc…`
|
|
30
|
+
* (i.e. `IRCase(IRConstr(0, [args]), [func])`). We therefore check the
|
|
31
|
+
* app-pattern *before* the IRCase trailing-error pruning so that a case
|
|
32
|
+
* that's really a function call gets unwrapped first.
|
|
33
|
+
*/
|
|
34
|
+
import { IRCase } from "../../IRNodes/IRCase.js";
|
|
35
|
+
import { IRDelayed } from "../../IRNodes/IRDelayed.js";
|
|
36
|
+
import { IRError } from "../../IRNodes/IRError.js";
|
|
37
|
+
import { IRForced } from "../../IRNodes/IRForced.js";
|
|
38
|
+
import { IRHoisted } from "../../IRNodes/IRHoisted.js";
|
|
39
|
+
import { IRLetted } from "../../IRNodes/IRLetted.js";
|
|
40
|
+
import { IRNative } from "../../IRNodes/IRNative/index.js";
|
|
41
|
+
import { IRNativeTag } from "../../IRNodes/IRNative/IRNativeTag.js";
|
|
42
|
+
import { IRFunc } from "../../IRNodes/IRFunc.js";
|
|
43
|
+
import { _modifyChildFromTo } from "../_internal/_modifyChildFromTo.js";
|
|
44
|
+
import { getApplicationTerms } from "../utils/getApplicationTerms.js";
|
|
45
|
+
/**
|
|
46
|
+
* `_makeAllNegativeNativesHoisted` wraps every `IRNative` reference in
|
|
47
|
+
* an `IRHoisted` (despite the name, it touches positive tags too), and
|
|
48
|
+
* subsequent sharing passes may further wrap in `IRLetted`. Unwrap so
|
|
49
|
+
* the pattern detector can see the underlying native tag.
|
|
50
|
+
*/
|
|
51
|
+
function unwrapToNative(t) {
|
|
52
|
+
while (t instanceof IRHoisted)
|
|
53
|
+
t = t.hoisted;
|
|
54
|
+
while (t instanceof IRLetted)
|
|
55
|
+
t = t.value;
|
|
56
|
+
return t;
|
|
57
|
+
}
|
|
58
|
+
export function rewriteToCaseOverConstAndReturnRoot(term) {
|
|
59
|
+
const stack = [term];
|
|
60
|
+
function modifyTermAndPushToReprocess(current, newTerm) {
|
|
61
|
+
const parent = current.parent;
|
|
62
|
+
if (parent) {
|
|
63
|
+
_modifyChildFromTo(parent, current, newTerm);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
term = newTerm;
|
|
67
|
+
term.parent = undefined;
|
|
68
|
+
}
|
|
69
|
+
stack.unshift(newTerm);
|
|
70
|
+
}
|
|
71
|
+
while (stack.length > 0) {
|
|
72
|
+
const current = stack.pop();
|
|
73
|
+
// LAZY pattern emitted by `_ir_lazyIfThenElse`:
|
|
74
|
+
// force( strictIfThenElse cond (delay t) (delay e) )
|
|
75
|
+
// Rewrite to a bare `case cond [e, t]` (Case branches are lazy).
|
|
76
|
+
if (current instanceof IRForced) {
|
|
77
|
+
const innerApp = getApplicationTerms(current.forced);
|
|
78
|
+
const innerFunc = innerApp ? unwrapToNative(innerApp.func) : undefined;
|
|
79
|
+
if (innerApp
|
|
80
|
+
&& innerFunc instanceof IRNative
|
|
81
|
+
&& innerFunc.tag === IRNativeTag.strictIfThenElse
|
|
82
|
+
&& innerApp.args.length === 3
|
|
83
|
+
&& innerApp.args[1] instanceof IRDelayed
|
|
84
|
+
&& innerApp.args[2] instanceof IRDelayed) {
|
|
85
|
+
const cond = innerApp.args[0];
|
|
86
|
+
const tBranch = innerApp.args[1].delayed;
|
|
87
|
+
const eBranch = innerApp.args[2].delayed;
|
|
88
|
+
const newTerm = new IRCase(cond, [eBranch, tBranch]);
|
|
89
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
// `IRForced(IRCase(s, [b0, b1, …]))` where every branch is
|
|
93
|
+
// either `IRDelayed(v)` or `IRFunc(params, IRDelayed(v))` can
|
|
94
|
+
// be simplified by stripping the force/delay pair: case
|
|
95
|
+
// branches are naturally lazy in UPLC `case`. The
|
|
96
|
+
// wrap typically comes from `_ir_lazyIfThenElse` lowering an
|
|
97
|
+
// `if/else` whose condition then got rewritten to a list-case
|
|
98
|
+
// (e.g. `if(nullList(L)) ...`) — the outer force is left
|
|
99
|
+
// dangling around the resulting IRCase.
|
|
100
|
+
if (current.forced instanceof IRCase) {
|
|
101
|
+
const caseTerm = current.forced;
|
|
102
|
+
const conts = caseTerm.continuations;
|
|
103
|
+
const stripped = [];
|
|
104
|
+
let allOk = true;
|
|
105
|
+
for (let i = 0; i < conts.length; i++) {
|
|
106
|
+
const c = conts[i];
|
|
107
|
+
if (c instanceof IRDelayed) {
|
|
108
|
+
stripped.push(c.delayed);
|
|
109
|
+
}
|
|
110
|
+
else if (c instanceof IRFunc
|
|
111
|
+
&& c.body instanceof IRDelayed) {
|
|
112
|
+
stripped.push(new IRFunc(c.params.slice(), c.body.delayed));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
allOk = false;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (allOk) {
|
|
120
|
+
const newCase = new IRCase(caseTerm.constrTerm.clone(), stripped);
|
|
121
|
+
modifyTermAndPushToReprocess(current, newCase);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
stack.unshift(...current.children());
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
// Application-pattern rewrites (raw IRApp chain OR case-constr-app
|
|
129
|
+
// encoding produced by `performUplcOptimizationsAndReturnRoot`).
|
|
130
|
+
const appTerms = getApplicationTerms(current);
|
|
131
|
+
if (appTerms) {
|
|
132
|
+
const { func, args } = appTerms;
|
|
133
|
+
const unwrappedFunc = unwrapToNative(func);
|
|
134
|
+
// strictIfThenElse cond then else → case cond [else, then]
|
|
135
|
+
if (unwrappedFunc instanceof IRNative
|
|
136
|
+
&& unwrappedFunc.tag === IRNativeTag.strictIfThenElse
|
|
137
|
+
&& args.length === 3) {
|
|
138
|
+
const [cond, thenBranch, elseBranch] = args;
|
|
139
|
+
const newTerm = new IRCase(cond, [elseBranch, thenBranch]);
|
|
140
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
// No app-pattern match — but if the node is itself an IRCase
|
|
144
|
+
// (a case-constr-app encoding), we still want trailing-error
|
|
145
|
+
// pruning on the original case, so don't `continue` yet.
|
|
146
|
+
if (!(current instanceof IRCase)) {
|
|
147
|
+
stack.unshift(...current.children());
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Trailing-error pruning on any IRCase node we encounter.
|
|
152
|
+
if (current instanceof IRCase) {
|
|
153
|
+
const conts = current.continuations;
|
|
154
|
+
let lastNonError = conts.length;
|
|
155
|
+
while (lastNonError > 0 && conts[lastNonError - 1] instanceof IRError) {
|
|
156
|
+
lastNonError--;
|
|
157
|
+
}
|
|
158
|
+
if (lastNonError < conts.length && lastNonError > 0) {
|
|
159
|
+
const pruned = new IRCase(current.constrTerm.clone(), Array.from({ length: lastNonError }, (_, i) => conts[i].clone()));
|
|
160
|
+
modifyTermAndPushToReprocess(current, pruned);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
stack.unshift(...current.children());
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
stack.unshift(...current.children());
|
|
167
|
+
}
|
|
168
|
+
return term;
|
|
169
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IRCase } from "../IRNodes/IRCase.js";
|
|
2
|
+
import type { IRTerm } from "../IRTerm.js";
|
|
3
|
+
/**
|
|
4
|
+
* case list of
|
|
5
|
+
* h::t -> caseCons (h, t are bound only if `consParams` is provided)
|
|
6
|
+
* [] -> caseNil
|
|
7
|
+
*
|
|
8
|
+
* Lowers to UPLC `Case`. Branches are naturally lazy, so callers
|
|
9
|
+
* should pass plain (un-delayed) expressions — no `force` is needed around
|
|
10
|
+
* the result.
|
|
11
|
+
*/
|
|
12
|
+
export declare function _ir_caseList(listTerm: IRTerm, caseNil: IRTerm, caseCons: IRTerm, consParams?: {
|
|
13
|
+
head: symbol;
|
|
14
|
+
tail: symbol;
|
|
15
|
+
}): IRCase;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { IRCase } from "../IRNodes/IRCase.js";
|
|
2
|
+
import { IRFunc } from "../IRNodes/IRFunc.js";
|
|
3
|
+
/**
|
|
4
|
+
* case list of
|
|
5
|
+
* h::t -> caseCons (h, t are bound only if `consParams` is provided)
|
|
6
|
+
* [] -> caseNil
|
|
7
|
+
*
|
|
8
|
+
* Lowers to UPLC `Case`. Branches are naturally lazy, so callers
|
|
9
|
+
* should pass plain (un-delayed) expressions — no `force` is needed around
|
|
10
|
+
* the result.
|
|
11
|
+
*/
|
|
12
|
+
export function _ir_caseList(listTerm, caseNil, caseCons, consParams) {
|
|
13
|
+
const h = consParams?.head ?? Symbol("_caseList_h");
|
|
14
|
+
const t = consParams?.tail ?? Symbol("_caseList_t");
|
|
15
|
+
return new IRCase(listTerm, [
|
|
16
|
+
new IRFunc([h, t], caseCons),
|
|
17
|
+
caseNil
|
|
18
|
+
]);
|
|
19
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IRHoisted } from "../IRNodes/IRHoisted.js";
|
|
2
|
+
/**
|
|
3
|
+
* Hoisted IR term: `bytes -> bytes`
|
|
4
|
+
*
|
|
5
|
+
* Converts a bytestring to its lowercase hex (`0-9a-f`) UTF-8 encoding.
|
|
6
|
+
* 1-byte input becomes 2 bytes; 32-byte input (e.g. a hash) becomes 64 bytes.
|
|
7
|
+
*/
|
|
8
|
+
export declare const hoisted_bytesToHex: IRHoisted;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { _ir_apps } from "../IRNodes/IRApp.js";
|
|
2
|
+
import { IRConst } from "../IRNodes/IRConst.js";
|
|
3
|
+
import { IRFunc } from "../IRNodes/IRFunc.js";
|
|
4
|
+
import { IRHoisted } from "../IRNodes/IRHoisted.js";
|
|
5
|
+
import { IRNative } from "../IRNodes/IRNative/index.js";
|
|
6
|
+
import { IRRecursive } from "../IRNodes/IRRecursive.js";
|
|
7
|
+
import { IRSelfCall } from "../IRNodes/IRSelfCall.js";
|
|
8
|
+
import { IRVar } from "../IRNodes/IRVar.js";
|
|
9
|
+
import { _ir_lazyIfThenElse } from "./_ir_lazyIfThenElse.js";
|
|
10
|
+
// hexChar(n) = if n < 10 then n + 48 else n + 87 // '0' = 48, 'a' = 97 = 87+10
|
|
11
|
+
// goAt(bs, len, i) = if i >= len then ""
|
|
12
|
+
// else cons(hexChar(b/16), cons(hexChar(b%16), goAt(bs, len, i+1)))
|
|
13
|
+
// where b = indexByteString(bs, i)
|
|
14
|
+
// bytesToHex(bs) = goAt(bs, lengthOfByteString(bs), 0)
|
|
15
|
+
const emptyBs = IRConst.bytes(new Uint8Array(0));
|
|
16
|
+
const hexCharSym = Symbol("hexChar_n");
|
|
17
|
+
const hoisted_hexChar = new IRHoisted(new IRFunc([hexCharSym], _ir_lazyIfThenElse(
|
|
18
|
+
// n < 10
|
|
19
|
+
_ir_apps(IRNative.lessThanInteger, new IRVar(hexCharSym), IRConst.int(10)),
|
|
20
|
+
// then n + 48
|
|
21
|
+
_ir_apps(IRNative.addInteger, new IRVar(hexCharSym), IRConst.int(48)),
|
|
22
|
+
// else n + 87
|
|
23
|
+
_ir_apps(IRNative.addInteger, new IRVar(hexCharSym), IRConst.int(87)))));
|
|
24
|
+
hoisted_hexChar.hash;
|
|
25
|
+
// Iteration over the bytes of `bs` from offset 0 to len (passed in as args).
|
|
26
|
+
// We avoid re-computing length on each step.
|
|
27
|
+
//
|
|
28
|
+
// self(bs, len, i) =
|
|
29
|
+
// if i >= len then ""
|
|
30
|
+
// else
|
|
31
|
+
// let b = indexByteString(bs, i)
|
|
32
|
+
// cons( hexChar( quotient(b, 16) ),
|
|
33
|
+
// cons( hexChar( mod(b, 16) ),
|
|
34
|
+
// self(bs, len, i + 1)))
|
|
35
|
+
const self_sym = Symbol("bytesToHex_self");
|
|
36
|
+
const bs_sym = Symbol("bytesToHex_bs");
|
|
37
|
+
const len_sym = Symbol("bytesToHex_len");
|
|
38
|
+
const i_sym = Symbol("bytesToHex_i");
|
|
39
|
+
const b_sym = Symbol("bytesToHex_b");
|
|
40
|
+
const hoisted_bytesToHex_loop = new IRHoisted(new IRRecursive(self_sym, new IRFunc([bs_sym, len_sym, i_sym], _ir_lazyIfThenElse(
|
|
41
|
+
// i >= len <=> NOT (i < len)
|
|
42
|
+
_ir_apps(IRNative.lessThanInteger, new IRVar(i_sym), new IRVar(len_sym)),
|
|
43
|
+
// then: process byte at i and recurse
|
|
44
|
+
(() => {
|
|
45
|
+
// let b = indexByteString(bs, i)
|
|
46
|
+
const b = _ir_apps(IRNative.indexByteString, new IRVar(bs_sym), new IRVar(i_sym));
|
|
47
|
+
// The IR currently doesn't have a direct `let` form here; we
|
|
48
|
+
// emit b twice. The optimiser hoists common sub-expressions
|
|
49
|
+
// when they're cheap; for the byte-at-index access this is
|
|
50
|
+
// acceptable (two cheap builtin calls each iteration).
|
|
51
|
+
const high = _ir_apps(hoisted_hexChar.clone(), _ir_apps(IRNative.quotientInteger, b, IRConst.int(16)));
|
|
52
|
+
const lowB = _ir_apps(IRNative.indexByteString, new IRVar(bs_sym), new IRVar(i_sym));
|
|
53
|
+
const low = _ir_apps(hoisted_hexChar.clone(), _ir_apps(IRNative.modInteger, lowB, IRConst.int(16)));
|
|
54
|
+
return _ir_apps(IRNative.consByteString, high, _ir_apps(IRNative.consByteString, low,
|
|
55
|
+
// self(bs, len, i + 1)
|
|
56
|
+
_ir_apps(new IRSelfCall(self_sym), new IRVar(bs_sym), new IRVar(len_sym), _ir_apps(IRNative.addInteger, new IRVar(i_sym), IRConst.int(1)))));
|
|
57
|
+
})(),
|
|
58
|
+
// else: empty bytes
|
|
59
|
+
emptyBs.clone()))));
|
|
60
|
+
hoisted_bytesToHex_loop.hash;
|
|
61
|
+
const outer_bs_sym = Symbol("bytesToHex_outer_bs");
|
|
62
|
+
/**
|
|
63
|
+
* Hoisted IR term: `bytes -> bytes`
|
|
64
|
+
*
|
|
65
|
+
* Converts a bytestring to its lowercase hex (`0-9a-f`) UTF-8 encoding.
|
|
66
|
+
* 1-byte input becomes 2 bytes; 32-byte input (e.g. a hash) becomes 64 bytes.
|
|
67
|
+
*/
|
|
68
|
+
export const hoisted_bytesToHex = new IRHoisted(new IRFunc([outer_bs_sym], _ir_apps(hoisted_bytesToHex_loop.clone(), new IRVar(outer_bs_sym), _ir_apps(IRNative.lengthOfByteString, new IRVar(outer_bs_sym)), IRConst.int(0))));
|
|
69
|
+
hoisted_bytesToHex.hash;
|
|
@@ -3,20 +3,34 @@ import { SourceRange } from "../../../Source/SourceRange.js";
|
|
|
3
3
|
import { Identifier } from "../../common/Identifier.js";
|
|
4
4
|
import { HasSourceRange } from "../../HasSourceRange.js";
|
|
5
5
|
import { BlockStmt } from "../../statements/BlockStmt.js";
|
|
6
|
+
import { AstTypeExpr } from "../../types/AstTypeExpr.js";
|
|
6
7
|
import { AstFuncType } from "../../types/AstNativeTypeExpr.js";
|
|
7
8
|
import { PebbleExpr } from "../PebbleExpr.js";
|
|
8
9
|
import { ArrowKind } from "./ArrowKind.js";
|
|
10
|
+
/**
|
|
11
|
+
* A declared type parameter on a function declaration. Optionally constrained
|
|
12
|
+
* to an interface via `<T implements I>` syntax — when set, every concrete
|
|
13
|
+
* instantiation of the generic function must provide a type that implements
|
|
14
|
+
* `I`, and the compiler threads an implicit `I`-dictionary argument through
|
|
15
|
+
* the function body (see `monomorphizeGeneric`).
|
|
16
|
+
*/
|
|
17
|
+
export declare class TypeParamDecl implements HasSourceRange {
|
|
18
|
+
readonly name: Identifier;
|
|
19
|
+
readonly constraint: AstTypeExpr | undefined;
|
|
20
|
+
readonly range: SourceRange;
|
|
21
|
+
constructor(name: Identifier, constraint: AstTypeExpr | undefined, range: SourceRange);
|
|
22
|
+
}
|
|
9
23
|
/**
|
|
10
24
|
* a litteral function value
|
|
11
25
|
**/
|
|
12
26
|
export declare class FuncExpr implements HasSourceRange {
|
|
13
27
|
readonly name: Identifier;
|
|
14
28
|
readonly flags: CommonFlags;
|
|
15
|
-
readonly typeParams:
|
|
29
|
+
readonly typeParams: TypeParamDecl[];
|
|
16
30
|
readonly signature: AstFuncType;
|
|
17
31
|
body: BlockStmt | PebbleExpr;
|
|
18
32
|
readonly arrowKind: ArrowKind;
|
|
19
33
|
readonly range: SourceRange;
|
|
20
|
-
constructor(name: Identifier, flags: CommonFlags, typeParams:
|
|
34
|
+
constructor(name: Identifier, flags: CommonFlags, typeParams: TypeParamDecl[], signature: AstFuncType, body: BlockStmt | PebbleExpr, arrowKind: ArrowKind, range: SourceRange);
|
|
21
35
|
bodyBlockStmt(): BlockStmt;
|
|
22
36
|
}
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
import { BlockStmt } from "../../statements/BlockStmt.js";
|
|
2
2
|
import { ReturnStmt } from "../../statements/ReturnStmt.js";
|
|
3
|
+
/**
|
|
4
|
+
* A declared type parameter on a function declaration. Optionally constrained
|
|
5
|
+
* to an interface via `<T implements I>` syntax — when set, every concrete
|
|
6
|
+
* instantiation of the generic function must provide a type that implements
|
|
7
|
+
* `I`, and the compiler threads an implicit `I`-dictionary argument through
|
|
8
|
+
* the function body (see `monomorphizeGeneric`).
|
|
9
|
+
*/
|
|
10
|
+
export class TypeParamDecl {
|
|
11
|
+
name;
|
|
12
|
+
constraint;
|
|
13
|
+
range;
|
|
14
|
+
constructor(name, constraint, range) {
|
|
15
|
+
this.name = name;
|
|
16
|
+
this.constraint = constraint;
|
|
17
|
+
this.range = range;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
3
20
|
/**
|
|
4
21
|
* a litteral function value
|
|
5
22
|
**/
|
|
@@ -11,5 +11,6 @@ import { LitThisExpr } from "./LitThisExpr.js";
|
|
|
11
11
|
import { LitTrueExpr } from "./LitTrueExpr.js";
|
|
12
12
|
import { LitUndefExpr } from "./LitUndefExpr.js";
|
|
13
13
|
import { LitVoidExpr } from "./LitVoidExpr.js";
|
|
14
|
-
|
|
14
|
+
import { TemplateStrExpr } from "./TemplateStrExpr.js";
|
|
15
|
+
export type LitteralExpr = LitVoidExpr | LitUndefExpr | LitTrueExpr | LitFalseExpr | LitThisExpr | LitContextExpr | LitArrExpr | LitObjExpr | LitNamedObjExpr | LitStrExpr | TemplateStrExpr | LitIntExpr | LitHexBytesExpr | LitFailExpr;
|
|
15
16
|
export declare function isLitteralExpr(thing: any): thing is LitteralExpr;
|
|
@@ -11,6 +11,7 @@ import { LitThisExpr } from "./LitThisExpr.js";
|
|
|
11
11
|
import { LitTrueExpr } from "./LitTrueExpr.js";
|
|
12
12
|
import { LitUndefExpr } from "./LitUndefExpr.js";
|
|
13
13
|
import { LitVoidExpr } from "./LitVoidExpr.js";
|
|
14
|
+
import { TemplateStrExpr } from "./TemplateStrExpr.js";
|
|
14
15
|
export function isLitteralExpr(thing) {
|
|
15
16
|
return (thing instanceof LitVoidExpr
|
|
16
17
|
|| thing instanceof LitUndefExpr
|
|
@@ -22,6 +23,7 @@ export function isLitteralExpr(thing) {
|
|
|
22
23
|
|| thing instanceof LitObjExpr
|
|
23
24
|
|| thing instanceof LitNamedObjExpr
|
|
24
25
|
|| thing instanceof LitStrExpr
|
|
26
|
+
|| thing instanceof TemplateStrExpr
|
|
25
27
|
|| thing instanceof LitIntExpr
|
|
26
28
|
|| thing instanceof LitHexBytesExpr
|
|
27
29
|
|| thing instanceof LitFailExpr);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { SourceRange } from "../../../Source/SourceRange.js";
|
|
2
|
+
import { HasSourceRange } from "../../HasSourceRange.js";
|
|
3
|
+
import { PebbleExpr } from "../PebbleExpr.js";
|
|
4
|
+
/**
|
|
5
|
+
* A template string literal: backtick-delimited text with `${expr}`
|
|
6
|
+
* interpolation slots — e.g. `` `hello ${name}, count is ${n}` ``.
|
|
7
|
+
*
|
|
8
|
+
* Stored as alternating literal text fragments and interpolated expressions.
|
|
9
|
+
* For a template with N interpolations, `parts.length === N + 1`.
|
|
10
|
+
*
|
|
11
|
+
* Compilation produces a chain of UTF-8 byte concatenations:
|
|
12
|
+
*
|
|
13
|
+
* parts[0]_bytes
|
|
14
|
+
* ++ show-or-passthrough( exprs[0] )
|
|
15
|
+
* ++ parts[1]_bytes
|
|
16
|
+
* ++ show-or-passthrough( exprs[1] )
|
|
17
|
+
* ++ ...
|
|
18
|
+
* ++ parts[N]_bytes
|
|
19
|
+
*
|
|
20
|
+
* For each interpolated expression: if its type is `bytes` it is passed
|
|
21
|
+
* through verbatim (assumed to already be valid UTF-8 — same convention as
|
|
22
|
+
* `trace`); otherwise the compiler implicitly inserts `.show()` via the
|
|
23
|
+
* built-in Show interface dispatch.
|
|
24
|
+
*/
|
|
25
|
+
export declare class TemplateStrExpr implements HasSourceRange {
|
|
26
|
+
readonly parts: string[];
|
|
27
|
+
readonly exprs: PebbleExpr[];
|
|
28
|
+
readonly range: SourceRange;
|
|
29
|
+
constructor(parts: string[], exprs: PebbleExpr[], range: SourceRange);
|
|
30
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A template string literal: backtick-delimited text with `${expr}`
|
|
3
|
+
* interpolation slots — e.g. `` `hello ${name}, count is ${n}` ``.
|
|
4
|
+
*
|
|
5
|
+
* Stored as alternating literal text fragments and interpolated expressions.
|
|
6
|
+
* For a template with N interpolations, `parts.length === N + 1`.
|
|
7
|
+
*
|
|
8
|
+
* Compilation produces a chain of UTF-8 byte concatenations:
|
|
9
|
+
*
|
|
10
|
+
* parts[0]_bytes
|
|
11
|
+
* ++ show-or-passthrough( exprs[0] )
|
|
12
|
+
* ++ parts[1]_bytes
|
|
13
|
+
* ++ show-or-passthrough( exprs[1] )
|
|
14
|
+
* ++ ...
|
|
15
|
+
* ++ parts[N]_bytes
|
|
16
|
+
*
|
|
17
|
+
* For each interpolated expression: if its type is `bytes` it is passed
|
|
18
|
+
* through verbatim (assumed to already be valid UTF-8 — same convention as
|
|
19
|
+
* `trace`); otherwise the compiler implicitly inserts `.show()` via the
|
|
20
|
+
* built-in Show interface dispatch.
|
|
21
|
+
*/
|
|
22
|
+
export class TemplateStrExpr {
|
|
23
|
+
parts;
|
|
24
|
+
exprs;
|
|
25
|
+
range;
|
|
26
|
+
constructor(parts, exprs, range) {
|
|
27
|
+
this.parts = parts;
|
|
28
|
+
this.exprs = exprs;
|
|
29
|
+
this.range = range;
|
|
30
|
+
if (parts.length !== exprs.length + 1) {
|
|
31
|
+
throw new Error(`TemplateStrExpr: parts.length (${parts.length}) must equal ` +
|
|
32
|
+
`exprs.length + 1 (${exprs.length + 1})`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { SourceRange } from "../../Source/SourceRange.js";
|
|
2
2
|
import { HasSourceRange } from "../HasSourceRange.js";
|
|
3
|
-
import { BodyStmt } from "./PebbleStmt.js";
|
|
3
|
+
import { BodyStmt, TopLevelStmt } from "./PebbleStmt.js";
|
|
4
4
|
/**
|
|
5
5
|
* ```ts
|
|
6
6
|
* export <PebbleStmt>
|
|
7
7
|
* ```
|
|
8
8
|
*/
|
|
9
9
|
export declare class ExportStmt implements HasSourceRange {
|
|
10
|
-
readonly stmt: BodyStmt;
|
|
10
|
+
readonly stmt: BodyStmt | TopLevelStmt;
|
|
11
11
|
readonly range: SourceRange;
|
|
12
|
-
constructor(stmt: BodyStmt, range: SourceRange);
|
|
12
|
+
constructor(stmt: BodyStmt | TopLevelStmt, range: SourceRange);
|
|
13
13
|
}
|
|
@@ -19,13 +19,14 @@ import { TestStmt } from "./TestStmt.js";
|
|
|
19
19
|
import { VarStmt } from "./VarStmt.js";
|
|
20
20
|
import { WhileStmt } from "./WhileStmt.js";
|
|
21
21
|
import { AssignmentStmt } from "./AssignmentStmt.js";
|
|
22
|
-
import { UsingStmt } from "./UsingStmt.js";
|
|
22
|
+
import { UsingAliasStmt, UsingStmt } from "./UsingStmt.js";
|
|
23
23
|
import { FuncDecl } from "./declarations/FuncDecl.js";
|
|
24
24
|
import { ExportStmt } from "./ExportStmt.js";
|
|
25
25
|
import { InterfaceDecl } from "./declarations/InterfaceDecl.js";
|
|
26
26
|
import { ContractDecl } from "./declarations/ContractDecl.js";
|
|
27
|
+
import { NamespaceDecl } from "./declarations/NamespaceDecl.js";
|
|
27
28
|
import { TraceStmt } from "./TraceStmt.js";
|
|
28
|
-
export type TopLevelStmt = EmptyStmt | VarStmt | PebbleTypeDecl | InterfaceDecl | FuncDecl | TestStmt | ExportStmt | ExportStarStmt | ExportImportStmt | ImportStmt | ImportStarStmt | TypeImplementsStmt | UsingStmt | ContractDecl;
|
|
29
|
+
export type TopLevelStmt = EmptyStmt | VarStmt | PebbleTypeDecl | InterfaceDecl | FuncDecl | TestStmt | ExportStmt | ExportStarStmt | ExportImportStmt | ImportStmt | ImportStarStmt | TypeImplementsStmt | UsingStmt | UsingAliasStmt | NamespaceDecl | ContractDecl;
|
|
29
30
|
export declare function isTopLevelStmt(stmt: any): stmt is TopLevelStmt;
|
|
30
|
-
export type BodyStmt = IfStmt | VarStmt | ForStmt | ForOfStmt | WhileStmt | ReturnStmt | BlockStmt | BreakStmt | ContinueStmt | EmptyStmt | FailStmt | AssertStmt | TraceStmt | MatchStmt | AssignmentStmt | UsingStmt;
|
|
31
|
+
export type BodyStmt = IfStmt | VarStmt | ForStmt | ForOfStmt | WhileStmt | ReturnStmt | BlockStmt | BreakStmt | ContinueStmt | EmptyStmt | FailStmt | AssertStmt | TraceStmt | MatchStmt | AssignmentStmt | UsingStmt | UsingAliasStmt;
|
|
31
32
|
export declare function isBodyStmt(stmt: any): stmt is BodyStmt;
|
|
@@ -22,10 +22,11 @@ import { WhileStmt } from "./WhileStmt.js";
|
|
|
22
22
|
import { isAssignmentStmt } from "./AssignmentStmt.js";
|
|
23
23
|
import { IncrStmt } from "./IncrStmt.js";
|
|
24
24
|
import { DecrStmt } from "./DecrStmt.js";
|
|
25
|
-
import { UsingStmt } from "./UsingStmt.js";
|
|
25
|
+
import { UsingAliasStmt, UsingStmt } from "./UsingStmt.js";
|
|
26
26
|
import { FuncDecl } from "./declarations/FuncDecl.js";
|
|
27
27
|
import { ExportStmt } from "./ExportStmt.js";
|
|
28
28
|
import { ContractDecl } from "./declarations/ContractDecl.js";
|
|
29
|
+
import { NamespaceDecl } from "./declarations/NamespaceDecl.js";
|
|
29
30
|
import { TraceStmt } from "./TraceStmt.js";
|
|
30
31
|
export function isTopLevelStmt(stmt) {
|
|
31
32
|
return (stmt instanceof EmptyStmt
|
|
@@ -40,6 +41,8 @@ export function isTopLevelStmt(stmt) {
|
|
|
40
41
|
|| stmt instanceof ImportStarStmt
|
|
41
42
|
|| stmt instanceof TypeImplementsStmt
|
|
42
43
|
|| stmt instanceof UsingStmt
|
|
44
|
+
|| stmt instanceof UsingAliasStmt
|
|
45
|
+
|| stmt instanceof NamespaceDecl
|
|
43
46
|
|| stmt instanceof ContractDecl);
|
|
44
47
|
}
|
|
45
48
|
export function isBodyStmt(stmt) {
|
|
@@ -62,5 +65,6 @@ export function isBodyStmt(stmt) {
|
|
|
62
65
|
// || stmt instanceof ExprStmt
|
|
63
66
|
|| stmt instanceof IncrStmt
|
|
64
67
|
|| stmt instanceof DecrStmt
|
|
65
|
-
|| stmt instanceof UsingStmt
|
|
68
|
+
|| stmt instanceof UsingStmt
|
|
69
|
+
|| stmt instanceof UsingAliasStmt);
|
|
66
70
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SourceRange } from "../../Source/SourceRange.js";
|
|
2
|
+
import { Identifier } from "../common/Identifier.js";
|
|
3
|
+
import { PebbleExpr } from "../expr/PebbleExpr.js";
|
|
4
|
+
import { AstTypeExpr } from "../types/AstTypeExpr.js";
|
|
5
|
+
import { HasSourceRange } from "../HasSourceRange.js";
|
|
6
|
+
/**
|
|
7
|
+
* A parameter of a `test` declaration: `<name>: <type> ( via <expr> )?`.
|
|
8
|
+
*
|
|
9
|
+
* This is intentionally a separate node from `SimpleVarDecl` / `VarDecl` so the
|
|
10
|
+
* `via` keyword cannot leak into function/method/contract parameter grammar.
|
|
11
|
+
*/
|
|
12
|
+
export declare class TestParam implements HasSourceRange {
|
|
13
|
+
readonly name: Identifier;
|
|
14
|
+
readonly type: AstTypeExpr;
|
|
15
|
+
readonly viaExpr: PebbleExpr | undefined;
|
|
16
|
+
readonly range: SourceRange;
|
|
17
|
+
constructor(name: Identifier, type: AstTypeExpr, viaExpr: PebbleExpr | undefined, range: SourceRange);
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A parameter of a `test` declaration: `<name>: <type> ( via <expr> )?`.
|
|
3
|
+
*
|
|
4
|
+
* This is intentionally a separate node from `SimpleVarDecl` / `VarDecl` so the
|
|
5
|
+
* `via` keyword cannot leak into function/method/contract parameter grammar.
|
|
6
|
+
*/
|
|
7
|
+
export class TestParam {
|
|
8
|
+
name;
|
|
9
|
+
type;
|
|
10
|
+
viaExpr;
|
|
11
|
+
range;
|
|
12
|
+
constructor(name, type, viaExpr, range) {
|
|
13
|
+
this.name = name;
|
|
14
|
+
this.type = type;
|
|
15
|
+
this.viaExpr = viaExpr;
|
|
16
|
+
this.range = range;
|
|
17
|
+
}
|
|
18
|
+
}
|