@harmoniclabs/pebble 0.1.10 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/dist/IR/CompilationCtx.d.ts +40 -0
  2. package/dist/IR/CompilationCtx.js +54 -0
  3. package/dist/IR/IRHash.d.ts +23 -2
  4. package/dist/IR/IRHash.js +10 -60
  5. package/dist/IR/IRNodes/IRConst.js +35 -4
  6. package/dist/IR/IRNodes/IRHoisted.d.ts +0 -1
  7. package/dist/IR/IRNodes/IRHoisted.js +4 -6
  8. package/dist/IR/IRNodes/IRLetted.d.ts +0 -1
  9. package/dist/IR/IRNodes/IRLetted.js +4 -6
  10. package/dist/IR/IRNodes/IRNative/IRNativeTag.d.ts +22 -2
  11. package/dist/IR/IRNodes/IRNative/IRNativeTag.js +26 -2
  12. package/dist/IR/IRNodes/IRNative/index.d.ts +16 -1
  13. package/dist/IR/IRNodes/IRNative/index.js +31 -2
  14. package/dist/IR/IRNodes/utils/hashVarSym.d.ts +0 -1
  15. package/dist/IR/IRNodes/utils/hashVarSym.js +27 -33
  16. package/dist/IR/toUPLC/CompilerOptions.d.ts +34 -7
  17. package/dist/IR/toUPLC/CompilerOptions.js +19 -10
  18. package/dist/IR/toUPLC/compileIRToUPLC.js +39 -3
  19. package/dist/IR/toUPLC/subRoutines/inlineSingleUseLetBindingsAndReturnRoot.d.ts +23 -0
  20. package/dist/IR/toUPLC/subRoutines/inlineSingleUseLetBindingsAndReturnRoot.js +263 -0
  21. package/dist/IR/toUPLC/subRoutines/introduceCaseForDualHeadTailAndReturnRoot.d.ts +35 -0
  22. package/dist/IR/toUPLC/subRoutines/introduceCaseForDualHeadTailAndReturnRoot.js +169 -0
  23. package/dist/IR/toUPLC/subRoutines/replaceHoistedWithLetted.d.ts +0 -1
  24. package/dist/IR/toUPLC/subRoutines/replaceHoistedWithLetted.js +6 -6
  25. package/dist/IR/toUPLC/subRoutines/replaceNatives/nativeToIR.d.ts +2 -3
  26. package/dist/IR/toUPLC/subRoutines/replaceNatives/nativeToIR.js +106 -65
  27. package/dist/IR/toUPLC/subRoutines/rewriteHeadTailInCaseConsAndReturnRoot.d.ts +30 -0
  28. package/dist/IR/toUPLC/subRoutines/rewriteHeadTailInCaseConsAndReturnRoot.js +95 -0
  29. package/dist/IR/toUPLC/subRoutines/rewriteNativesAppliedToConstantsAndReturnRoot.js +36 -5
  30. package/dist/IR/toUPLC/subRoutines/rewriteToCaseOverConstAndReturnRoot.d.ts +35 -0
  31. package/dist/IR/toUPLC/subRoutines/rewriteToCaseOverConstAndReturnRoot.js +169 -0
  32. package/dist/IR/tree_utils/_ir_caseList.d.ts +15 -0
  33. package/dist/IR/tree_utils/_ir_caseList.js +19 -0
  34. package/dist/IR/tree_utils/bytesToHex.d.ts +8 -0
  35. package/dist/IR/tree_utils/bytesToHex.js +69 -0
  36. package/dist/ast/nodes/expr/functions/FuncExpr.d.ts +16 -2
  37. package/dist/ast/nodes/expr/functions/FuncExpr.js +17 -0
  38. package/dist/ast/nodes/expr/litteral/LitteralExpr.d.ts +2 -1
  39. package/dist/ast/nodes/expr/litteral/LitteralExpr.js +2 -0
  40. package/dist/ast/nodes/expr/litteral/TemplateStrExpr.d.ts +30 -0
  41. package/dist/ast/nodes/expr/litteral/TemplateStrExpr.js +35 -0
  42. package/dist/ast/nodes/statements/ExportStmt.d.ts +3 -3
  43. package/dist/ast/nodes/statements/PebbleStmt.d.ts +4 -3
  44. package/dist/ast/nodes/statements/PebbleStmt.js +6 -2
  45. package/dist/ast/nodes/statements/TestParam.d.ts +18 -0
  46. package/dist/ast/nodes/statements/TestParam.js +18 -0
  47. package/dist/ast/nodes/statements/TestStmt.d.ts +5 -3
  48. package/dist/ast/nodes/statements/TestStmt.js +3 -1
  49. package/dist/ast/nodes/statements/UsingStmt.d.ts +32 -2
  50. package/dist/ast/nodes/statements/UsingStmt.js +39 -3
  51. package/dist/ast/nodes/statements/declarations/NamespaceDecl.d.ts +21 -0
  52. package/dist/ast/nodes/statements/declarations/NamespaceDecl.js +31 -0
  53. package/dist/ast/nodes/statements/declarations/StructDecl.d.ts +16 -2
  54. package/dist/ast/nodes/statements/declarations/StructDecl.js +15 -1
  55. package/dist/compiler/AstCompiler/AstCompiler.d.ts +27 -0
  56. package/dist/compiler/AstCompiler/AstCompiler.js +244 -7
  57. package/dist/compiler/AstCompiler/internal/_deriveContractBody/_deriveContractBody.js +16 -5
  58. package/dist/compiler/AstCompiler/internal/exprs/_compileCallExpr.js +97 -6
  59. package/dist/compiler/AstCompiler/internal/exprs/_compileCaseExpr.js +31 -0
  60. package/dist/compiler/AstCompiler/internal/exprs/_compileFuncExpr.js +12 -5
  61. package/dist/compiler/AstCompiler/internal/exprs/_compileIsExpr.js +12 -0
  62. package/dist/compiler/AstCompiler/internal/exprs/_compileLitteralExpr.js +59 -0
  63. package/dist/compiler/AstCompiler/internal/exprs/_compilePropAccessExpr.d.ts +2 -3
  64. package/dist/compiler/AstCompiler/internal/exprs/_compilePropAccessExpr.js +64 -0
  65. package/dist/compiler/AstCompiler/internal/exprs/_compileUnaryPrefixExpr.js +13 -1
  66. package/dist/compiler/AstCompiler/internal/exprs/_compileVarAccessExpr.js +2 -0
  67. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileAddExpr.js +18 -5
  68. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileEqualExpr.js +3 -1
  69. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileGreaterThanEqualExpr.js +2 -1
  70. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileGreaterThanExpr.js +2 -1
  71. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileLessThanEqualExpr.js +2 -1
  72. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileLessThanExpr.js +2 -1
  73. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileMultExpr.js +24 -6
  74. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileNotEqualExpr.js +2 -1
  75. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileSubExpr.js +16 -5
  76. package/dist/compiler/AstCompiler/internal/statements/_compileMatchStmt.js +33 -20
  77. package/dist/compiler/AstCompiler/internal/statements/_compileStatement.js +4 -1
  78. package/dist/compiler/AstCompiler/internal/statements/_compileTestStmt.d.ts +15 -1
  79. package/dist/compiler/AstCompiler/internal/statements/_compileTestStmt.js +70 -30
  80. package/dist/compiler/AstCompiler/internal/statements/_compileUsingAliasStmt.d.ts +11 -0
  81. package/dist/compiler/AstCompiler/internal/statements/_compileUsingAliasStmt.js +26 -0
  82. package/dist/compiler/AstCompiler/internal/statements/_compileUsingStmt.d.ts +9 -4
  83. package/dist/compiler/AstCompiler/internal/statements/_compileUsingStmt.js +51 -10
  84. package/dist/compiler/AstCompiler/internal/types/_compileDataEncodedConcreteType.js +21 -2
  85. package/dist/compiler/AstCompiler/internal/types/_compileSopEncodedConcreteType.js +17 -2
  86. package/dist/compiler/AstCompiler/scope/AstScope.d.ts +70 -1
  87. package/dist/compiler/AstCompiler/scope/AstScope.js +91 -0
  88. package/dist/compiler/AstCompiler/utils/getPropAccessReturnType.js +36 -1
  89. package/dist/compiler/AstCompiler/utils/monomorphizeGeneric.d.ts +36 -0
  90. package/dist/compiler/AstCompiler/utils/monomorphizeGeneric.js +123 -0
  91. package/dist/compiler/AstCompiler/utils/resolveNamespaceChain.d.ts +28 -0
  92. package/dist/compiler/AstCompiler/utils/resolveNamespaceChain.js +95 -0
  93. package/dist/compiler/AstCompiler/utils/resolveNamespacePath.d.ts +37 -0
  94. package/dist/compiler/AstCompiler/utils/resolveNamespacePath.js +93 -0
  95. package/dist/compiler/Compiler.d.ts +9 -1
  96. package/dist/compiler/Compiler.js +218 -30
  97. package/dist/compiler/TirCompiler/expressify/ExpressifyCtx.js +1 -1
  98. package/dist/compiler/TirCompiler/expressify/expressify.js +30 -2
  99. package/dist/compiler/TirCompiler/expressify/expressifyForStmt.d.ts +2 -1
  100. package/dist/compiler/TirCompiler/expressify/expressifyForStmt.js +45 -7
  101. package/dist/compiler/TirCompiler/expressify/expressifyVars.d.ts +0 -1
  102. package/dist/compiler/TirCompiler/expressify/expressifyVars.js +49 -15
  103. package/dist/compiler/test/TestResult.d.ts +38 -0
  104. package/dist/compiler/test/TestResult.js +6 -0
  105. package/dist/compiler/test/fuzz/PRNG.d.ts +26 -0
  106. package/dist/compiler/test/fuzz/PRNG.js +59 -0
  107. package/dist/compiler/tir/expressions/TirCaseExpr.d.ts +9 -0
  108. package/dist/compiler/tir/expressions/TirCaseExpr.js +144 -122
  109. package/dist/compiler/tir/expressions/TirElemAccessExpr.js +2 -2
  110. package/dist/compiler/tir/expressions/TirExpr.d.ts +2 -1
  111. package/dist/compiler/tir/expressions/TirExpr.js +2 -0
  112. package/dist/compiler/tir/expressions/TirFromDataExpr.js +102 -67
  113. package/dist/compiler/tir/expressions/TirIsExpr.js +14 -1
  114. package/dist/compiler/tir/expressions/TirNativeFunc.d.ts +18 -2
  115. package/dist/compiler/tir/expressions/TirNativeFunc.js +55 -118
  116. package/dist/compiler/tir/expressions/TirShowExpr.d.ts +52 -0
  117. package/dist/compiler/tir/expressions/TirShowExpr.js +199 -0
  118. package/dist/compiler/tir/expressions/TirToDataExpr.js +3 -0
  119. package/dist/compiler/tir/expressions/TirTraceExpr.js +11 -7
  120. package/dist/compiler/tir/expressions/TirTypeConversionExpr.js +10 -0
  121. package/dist/compiler/tir/expressions/TirVariableAccessExpr.d.ts +2 -3
  122. package/dist/compiler/tir/expressions/TirVariableAccessExpr.js +1 -4
  123. package/dist/compiler/tir/expressions/ToIRTermCtx.d.ts +20 -3
  124. package/dist/compiler/tir/expressions/ToIRTermCtx.js +48 -3
  125. package/dist/compiler/tir/expressions/binary/TirBinaryExpr.d.ts +2 -2
  126. package/dist/compiler/tir/expressions/binary/TirBinaryExpr.js +45 -8
  127. package/dist/compiler/tir/expressions/litteral/TirLitEnumMemberExpr.d.ts +19 -0
  128. package/dist/compiler/tir/expressions/litteral/TirLitEnumMemberExpr.js +24 -0
  129. package/dist/compiler/tir/expressions/litteral/TirLitteralExpr.d.ts +2 -1
  130. package/dist/compiler/tir/expressions/litteral/TirLitteralExpr.js +2 -0
  131. package/dist/compiler/tir/expressions/unary/TirUnaryMinus.js +4 -1
  132. package/dist/compiler/tir/program/TypedProgram.d.ts +101 -0
  133. package/dist/compiler/tir/program/TypedProgram.js +43 -0
  134. package/dist/compiler/tir/program/stdScope/populateBuiltinInterfaces.d.ts +17 -0
  135. package/dist/compiler/tir/program/stdScope/populateBuiltinInterfaces.js +70 -0
  136. package/dist/compiler/tir/program/stdScope/populateStdNamespace.d.ts +22 -0
  137. package/dist/compiler/tir/program/stdScope/populateStdNamespace.js +619 -0
  138. package/dist/compiler/tir/program/stdScope/prelude/preludeTypesSrc.js +35 -2
  139. package/dist/compiler/tir/program/stdScope/stdScope.d.ts +8 -0
  140. package/dist/compiler/tir/program/stdScope/stdScope.js +84 -41
  141. package/dist/compiler/tir/statements/TirStmt.js +0 -1
  142. package/dist/compiler/tir/statements/TirTestStmt.d.ts +46 -0
  143. package/dist/compiler/tir/statements/TirTestStmt.js +35 -0
  144. package/dist/compiler/tir/types/TirEnumType.d.ts +21 -0
  145. package/dist/compiler/tir/types/TirEnumType.js +36 -0
  146. package/dist/compiler/tir/types/TirNativeType/TirNativeType.d.ts +53 -2
  147. package/dist/compiler/tir/types/TirNativeType/TirNativeType.js +58 -1
  148. package/dist/compiler/tir/types/TirNativeType/native/array.d.ts +16 -0
  149. package/dist/compiler/tir/types/TirNativeType/native/array.js +38 -0
  150. package/dist/compiler/tir/types/TirNativeType/native/index.d.ts +2 -0
  151. package/dist/compiler/tir/types/TirNativeType/native/index.js +2 -0
  152. package/dist/compiler/tir/types/TirNativeType/native/value.d.ts +18 -0
  153. package/dist/compiler/tir/types/TirNativeType/native/value.js +17 -0
  154. package/dist/compiler/tir/types/TirStructType.js +6 -1
  155. package/dist/compiler/tir/types/TirType.d.ts +3 -2
  156. package/dist/compiler/tir/types/TirType.js +7 -2
  157. package/dist/compiler/tir/types/utils/canAssignTo.js +36 -1
  158. package/dist/compiler/tir/types/utils/canCastTo.js +14 -1
  159. package/dist/compiler/tir/types/utils/getDeconstructableType.d.ts +2 -1
  160. package/dist/compiler/tir/types/utils/getDeconstructableType.js +2 -0
  161. package/dist/compiler/tir/types/utils/inferTypeArgs.d.ts +19 -0
  162. package/dist/compiler/tir/types/utils/inferTypeArgs.js +83 -0
  163. package/dist/compiler/tir/types/utils/normalizeEnumToInt.d.ts +10 -0
  164. package/dist/compiler/tir/types/utils/normalizeEnumToInt.js +17 -0
  165. package/dist/compiler/tir/types/utils/substituteTypeParams.d.ts +9 -0
  166. package/dist/compiler/tir/types/utils/substituteTypeParams.js +67 -0
  167. package/dist/diagnostics/diagnosticMessages.generated.d.ts +10 -0
  168. package/dist/diagnostics/diagnosticMessages.generated.js +20 -0
  169. package/dist/index.d.ts +2 -0
  170. package/dist/index.js +2 -0
  171. package/dist/parser/Parser.d.ts +73 -3
  172. package/dist/parser/Parser.js +362 -46
  173. package/dist/tokenizer/Token.d.ts +106 -102
  174. package/dist/tokenizer/Token.js +111 -109
  175. package/dist/tokenizer/utils/tokenFromKeyword.js +11 -6
  176. package/dist/utils/semverSatisfies.d.ts +1 -0
  177. package/dist/utils/semverSatisfies.js +161 -0
  178. package/dist/version.generated.d.ts +1 -0
  179. package/dist/version.generated.js +2 -0
  180. package/package.json +5 -4
  181. package/dist/IR/tree_utils/_ir_lazyChooseList.d.ts +0 -3
  182. package/dist/IR/tree_utils/_ir_lazyChooseList.js +0 -7
@@ -0,0 +1,199 @@
1
+ import { _ir_apps } from "../../../IR/IRNodes/IRApp.js";
2
+ import { IRConst } from "../../../IR/IRNodes/IRConst.js";
3
+ import { IRFunc } from "../../../IR/IRNodes/IRFunc.js";
4
+ import { IRHoisted } from "../../../IR/IRNodes/IRHoisted.js";
5
+ import { IRNative } from "../../../IR/IRNodes/IRNative/index.js";
6
+ import { IRRecursive } from "../../../IR/IRNodes/IRRecursive.js";
7
+ import { IRSelfCall } from "../../../IR/IRNodes/IRSelfCall.js";
8
+ import { IRVar } from "../../../IR/IRNodes/IRVar.js";
9
+ import { hoisted_bytesToHex } from "../../../IR/tree_utils/bytesToHex.js";
10
+ import { hoisted_intToUtf8Bytes } from "../../../IR/tree_utils/intToUtf8Bytes.js";
11
+ import { _ir_lazyIfThenElse } from "../../../IR/tree_utils/_ir_lazyIfThenElse.js";
12
+ import { fromUtf8 } from "@harmoniclabs/uint8array-utils";
13
+ import { bytes_t } from "../program/stdScope/stdScope.js";
14
+ import { TirDataStructType } from "../types/TirStructType.js";
15
+ import { TirBoolT } from "../types/TirNativeType/native/bool.js";
16
+ import { TirBytesT } from "../types/TirNativeType/native/bytes.js";
17
+ import { TirDataT } from "../types/TirNativeType/native/data.js";
18
+ import { TirIntT } from "../types/TirNativeType/native/int.js";
19
+ import { TirLinearMapT } from "../types/TirNativeType/native/linearMap.js";
20
+ import { TirListT } from "../types/TirNativeType/native/list.js";
21
+ import { TirStringT } from "../types/TirNativeType/native/string.js";
22
+ import { TirDataOptT } from "../types/TirNativeType/native/Optional/data.js";
23
+ import { TirVoidT } from "../types/TirNativeType/native/void.js";
24
+ import { getListTypeArg } from "../types/utils/getListTypeArg.js";
25
+ import { getUnaliased } from "../types/utils/getUnaliased.js";
26
+ /**
27
+ * `_showIR`-backed compile-time-dispatched show expression.
28
+ *
29
+ * Created when the user writes `expr.show()` on a built-in type whose Show
30
+ * impl the compiler provides (int, bytes, bool, data, void, string,
31
+ * List<T>, LinearMap<K,V>, data-encoded structs). For user-declared
32
+ * `type X implements Show { show(self): bytes { ... } }` impls the
33
+ * regular method-dispatch path in `expressifyVars` keeps applying — this
34
+ * expr is only emitted when no user impl is registered.
35
+ */
36
+ export class TirShowExpr {
37
+ inner;
38
+ range;
39
+ constructor(inner, range) {
40
+ this.inner = inner;
41
+ this.range = range;
42
+ }
43
+ get type() { return bytes_t; }
44
+ get isConstant() { return this.inner.isConstant; }
45
+ toString() { return `show( ${this.inner.toString()} )`; }
46
+ pretty(indent) {
47
+ return `show( ${this.inner.pretty(indent)} )`;
48
+ }
49
+ clone() {
50
+ return new TirShowExpr(this.inner.clone(), this.range.clone());
51
+ }
52
+ deps() { return this.inner.deps(); }
53
+ toIR(ctx) {
54
+ return _showIR(this.inner.type, this.inner.toIR(ctx));
55
+ }
56
+ }
57
+ /**
58
+ * Inline an `IRTerm` of type `t` into its UTF-8 textual representation
59
+ * (also bytes). Returns the IR producing the show-encoded bytes.
60
+ *
61
+ * Mirrors `_inlineToData` — fully compile-time-dispatched per source type:
62
+ *
63
+ * int -> hoisted_intToUtf8Bytes (decimal, sign-aware)
64
+ * bytes -> hoisted_bytesToHex (lowercase hex)
65
+ * bool -> "true" / "false" via lazy ifThenElse
66
+ * data -> serialiseData -> bytesToHex
67
+ * void -> "()"
68
+ * string -> encodeUtf8 (treat as already-readable text)
69
+ * List<T> -> "[" + intercalate(", ", map(_showIR(T), elems)) + "]"
70
+ * LinearMap<K,V> -> "{" + intercalate(", ", map((k,v) -> showK(k) ++ ": " ++ showV(v), entries)) + "}"
71
+ *
72
+ * For struct-typed receivers (TirDataStructType / TirSoPStructType) this
73
+ * function does not produce IR — those should reach a user-declared
74
+ * `type X implements Show { show(self): bytes { ... } }` and dispatch
75
+ * through the regular method-call path. The caller is expected to detect
76
+ * that case before invoking `_showIR`.
77
+ */
78
+ export function _showIR(origin_t, exprIR) {
79
+ const t = getUnaliased(origin_t);
80
+ if (t instanceof TirIntT)
81
+ return _ir_apps(hoisted_intToUtf8Bytes.clone(), exprIR);
82
+ if (t instanceof TirBytesT)
83
+ return _ir_apps(hoisted_bytesToHex.clone(), exprIR);
84
+ if (t instanceof TirBoolT)
85
+ return _ir_lazyIfThenElse(exprIR, _hoisted_litBytes("true").clone(), _hoisted_litBytes("false").clone());
86
+ if (t instanceof TirDataT)
87
+ return _ir_apps(hoisted_bytesToHex.clone(), _ir_apps(IRNative.serialiseData, exprIR));
88
+ if (t instanceof TirVoidT)
89
+ return _hoisted_litBytes("()").clone();
90
+ if (t instanceof TirStringT)
91
+ return _ir_apps(IRNative.encodeUtf8, exprIR);
92
+ if (t instanceof TirListT)
93
+ return _showListIR(t, exprIR);
94
+ if (t instanceof TirLinearMapT)
95
+ return _showLinearMapIR(t, exprIR);
96
+ // data-encoded structs and Optional<T> auto-show via serialiseData + hex.
97
+ // Users can override by declaring `type X implements Show { ... }` —
98
+ // that path is handled before _showIR is reached.
99
+ if (t instanceof TirDataStructType
100
+ || t instanceof TirDataOptT)
101
+ return _ir_apps(hoisted_bytesToHex.clone(), _ir_apps(IRNative.serialiseData, exprIR));
102
+ throw new Error(`_showIR: no built-in Show impl for type ${origin_t.toString()}; ` +
103
+ `the type must declare \`type X implements Show { show(self): bytes { ... } }\``);
104
+ }
105
+ // ---- helpers ----
106
+ const _hoistedLits = {};
107
+ function _hoisted_litBytes(s) {
108
+ let cached = _hoistedLits[s];
109
+ if (!cached) {
110
+ cached = new IRHoisted(IRConst.bytes(fromUtf8(s)));
111
+ cached.hash;
112
+ _hoistedLits[s] = cached;
113
+ }
114
+ return cached;
115
+ }
116
+ // recurses through `_showIR`. Caches per element-type to avoid repeated
117
+ // IR construction across multiple call sites for the same `List<T>`.
118
+ const _listShowCache = new Map();
119
+ function _showListIR(listT, exprIR) {
120
+ const elemT = getUnaliased(getListTypeArg(listT));
121
+ if (!elemT)
122
+ throw new Error("_showListIR: missing element type");
123
+ const key = elemT.toConcreteTirTypeName();
124
+ let hoisted = _listShowCache.get(key);
125
+ if (!hoisted) {
126
+ // \xs ->
127
+ // "[" ++
128
+ // ( recur xs True )
129
+ // ++ "]"
130
+ // recur = fix \self \xs \first ->
131
+ // if nullList xs then ""
132
+ // else
133
+ // let head = headList xs
134
+ // let tail = tailList xs
135
+ // ( if first then "" else ", " )
136
+ // ++ showElem(head)
137
+ // ++ self(tail, False)
138
+ const xsOuter = Symbol("show_list_xs_outer");
139
+ const recSelf = Symbol("show_list_self");
140
+ const xs = Symbol("show_list_xs");
141
+ const first = Symbol("show_list_first");
142
+ const recur = new IRRecursive(recSelf, new IRFunc([xs, first], _ir_lazyIfThenElse(_ir_apps(IRNative.nullList, new IRVar(xs)), _hoisted_litBytes("").clone(),
143
+ // separator + show(head) + recur(tail, false)
144
+ _ir_apps(IRNative.appendByteString,
145
+ // separator
146
+ _ir_lazyIfThenElse(new IRVar(first), _hoisted_litBytes("").clone(), _hoisted_litBytes(", ").clone()), _ir_apps(IRNative.appendByteString,
147
+ // show(head)
148
+ _showIR(elemT, _ir_apps(IRNative.headList, new IRVar(xs))),
149
+ // recur(tail, false)
150
+ _ir_apps(new IRSelfCall(recSelf), _ir_apps(IRNative.tailList, new IRVar(xs)), IRConst.bool(false)))))));
151
+ hoisted = new IRHoisted(new IRFunc([xsOuter], _ir_apps(IRNative.appendByteString, _hoisted_litBytes("[").clone(), _ir_apps(IRNative.appendByteString, _ir_apps(recur, new IRVar(xsOuter), IRConst.bool(true)), _hoisted_litBytes("]").clone()))));
152
+ hoisted.hash;
153
+ _listShowCache.set(key, hoisted);
154
+ }
155
+ return _ir_apps(hoisted.clone(), exprIR);
156
+ }
157
+ const _linearMapShowCache = new Map();
158
+ function _showLinearMapIR(mapT, exprIR) {
159
+ const keyT = getUnaliased(mapT.keyTypeArg);
160
+ const valT = getUnaliased(mapT.valTypeArg);
161
+ const cacheKey = keyT.toConcreteTirTypeName() + "→" + valT.toConcreteTirTypeName();
162
+ let hoisted = _linearMapShowCache.get(cacheKey);
163
+ if (!hoisted) {
164
+ // LinearMap is List<PairData> at the IR level. Iterate similarly to
165
+ // _showListIR, but on each entry call showK(fst(entry)) ++ ": " ++
166
+ // showV(snd(entry)). Both sides go through `unBData / unIData / etc.`
167
+ // implicitly because the Pebble runtime stores keys/values as data.
168
+ //
169
+ // For show purposes we treat the entry as an opaque pair-of-data and
170
+ // recover the value bytes via `_inlineFromData(...)`-like dispatch.
171
+ // To keep this turn focused, we invoke `_showIR` with `data` and
172
+ // accept that K/V are shown via their data encoding (compact). A
173
+ // future polish pass can recover the original K/V types and call
174
+ // `_showIR(K)` / `_showIR(V)` directly.
175
+ const xsOuter = Symbol("show_map_outer");
176
+ const recSelf = Symbol("show_map_self");
177
+ const xs = Symbol("show_map_xs");
178
+ const first = Symbol("show_map_first");
179
+ // key/value extraction at the IR level: an entry is a Pair<Data,Data>;
180
+ // fst gets the data-encoded key, snd the data-encoded value. We then
181
+ // just call _showIR(data, ...) on both, which is `serialiseData ++ hex`.
182
+ const showEntry = (entryIR) => _ir_apps(IRNative.appendByteString, _showIR(/* data */ /* fall back to data show */
183
+ /* Pebble stores K and V as data inside LinearMap */
184
+ /* see TirLinearMapT.toUplcConstType */
185
+ /* TirDataT */
186
+ /* hack: reach the singleton via a fresh instance */
187
+ new (require("../types/TirNativeType/native/data.js").TirDataT)(), _ir_apps(IRNative.fstPair, entryIR)), _ir_apps(IRNative.appendByteString, _hoisted_litBytes(": ").clone(), _showIR(new (require("../types/TirNativeType/native/data.js").TirDataT)(), _ir_apps(IRNative.sndPair, entryIR))));
188
+ const recur = new IRRecursive(recSelf, new IRFunc([xs, first], _ir_lazyIfThenElse(_ir_apps(IRNative.nullList, new IRVar(xs)), _hoisted_litBytes("").clone(), _ir_apps(IRNative.appendByteString, _ir_lazyIfThenElse(new IRVar(first), _hoisted_litBytes("").clone(), _hoisted_litBytes(", ").clone()), _ir_apps(IRNative.appendByteString, showEntry(_ir_apps(IRNative.headList, new IRVar(xs))), _ir_apps(new IRSelfCall(recSelf), _ir_apps(IRNative.tailList, new IRVar(xs)), IRConst.bool(false)))))));
189
+ hoisted = new IRHoisted(new IRFunc([xsOuter], _ir_apps(IRNative.appendByteString, _hoisted_litBytes("{").clone(), _ir_apps(IRNative.appendByteString, _ir_apps(recur, new IRVar(xsOuter), IRConst.bool(true)), _hoisted_litBytes("}").clone()))));
190
+ hoisted.hash;
191
+ _linearMapShowCache.set(cacheKey, hoisted);
192
+ }
193
+ return _ir_apps(hoisted.clone(), exprIR);
194
+ }
195
+ /** A canonical 1-arg `(T) -> bytes` IR closure for use as a `Show` dictionary entry. */
196
+ export function _showUplcFunc(origin_t) {
197
+ const xSym = Symbol("show_self");
198
+ return new IRHoisted(new IRFunc([xSym], _showIR(origin_t, new IRVar(xSym))));
199
+ }
@@ -7,6 +7,7 @@ import { IRNative } from "../../../IR/IRNodes/IRNative/index.js";
7
7
  import { IRVar } from "../../../IR/IRNodes/IRVar.js";
8
8
  import { data_t } from "../program/stdScope/stdScope.js";
9
9
  import { TirDataStructType, TirSoPStructType } from "../types/TirStructType.js";
10
+ import { TirEnumType } from "../types/TirEnumType.js";
10
11
  import { isTirType } from "../types/TirType.js";
11
12
  import { getListTypeArg } from "../types/utils/getListTypeArg.js";
12
13
  import { getOptTypeArg } from "../types/utils/getOptTypeArg.js";
@@ -99,6 +100,8 @@ export function _toDataUplcFunc(origin_t) {
99
100
  return IRNative._id;
100
101
  if (from_t instanceof TirIntT)
101
102
  return IRNative.iData;
103
+ if (from_t instanceof TirEnumType)
104
+ return IRNative.iData;
102
105
  if (from_t instanceof TirBytesT)
103
106
  return IRNative.bData;
104
107
  if (from_t instanceof TirVoidT)
@@ -2,10 +2,10 @@ import { _ir_apps } from "../../../IR/IRNodes/IRApp.js";
2
2
  import { IRDelayed } from "../../../IR/IRNodes/IRDelayed.js";
3
3
  import { IRForced } from "../../../IR/IRNodes/IRForced.js";
4
4
  import { IRNative } from "../../../IR/IRNodes/IRNative/index.js";
5
- import { hoisted_intToUtf8Bytes } from "../../../IR/tree_utils/intToUtf8Bytes.js";
6
5
  import { mergeSortedStrArrInplace } from "../../../utils/array/mergeSortedStrArrInplace.js";
7
- import { TirIntT } from "../types/TirNativeType/index.js";
6
+ import { TirBytesT } from "../types/TirNativeType/index.js";
8
7
  import { getUnaliased } from "../types/utils/getUnaliased.js";
8
+ import { _showIR } from "./TirShowExpr.js";
9
9
  export class TirTraceExpr {
10
10
  traceExpr;
11
11
  continuation;
@@ -40,13 +40,17 @@ export class TirTraceExpr {
40
40
  toIR(ctx) {
41
41
  let bytesIR;
42
42
  const exprType = getUnaliased(this.traceExpr.type);
43
- if (exprType instanceof TirIntT) {
44
- // int -> bytes via intToUtf8Bytes
45
- bytesIR = _ir_apps(hoisted_intToUtf8Bytes.clone(), this.traceExpr.toIR(ctx));
43
+ if (exprType instanceof TirBytesT) {
44
+ // bytes are assumed to already be valid UTF-8 — pass through
45
+ // unchanged, as documented for the Show interface.
46
+ bytesIR = this.traceExpr.toIR(ctx);
46
47
  }
47
48
  else {
48
- // assume bytes
49
- bytesIR = this.traceExpr.toIR(ctx);
49
+ // any other type implementing Show: dispatch through `_showIR`,
50
+ // which uses the per-type compile-time table (int → decimal,
51
+ // bool → "true"/"false", data → serialiseData+hex, struct →
52
+ // user impl or auto-derive, list/map → recursive, ...).
53
+ bytesIR = _showIR(exprType, this.traceExpr.toIR(ctx));
50
54
  }
51
55
  // Force(trace(msg, Delay(continuation)))
52
56
  // Delay prevents the continuation from being evaluated
@@ -7,6 +7,7 @@ import { TirIntT } from "../types/TirNativeType/native/int.js";
7
7
  import { TirDataOptT } from "../types/TirNativeType/native/Optional/data.js";
8
8
  import { TirStringT } from "../types/TirNativeType/native/string.js";
9
9
  import { TirDataStructType } from "../types/TirStructType.js";
10
+ import { TirEnumType } from "../types/TirEnumType.js";
10
11
  import { getUnaliased } from "../types/utils/getUnaliased.js";
11
12
  import { _inlineFromData } from "./TirFromDataExpr.js";
12
13
  import { _inlineToData } from "./TirToDataExpr.js";
@@ -49,12 +50,21 @@ export class TirTypeConversionExpr {
49
50
  if (to_t instanceof TirIntT) {
50
51
  if (from_t instanceof TirIntT)
51
52
  return exprIR;
53
+ // enum is already an int at runtime; identity conversion.
54
+ if (from_t instanceof TirEnumType)
55
+ return exprIR;
52
56
  if (from_t instanceof TirBytesT)
53
57
  return _ir_apps(IRNative._bytesToIntBE, exprIR);
54
58
  if (from_t instanceof TirBoolT)
55
59
  return _ir_apps(IRNative._boolToInt, exprIR);
56
60
  throw new Error(`Cannot convert from ${from_t.toString()} to ${to_t.toString()}`);
57
61
  }
62
+ if (to_t instanceof TirEnumType) {
63
+ // identity at runtime — same enum type.
64
+ if (from_t instanceof TirEnumType)
65
+ return exprIR;
66
+ throw new Error(`Cannot convert from ${from_t.toString()} to ${to_t.toString()}`);
67
+ }
58
68
  if (to_t instanceof TirBytesT) {
59
69
  if (from_t instanceof TirBytesT)
60
70
  return exprIR;
@@ -1,6 +1,5 @@
1
1
  import { SourceRange } from "../../../ast/Source/SourceRange.js";
2
- import { IRSelfCall } from "../../../IR/IRNodes/IRSelfCall.js";
3
- import { IRVar } from "../../../IR/IRNodes/IRVar.js";
2
+ import type { IRTerm } from "../../../IR/IRTerm.js";
4
3
  import { ResolveValueResult } from "../../AstCompiler/scope/AstScope.js";
5
4
  import { TirType } from "../types/TirType.js";
6
5
  import type { ITirExpr } from "./ITirExpr.js";
@@ -17,5 +16,5 @@ export declare class TirVariableAccessExpr implements ITirExpr {
17
16
  get isConstant(): boolean;
18
17
  get varName(): string;
19
18
  deps(): string[];
20
- toIR(ctx: ToIRTermCtx): IRVar | IRSelfCall;
19
+ toIR(ctx: ToIRTermCtx): IRTerm;
21
20
  }
@@ -1,5 +1,3 @@
1
- import { IRSelfCall } from "../../../IR/IRNodes/IRSelfCall.js";
2
- import { IRVar } from "../../../IR/IRNodes/IRVar.js";
3
1
  export class TirVariableAccessExpr {
4
2
  range;
5
3
  resolvedValue;
@@ -35,8 +33,7 @@ export class TirVariableAccessExpr {
35
33
  deps() { return [this.varName]; }
36
34
  toIR(ctx) {
37
35
  const ir = ctx.getVarAccessIR(this.varName);
38
- if (!(ir instanceof IRVar
39
- || ir instanceof IRSelfCall)) {
36
+ if (!ir) {
40
37
  throw new Error(`variable '${this.varName}' is missing in [${ctx.allVariables().join(", ")}]`);
41
38
  }
42
39
  return ir;
@@ -1,9 +1,17 @@
1
- import { IRVar } from "../../../IR/IRNodes/IRVar.js";
2
- import { IRSelfCall } from "../../../IR/IRNodes/IRSelfCall.js";
1
+ import type { IRTerm } from "../../../IR/IRTerm.js";
3
2
  export declare class ToIRTermCtx {
4
3
  readonly parent: ToIRTermCtx | undefined;
5
4
  readonly _creationStack?: string | undefined;
6
5
  private readonly localVars;
6
+ /**
7
+ * Per-name overrides whose lookup synthesizes a fresh IR term at each
8
+ * access (rather than resolving to a pre-allocated IRVar). Used to
9
+ * implement lazy field extraction in case-arms — the body's references
10
+ * to pattern-bound fields each emit an `IRLetted` over the extraction
11
+ * IR, so the letted-handling pass can dedup, hoist or eliminate as
12
+ * appropriate.
13
+ */
14
+ private readonly deferredAccess;
7
15
  private _firstVariableIsRecursive;
8
16
  _children: ToIRTermCtx[];
9
17
  constructor(parent: ToIRTermCtx | undefined);
@@ -13,7 +21,16 @@ export declare class ToIRTermCtx {
13
21
  newChild(): ToIRTermCtx;
14
22
  private localVarSym;
15
23
  getVarAccessSym(name: string): symbol | undefined;
16
- getVarAccessIR(name: string): IRVar | IRSelfCall | undefined;
24
+ private getDeferredAccessFactory;
25
+ getVarAccessIR(name: string): IRTerm | undefined;
26
+ /**
27
+ * Register a per-name lookup override. Subsequent `getVarAccessIR(name)`
28
+ * calls in this context (or its descendants) return the IR term produced
29
+ * by `factory()`. The factory is invoked once per access — wrap the
30
+ * result in `IRLetted` if you want the IR-level let-handling pass to
31
+ * dedup / hoist / eliminate as appropriate.
32
+ */
33
+ defineDeferredAccess(name: string, factory: () => IRTerm): void;
17
34
  /**
18
35
  * @returns the symbol of the defined variable (for eventual `new IRFunc( ... )`)
19
36
  **/
@@ -5,6 +5,15 @@ export class ToIRTermCtx {
5
5
  parent;
6
6
  _creationStack;
7
7
  localVars = new Map();
8
+ /**
9
+ * Per-name overrides whose lookup synthesizes a fresh IR term at each
10
+ * access (rather than resolving to a pre-allocated IRVar). Used to
11
+ * implement lazy field extraction in case-arms — the body's references
12
+ * to pattern-bound fields each emit an `IRLetted` over the extraction
13
+ * IR, so the letted-handling pass can dedup, hoist or eliminate as
14
+ * appropriate.
15
+ */
16
+ deferredAccess = new Map();
8
17
  _firstVariableIsRecursive = false;
9
18
  _children = [];
10
19
  constructor(parent) {
@@ -37,15 +46,51 @@ export class ToIRTermCtx {
37
46
  return (this.localVarSym(name)
38
47
  ?? this.parent?.getVarAccessSym(name));
39
48
  }
49
+ getDeferredAccessFactory(name) {
50
+ return (this.deferredAccess.get(name)
51
+ ?? this.parent?.getDeferredAccessFactory(name));
52
+ }
40
53
  getVarAccessIR(name) {
54
+ // deferred accesses (lazy field extraction in case-arms etc.)
55
+ // shadow symbol-based lookups when present.
56
+ const deferred = this.getDeferredAccessFactory(name);
57
+ if (deferred)
58
+ return deferred();
41
59
  const accessSym = this.getVarAccessSym(name);
42
60
  if (typeof accessSym !== "symbol")
43
61
  return undefined;
44
- if (this._firstVariableIsRecursive
45
- && name === this.localVars.keys().next().value)
46
- return new IRSelfCall(accessSym);
62
+ // Recursive accesses must use IRSelfCall (the recursive symbol is
63
+ // bound by an IRRecursive, not an IRFunc — IRVar references would
64
+ // not find a binder during the unused-var pass). Walk the parent
65
+ // chain to find the ctx that owns `name`; that ctx may not be the
66
+ // current one when we're deep inside the recursive function's body
67
+ // (e.g. inside a `case` continuation that newChild'd from it).
68
+ let cur = this;
69
+ while (cur) {
70
+ const localSym = cur.localVars.get(name);
71
+ if (localSym !== undefined) {
72
+ if (cur._firstVariableIsRecursive
73
+ && name === cur.localVars.keys().next().value)
74
+ return new IRSelfCall(accessSym);
75
+ break;
76
+ }
77
+ cur = cur.parent;
78
+ }
47
79
  return new IRVar(accessSym);
48
80
  }
81
+ /**
82
+ * Register a per-name lookup override. Subsequent `getVarAccessIR(name)`
83
+ * calls in this context (or its descendants) return the IR term produced
84
+ * by `factory()`. The factory is invoked once per access — wrap the
85
+ * result in `IRLetted` if you want the IR-level let-handling pass to
86
+ * dedup / hoist / eliminate as appropriate.
87
+ */
88
+ defineDeferredAccess(name, factory) {
89
+ if (this.localVars.has(name) || this.deferredAccess.has(name)) {
90
+ throw new Error(`variable '${name}' already defined in the current scope`);
91
+ }
92
+ this.deferredAccess.set(name, factory);
93
+ }
49
94
  /**
50
95
  * @returns the symbol of the defined variable (for eventual `new IRFunc( ... )`)
51
96
  **/
@@ -119,7 +119,7 @@ export declare class TirSubExpr implements ITirBinaryExpr {
119
119
  left: TirExpr;
120
120
  right: TirExpr;
121
121
  readonly range: SourceRange;
122
- readonly type: TirType;
122
+ get type(): TirType;
123
123
  constructor(left: TirExpr, right: TirExpr, range: SourceRange);
124
124
  toString(): string;
125
125
  pretty(indent: number): string;
@@ -132,7 +132,7 @@ export declare class TirMultExpr implements ITirBinaryExpr {
132
132
  left: TirExpr;
133
133
  right: TirExpr;
134
134
  readonly range: SourceRange;
135
- readonly type: TirType;
135
+ get type(): TirType;
136
136
  constructor(left: TirExpr, right: TirExpr, range: SourceRange);
137
137
  toString(): string;
138
138
  pretty(indent: number): string;
@@ -5,6 +5,8 @@ import { getUnaliased } from "../../types/utils/getUnaliased.js";
5
5
  import { CEKConst, Machine } from "@harmoniclabs/plutus-machine";
6
6
  import { TirBytesT } from "../../types/TirNativeType/native/bytes.js";
7
7
  import { TirIntT } from "../../types/TirNativeType/native/int.js";
8
+ import { TirEnumType } from "../../types/TirEnumType.js";
9
+ import { TirValueT } from "../../types/TirNativeType/native/value.js";
8
10
  import { IRNative } from "../../../../IR/IRNodes/IRNative/index.js";
9
11
  import { IRConst } from "../../../../IR/IRNodes/IRConst.js";
10
12
  import { compileIRToUPLC } from "../../../../IR/toUPLC/compileIRToUPLC.js";
@@ -87,7 +89,7 @@ export class TirLessThanExpr {
87
89
  get isConstant() { return this.left.isConstant && this.right.isConstant; }
88
90
  toIR(ctx) {
89
91
  const type = getUnaliased(this.left.type);
90
- const irFunc = (type instanceof TirIntT ? IRNative.lessThanInteger :
92
+ const irFunc = ((type instanceof TirIntT || type instanceof TirEnumType) ? IRNative.lessThanInteger :
91
93
  type instanceof TirBytesT ? IRNative.lessThanByteString :
92
94
  undefined);
93
95
  if (!irFunc)
@@ -124,7 +126,7 @@ export class TirGreaterThanExpr {
124
126
  get isConstant() { return this.left.isConstant && this.right.isConstant; }
125
127
  toIR(ctx) {
126
128
  const type = getUnaliased(this.left.type);
127
- const irFunc = (type instanceof TirIntT ? IRNative.lessThanInteger :
129
+ const irFunc = ((type instanceof TirIntT || type instanceof TirEnumType) ? IRNative.lessThanInteger :
128
130
  type instanceof TirBytesT ? IRNative.lessThanByteString :
129
131
  undefined);
130
132
  if (!irFunc)
@@ -163,7 +165,7 @@ export class TirLessThanEqualExpr {
163
165
  get isConstant() { return this.left.isConstant && this.right.isConstant; }
164
166
  toIR(ctx) {
165
167
  const type = getUnaliased(this.left.type);
166
- const irFunc = (type instanceof TirIntT ? IRNative.lessThanEqualInteger :
168
+ const irFunc = ((type instanceof TirIntT || type instanceof TirEnumType) ? IRNative.lessThanEqualInteger :
167
169
  type instanceof TirBytesT ? IRNative.lessThanEqualsByteString :
168
170
  undefined);
169
171
  if (!irFunc)
@@ -200,7 +202,7 @@ export class TirGreaterThanEqualExpr {
200
202
  get isConstant() { return this.left.isConstant && this.right.isConstant; }
201
203
  toIR(ctx) {
202
204
  const type = getUnaliased(this.left.type);
203
- const irFunc = (type instanceof TirIntT ? IRNative.lessThanEqualInteger :
205
+ const irFunc = ((type instanceof TirIntT || type instanceof TirEnumType) ? IRNative.lessThanEqualInteger :
204
206
  type instanceof TirBytesT ? IRNative.lessThanEqualsByteString :
205
207
  undefined);
206
208
  if (!irFunc)
@@ -285,9 +287,14 @@ export class TirAddExpr {
285
287
  _creationStack;
286
288
  get type() {
287
289
  const leftType = getUnaliased(this.left.type);
290
+ if (leftType instanceof TirValueT)
291
+ return this.left.type;
288
292
  if (leftType instanceof TirIntT
289
293
  || leftType instanceof TirBytesT)
290
294
  return leftType;
295
+ // enum + int yields an int (enums lower to ints at runtime)
296
+ if (leftType instanceof TirEnumType)
297
+ return int_t;
291
298
  throw new Error("invalid type for addition");
292
299
  }
293
300
  constructor(left, right, range) {
@@ -312,9 +319,10 @@ export class TirAddExpr {
312
319
  get isConstant() { return this.left.isConstant && this.right.isConstant; }
313
320
  toIR(ctx) {
314
321
  const type = getUnaliased(this.left.type);
315
- const irFunc = (type instanceof TirIntT ? IRNative.addInteger :
322
+ const irFunc = ((type instanceof TirIntT || type instanceof TirEnumType) ? IRNative.addInteger :
316
323
  type instanceof TirBytesT ? IRNative.appendByteString :
317
- undefined);
324
+ type instanceof TirValueT ? IRNative.unionValue :
325
+ undefined);
318
326
  if (!irFunc)
319
327
  throw new Error("invalid left type for TirAddExpr");
320
328
  return _ir_apps(irFunc, this.left.toIR(ctx), this.right.toIR(ctx));
@@ -329,7 +337,12 @@ export class TirSubExpr {
329
337
  left;
330
338
  right;
331
339
  range;
332
- type = int_t;
340
+ get type() {
341
+ const leftType = getUnaliased(this.left.type);
342
+ if (leftType instanceof TirValueT)
343
+ return this.left.type;
344
+ return int_t;
345
+ }
333
346
  constructor(left, right, range) {
334
347
  this.left = left;
335
348
  this.right = right;
@@ -348,6 +361,11 @@ export class TirSubExpr {
348
361
  }
349
362
  get isConstant() { return this.left.isConstant && this.right.isConstant; }
350
363
  toIR(ctx) {
364
+ const type = getUnaliased(this.left.type);
365
+ if (type instanceof TirValueT) {
366
+ // a - b → unionValue a (negateValue b)
367
+ return _ir_apps(IRNative.unionValue, this.left.toIR(ctx), _ir_apps(IRNative._negateValue, this.right.toIR(ctx)));
368
+ }
351
369
  return _ir_apps(IRNative.subtractInteger, this.left.toIR(ctx), this.right.toIR(ctx));
352
370
  }
353
371
  deps() {
@@ -360,7 +378,15 @@ export class TirMultExpr {
360
378
  left;
361
379
  right;
362
380
  range;
363
- type = int_t;
381
+ get type() {
382
+ const leftTy = getUnaliased(this.left.type);
383
+ const rightTy = getUnaliased(this.right.type);
384
+ if (leftTy instanceof TirValueT)
385
+ return this.left.type;
386
+ if (rightTy instanceof TirValueT)
387
+ return this.right.type;
388
+ return int_t;
389
+ }
364
390
  constructor(left, right, range) {
365
391
  this.left = left;
366
392
  this.right = right;
@@ -379,6 +405,17 @@ export class TirMultExpr {
379
405
  }
380
406
  get isConstant() { return this.left.isConstant && this.right.isConstant; }
381
407
  toIR(ctx) {
408
+ const leftTy = getUnaliased(this.left.type);
409
+ const rightTy = getUnaliased(this.right.type);
410
+ // scaleValue :: int -> Value -> Value
411
+ if (leftTy instanceof TirValueT) {
412
+ // Value * int → scaleValue int Value
413
+ return _ir_apps(IRNative.scaleValue, this.right.toIR(ctx), this.left.toIR(ctx));
414
+ }
415
+ if (rightTy instanceof TirValueT) {
416
+ // int * Value → scaleValue int Value
417
+ return _ir_apps(IRNative.scaleValue, this.left.toIR(ctx), this.right.toIR(ctx));
418
+ }
382
419
  return _ir_apps(IRNative.multiplyInteger, this.left.toIR(ctx), this.right.toIR(ctx));
383
420
  }
384
421
  deps() {
@@ -0,0 +1,19 @@
1
+ import { ITirExpr } from "../ITirExpr.js";
2
+ import { SourceRange } from "../../../../ast/Source/SourceRange.js";
3
+ import { TirEnumType } from "../../types/TirEnumType.js";
4
+ import { ToIRTermCtx } from "../ToIRTermCtx.js";
5
+ import { IRTerm } from "../../../../IR/index.js";
6
+ import type { TirExpr } from "../TirExpr.js";
7
+ export declare class TirLitEnumMemberExpr implements ITirExpr {
8
+ readonly type: TirEnumType;
9
+ readonly memberIdx: number;
10
+ readonly range: SourceRange;
11
+ readonly isConstant: boolean;
12
+ constructor(type: TirEnumType, memberIdx: number, range: SourceRange);
13
+ get memberName(): string;
14
+ pretty(): string;
15
+ toString(): string;
16
+ clone(): TirExpr;
17
+ deps(): string[];
18
+ toIR(_ctx: ToIRTermCtx): IRTerm;
19
+ }
@@ -0,0 +1,24 @@
1
+ import { IRConst } from "../../../../IR/index.js";
2
+ export class TirLitEnumMemberExpr {
3
+ type;
4
+ memberIdx;
5
+ range;
6
+ isConstant = true;
7
+ constructor(type, memberIdx, range) {
8
+ this.type = type;
9
+ this.memberIdx = memberIdx;
10
+ this.range = range;
11
+ }
12
+ get memberName() { return this.type.members[this.memberIdx]; }
13
+ pretty() { return this.toString(); }
14
+ toString() {
15
+ return `${this.type.name}.${this.memberName}`;
16
+ }
17
+ clone() {
18
+ return new TirLitEnumMemberExpr(this.type.clone(), this.memberIdx, this.range.clone());
19
+ }
20
+ deps() { return []; }
21
+ toIR(_ctx) {
22
+ return IRConst.int(BigInt(this.memberIdx));
23
+ }
24
+ }
@@ -1,4 +1,5 @@
1
1
  import { TirLitArrExpr } from "./TirLitArrExpr.js";
2
+ import { TirLitEnumMemberExpr } from "./TirLitEnumMemberExpr.js";
2
3
  import { TirLitFailExpr } from "./TirLitFailExpr.js";
3
4
  import { TirLitFalseExpr } from "./TirLitFalseExpr.js";
4
5
  import { TirLitHexBytesExpr } from "./TirLitHexBytesExpr.js";
@@ -10,5 +11,5 @@ import { TirLitThisExpr } from "./TirLitThisExpr.js";
10
11
  import { TirLitTrueExpr } from "./TirLitTrueExpr.js";
11
12
  import { TirLitUndefExpr } from "./TirLitUndefExpr.js";
12
13
  import { TirLitVoidExpr } from "./TirLitVoidExpr.js";
13
- export type TirLitteralExpr = TirLitVoidExpr | TirLitUndefExpr | TirLitTrueExpr | TirLitFalseExpr | TirLitStrExpr | TirLitIntExpr | TirLitHexBytesExpr | TirLitThisExpr | TirLitArrExpr | TirLitObjExpr | TirLitNamedObjExpr | TirLitFailExpr;
14
+ export type TirLitteralExpr = TirLitVoidExpr | TirLitUndefExpr | TirLitTrueExpr | TirLitFalseExpr | TirLitStrExpr | TirLitIntExpr | TirLitHexBytesExpr | TirLitThisExpr | TirLitArrExpr | TirLitObjExpr | TirLitNamedObjExpr | TirLitEnumMemberExpr | TirLitFailExpr;
14
15
  export declare function isTirLitteralExpr(thing: any): thing is TirLitteralExpr;
@@ -1,4 +1,5 @@
1
1
  import { TirLitArrExpr } from "./TirLitArrExpr.js";
2
+ import { TirLitEnumMemberExpr } from "./TirLitEnumMemberExpr.js";
2
3
  import { TirLitFailExpr } from "./TirLitFailExpr.js";
3
4
  import { TirLitFalseExpr } from "./TirLitFalseExpr.js";
4
5
  import { TirLitHexBytesExpr } from "./TirLitHexBytesExpr.js";
@@ -19,6 +20,7 @@ export function isTirLitteralExpr(thing) {
19
20
  || thing instanceof TirLitArrExpr
20
21
  || thing instanceof TirLitObjExpr
21
22
  || thing instanceof TirLitNamedObjExpr
23
+ || thing instanceof TirLitEnumMemberExpr
22
24
  || thing instanceof TirLitStrExpr
23
25
  || thing instanceof TirLitIntExpr
24
26
  || thing instanceof TirLitHexBytesExpr