@harmoniclabs/pebble 0.1.4-dev1 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/IR/IRNodes/IRConst.js +6 -0
- package/dist/IR/IRNodes/IRNative/index.js +3 -2
- package/dist/IR/toUPLC/subRoutines/replaceNatives/nativeToIR.js +2 -2
- package/dist/compiler/AstCompiler/AstCompiler.js +2 -2
- package/dist/compiler/AstCompiler/internal/exprs/_compileElemAccessExpr.d.ts +2 -2
- package/dist/compiler/AstCompiler/internal/exprs/_compileElemAccessExpr.js +39 -3
- package/dist/compiler/AstCompiler/internal/statements/_compileVarStmt.js +15 -0
- package/dist/compiler/AstCompiler/utils/getPropAccessReturnType.js +25 -2
- package/dist/compiler/Compiler.js +2 -2
- package/dist/compiler/SourceTypeMap.d.ts +1 -0
- package/dist/compiler/SourceTypeMap.js +25 -0
- package/dist/compiler/TirCompiler/expressify/expressify.js +21 -1
- package/dist/compiler/TirCompiler/expressify/expressifyVars.js +38 -2
- package/dist/compiler/TirCompiler/expressify/toNamedDeconstructVarDecl.js +7 -0
- package/dist/compiler/path/getAbsolutePath.js +2 -1
- package/dist/compiler/tir/expressions/TirFromDataExpr.js +4 -0
- package/dist/compiler/tir/expressions/TirNativeFunc.d.ts +2 -0
- package/dist/compiler/tir/expressions/TirNativeFunc.js +9 -0
- package/dist/compiler/tir/program/stdScope/stdScope.d.ts +2 -0
- package/dist/compiler/tir/program/stdScope/stdScope.js +27 -1
- package/dist/compiler/tir/types/TirNativeType/TirNativeType.d.ts +2 -1
- package/dist/compiler/tir/types/TirNativeType/TirNativeType.js +2 -0
- package/dist/compiler/tir/types/TirNativeType/native/index.d.ts +1 -0
- package/dist/compiler/tir/types/TirNativeType/native/index.js +1 -0
- package/dist/compiler/tir/types/TirNativeType/native/linearMapEntry.d.ts +17 -0
- package/dist/compiler/tir/types/TirNativeType/native/linearMapEntry.js +44 -0
- package/dist/compiler/tir/types/utils/canAssignTo.js +7 -0
- package/dist/compiler/tir/types/utils/canCastTo.js +8 -0
- package/dist/compiler/tir/types/utils/getListTypeArg.d.ts +1 -0
- package/dist/compiler/tir/types/utils/getListTypeArg.js +8 -0
- package/dist/parser/Parser.js +24 -0
- package/dist/tokenizer/Tokenizer.js +2 -2
- package/package.json +2 -1
|
@@ -18,6 +18,7 @@ import { TirDataT } from "../../compiler/tir/types/TirNativeType/native/data.js"
|
|
|
18
18
|
import { TirFuncT } from "../../compiler/tir/types/TirNativeType/native/function.js";
|
|
19
19
|
import { TirIntT } from "../../compiler/tir/types/TirNativeType/native/int.js";
|
|
20
20
|
import { TirLinearMapT } from "../../compiler/tir/types/TirNativeType/native/linearMap.js";
|
|
21
|
+
import { TirLinearMapEntryT } from "../../compiler/tir/types/TirNativeType/native/linearMapEntry.js";
|
|
21
22
|
import { TirListT } from "../../compiler/tir/types/TirNativeType/native/list.js";
|
|
22
23
|
import { TirDataOptT } from "../../compiler/tir/types/TirNativeType/native/Optional/data.js";
|
|
23
24
|
import { TirSopOptT } from "../../compiler/tir/types/TirNativeType/native/Optional/sop.js";
|
|
@@ -166,6 +167,8 @@ function isValueAssignableToType(value, type) {
|
|
|
166
167
|
return (Array.isArray(value) &&
|
|
167
168
|
value.every(v => isValueAssignableToType(v, elemsT)));
|
|
168
169
|
}
|
|
170
|
+
if (type instanceof TirLinearMapEntryT)
|
|
171
|
+
return isIRConstPair(value);
|
|
169
172
|
const tsEnsureExsaustiveCheck = type;
|
|
170
173
|
return false;
|
|
171
174
|
}
|
|
@@ -216,6 +219,7 @@ function serializeIRConstValue(value, type) {
|
|
|
216
219
|
return dataToCbor(value);
|
|
217
220
|
if (type instanceof TirFuncT
|
|
218
221
|
|| type instanceof TirSopOptT
|
|
222
|
+
|| type instanceof TirLinearMapEntryT
|
|
219
223
|
|| type instanceof TirSoPStructType
|
|
220
224
|
|| type instanceof TirTypeParam)
|
|
221
225
|
throw new Error("invalid uplc const type");
|
|
@@ -270,6 +274,8 @@ export function tirTypeToUplcType(t) {
|
|
|
270
274
|
return constT.listOf(constT.pairOf(constT.data, constT.data));
|
|
271
275
|
if (t instanceof TirUnConstrDataResultT)
|
|
272
276
|
return constT.pairOf(constT.int, constT.listOf(constT.data));
|
|
277
|
+
if (t instanceof TirLinearMapEntryT)
|
|
278
|
+
return constT.pairOf(constT.data, constT.data);
|
|
273
279
|
if (t instanceof TirAliasType
|
|
274
280
|
|| t instanceof TirFuncT
|
|
275
281
|
|| t instanceof TirSopOptT
|
|
@@ -14,6 +14,7 @@ import { TirBytesT } from "../../../compiler/tir/types/TirNativeType/native/byte
|
|
|
14
14
|
import { TirDataT } from "../../../compiler/tir/types/TirNativeType/native/data.js";
|
|
15
15
|
import { TirIntT } from "../../../compiler/tir/types/TirNativeType/native/int.js";
|
|
16
16
|
import { TirLinearMapT } from "../../../compiler/tir/types/TirNativeType/native/linearMap.js";
|
|
17
|
+
import { TirLinearMapEntryT } from "../../../compiler/tir/types/TirNativeType/native/linearMapEntry.js";
|
|
17
18
|
import { TirListT } from "../../../compiler/tir/types/TirNativeType/native/list.js";
|
|
18
19
|
import { TirDataOptT } from "../../../compiler/tir/types/TirNativeType/native/Optional/data.js";
|
|
19
20
|
import { TirStringT } from "../../../compiler/tir/types/TirNativeType/native/string.js";
|
|
@@ -242,8 +243,8 @@ export class IRNative {
|
|
|
242
243
|
return IRNative.equalListOf(getListTypeArg(type));
|
|
243
244
|
if (type instanceof TirLinearMapT)
|
|
244
245
|
return IRNative.equalListOf(new TirPairDataT());
|
|
245
|
-
if (type instanceof
|
|
246
|
-
return IRNative.
|
|
246
|
+
if (type instanceof TirLinearMapEntryT)
|
|
247
|
+
return IRNative._equalPairData;
|
|
247
248
|
if (type instanceof TirUnConstrDataResultT)
|
|
248
249
|
return getEqUnConstr();
|
|
249
250
|
if (type instanceof TirVoidT)
|
|
@@ -351,12 +351,12 @@ new IRDelayed(IRConst.int(0)),
|
|
|
351
351
|
// token map cons
|
|
352
352
|
new IRDelayed(_ir_let(_ir_apps(IRNative.headList, new IRVar(amount_tokenMap)), pairDataTokenSym => new IRForced(_ir_apps(IRNative.strictIfThenElse,
|
|
353
353
|
// isTokenName( fst pairDataToken as bytes )
|
|
354
|
-
_ir_apps(new IRVar(amount_isTokenName), _ir_apps(IRNative.unBData, _ir_apps(IRNative.fstPair, new IRVar(pairDataTokenSym))),
|
|
354
|
+
_ir_apps(new IRVar(amount_isTokenName), _ir_apps(IRNative.unBData, _ir_apps(IRNative.fstPair, new IRVar(pairDataTokenSym)))),
|
|
355
355
|
// then: return amount
|
|
356
356
|
new IRDelayed(_ir_apps(IRNative.unIData, _ir_apps(IRNative.sndPair, new IRVar(pairDataTokenSym)))),
|
|
357
357
|
// else: recurse tail
|
|
358
358
|
new IRDelayed(_ir_apps(new IRSelfCall(amount_tokenNameLoop), _ir_apps(IRNative.tailList, new IRVar(amount_tokenMap) // tokenMap list
|
|
359
|
-
)))))))))))
|
|
359
|
+
))))))))))),
|
|
360
360
|
// pass token map (snd pairData)
|
|
361
361
|
_ir_apps(IRNative.unMapData, _ir_apps(IRNative.sndPair, new IRVar(pairDataSym)))))),
|
|
362
362
|
// else: recurse policyLoop on tail value list
|
|
@@ -231,8 +231,8 @@ export class AstCompiler extends DiagnosticEmitter {
|
|
|
231
231
|
console.log( msg.toString() );
|
|
232
232
|
//*/
|
|
233
233
|
}
|
|
234
|
-
|
|
235
|
-
throw new Error("AstCompiler.compile: failed with " + nDiags + " diagnostic messages; first message: " + fstErrorMsg);
|
|
234
|
+
return this.program;
|
|
235
|
+
// throw new Error("AstCompiler.compile: failed with " + nDiags + " diagnostic messages; first message: " + fstErrorMsg );
|
|
236
236
|
}
|
|
237
237
|
const mainFuncExpr = this.program.functions.get(this.program.contractTirFuncName);
|
|
238
238
|
if (this.program.contractTirFuncName === "" || !mainFuncExpr) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ElemAccessExpr } from "../../../../ast/nodes/expr/ElemAccessExpr.js";
|
|
2
|
-
import {
|
|
2
|
+
import { TirExpr } from "../../../tir/expressions/TirExpr.js";
|
|
3
3
|
import { TirType } from "../../../tir/types/TirType.js";
|
|
4
4
|
import { AstCompilationCtx } from "../../AstCompilationCtx.js";
|
|
5
|
-
export declare function _compileElemAccessExpr(ctx: AstCompilationCtx, expr: ElemAccessExpr, typeHint: TirType | undefined):
|
|
5
|
+
export declare function _compileElemAccessExpr(ctx: AstCompilationCtx, expr: ElemAccessExpr, typeHint: TirType | undefined): TirExpr | undefined;
|
|
@@ -1,16 +1,52 @@
|
|
|
1
1
|
import { DiagnosticCode } from "../../../../diagnostics/diagnosticMessages.generated.js";
|
|
2
|
+
import { TirCallExpr } from "../../../tir/expressions/TirCallExpr.js";
|
|
3
|
+
import { TirCaseExpr, TirCaseMatcher } from "../../../tir/expressions/TirCaseExpr.js";
|
|
2
4
|
import { TirElemAccessExpr } from "../../../tir/expressions/TirElemAccessExpr.js";
|
|
5
|
+
import { TirFailExpr } from "../../../tir/expressions/TirFailExpr.js";
|
|
6
|
+
import { TirNativeFunc } from "../../../tir/expressions/TirNativeFunc.js";
|
|
7
|
+
import { TirToDataExpr } from "../../../tir/expressions/TirToDataExpr.js";
|
|
8
|
+
import { TirVariableAccessExpr } from "../../../tir/expressions/TirVariableAccessExpr.js";
|
|
9
|
+
import { TirNamedDeconstructVarDecl } from "../../../tir/statements/TirVarDecl/TirNamedDeconstructVarDecl.js";
|
|
10
|
+
import { TirSimpleVarDecl } from "../../../tir/statements/TirVarDecl/TirSimpleVarDecl.js";
|
|
3
11
|
import { TirListT } from "../../../tir/types/TirNativeType/native/list.js";
|
|
12
|
+
import { TirSopOptT } from "../../../tir/types/TirNativeType/native/Optional/sop.js";
|
|
4
13
|
import { canAssignTo } from "../../../tir/types/utils/canAssignTo.js";
|
|
14
|
+
import { getLinearMapTypeArgs } from "../../../tir/types/utils/getListTypeArg.js";
|
|
5
15
|
import { getListTypeArg } from "../../../tir/types/utils/getListTypeArg.js";
|
|
16
|
+
import { getUnaliased } from "../../../tir/types/utils/getUnaliased.js";
|
|
6
17
|
import { _compileExpr } from "./_compileExpr.js";
|
|
7
18
|
export function _compileElemAccessExpr(ctx, expr, typeHint) {
|
|
8
19
|
const int_t = ctx.program.stdTypes.int;
|
|
9
|
-
const
|
|
10
|
-
const arrLikeExpr = _compileExpr(ctx, expr.arrLikeExpr, litsTypeHint);
|
|
20
|
+
const arrLikeExpr = _compileExpr(ctx, expr.arrLikeExpr, undefined);
|
|
11
21
|
if (!arrLikeExpr)
|
|
12
22
|
return undefined;
|
|
13
|
-
const arrLikeType = arrLikeExpr.type;
|
|
23
|
+
const arrLikeType = getUnaliased(arrLikeExpr.type);
|
|
24
|
+
// LinearMap<K,V>: map[key] desugars to map.lookup(key)!
|
|
25
|
+
const mapTypeArgs = getLinearMapTypeArgs(arrLikeType);
|
|
26
|
+
if (mapTypeArgs) {
|
|
27
|
+
const [kT, vT] = mapTypeArgs;
|
|
28
|
+
const indexExpr = _compileExpr(ctx, expr.indexExpr, kT);
|
|
29
|
+
if (!indexExpr)
|
|
30
|
+
return undefined;
|
|
31
|
+
if (!canAssignTo(indexExpr.type, kT))
|
|
32
|
+
return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.indexExpr.range, indexExpr.type.toString(), kT.toString());
|
|
33
|
+
const optType = new TirSopOptT(vT);
|
|
34
|
+
// _lookupLinearMap expects data-encoded key
|
|
35
|
+
const keyAsData = new TirToDataExpr(indexExpr, expr.indexExpr.range);
|
|
36
|
+
const lookupCall = new TirCallExpr(TirNativeFunc._lookupLinearMap(kT, vT), [keyAsData, arrLikeExpr], optType, expr.range);
|
|
37
|
+
// unwrap: case lookup is Some{ value } => value, None => fail
|
|
38
|
+
return new TirCaseExpr(lookupCall, [
|
|
39
|
+
new TirCaseMatcher(new TirNamedDeconstructVarDecl("Some", new Map([
|
|
40
|
+
["value", new TirSimpleVarDecl("value", vT, undefined, true, expr.range)]
|
|
41
|
+
]), undefined, optType, undefined, true, expr.range), new TirVariableAccessExpr({
|
|
42
|
+
variableInfos: { name: "value", type: vT, isConstant: true },
|
|
43
|
+
isDefinedOutsideFuncScope: false,
|
|
44
|
+
}, expr.range), expr.range),
|
|
45
|
+
new TirCaseMatcher(new TirNamedDeconstructVarDecl("None", new Map(), undefined, optType, undefined, true, expr.range), new TirFailExpr(undefined, vT, expr.range), expr.range)
|
|
46
|
+
], undefined, vT, expr.range);
|
|
47
|
+
}
|
|
48
|
+
// List<T>: list[index]
|
|
49
|
+
const litsTypeHint = typeHint ? new TirListT(typeHint) : undefined;
|
|
14
50
|
const elemsType = getListTypeArg(arrLikeType);
|
|
15
51
|
if (!elemsType)
|
|
16
52
|
return ctx.error(DiagnosticCode.This_expression_cannot_be_indexed, expr.arrLikeExpr.range);
|
|
@@ -9,10 +9,12 @@ import { TirSimpleVarDecl } from "../../../tir/statements/TirVarDecl/TirSimpleVa
|
|
|
9
9
|
import { TirSingleDeconstructVarDecl } from "../../../tir/statements/TirVarDecl/TirSingleDeconstructVarDecl.js";
|
|
10
10
|
import { TirDataT } from "../../../tir/types/TirNativeType/native/data.js";
|
|
11
11
|
import { isTirOptType } from "../../../tir/types/TirNativeType/native/Optional/isTirOptType.js";
|
|
12
|
+
import { TirLinearMapEntryT } from "../../../tir/types/TirNativeType/native/linearMapEntry.js";
|
|
12
13
|
import { isTirStructType, TirStructConstr, TirStructField } from "../../../tir/types/TirStructType.js";
|
|
13
14
|
import { getNamedDestructableType, getStructType, canAssignTo } from "../../../tir/types/utils/canAssignTo.js";
|
|
14
15
|
import { canCastToData } from "../../../tir/types/utils/canCastTo.js";
|
|
15
16
|
import { getListTypeArg } from "../../../tir/types/utils/getListTypeArg.js";
|
|
17
|
+
import { getUnaliased } from "../../../tir/types/utils/getUnaliased.js";
|
|
16
18
|
import { _compileExpr } from "../exprs/_compileExpr.js";
|
|
17
19
|
import { _compileSopEncodedConcreteType } from "../types/_compileSopEncodedConcreteType.js";
|
|
18
20
|
export function _compileVarStmt(ctx, stmt) {
|
|
@@ -105,6 +107,19 @@ export function _compileSingleDeconstructVarDecl(ctx, decl, typeHint) {
|
|
|
105
107
|
if (!typeAndExpr)
|
|
106
108
|
return undefined;
|
|
107
109
|
const [finalVarType, initExpr, typeAnnotationRange] = typeAndExpr;
|
|
110
|
+
// LinearMapEntry<K,V> can be destructured as { key, value }
|
|
111
|
+
const unaliasedVarType = getUnaliased(finalVarType);
|
|
112
|
+
if (unaliasedVarType instanceof TirLinearMapEntryT) {
|
|
113
|
+
const virtualConstr = new TirStructConstr("Entry", [
|
|
114
|
+
new TirStructField("key", unaliasedVarType.keyTypeArg),
|
|
115
|
+
new TirStructField("value", unaliasedVarType.valTypeArg),
|
|
116
|
+
]);
|
|
117
|
+
const deconstructedFields = _getDeconstructedFields(ctx, decl, virtualConstr);
|
|
118
|
+
if (!deconstructedFields)
|
|
119
|
+
return undefined;
|
|
120
|
+
const [fields, rest, fieldLabelRanges] = deconstructedFields;
|
|
121
|
+
return new TirSingleDeconstructVarDecl(fields, rest, finalVarType, initExpr, decl.isConst(), decl.range, fieldLabelRanges, typeAnnotationRange);
|
|
122
|
+
}
|
|
108
123
|
const finalStructType = getStructType(finalVarType);
|
|
109
124
|
if (!finalStructType)
|
|
110
125
|
return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, decl.range, finalVarType.toString(), "Struct");
|
|
@@ -9,6 +9,7 @@ import { TirDataT } from "../../tir/types/TirNativeType/native/data.js";
|
|
|
9
9
|
import { TirFuncT } from "../../tir/types/TirNativeType/native/function.js";
|
|
10
10
|
import { TirIntT } from "../../tir/types/TirNativeType/native/int.js";
|
|
11
11
|
import { TirLinearMapT } from "../../tir/types/TirNativeType/native/linearMap.js";
|
|
12
|
+
import { TirLinearMapEntryT } from "../../tir/types/TirNativeType/native/linearMapEntry.js";
|
|
12
13
|
import { TirListT } from "../../tir/types/TirNativeType/native/list.js";
|
|
13
14
|
import { isTirOptType } from "../../tir/types/TirNativeType/native/Optional/isTirOptType.js";
|
|
14
15
|
import { TirSopOptT } from "../../tir/types/TirNativeType/native/Optional/sop.js";
|
|
@@ -46,6 +47,13 @@ export function getPropAccessReturnType(ctx, objType, propId) {
|
|
|
46
47
|
return undefined;
|
|
47
48
|
if (objType instanceof TirListT)
|
|
48
49
|
return getListMethods(objType.typeArg)[propName];
|
|
50
|
+
if (objType instanceof TirLinearMapEntryT) {
|
|
51
|
+
if (propName === "key")
|
|
52
|
+
return objType.keyTypeArg;
|
|
53
|
+
if (propName === "value")
|
|
54
|
+
return objType.valTypeArg;
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
49
57
|
if (objType instanceof TirLinearMapT)
|
|
50
58
|
return getLinearMapMethods(objType.keyTypeArg, objType.valTypeArg)[propName];
|
|
51
59
|
if (objType instanceof TirUnConstrDataResultT)
|
|
@@ -85,9 +93,24 @@ function getListMethods(elemsType) {
|
|
|
85
93
|
};
|
|
86
94
|
}
|
|
87
95
|
function getLinearMapMethods(kT, vT) {
|
|
96
|
+
const entryType = new TirLinearMapEntryT(kT, vT);
|
|
97
|
+
const mapType = new TirLinearMapT(kT, vT);
|
|
98
|
+
const mapReturnT = new TirTypeParam("T");
|
|
88
99
|
return {
|
|
89
|
-
|
|
90
|
-
|
|
100
|
+
length: new TirFuncT([], int_t),
|
|
101
|
+
isEmpty: new TirFuncT([], bool_t),
|
|
102
|
+
show: new TirFuncT([], bytes_t),
|
|
103
|
+
head: new TirFuncT([], entryType),
|
|
104
|
+
tail: new TirFuncT([], mapType),
|
|
105
|
+
reverse: new TirFuncT([], mapType),
|
|
106
|
+
find: new TirFuncT([new TirFuncT([entryType], bool_t)], new TirSopOptT(entryType)),
|
|
107
|
+
filter: new TirFuncT([new TirFuncT([entryType], bool_t)], mapType),
|
|
108
|
+
prepend: new TirFuncT([kT, vT], mapType),
|
|
109
|
+
map: new TirFuncT([new TirFuncT([entryType], mapReturnT)], new TirListT(mapReturnT)),
|
|
110
|
+
every: new TirFuncT([new TirFuncT([entryType], bool_t)], bool_t),
|
|
111
|
+
some: new TirFuncT([new TirFuncT([entryType], bool_t)], bool_t),
|
|
112
|
+
includes: new TirFuncT([entryType], bool_t),
|
|
113
|
+
lookup: new TirFuncT([kT], new TirSopOptT(vT)),
|
|
91
114
|
};
|
|
92
115
|
}
|
|
93
116
|
const bytesMethods = Object.freeze({
|
|
@@ -42,7 +42,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
|
42
42
|
const program = await astCompiler.compile();
|
|
43
43
|
if (this.diagnostics.length > 0) {
|
|
44
44
|
let msg;
|
|
45
|
-
globalThis.console && console.log(this.diagnostics);
|
|
45
|
+
// globalThis.console && console.log( this.diagnostics );
|
|
46
46
|
const fstErrorMsg = this.diagnostics[0].toString();
|
|
47
47
|
const nDiags = this.diagnostics.length;
|
|
48
48
|
for (msg of this.diagnostics) {
|
|
@@ -73,7 +73,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
|
73
73
|
while (msg = this.diagnostics.shift()) {
|
|
74
74
|
this.io.stdout.write(msg.toString() + "\n");
|
|
75
75
|
}
|
|
76
|
-
throw new Error("compilation failed with " + nDiags + " diagnostic messages; first message: " + fstErrorMsg);
|
|
76
|
+
// throw new Error("compilation failed with " + nDiags + " diagnostic messages; first message: " + fstErrorMsg );
|
|
77
77
|
}
|
|
78
78
|
return this._compileBackend(cfg, program);
|
|
79
79
|
}
|
|
@@ -4,6 +4,7 @@ import { isTirStructType } from "./tir/types/TirStructType.js";
|
|
|
4
4
|
import { TirFuncT } from "./tir/types/TirNativeType/native/function.js";
|
|
5
5
|
import { TirListT } from "./tir/types/TirNativeType/native/list.js";
|
|
6
6
|
import { TirLinearMapT } from "./tir/types/TirNativeType/native/linearMap.js";
|
|
7
|
+
import { TirLinearMapEntryT } from "./tir/types/TirNativeType/native/linearMapEntry.js";
|
|
7
8
|
import { TirBytesT } from "./tir/types/TirNativeType/native/bytes.js";
|
|
8
9
|
import { TirStringT } from "./tir/types/TirNativeType/native/string.js";
|
|
9
10
|
import { TirBoolT } from "./tir/types/TirNativeType/native/bool.js";
|
|
@@ -130,6 +131,8 @@ export class SourceTypeMap {
|
|
|
130
131
|
return [];
|
|
131
132
|
if (type instanceof TirListT)
|
|
132
133
|
return this.listMembers(type.typeArg);
|
|
134
|
+
if (type instanceof TirLinearMapEntryT)
|
|
135
|
+
return this.linearMapEntryMembers(type);
|
|
133
136
|
if (type instanceof TirLinearMapT)
|
|
134
137
|
return this.linearMapMembers(type.keyTypeArg, type.valTypeArg);
|
|
135
138
|
return [];
|
|
@@ -207,8 +210,30 @@ export class SourceTypeMap {
|
|
|
207
210
|
{ name: "encodeUtf8", type: new TirFuncT([], bytes_t), kind: "method" },
|
|
208
211
|
];
|
|
209
212
|
}
|
|
213
|
+
linearMapEntryMembers(type) {
|
|
214
|
+
return [
|
|
215
|
+
{ name: "key", type: type.keyTypeArg, kind: "field" },
|
|
216
|
+
{ name: "value", type: type.valTypeArg, kind: "field" },
|
|
217
|
+
];
|
|
218
|
+
}
|
|
210
219
|
linearMapMembers(kT, vT) {
|
|
220
|
+
const entryType = new TirLinearMapEntryT(kT, vT);
|
|
221
|
+
const mapType = new TirLinearMapT(kT, vT);
|
|
222
|
+
const mapReturnT = new TirTypeParam("T");
|
|
211
223
|
return [
|
|
224
|
+
{ name: "length", type: new TirFuncT([], int_t), kind: "method" },
|
|
225
|
+
{ name: "isEmpty", type: new TirFuncT([], bool_t), kind: "method" },
|
|
226
|
+
{ name: "show", type: new TirFuncT([], bytes_t), kind: "method" },
|
|
227
|
+
{ name: "head", type: new TirFuncT([], entryType), kind: "method" },
|
|
228
|
+
{ name: "tail", type: new TirFuncT([], mapType), kind: "method" },
|
|
229
|
+
{ name: "reverse", type: new TirFuncT([], mapType), kind: "method" },
|
|
230
|
+
{ name: "find", type: new TirFuncT([new TirFuncT([entryType], bool_t)], new TirSopOptT(entryType)), kind: "method" },
|
|
231
|
+
{ name: "filter", type: new TirFuncT([new TirFuncT([entryType], bool_t)], mapType), kind: "method" },
|
|
232
|
+
{ name: "prepend", type: new TirFuncT([kT, vT], mapType), kind: "method" },
|
|
233
|
+
{ name: "map", type: new TirFuncT([new TirFuncT([entryType], mapReturnT)], new TirListT(mapReturnT)), kind: "method" },
|
|
234
|
+
{ name: "every", type: new TirFuncT([new TirFuncT([entryType], bool_t)], bool_t), kind: "method" },
|
|
235
|
+
{ name: "some", type: new TirFuncT([new TirFuncT([entryType], bool_t)], bool_t), kind: "method" },
|
|
236
|
+
{ name: "includes", type: new TirFuncT([entryType], bool_t), kind: "method" },
|
|
212
237
|
{ name: "lookup", type: new TirFuncT([kT], new TirSopOptT(vT)), kind: "method" },
|
|
213
238
|
];
|
|
214
239
|
}
|
|
@@ -23,7 +23,11 @@ import { TirNamedDeconstructVarDecl } from "../../tir/statements/TirVarDecl/TirN
|
|
|
23
23
|
import { TirSimpleVarDecl } from "../../tir/statements/TirVarDecl/TirSimpleVarDecl.js";
|
|
24
24
|
import { TirSingleDeconstructVarDecl } from "../../tir/statements/TirVarDecl/TirSingleDeconstructVarDecl.js";
|
|
25
25
|
import { TirWhileStmt } from "../../tir/statements/TirWhileStmt.js";
|
|
26
|
+
import { TirFromDataExpr } from "../../tir/expressions/TirFromDataExpr.js";
|
|
27
|
+
import { data_t } from "../../tir/program/stdScope/stdScope.js";
|
|
28
|
+
import { TirLinearMapEntryT } from "../../tir/types/TirNativeType/native/linearMapEntry.js";
|
|
26
29
|
import { TirDataStructType, TirSoPStructType } from "../../tir/types/TirStructType.js";
|
|
30
|
+
import { getUnaliased } from "../../tir/types/utils/getUnaliased.js";
|
|
27
31
|
import { ExpressifyCtx } from "./ExpressifyCtx.js";
|
|
28
32
|
import { expressifyVarAssignmentStmt } from "./expressifyVarAssignmentStmt.js";
|
|
29
33
|
import { isSingleConstrStruct } from "./isSingleConstrStruct.js";
|
|
@@ -130,7 +134,23 @@ loopReplacements, assertions = []) {
|
|
|
130
134
|
stmt.initExpr = initExpr;
|
|
131
135
|
const lettedName = getUniqueInternalName(stmt.type.toString().toLowerCase());
|
|
132
136
|
const lettedExpr = ctx.introduceLettedConstant(lettedName, initExpr, stmt.range);
|
|
133
|
-
|
|
137
|
+
const stmtUnaliasedType = getUnaliased(stmt.type);
|
|
138
|
+
if (stmtUnaliasedType instanceof TirLinearMapEntryT) {
|
|
139
|
+
// LinearMapEntry<K,V> is Pair<Data,Data> at runtime
|
|
140
|
+
// extract fields via fstPair/sndPair + _inlineFromData
|
|
141
|
+
for (const [fieldName, varDecl] of stmt.fields) {
|
|
142
|
+
if (!(varDecl instanceof TirSimpleVarDecl))
|
|
143
|
+
throw new Error("expected simple var decl in entry deconstruction");
|
|
144
|
+
const isKey = fieldName === "key";
|
|
145
|
+
const fieldType = isKey ? stmtUnaliasedType.keyTypeArg : stmtUnaliasedType.valTypeArg;
|
|
146
|
+
const pairAccessor = isKey ? TirNativeFunc.fstPairData : TirNativeFunc.sndPairData;
|
|
147
|
+
const fieldLettedName = getUniqueInternalName(`${lettedExpr.varName}_${fieldName}`);
|
|
148
|
+
const lettedField = ctx.introduceLettedConstant(fieldLettedName, expressifyVars(ctx, new TirFromDataExpr(new TirCallExpr(pairAccessor, [lettedExpr], data_t, stmt.range), fieldType, stmt.range)), stmt.range);
|
|
149
|
+
ctx.setNewVariableName(varDecl.name, lettedField.varName);
|
|
150
|
+
}
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
else if (stmtUnaliasedType instanceof TirSoPStructType) {
|
|
134
154
|
const nestedDeconstructs = flattenSopNamedDeconstructInplace_addTopDestructToCtx_getNestedDeconstruct(stmt, ctx);
|
|
135
155
|
// nested single constr structs
|
|
136
156
|
// are added as destructed variables in the matcher body
|
|
@@ -36,7 +36,8 @@ import { TirUnaryMinus } from "../../tir/expressions/unary/TirUnaryMinus.js";
|
|
|
36
36
|
import { TirUnaryPlus } from "../../tir/expressions/unary/TirUnaryPlus.js";
|
|
37
37
|
import { isTirUnaryPrefixExpr } from "../../tir/expressions/unary/TirUnaryPrefixExpr.js";
|
|
38
38
|
import { TirUnaryTilde } from "../../tir/expressions/unary/TirUnaryTilde.js";
|
|
39
|
-
import { bool_t } from "../../tir/program/stdScope/stdScope.js";
|
|
39
|
+
import { bool_t, bytes_t, data_t, int_t, valueAmountOfName } from "../../tir/program/stdScope/stdScope.js";
|
|
40
|
+
import { IRNativeTag } from "../../../IR/IRNodes/IRNative/IRNativeTag.js";
|
|
40
41
|
import { TirReturnStmt } from "../../tir/statements/TirReturnStmt.js";
|
|
41
42
|
import { TirArrayLikeDeconstr } from "../../tir/statements/TirVarDecl/TirArrayLikeDeconstr.js";
|
|
42
43
|
import { TirNamedDeconstructVarDecl } from "../../tir/statements/TirVarDecl/TirNamedDeconstructVarDecl.js";
|
|
@@ -44,6 +45,7 @@ import { TirSimpleVarDecl } from "../../tir/statements/TirVarDecl/TirSimpleVarDe
|
|
|
44
45
|
import { TirAliasType } from "../../tir/types/TirAliasType.js";
|
|
45
46
|
import { TirFuncT, TirListT, TirPairDataT } from "../../tir/types/TirNativeType/index.js";
|
|
46
47
|
import { TirLinearMapT } from "../../tir/types/TirNativeType/native/linearMap.js";
|
|
48
|
+
import { TirLinearMapEntryT } from "../../tir/types/TirNativeType/native/linearMapEntry.js";
|
|
47
49
|
import { TirDataStructType, TirSoPStructType } from "../../tir/types/TirStructType.js";
|
|
48
50
|
import { getListTypeArg } from "../../tir/types/utils/getListTypeArg.js";
|
|
49
51
|
import { getUnaliased } from "../../tir/types/utils/getUnaliased.js";
|
|
@@ -330,6 +332,18 @@ function expressifyPropAccess(ctx, propAccessExpr) {
|
|
|
330
332
|
// we extract the property inplace below (outside this block)
|
|
331
333
|
}
|
|
332
334
|
const objType = getUnaliased(expr.type);
|
|
335
|
+
if (objType instanceof TirLinearMapEntryT) {
|
|
336
|
+
// LinearMapEntry<K,V> is Pair<Data,Data> at runtime
|
|
337
|
+
// .key => fstPair(expr) then decode from data to K
|
|
338
|
+
// .value => sndPair(expr) then decode from data to V
|
|
339
|
+
if (prop === "key") {
|
|
340
|
+
return new TirFromDataExpr(new TirCallExpr(TirNativeFunc.fstPairData, [expr], data_t, propAccessExpr.range), objType.keyTypeArg, propAccessExpr.range);
|
|
341
|
+
}
|
|
342
|
+
if (prop === "value") {
|
|
343
|
+
return new TirFromDataExpr(new TirCallExpr(TirNativeFunc.sndPairData, [expr], data_t, propAccessExpr.range), objType.valTypeArg, propAccessExpr.range);
|
|
344
|
+
}
|
|
345
|
+
throw new Error(`Property '${prop}' does not exist on LinearMapEntry`);
|
|
346
|
+
}
|
|
333
347
|
if (!isSingleConstrStruct(objType)) {
|
|
334
348
|
// IMPORTANT: we only care about fields here
|
|
335
349
|
// any methods should have already been converted to functions
|
|
@@ -378,10 +392,23 @@ function expressifyMethodCall(ctx, methodCall) {
|
|
|
378
392
|
objectType = objectType.aliased;
|
|
379
393
|
continue;
|
|
380
394
|
}
|
|
395
|
+
const callRange = SourceRange.join(methodIdentifierProp.range, methodCall.range.atEnd());
|
|
396
|
+
// fast-path: `Value.amountOf(policy, name)` compiles directly to
|
|
397
|
+
// `_amountOfValue(eqByteString(policy))(value)(eqByteString(name))`
|
|
398
|
+
// skipping the wrapper function indirection.
|
|
399
|
+
if (tirMethodName === valueAmountOfName
|
|
400
|
+
&& methodCall.args.length === 2) {
|
|
401
|
+
const [policyArg, nameArg] = methodCall.args;
|
|
402
|
+
const bytesToBoolT = new TirFuncT([bytes_t], bool_t);
|
|
403
|
+
const isPolicy = new TirLettedExpr("value_amountOf_isPolicy", new TirCallExpr(TirNativeFunc.equalsByteString, [policyArg], bytesToBoolT, policyArg.range), policyArg.range);
|
|
404
|
+
const isTokenName = new TirLettedExpr("value_amountOf_isTokenName", new TirCallExpr(TirNativeFunc.equalsByteString, [nameArg], bytesToBoolT, nameArg.range), nameArg.range);
|
|
405
|
+
const amountOfValueNative = new TirNativeFunc(IRNativeTag._amountOfValue, new TirFuncT([bytesToBoolT, objectExpr.type, bytesToBoolT], int_t));
|
|
406
|
+
return new TirCallExpr(amountOfValueNative, [isPolicy, objectExpr, isTokenName], int_t, callRange);
|
|
407
|
+
}
|
|
381
408
|
const funcExpr = ctx.program.functions.get(tirMethodName);
|
|
382
409
|
if (!funcExpr)
|
|
383
410
|
throw new Error(`Definition of method '${methodName}' on type '${objectType.toString()}' is missing.`);
|
|
384
|
-
return new TirCallExpr(funcExpr, [objectExpr, ...methodCall.args], methodCall.type,
|
|
411
|
+
return new TirCallExpr(funcExpr, [objectExpr, ...methodCall.args], methodCall.type, callRange);
|
|
385
412
|
}
|
|
386
413
|
if (objectType instanceof TirDataStructType
|
|
387
414
|
|| objectType instanceof TirSoPStructType) {
|
|
@@ -429,6 +456,15 @@ function expressifyMethodCall(ctx, methodCall) {
|
|
|
429
456
|
throw new Error(`Method 'lookup' of type 'LinearMap' takes 1 argument, ${methodCall.args.length} provided`);
|
|
430
457
|
return new TirCallExpr(TirNativeFunc._lookupLinearMap(objectType.keyTypeArg, objectType.valTypeArg), [methodCall.args[0], objectExpr], methodCall.type, exprRange);
|
|
431
458
|
}
|
|
459
|
+
if (methodName === "prepend") {
|
|
460
|
+
if (methodCall.args.length !== 2)
|
|
461
|
+
throw new Error(`Method 'prepend' of type 'LinearMap' takes 2 arguments (key, value), ${methodCall.args.length} provided`);
|
|
462
|
+
// encode key and value to data, construct a Pair<Data,Data>, then mkCons
|
|
463
|
+
const keyToData = new TirToDataExpr(methodCall.args[0], methodCall.args[0].range);
|
|
464
|
+
const valToData = new TirToDataExpr(methodCall.args[1], methodCall.args[1].range);
|
|
465
|
+
const mkPair = new TirCallExpr(new TirNativeFunc(IRNativeTag.mkPairData, new TirFuncT([data_t, data_t], new TirPairDataT())), [keyToData, valToData], new TirPairDataT(), exprRange);
|
|
466
|
+
return new TirCallExpr(TirNativeFunc.mkCons(new TirPairDataT()), [mkPair, objectExpr], methodCall.type, exprRange);
|
|
467
|
+
}
|
|
432
468
|
// LinearMap is List<PairData> at UPLC level; delegate list methods
|
|
433
469
|
const listType = new TirListT(new TirPairDataT());
|
|
434
470
|
const result = expressifyListMethodCall(ctx, objectExpr, methodCall, methodName, listType, exprRange);
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { TirNamedDeconstructVarDecl } from "../../tir/statements/TirVarDecl/TirNamedDeconstructVarDecl.js";
|
|
2
2
|
import { TirSingleDeconstructVarDecl } from "../../tir/statements/TirVarDecl/TirSingleDeconstructVarDecl.js";
|
|
3
|
+
import { TirLinearMapEntryT } from "../../tir/types/TirNativeType/native/linearMapEntry.js";
|
|
4
|
+
import { getUnaliased } from "../../tir/types/utils/getUnaliased.js";
|
|
3
5
|
import { isSingleConstrStruct } from "./isSingleConstrStruct.js";
|
|
4
6
|
export function toNamedDeconstructVarDecl(varDecl) {
|
|
5
7
|
if (varDecl instanceof TirNamedDeconstructVarDecl)
|
|
6
8
|
return varDecl;
|
|
7
9
|
if (varDecl instanceof TirSingleDeconstructVarDecl) {
|
|
8
10
|
const declType = varDecl.type;
|
|
11
|
+
// LinearMapEntry<K,V> uses virtual "Entry" constructor name
|
|
12
|
+
const unaliased = getUnaliased(declType);
|
|
13
|
+
if (unaliased instanceof TirLinearMapEntryT) {
|
|
14
|
+
return new TirNamedDeconstructVarDecl("Entry", varDecl.fields, varDecl.rest, varDecl.type, varDecl.initExpr, varDecl.isConst, varDecl.range);
|
|
15
|
+
}
|
|
9
16
|
if (!isSingleConstrStruct(declType))
|
|
10
17
|
throw new Error("expected single constr struct type in single deconstruct var decl");
|
|
11
18
|
const singleConstrName = declType.constructors[0].name;
|
|
@@ -52,7 +52,8 @@ function addExtension(path, endsWithSlash) {
|
|
|
52
52
|
return path + extension;
|
|
53
53
|
}
|
|
54
54
|
export function isAbsolutePath(path) {
|
|
55
|
-
|
|
55
|
+
// Support both Unix (/) and Windows (C:/, D:/) absolute paths
|
|
56
|
+
return path.startsWith(PATH_DELIMITER) || /^[A-Za-z]:[\\/]/.test(path);
|
|
56
57
|
}
|
|
57
58
|
export function getEnvRelativePath(filePath, projectRoot) {
|
|
58
59
|
if (!(typeof filePath === 'string' &&
|
|
@@ -13,6 +13,7 @@ import { TirBytesT } from "../types/TirNativeType/native/bytes.js";
|
|
|
13
13
|
import { TirDataT } from "../types/TirNativeType/native/data.js";
|
|
14
14
|
import { TirIntT } from "../types/TirNativeType/native/int.js";
|
|
15
15
|
import { TirLinearMapT } from "../types/TirNativeType/native/linearMap.js";
|
|
16
|
+
import { TirLinearMapEntryT } from "../types/TirNativeType/native/linearMapEntry.js";
|
|
16
17
|
import { TirListT } from "../types/TirNativeType/native/list.js";
|
|
17
18
|
import { TirDataOptT } from "../types/TirNativeType/native/Optional/data.js";
|
|
18
19
|
import { TirSopOptT } from "../types/TirNativeType/native/Optional/sop.js";
|
|
@@ -64,6 +65,9 @@ export function _inlineFromData(target_t, dataExprIR) {
|
|
|
64
65
|
// linear maps only have pairs as elements
|
|
65
66
|
// and we only support pairs of data (bc we only have `mkPairData`)
|
|
66
67
|
IRNative.unMapData, dataExprIR);
|
|
68
|
+
// LinearMapEntry is Pair<Data,Data> at runtime — no conversion needed
|
|
69
|
+
if (to_t instanceof TirLinearMapEntryT)
|
|
70
|
+
return dataExprIR;
|
|
67
71
|
if (to_t instanceof TirListT) {
|
|
68
72
|
const elems_t = getUnaliased(getListTypeArg(to_t));
|
|
69
73
|
const listOfDataExpr = _ir_apps(IRNative.unListData, dataExprIR);
|
|
@@ -99,6 +99,8 @@ export declare class TirNativeFunc implements ITirExpr {
|
|
|
99
99
|
static get _gtEqBS(): TirNativeFunc;
|
|
100
100
|
static get _gtInt(): TirNativeFunc;
|
|
101
101
|
static get _gtEqInt(): TirNativeFunc;
|
|
102
|
+
static get fstPairData(): TirNativeFunc;
|
|
103
|
+
static get sndPairData(): TirNativeFunc;
|
|
102
104
|
static get _pairDataToData(): TirNativeFunc;
|
|
103
105
|
static get _pairDataFromData(): TirNativeFunc;
|
|
104
106
|
static _mkEqualsList(elemT: TirType): TirNativeFunc;
|
|
@@ -5,6 +5,7 @@ import { bool_t, bytes_t, data_t, int_t, void_t } from "../program/stdScope/stdS
|
|
|
5
5
|
import { TirUnConstrDataResultT, TirPairDataT, TirIntT, TirBytesT, TirDataT, TirBoolT, TirSopOptT } from "../types/TirNativeType/index.js";
|
|
6
6
|
import { TirFuncT } from "../types/TirNativeType/native/function.js";
|
|
7
7
|
import { TirLinearMapT } from "../types/TirNativeType/native/linearMap.js";
|
|
8
|
+
import { TirLinearMapEntryT } from "../types/TirNativeType/native/linearMapEntry.js";
|
|
8
9
|
import { TirListT } from "../types/TirNativeType/native/list.js";
|
|
9
10
|
import { TirDataOptT } from "../types/TirNativeType/native/Optional/data.js";
|
|
10
11
|
import { TirDataStructType } from "../types/TirStructType.js";
|
|
@@ -783,6 +784,12 @@ export class TirNativeFunc {
|
|
|
783
784
|
int_t
|
|
784
785
|
], bool_t));
|
|
785
786
|
}
|
|
787
|
+
static get fstPairData() {
|
|
788
|
+
return new TirNativeFunc(IRNativeTag.fstPair, new TirFuncT([new TirPairDataT()], data_t));
|
|
789
|
+
}
|
|
790
|
+
static get sndPairData() {
|
|
791
|
+
return new TirNativeFunc(IRNativeTag.sndPair, new TirFuncT([new TirPairDataT()], data_t));
|
|
792
|
+
}
|
|
786
793
|
static get _pairDataToData() {
|
|
787
794
|
return new TirNativeFunc(IRNativeTag._pairDataToData, new TirFuncT([
|
|
788
795
|
// pair
|
|
@@ -832,6 +839,8 @@ export class TirNativeFunc {
|
|
|
832
839
|
return this.equalsByteString;
|
|
833
840
|
if (t instanceof TirPairDataT)
|
|
834
841
|
return this._equalPairData;
|
|
842
|
+
if (t instanceof TirLinearMapEntryT)
|
|
843
|
+
return this._equalPairData;
|
|
835
844
|
if (t instanceof TirBoolT)
|
|
836
845
|
return this._equalBoolean;
|
|
837
846
|
if (t instanceof TirDataT
|
|
@@ -11,5 +11,7 @@ export declare const string_t: TirStringT;
|
|
|
11
11
|
export declare const bytes_t: TirBytesT;
|
|
12
12
|
export declare const bool_t: TirBoolT;
|
|
13
13
|
export declare const data_t: TirDataT;
|
|
14
|
+
export declare const valueLovelacesName: string;
|
|
15
|
+
export declare const valueAmountOfName: string;
|
|
14
16
|
export declare function populateStdScope(program: TypedProgram): void;
|
|
15
17
|
export declare function populatePreludeScope(program: TypedProgram): void;
|
|
@@ -15,12 +15,17 @@ import { SourceRange } from "../../../../ast/Source/SourceRange.js";
|
|
|
15
15
|
import { TirInlineClosedIR } from "../../expressions/TirInlineClosedIR.js";
|
|
16
16
|
import { TirFuncT } from "../../types/TirNativeType/index.js";
|
|
17
17
|
import { IRNative } from "../../../../IR/IRNodes/IRNative/index.js";
|
|
18
|
+
import { IRFunc } from "../../../../IR/IRNodes/IRFunc.js";
|
|
19
|
+
import { IRVar } from "../../../../IR/IRNodes/IRVar.js";
|
|
20
|
+
import { _ir_apps } from "../../../../IR/IRNodes/IRApp.js";
|
|
18
21
|
export const void_t = new TirVoidT();
|
|
19
22
|
export const int_t = new TirIntT();
|
|
20
23
|
export const string_t = new TirStringT();
|
|
21
24
|
export const bytes_t = new TirBytesT();
|
|
22
25
|
export const bool_t = new TirBoolT();
|
|
23
26
|
export const data_t = new TirDataT();
|
|
27
|
+
export const valueLovelacesName = PEBBLE_INTERNAL_IDENTIFIER_PREFIX + "sortedValueLovelaces";
|
|
28
|
+
export const valueAmountOfName = PEBBLE_INTERNAL_IDENTIFIER_PREFIX + "amountOfValue";
|
|
24
29
|
export function populateStdScope(program) {
|
|
25
30
|
const stdScope = program.stdScope;
|
|
26
31
|
function _defineStdUnambigous(t) {
|
|
@@ -544,14 +549,35 @@ export function populatePreludeScope(program) {
|
|
|
544
549
|
const map_policyId_map_tokenName_int_t = program.getAppliedGeneric(TirLinearMapT.toTirTypeKey(), [policyId_t, map_tokenName_int_t]);
|
|
545
550
|
if (!map_policyId_map_tokenName_int_t)
|
|
546
551
|
throw new Error("expected map_policyId_map_tokenName_int_t");
|
|
547
|
-
const valueLovelacesName = PEBBLE_INTERNAL_IDENTIFIER_PREFIX + "sortedValueLovelaces";
|
|
548
552
|
const value_t = _defineUnambigousAlias("Value", map_policyId_map_tokenName_int_t, new Map([
|
|
549
553
|
[
|
|
550
554
|
"lovelaces",
|
|
551
555
|
valueLovelacesName
|
|
552
556
|
],
|
|
557
|
+
[
|
|
558
|
+
"amountOf",
|
|
559
|
+
valueAmountOfName
|
|
560
|
+
],
|
|
553
561
|
]));
|
|
554
562
|
preludeScope.program.functions.set(valueLovelacesName, new TirInlineClosedIR(new TirFuncT([value_t], int_t), (ctx) => IRNative._sortedValueLovelaces, SourceRange.unknown));
|
|
563
|
+
// Value.amountOf( policy: PolicyId, name: bytes ): int
|
|
564
|
+
// The IR native _amountOfValue is curried as: (isPolicy)(value)(isTokenName) => int
|
|
565
|
+
// where isPolicy and isTokenName are equality-check predicates.
|
|
566
|
+
// This wrapper adapts (self, policy, tokenName) => _amountOfValue(p => equalsByteString(p, policy))(self)(tn => equalsByteString(tn, tokenName))
|
|
567
|
+
preludeScope.program.functions.set(valueAmountOfName, new TirInlineClosedIR(new TirFuncT([value_t, policyId_t, bytes_t], int_t), (ctx) => {
|
|
568
|
+
const self = Symbol("amtOf_self");
|
|
569
|
+
const policy = Symbol("amtOf_policy");
|
|
570
|
+
const tokenName = Symbol("amtOf_tokenName");
|
|
571
|
+
const p = Symbol("amtOf_p");
|
|
572
|
+
const tn = Symbol("amtOf_tn");
|
|
573
|
+
return new IRFunc([self, policy, tokenName], _ir_apps(_ir_apps(_ir_apps(IRNative._amountOfValue,
|
|
574
|
+
// isPolicy predicate: \p -> equalsByteString(p, policy)
|
|
575
|
+
_ir_apps(IRNative.equalsByteString, new IRVar(policy))),
|
|
576
|
+
// value (self)
|
|
577
|
+
new IRVar(self)),
|
|
578
|
+
// isTokenName predicate: \tn -> equalsByteString(tn, tokenName)
|
|
579
|
+
_ir_apps(IRNative.equalsByteString, new IRVar(tokenName))));
|
|
580
|
+
}, SourceRange.unknown));
|
|
555
581
|
/* // TODO
|
|
556
582
|
untagged struct FlatValueEntry {
|
|
557
583
|
policy: PolicyId,
|
|
@@ -6,6 +6,7 @@ import { TirDataT } from "./native/data.js";
|
|
|
6
6
|
import { TirFuncT } from "./native/function.js";
|
|
7
7
|
import { TirIntT } from "./native/int.js";
|
|
8
8
|
import { TirLinearMapT } from "./native/linearMap.js";
|
|
9
|
+
import { TirLinearMapEntryT } from "./native/linearMapEntry.js";
|
|
9
10
|
import { TirListT } from "./native/list.js";
|
|
10
11
|
import { TirDataOptT } from "./native/Optional/data.js";
|
|
11
12
|
import { TirSopOptT } from "./native/Optional/sop.js";
|
|
@@ -13,7 +14,7 @@ import { TirStringT } from "./native/string.js";
|
|
|
13
14
|
import { TirVoidT } from "./native/void.js";
|
|
14
15
|
export type TirNamedDestructableNativeType = TirDataT | TirDataOptT<TirType> | TirSopOptT<TirType> | TirListT<TirType> | TirLinearMapT<TirType, TirType>;
|
|
15
16
|
export declare function isTirNamedDestructableNativeType(t: any): t is TirNamedDestructableNativeType;
|
|
16
|
-
export type TirNativeType = TirVoidT | TirBoolT | TirIntT | TirBytesT | TirStringT | TirDataT | TirDataOptT<TirType> | TirSopOptT<TirType> | TirListT<TirType> | TirLinearMapT<TirType, TirType> | TirFuncT | TirUnConstrDataResultT | TirPairDataT;
|
|
17
|
+
export type TirNativeType = TirVoidT | TirBoolT | TirIntT | TirBytesT | TirStringT | TirDataT | TirDataOptT<TirType> | TirSopOptT<TirType> | TirListT<TirType> | TirLinearMapT<TirType, TirType> | TirLinearMapEntryT<TirType, TirType> | TirFuncT | TirUnConstrDataResultT | TirPairDataT;
|
|
17
18
|
export declare function isTirNativeType(t: any): t is TirNativeType;
|
|
18
19
|
export declare class TirUnConstrDataResultT implements ITirType {
|
|
19
20
|
constructor();
|
|
@@ -5,6 +5,7 @@ import { TirDataT } from "./native/data.js";
|
|
|
5
5
|
import { TirFuncT } from "./native/function.js";
|
|
6
6
|
import { TirIntT } from "./native/int.js";
|
|
7
7
|
import { TirLinearMapT } from "./native/linearMap.js";
|
|
8
|
+
import { TirLinearMapEntryT } from "./native/linearMapEntry.js";
|
|
8
9
|
import { TirListT } from "./native/list.js";
|
|
9
10
|
import { TirDataOptT } from "./native/Optional/data.js";
|
|
10
11
|
import { TirSopOptT } from "./native/Optional/sop.js";
|
|
@@ -28,6 +29,7 @@ export function isTirNativeType(t) {
|
|
|
28
29
|
|| t instanceof TirSopOptT
|
|
29
30
|
|| t instanceof TirListT
|
|
30
31
|
|| t instanceof TirLinearMapT
|
|
32
|
+
|| t instanceof TirLinearMapEntryT
|
|
31
33
|
|| t instanceof TirFuncT // =>
|
|
32
34
|
|| t instanceof TirUnConstrDataResultT
|
|
33
35
|
|| t instanceof TirPairDataT);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ConstType } from "@harmoniclabs/uplc";
|
|
2
|
+
import { TirType, ITirType } from "../../TirType.js";
|
|
3
|
+
export declare class TirLinearMapEntryT<K extends TirType = TirType, V extends TirType = TirType> implements ITirType {
|
|
4
|
+
readonly keyTypeArg: K;
|
|
5
|
+
readonly valTypeArg: V;
|
|
6
|
+
constructor(keyTypeArg: K, valTypeArg: V);
|
|
7
|
+
hasDataEncoding(): boolean;
|
|
8
|
+
static toTirTypeKey(): string;
|
|
9
|
+
toTirTypeKey(): string;
|
|
10
|
+
toAstName(): string;
|
|
11
|
+
toConcreteTirTypeName(): string;
|
|
12
|
+
toString(): string;
|
|
13
|
+
private _isConcrete;
|
|
14
|
+
isConcrete(): boolean;
|
|
15
|
+
clone(): TirLinearMapEntryT<K, V>;
|
|
16
|
+
toUplcConstType(): ConstType;
|
|
17
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { constT } from "@harmoniclabs/uplc";
|
|
2
|
+
import { getAppliedTirTypeName } from "../../../program/TypedProgram.js";
|
|
3
|
+
export class TirLinearMapEntryT {
|
|
4
|
+
keyTypeArg;
|
|
5
|
+
valTypeArg;
|
|
6
|
+
constructor(keyTypeArg, valTypeArg) {
|
|
7
|
+
this.keyTypeArg = keyTypeArg;
|
|
8
|
+
this.valTypeArg = valTypeArg;
|
|
9
|
+
}
|
|
10
|
+
hasDataEncoding() { return false; }
|
|
11
|
+
static toTirTypeKey() {
|
|
12
|
+
return "linear_map_entry";
|
|
13
|
+
}
|
|
14
|
+
toTirTypeKey() {
|
|
15
|
+
return TirLinearMapEntryT.toTirTypeKey();
|
|
16
|
+
}
|
|
17
|
+
toAstName() {
|
|
18
|
+
return this.toTirTypeKey();
|
|
19
|
+
}
|
|
20
|
+
toConcreteTirTypeName() {
|
|
21
|
+
return getAppliedTirTypeName(this.toTirTypeKey(), [
|
|
22
|
+
this.keyTypeArg.toConcreteTirTypeName(),
|
|
23
|
+
this.valTypeArg.toConcreteTirTypeName()
|
|
24
|
+
]);
|
|
25
|
+
}
|
|
26
|
+
toString() {
|
|
27
|
+
return `${this.toTirTypeKey()}<${this.keyTypeArg.toString()},${this.valTypeArg.toString()}>`;
|
|
28
|
+
}
|
|
29
|
+
_isConcrete = undefined;
|
|
30
|
+
isConcrete() {
|
|
31
|
+
if (typeof this._isConcrete !== "boolean")
|
|
32
|
+
this._isConcrete = (this.keyTypeArg.isConcrete()
|
|
33
|
+
&& this.valTypeArg.isConcrete());
|
|
34
|
+
return this._isConcrete ?? false;
|
|
35
|
+
}
|
|
36
|
+
clone() {
|
|
37
|
+
const result = new TirLinearMapEntryT(this.keyTypeArg.clone(), this.valTypeArg.clone());
|
|
38
|
+
result._isConcrete = this._isConcrete;
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
toUplcConstType() {
|
|
42
|
+
return constT.pairOf(constT.data, constT.data);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -6,6 +6,7 @@ import { TirDataT } from "../TirNativeType/native/data.js";
|
|
|
6
6
|
import { TirFuncT } from "../TirNativeType/native/function.js";
|
|
7
7
|
import { TirIntT } from "../TirNativeType/native/int.js";
|
|
8
8
|
import { TirLinearMapT } from "../TirNativeType/native/linearMap.js";
|
|
9
|
+
import { TirLinearMapEntryT } from "../TirNativeType/native/linearMapEntry.js";
|
|
9
10
|
import { TirListT } from "../TirNativeType/native/list.js";
|
|
10
11
|
import { TirDataOptT } from "../TirNativeType/native/Optional/data.js";
|
|
11
12
|
import { TirSopOptT } from "../TirNativeType/native/Optional/sop.js";
|
|
@@ -181,6 +182,12 @@ function uncheckedGetCanAssign(a, b, symbols) {
|
|
|
181
182
|
return CanAssign.RequiresExplicitCast;
|
|
182
183
|
return CanAssign.No;
|
|
183
184
|
}
|
|
185
|
+
if (b instanceof TirLinearMapEntryT) {
|
|
186
|
+
if (a instanceof TirLinearMapEntryT) {
|
|
187
|
+
return decideCanAssignField(uncheckedGetCanAssign(a.keyTypeArg, b.keyTypeArg, symbols), uncheckedGetCanAssign(a.valTypeArg, b.valTypeArg, symbols));
|
|
188
|
+
}
|
|
189
|
+
return CanAssign.No;
|
|
190
|
+
}
|
|
184
191
|
if (b instanceof TirDataT) {
|
|
185
192
|
if (a instanceof TirDataT)
|
|
186
193
|
return CanAssign.Yes;
|
|
@@ -5,6 +5,7 @@ import { TirDataT } from "../TirNativeType/native/data.js";
|
|
|
5
5
|
import { TirFuncT } from "../TirNativeType/native/function.js";
|
|
6
6
|
import { TirIntT } from "../TirNativeType/native/int.js";
|
|
7
7
|
import { TirLinearMapT } from "../TirNativeType/native/linearMap.js";
|
|
8
|
+
import { TirLinearMapEntryT } from "../TirNativeType/native/linearMapEntry.js";
|
|
8
9
|
import { TirListT } from "../TirNativeType/native/list.js";
|
|
9
10
|
import { TirDataOptT } from "../TirNativeType/native/Optional/data.js";
|
|
10
11
|
import { TirSopOptT } from "../TirNativeType/native/Optional/sop.js";
|
|
@@ -107,6 +108,13 @@ export function canCastTo(a, b) {
|
|
|
107
108
|
&& canCastToData(b.valTypeArg));
|
|
108
109
|
return false;
|
|
109
110
|
}
|
|
111
|
+
if (b instanceof TirLinearMapEntryT) {
|
|
112
|
+
if (a instanceof TirLinearMapEntryT) {
|
|
113
|
+
return (canCastTo(a.keyTypeArg, b.keyTypeArg)
|
|
114
|
+
&& canCastTo(a.valTypeArg, b.valTypeArg));
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
110
118
|
if (b instanceof TirFuncT) {
|
|
111
119
|
if (!(a instanceof TirFuncT))
|
|
112
120
|
return false;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TirAliasType } from "../TirAliasType.js";
|
|
2
|
+
import { TirLinearMapT } from "../TirNativeType/native/linearMap.js";
|
|
2
3
|
import { TirListT } from "../TirNativeType/native/list.js";
|
|
3
4
|
export function getListTypeArg(list_t) {
|
|
4
5
|
while (list_t instanceof TirAliasType)
|
|
@@ -7,3 +8,10 @@ export function getListTypeArg(list_t) {
|
|
|
7
8
|
return list_t.typeArg;
|
|
8
9
|
return undefined;
|
|
9
10
|
}
|
|
11
|
+
export function getLinearMapTypeArgs(map_t) {
|
|
12
|
+
while (map_t instanceof TirAliasType)
|
|
13
|
+
map_t = map_t.aliased;
|
|
14
|
+
if (map_t instanceof TirLinearMapT)
|
|
15
|
+
return [map_t.keyTypeArg, map_t.valTypeArg];
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
package/dist/parser/Parser.js
CHANGED
|
@@ -2409,6 +2409,30 @@ export class Parser extends DiagnosticEmitter {
|
|
|
2409
2409
|
tn.reset(tnState);
|
|
2410
2410
|
return true;
|
|
2411
2411
|
}
|
|
2412
|
+
// possibly a destructured parameter
|
|
2413
|
+
// ( { field, ... } ) => ...
|
|
2414
|
+
// or a parenthesized object expression
|
|
2415
|
+
// ( { a: 1, b: 2 } )
|
|
2416
|
+
case Token.OpenBrace: {
|
|
2417
|
+
// skip past the balanced braces
|
|
2418
|
+
this.skipBlock(tn);
|
|
2419
|
+
// check what follows the `}`
|
|
2420
|
+
const afterBrace = tn.next();
|
|
2421
|
+
if (afterBrace === Token.CloseParen) {
|
|
2422
|
+
// ( { ... } ) — check for `=>`
|
|
2423
|
+
const isArrow = tn.skip(Token.FatArrow);
|
|
2424
|
+
tn.reset(tnState);
|
|
2425
|
+
return isArrow;
|
|
2426
|
+
}
|
|
2427
|
+
if (afterBrace === Token.Comma) {
|
|
2428
|
+
// ( { ... }, ... ) — multiple params, must be arrow func
|
|
2429
|
+
tn.reset(tnState);
|
|
2430
|
+
return true;
|
|
2431
|
+
}
|
|
2432
|
+
// anything else — parenthesized expression
|
|
2433
|
+
tn.reset(tnState);
|
|
2434
|
+
return false;
|
|
2435
|
+
}
|
|
2412
2436
|
// can be both parenthesized expression or function parameter
|
|
2413
2437
|
// ( Identifier...
|
|
2414
2438
|
case Token.Identifier: {
|
|
@@ -2,7 +2,7 @@ import { SourceRange } from "../ast/Source/SourceRange.js";
|
|
|
2
2
|
import { DiagnosticEmitter } from "../diagnostics/DiagnosticEmitter.js";
|
|
3
3
|
import { DiagnosticCode } from "../diagnostics/diagnosticMessages.generated.js";
|
|
4
4
|
import { assert } from "../utils/assert.js";
|
|
5
|
-
import { isHighSurrogate, combineSurrogates, isIdentifierStart, numCodeUnits, isIdentifierPart, isWhiteSpace, isLineBreak, isDecimal, isOctal, isHexBase } from "../utils/text.js";
|
|
5
|
+
import { isHighSurrogate, combineSurrogates, isIdentifierStart, numCodeUnits, isIdentifierPart, isWhiteSpace, isLineBreak, isDecimal, isOctal, isHexBase, isHexOrDecimal } from "../utils/text.js";
|
|
6
6
|
import { IdentifierHandling } from "./IdentifierHandling.js";
|
|
7
7
|
import { OnNewLine } from "./OnNewLine.js";
|
|
8
8
|
import { Token } from "./Token.js";
|
|
@@ -926,7 +926,7 @@ export class Tokenizer extends DiagnosticEmitter {
|
|
|
926
926
|
let length = 0;
|
|
927
927
|
while (pos < end) {
|
|
928
928
|
let c = text.charCodeAt(pos);
|
|
929
|
-
if (
|
|
929
|
+
if (isHexOrDecimal(c)) {
|
|
930
930
|
length++;
|
|
931
931
|
pos++;
|
|
932
932
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harmoniclabs/pebble",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "A simple, yet rock solid, functional language with an imperative bias, targeting UPLC",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@babel/preset-env": "^7.18.6",
|
|
65
65
|
"@babel/preset-typescript": "^7.18.6",
|
|
66
|
+
"@harmoniclabs/buildooor": "^0.2.6",
|
|
66
67
|
"@types/jest": "^28.1.4",
|
|
67
68
|
"@types/node": "^18.14.6",
|
|
68
69
|
"jest": "^29.4.3",
|