@harmoniclabs/pebble 0.2.0 → 0.3.1

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 (117) 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 +22 -2
  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 +27 -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 +12 -0
  17. package/dist/IR/toUPLC/CompilerOptions.js +14 -9
  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/ast/nodes/statements/declarations/StructDecl.d.ts +16 -2
  35. package/dist/ast/nodes/statements/declarations/StructDecl.js +15 -1
  36. package/dist/compiler/AstCompiler/AstCompiler.d.ts +1 -0
  37. package/dist/compiler/AstCompiler/AstCompiler.js +41 -4
  38. package/dist/compiler/AstCompiler/internal/_deriveContractBody/_deriveContractBody.js +3 -3
  39. package/dist/compiler/AstCompiler/internal/exprs/_compileCallExpr.js +57 -10
  40. package/dist/compiler/AstCompiler/internal/exprs/_compileCaseExpr.js +31 -0
  41. package/dist/compiler/AstCompiler/internal/exprs/_compileIsExpr.js +12 -0
  42. package/dist/compiler/AstCompiler/internal/exprs/_compilePropAccessExpr.js +36 -0
  43. package/dist/compiler/AstCompiler/internal/exprs/_compileUnaryPrefixExpr.js +13 -1
  44. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileAddExpr.js +18 -5
  45. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileEqualExpr.js +3 -1
  46. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileGreaterThanEqualExpr.js +2 -1
  47. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileGreaterThanExpr.js +2 -1
  48. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileLessThanEqualExpr.js +2 -1
  49. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileLessThanExpr.js +2 -1
  50. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileMultExpr.js +24 -6
  51. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileNotEqualExpr.js +2 -1
  52. package/dist/compiler/AstCompiler/internal/exprs/binary/_compileSubExpr.js +16 -5
  53. package/dist/compiler/AstCompiler/internal/statements/_compileMatchStmt.js +33 -20
  54. package/dist/compiler/AstCompiler/utils/getPropAccessReturnType.js +11 -0
  55. package/dist/compiler/Compiler.js +20 -27
  56. package/dist/compiler/TirCompiler/expressify/ExpressifyCtx.js +1 -1
  57. package/dist/compiler/TirCompiler/expressify/expressify.js +30 -2
  58. package/dist/compiler/TirCompiler/expressify/expressifyForStmt.d.ts +2 -1
  59. package/dist/compiler/TirCompiler/expressify/expressifyForStmt.js +45 -7
  60. package/dist/compiler/TirCompiler/expressify/expressifyVars.d.ts +0 -1
  61. package/dist/compiler/TirCompiler/expressify/expressifyVars.js +23 -8
  62. package/dist/compiler/tir/expressions/TirCaseExpr.d.ts +9 -0
  63. package/dist/compiler/tir/expressions/TirCaseExpr.js +144 -122
  64. package/dist/compiler/tir/expressions/TirElemAccessExpr.js +2 -2
  65. package/dist/compiler/tir/expressions/TirFromDataExpr.js +102 -67
  66. package/dist/compiler/tir/expressions/TirIsExpr.js +14 -1
  67. package/dist/compiler/tir/expressions/TirNativeFunc.d.ts +1 -2
  68. package/dist/compiler/tir/expressions/TirNativeFunc.js +2 -12
  69. package/dist/compiler/tir/expressions/TirToDataExpr.js +3 -0
  70. package/dist/compiler/tir/expressions/TirTypeConversionExpr.js +10 -0
  71. package/dist/compiler/tir/expressions/TirVariableAccessExpr.d.ts +2 -3
  72. package/dist/compiler/tir/expressions/TirVariableAccessExpr.js +1 -4
  73. package/dist/compiler/tir/expressions/ToIRTermCtx.d.ts +20 -3
  74. package/dist/compiler/tir/expressions/ToIRTermCtx.js +48 -3
  75. package/dist/compiler/tir/expressions/binary/TirBinaryExpr.d.ts +2 -2
  76. package/dist/compiler/tir/expressions/binary/TirBinaryExpr.js +45 -8
  77. package/dist/compiler/tir/expressions/litteral/TirLitEnumMemberExpr.d.ts +19 -0
  78. package/dist/compiler/tir/expressions/litteral/TirLitEnumMemberExpr.js +24 -0
  79. package/dist/compiler/tir/expressions/litteral/TirLitteralExpr.d.ts +2 -1
  80. package/dist/compiler/tir/expressions/litteral/TirLitteralExpr.js +2 -0
  81. package/dist/compiler/tir/expressions/unary/TirUnaryMinus.js +4 -1
  82. package/dist/compiler/tir/program/stdScope/populateStdNamespace.js +49 -4
  83. package/dist/compiler/tir/program/stdScope/prelude/preludeTypesSrc.js +35 -2
  84. package/dist/compiler/tir/program/stdScope/stdScope.d.ts +7 -0
  85. package/dist/compiler/tir/program/stdScope/stdScope.js +83 -40
  86. package/dist/compiler/tir/types/TirEnumType.d.ts +21 -0
  87. package/dist/compiler/tir/types/TirEnumType.js +36 -0
  88. package/dist/compiler/tir/types/TirNativeType/TirNativeType.d.ts +4 -2
  89. package/dist/compiler/tir/types/TirNativeType/TirNativeType.js +5 -0
  90. package/dist/compiler/tir/types/TirNativeType/native/array.d.ts +16 -0
  91. package/dist/compiler/tir/types/TirNativeType/native/array.js +38 -0
  92. package/dist/compiler/tir/types/TirNativeType/native/index.d.ts +2 -0
  93. package/dist/compiler/tir/types/TirNativeType/native/index.js +2 -0
  94. package/dist/compiler/tir/types/TirNativeType/native/value.d.ts +18 -0
  95. package/dist/compiler/tir/types/TirNativeType/native/value.js +17 -0
  96. package/dist/compiler/tir/types/TirStructType.js +6 -1
  97. package/dist/compiler/tir/types/TirType.d.ts +3 -2
  98. package/dist/compiler/tir/types/TirType.js +4 -1
  99. package/dist/compiler/tir/types/utils/canAssignTo.js +28 -0
  100. package/dist/compiler/tir/types/utils/canCastTo.js +14 -1
  101. package/dist/compiler/tir/types/utils/getDeconstructableType.d.ts +2 -1
  102. package/dist/compiler/tir/types/utils/getDeconstructableType.js +2 -0
  103. package/dist/compiler/tir/types/utils/inferTypeArgs.js +4 -0
  104. package/dist/compiler/tir/types/utils/normalizeEnumToInt.d.ts +10 -0
  105. package/dist/compiler/tir/types/utils/normalizeEnumToInt.js +17 -0
  106. package/dist/compiler/tir/types/utils/substituteTypeParams.js +5 -0
  107. package/dist/diagnostics/diagnosticMessages.generated.d.ts +5 -0
  108. package/dist/diagnostics/diagnosticMessages.generated.js +10 -0
  109. package/dist/parser/Parser.js +29 -13
  110. package/dist/tokenizer/Token.d.ts +8 -7
  111. package/dist/tokenizer/Token.js +8 -7
  112. package/dist/tokenizer/utils/tokenFromKeyword.js +2 -0
  113. package/dist/version.generated.d.ts +1 -1
  114. package/dist/version.generated.js +1 -1
  115. package/package.json +3 -3
  116. package/dist/IR/tree_utils/_ir_lazyChooseList.d.ts +0 -3
  117. package/dist/IR/tree_utils/_ir_lazyChooseList.js +0 -7
@@ -1,13 +1,11 @@
1
- import { _ir_apps, IRApp } from "../../../IR/IRNodes/IRApp.js";
1
+ import { _ir_apps } from "../../../IR/IRNodes/IRApp.js";
2
+ import { IRCase } from "../../../IR/IRNodes/IRCase.js";
2
3
  import { IRConst } from "../../../IR/IRNodes/IRConst.js";
3
4
  import { IRConstr } from "../../../IR/IRNodes/IRConstr.js";
4
- import { IRDelayed } from "../../../IR/IRNodes/IRDelayed.js";
5
- import { IRForced } from "../../../IR/IRNodes/IRForced.js";
6
5
  import { IRFunc } from "../../../IR/IRNodes/IRFunc.js";
7
6
  import { IRHoisted } from "../../../IR/IRNodes/IRHoisted.js";
8
7
  import { IRNative } from "../../../IR/IRNodes/IRNative/index.js";
9
8
  import { IRVar } from "../../../IR/IRNodes/IRVar.js";
10
- import { _ir_let } from "../../../IR/tree_utils/_ir_let.js";
11
9
  import { TirBoolT } from "../types/TirNativeType/native/bool.js";
12
10
  import { TirBytesT } from "../types/TirNativeType/native/bytes.js";
13
11
  import { TirDataT } from "../types/TirNativeType/native/data.js";
@@ -19,7 +17,10 @@ import { TirDataOptT } from "../types/TirNativeType/native/Optional/data.js";
19
17
  import { TirSopOptT } from "../types/TirNativeType/native/Optional/sop.js";
20
18
  import { TirStringT } from "../types/TirNativeType/native/string.js";
21
19
  import { TirVoidT } from "../types/TirNativeType/native/void.js";
20
+ import { TirValueT } from "../types/TirNativeType/native/value.js";
21
+ import { TirArrayT } from "../types/TirNativeType/native/array.js";
22
22
  import { TirDataStructType, TirSoPStructType } from "../types/TirStructType.js";
23
+ import { TirEnumType } from "../types/TirEnumType.js";
23
24
  import { isTirType } from "../types/TirType.js";
24
25
  import { getListTypeArg } from "../types/utils/getListTypeArg.js";
25
26
  import { getOptTypeArg } from "../types/utils/getOptTypeArg.js";
@@ -68,6 +69,20 @@ export function _inlineFromData(target_t, dataExprIR) {
68
69
  // LinearMapEntry is Pair<Data,Data> at runtime — no conversion needed
69
70
  if (to_t instanceof TirLinearMapEntryT)
70
71
  return dataExprIR;
72
+ // Native Value: data -> Value via `unValueData`
73
+ if (to_t instanceof TirValueT)
74
+ return _ir_apps(IRNative.unValueData, dataExprIR);
75
+ // Native Array<T>: data -> [data] (unListData) -> Array<T>
76
+ // for non-data element types we map elements through their fromData first.
77
+ if (to_t instanceof TirArrayT) {
78
+ const elems_t = getUnaliased(to_t.typeArg);
79
+ const listOfDataExpr = _ir_apps(IRNative.unListData, dataExprIR);
80
+ if (elems_t instanceof TirDataStructType
81
+ || elems_t instanceof TirDataOptT
82
+ || elems_t instanceof TirDataT)
83
+ return _ir_apps(IRNative.listToArray, listOfDataExpr);
84
+ return _ir_apps(IRNative.listToArray, _ir_apps(IRNative._mkMapList, IRConst.listOf(elems_t)([]), _fromDataUplcFunc(elems_t), listOfDataExpr));
85
+ }
71
86
  if (to_t instanceof TirListT) {
72
87
  const elems_t = getUnaliased(getListTypeArg(to_t));
73
88
  const listOfDataExpr = _ir_apps(IRNative.unListData, dataExprIR);
@@ -81,16 +96,24 @@ export function _inlineFromData(target_t, dataExprIR) {
81
96
  const value_t = getOptTypeArg(to_t);
82
97
  if (!isTirType(value_t))
83
98
  throw new Error("TirFromDataExpr: unreachable");
84
- return _ir_let(// introuduce a var
85
- _ir_apps(IRNative.unConstrData, dataExprIR), unConstrDataResultSym => _ir_apps(IRNative.strictIfThenElse, _ir_apps(IRNative.equalsInteger, _ir_apps(IRNative.fstPair, new IRVar(unConstrDataResultSym) // unConstrData result
86
- ), IRConst.int(0)),
87
- // then (Just value)
88
- new IRConstr(0, [
89
- _ir_apps(_fromDataUplcFunc(value_t), _ir_apps(IRNative.headList, _ir_apps(IRNative.sndPair, new IRVar(unConstrDataResultSym) // unConstrData result
90
- )))
91
- ]),
92
- // else (Nothing)
93
- new IRHoisted(new IRConstr(1, []))));
99
+ // Case(unConstrData(data), [\idxSym fieldsSym ->
100
+ // Case(idxSym, [
101
+ // IRConstr(0, [fromData(headList(fieldsSym))]), -- Some
102
+ // IRConstr(1, []) -- None
103
+ // ])
104
+ // ])
105
+ const idxSym = Symbol("optIdx");
106
+ const fieldsListSym = Symbol("optFields");
107
+ return new IRCase(_ir_apps(IRNative.unConstrData, dataExprIR), [
108
+ new IRFunc([idxSym, fieldsListSym], new IRCase(new IRVar(idxSym), [
109
+ // ctor 0: Some
110
+ new IRConstr(0, [
111
+ _ir_apps(_fromDataUplcFunc(value_t), _ir_apps(IRNative.headList, new IRVar(fieldsListSym)))
112
+ ]),
113
+ // ctor 1: None
114
+ new IRHoisted(new IRConstr(1, []))
115
+ ]))
116
+ ]);
94
117
  }
95
118
  if (to_t instanceof TirSoPStructType) {
96
119
  return _inlineMultiSopConstrFromData(to_t, dataExprIR);
@@ -106,6 +129,8 @@ export function _fromDataUplcFunc(_target_t) {
106
129
  return IRNative._id;
107
130
  if (target_t instanceof TirIntT)
108
131
  return IRNative.unIData;
132
+ if (target_t instanceof TirEnumType)
133
+ return IRNative.unIData;
109
134
  if (target_t instanceof TirBytesT)
110
135
  return IRNative.unBData;
111
136
  if (target_t instanceof TirVoidT)
@@ -114,6 +139,9 @@ export function _fromDataUplcFunc(_target_t) {
114
139
  return _boolFromData.clone();
115
140
  if (target_t instanceof TirStringT)
116
141
  return _strFromData.clone();
142
+ // Native Value: data -> Value via `unValueData`
143
+ if (target_t instanceof TirValueT)
144
+ return IRNative.unValueData;
117
145
  if (target_t instanceof TirLinearMapT)
118
146
  // linear maps only have pairs as elements
119
147
  // and we only support pairs of data (bc we only have `mkPairData`)
@@ -136,8 +164,21 @@ export function _fromDataUplcFunc(_target_t) {
136
164
  const _unitFromDataSym = Symbol("unit");
137
165
  const _mkUnit = new IRHoisted(new IRFunc([_unitFromDataSym], IRConst.unit));
138
166
  const _boolFromDataDataSym = Symbol("boolData");
167
+ // Case(unConstrData(data), [\idxSym _fieldsSym ->
168
+ // Case(idxSym, [
169
+ // IRConst.bool(true), -- ctor 0 → true (preserves equalsInteger(_, 0) semantics)
170
+ // IRConst.bool(false) -- ctor 1 → false
171
+ // ])
172
+ // ])
173
+ const _boolFromDataIdxSym = Symbol("boolIdx");
174
+ const _boolFromDataFieldsSym = Symbol("boolFields_unused");
139
175
  const _boolFromData = new IRHoisted(new IRFunc([_boolFromDataDataSym], // data
140
- _ir_apps(IRNative.equalsInteger, new IRApp(IRNative.fstPair, new IRApp(IRNative.unConstrData, new IRVar(_boolFromDataDataSym))), IRConst.int(0))));
176
+ new IRCase(_ir_apps(IRNative.unConstrData, new IRVar(_boolFromDataDataSym)), [
177
+ new IRFunc([_boolFromDataIdxSym, _boolFromDataFieldsSym], new IRCase(new IRVar(_boolFromDataIdxSym), [
178
+ IRConst.bool(true),
179
+ IRConst.bool(false)
180
+ ]))
181
+ ])));
141
182
  const _strFromDataDataSym = Symbol("strData");
142
183
  const _strFromData = new IRHoisted(new IRFunc([_strFromDataDataSym], // data
143
184
  _ir_apps(IRNative.decodeUtf8, _ir_apps(IRNative.unBData, new IRVar(_strFromDataDataSym)))));
@@ -147,63 +188,57 @@ export function _inilneSingeSopConstrFromData(sop_t, dataExprIR) {
147
188
  const constr = sop_t.constructors[0];
148
189
  if (constr.fields.length === 0)
149
190
  return new IRHoisted(new IRConstr(0, []));
150
- if (constr.fields.length === 1) {
151
- const value_t = getUnaliased(constr.fields[0].type);
152
- if (!isTirType(value_t))
153
- throw new Error("TirFromDataExpr: unreachable");
154
- return new IRConstr(0, [
155
- _inlineFromData(value_t,
156
- // get head of fields list
157
- _ir_apps(IRNative.headList, _ir_apps(IRNative.sndPair, _ir_apps(IRNative.unConstrData, dataExprIR))))
158
- ]);
159
- }
160
- return _ir_let(_ir_apps(IRNative.sndPair, _ir_apps(IRNative.unConstrData, dataExprIR)), // introduce fields list
161
- // introduce fields list
162
- fieldsListSym => new IRConstr(0, constr.fields.map((field, i) => {
163
- const field_t = getUnaliased(field.type);
164
- if (!isTirType(field_t))
165
- throw new Error("TirFromDataExpr: unreachable");
166
- return _inlineFromData(field_t, _ir_apps(IRNative.headList, i === 0
167
- ? new IRVar(fieldsListSym)
168
- : _ir_apps(IRNative._dropList, IRConst.int(i), new IRVar(fieldsListSym))));
169
- })));
191
+ // Case(unConstrData(data), [\_idxSym fieldsListSym -> IRConstr(0, [...fields])])
192
+ // Single ctor, so the index is ignored — the outer Case destructures
193
+ // the pair via a 2-arg branch and we only consume the fields list.
194
+ const idxSym = Symbol("singleCtorIdx_unused");
195
+ const fieldsListSym = Symbol("fieldsList");
196
+ return new IRCase(_ir_apps(IRNative.unConstrData, dataExprIR), [
197
+ new IRFunc([idxSym, fieldsListSym], new IRConstr(0, constr.fields.map((field, i) => {
198
+ const field_t = getUnaliased(field.type);
199
+ if (!isTirType(field_t))
200
+ throw new Error("TirFromDataExpr: unreachable");
201
+ return _inlineFromData(field_t, _ir_apps(IRNative.headList, i === 0
202
+ ? new IRVar(fieldsListSym)
203
+ : _ir_apps(IRNative.dropList, IRConst.int(i), new IRVar(fieldsListSym))));
204
+ })))
205
+ ]);
170
206
  }
171
207
  export function _inlineMultiSopConstrFromData(sop_t, dataExprIR) {
172
208
  if (sop_t.constructors.length <= 1)
173
209
  return _inilneSingeSopConstrFromData(sop_t, dataExprIR);
174
- return _ir_let(_ir_apps(IRNative.unConstrData, dataExprIR), // introduce unConstrData result
175
- // introduce unConstrData result
176
- unConstrDataSym => _ir_let(_ir_apps(IRNative.equalsInteger, _ir_apps(IRNative.fstPair, new IRVar(unConstrDataSym))), // introduce isConstrIdx predicate (a function expecting an int)
177
- // introduce isConstrIdx predicate (a function expecting an int)
178
- isConstrIdxSym => _ir_let(_ir_apps(IRNative.sndPair, new IRVar(unConstrDataSym)), // introduce fields list
179
- // introduce fields list
180
- fieldsListSym => {
181
- const continuations = sop_t.constructors.map((constr, constrIdx) => {
182
- if (constr.fields.length === 0)
183
- return new IRHoisted(new IRConstr(constrIdx, []));
184
- if (constr.fields.length === 1) {
185
- const value_t = getUnaliased(constr.fields[0].type);
186
- if (!isTirType(value_t))
187
- throw new Error("TirFromDataExpr: unreachable");
188
- return new IRConstr(constrIdx, [
189
- _inlineFromData(value_t, _ir_apps(IRNative.headList, new IRVar(fieldsListSym)))
190
- ]);
191
- }
192
- return new IRConstr(constrIdx, constr.fields.map((field, i) => {
193
- const field_t = getUnaliased(field.type);
194
- if (!isTirType(field_t))
195
- throw new Error("TirFromDataExpr: unreachable");
196
- return _inlineFromData(field_t, _ir_apps(IRNative.headList, i === 0
197
- ? new IRVar(fieldsListSym)
198
- : _ir_apps(IRNative._dropList, IRConst.int(i), new IRVar(fieldsListSym))));
199
- }));
200
- });
201
- let finalIfThenElseChain = continuations[continuations.length - 1];
202
- for (let i = continuations.length - 2; i >= 0; i--) {
203
- finalIfThenElseChain = new IRForced(_ir_apps(IRNative.strictIfThenElse, _ir_apps(new IRVar(isConstrIdxSym), IRConst.int(i)), new IRDelayed(continuations[i]), new IRDelayed(finalIfThenElseChain)));
210
+ // Case(unConstrData(data), [\idxSym fieldsListSym ->
211
+ // Case(idxSym, [
212
+ // IRConstr(0, [...fields_of_ctor_0]),
213
+ // IRConstr(1, [...fields_of_ctor_1]),
214
+ // ...
215
+ // ])
216
+ // ])
217
+ const idxSym = Symbol("ctorIdx");
218
+ const fieldsListSym = Symbol("fieldsList");
219
+ const continuations = sop_t.constructors.map((constr, constrIdx) => {
220
+ if (constr.fields.length === 0)
221
+ return new IRHoisted(new IRConstr(constrIdx, []));
222
+ if (constr.fields.length === 1) {
223
+ const value_t = getUnaliased(constr.fields[0].type);
224
+ if (!isTirType(value_t))
225
+ throw new Error("TirFromDataExpr: unreachable");
226
+ return new IRConstr(constrIdx, [
227
+ _inlineFromData(value_t, _ir_apps(IRNative.headList, new IRVar(fieldsListSym)))
228
+ ]);
204
229
  }
205
- return finalIfThenElseChain;
206
- })));
230
+ return new IRConstr(constrIdx, constr.fields.map((field, i) => {
231
+ const field_t = getUnaliased(field.type);
232
+ if (!isTirType(field_t))
233
+ throw new Error("TirFromDataExpr: unreachable");
234
+ return _inlineFromData(field_t, _ir_apps(IRNative.headList, i === 0
235
+ ? new IRVar(fieldsListSym)
236
+ : _ir_apps(IRNative.dropList, IRConst.int(i), new IRVar(fieldsListSym))));
237
+ }));
238
+ });
239
+ return new IRCase(_ir_apps(IRNative.unConstrData, dataExprIR), [
240
+ new IRFunc([idxSym, fieldsListSym], new IRCase(new IRVar(idxSym), continuations))
241
+ ]);
207
242
  }
208
243
  // new cached hoisted helpers (mirroring TirToDataExpr pattern)
209
244
  const _mapListFromDataOfType = {};
@@ -4,6 +4,7 @@ import { IRConst } from "../../../IR/IRNodes/IRConst.js";
4
4
  import { IRFunc } from "../../../IR/IRNodes/IRFunc.js";
5
5
  import { IRNative } from "../../../IR/IRNodes/IRNative/index.js";
6
6
  import { TirDataStructType, TirSoPStructType } from "../types/TirStructType.js";
7
+ import { TirEnumType } from "../types/TirEnumType.js";
7
8
  import { getUnaliased } from "../types/utils/getUnaliased.js";
8
9
  export class TirIsExpr {
9
10
  instanceExpr;
@@ -34,8 +35,20 @@ export class TirIsExpr {
34
35
  }
35
36
  get isConstant() { return this.instanceExpr.isConstant; }
36
37
  toIR(ctx) {
37
- const structType = getUnaliased(this.instanceExpr.type);
38
+ const unaliased = getUnaliased(this.instanceExpr.type);
39
+ if (unaliased instanceof TirEnumType) {
40
+ // enums lower to a plain int; `is Member` is integer equality
41
+ return _ir_apps(IRNative.equalsInteger, IRConst.int(this.parentCtorIdx), this.instanceExpr.toIR(ctx));
42
+ }
43
+ const structType = unaliased;
38
44
  if (structType instanceof TirDataStructType) {
45
+ // untagged data structs have exactly one constructor; the
46
+ // runtime value carries no tag — `is Ctor` is statically true.
47
+ // We still evaluate `instanceExpr` to preserve any error it
48
+ // would produce (the redundancy is also flagged with a warning
49
+ // at AstCompiler time).
50
+ if (structType.untagged)
51
+ return _ir_apps(new IRFunc([Symbol("_unused_is_untagged")], IRConst.bool(true)), this.instanceExpr.toIR(ctx));
39
52
  // equalsInteger(parentCtorIdx, fstPair(unConstrData(<instance>)))
40
53
  return _ir_apps(IRNative.equalsInteger, IRConst.int(this.parentCtorIdx), _ir_apps(IRNative.fstPair, _ir_apps(IRNative.unConstrData, this.instanceExpr.toIR(ctx))));
41
54
  }
@@ -42,7 +42,6 @@ export declare class TirNativeFunc implements ITirExpr {
42
42
  static get verifyEd25519Signature(): TirNativeFunc;
43
43
  static strictIfThenElse(returnT: TirType): TirNativeFunc;
44
44
  static chooseUnit(returnT: TirType): TirNativeFunc;
45
- static strictChooseList(elemT: TirType, returnT: TirType): TirNativeFunc;
46
45
  static mkCons(elemT: TirType): TirNativeFunc;
47
46
  static headList(elemT: TirType): TirNativeFunc;
48
47
  static tailList(elemT: TirType): TirNativeFunc;
@@ -98,7 +97,7 @@ export declare class TirNativeFunc implements ITirExpr {
98
97
  static get countSetBits(): TirNativeFunc;
99
98
  static get findFirstSetBit(): TirNativeFunc;
100
99
  static get ripemd_160(): TirNativeFunc;
101
- static _dropList(elemT: TirType): TirNativeFunc;
100
+ static dropList(elemT: TirType): TirNativeFunc;
102
101
  static _foldr(elemT: TirType, returnT: TirType): TirNativeFunc;
103
102
  static _foldl(elemT: TirType, returnT: TirType): TirNativeFunc;
104
103
  static _findSopOptional(elems_t: TirType): TirNativeFunc;
@@ -229,16 +229,6 @@ export class TirNativeFunc {
229
229
  void_t
230
230
  ], returnT));
231
231
  }
232
- static strictChooseList(elemT, returnT) {
233
- return new TirNativeFunc(IRNativeTag.strictChooseList, new TirFuncT([
234
- // list
235
- new TirListT(elemT),
236
- // caseNil
237
- returnT,
238
- // caseCons
239
- returnT
240
- ], returnT));
241
- }
242
232
  // List operations with type parameters
243
233
  static mkCons(elemT) {
244
234
  return new TirNativeFunc(IRNativeTag.mkCons, new TirFuncT([
@@ -577,8 +567,8 @@ export class TirNativeFunc {
577
567
  ], bytes_t));
578
568
  }
579
569
  // Custom utility functions
580
- static _dropList(elemT) {
581
- return new TirNativeFunc(IRNativeTag._dropList, new TirFuncT([
570
+ static dropList(elemT) {
571
+ return new TirNativeFunc(IRNativeTag.dropList, new TirFuncT([
582
572
  // n
583
573
  int_t,
584
574
  // list
@@ -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)
@@ -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() {