@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.
- 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 +22 -2
- 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 +27 -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 +12 -0
- package/dist/IR/toUPLC/CompilerOptions.js +14 -9
- 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/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 +1 -0
- package/dist/compiler/AstCompiler/AstCompiler.js +41 -4
- package/dist/compiler/AstCompiler/internal/_deriveContractBody/_deriveContractBody.js +3 -3
- package/dist/compiler/AstCompiler/internal/exprs/_compileCallExpr.js +57 -10
- package/dist/compiler/AstCompiler/internal/exprs/_compileCaseExpr.js +31 -0
- package/dist/compiler/AstCompiler/internal/exprs/_compileIsExpr.js +12 -0
- package/dist/compiler/AstCompiler/internal/exprs/_compilePropAccessExpr.js +36 -0
- package/dist/compiler/AstCompiler/internal/exprs/_compileUnaryPrefixExpr.js +13 -1
- 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/utils/getPropAccessReturnType.js +11 -0
- package/dist/compiler/Compiler.js +20 -27
- 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 +23 -8
- 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/TirFromDataExpr.js +102 -67
- package/dist/compiler/tir/expressions/TirIsExpr.js +14 -1
- package/dist/compiler/tir/expressions/TirNativeFunc.d.ts +1 -2
- package/dist/compiler/tir/expressions/TirNativeFunc.js +2 -12
- package/dist/compiler/tir/expressions/TirToDataExpr.js +3 -0
- 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/stdScope/populateStdNamespace.js +49 -4
- package/dist/compiler/tir/program/stdScope/prelude/preludeTypesSrc.js +35 -2
- package/dist/compiler/tir/program/stdScope/stdScope.d.ts +7 -0
- package/dist/compiler/tir/program/stdScope/stdScope.js +83 -40
- 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 +4 -2
- package/dist/compiler/tir/types/TirNativeType/TirNativeType.js +5 -0
- 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 +4 -1
- package/dist/compiler/tir/types/utils/canAssignTo.js +28 -0
- 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.js +4 -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.js +5 -0
- package/dist/diagnostics/diagnosticMessages.generated.d.ts +5 -0
- package/dist/diagnostics/diagnosticMessages.generated.js +10 -0
- package/dist/parser/Parser.js +29 -13
- package/dist/tokenizer/Token.d.ts +8 -7
- package/dist/tokenizer/Token.js +8 -7
- package/dist/tokenizer/utils/tokenFromKeyword.js +2 -0
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/package.json +3 -3
- package/dist/IR/tree_utils/_ir_lazyChooseList.d.ts +0 -3
- package/dist/IR/tree_utils/_ir_lazyChooseList.js +0 -7
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import { _ir_apps
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|
-
|
|
175
|
-
//
|
|
176
|
-
|
|
177
|
-
//
|
|
178
|
-
|
|
179
|
-
//
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
581
|
-
return new TirNativeFunc(IRNativeTag.
|
|
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 {
|
|
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):
|
|
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 (!
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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() {
|