@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.
Files changed (33) hide show
  1. package/dist/IR/IRNodes/IRConst.js +6 -0
  2. package/dist/IR/IRNodes/IRNative/index.js +3 -2
  3. package/dist/IR/toUPLC/subRoutines/replaceNatives/nativeToIR.js +2 -2
  4. package/dist/compiler/AstCompiler/AstCompiler.js +2 -2
  5. package/dist/compiler/AstCompiler/internal/exprs/_compileElemAccessExpr.d.ts +2 -2
  6. package/dist/compiler/AstCompiler/internal/exprs/_compileElemAccessExpr.js +39 -3
  7. package/dist/compiler/AstCompiler/internal/statements/_compileVarStmt.js +15 -0
  8. package/dist/compiler/AstCompiler/utils/getPropAccessReturnType.js +25 -2
  9. package/dist/compiler/Compiler.js +2 -2
  10. package/dist/compiler/SourceTypeMap.d.ts +1 -0
  11. package/dist/compiler/SourceTypeMap.js +25 -0
  12. package/dist/compiler/TirCompiler/expressify/expressify.js +21 -1
  13. package/dist/compiler/TirCompiler/expressify/expressifyVars.js +38 -2
  14. package/dist/compiler/TirCompiler/expressify/toNamedDeconstructVarDecl.js +7 -0
  15. package/dist/compiler/path/getAbsolutePath.js +2 -1
  16. package/dist/compiler/tir/expressions/TirFromDataExpr.js +4 -0
  17. package/dist/compiler/tir/expressions/TirNativeFunc.d.ts +2 -0
  18. package/dist/compiler/tir/expressions/TirNativeFunc.js +9 -0
  19. package/dist/compiler/tir/program/stdScope/stdScope.d.ts +2 -0
  20. package/dist/compiler/tir/program/stdScope/stdScope.js +27 -1
  21. package/dist/compiler/tir/types/TirNativeType/TirNativeType.d.ts +2 -1
  22. package/dist/compiler/tir/types/TirNativeType/TirNativeType.js +2 -0
  23. package/dist/compiler/tir/types/TirNativeType/native/index.d.ts +1 -0
  24. package/dist/compiler/tir/types/TirNativeType/native/index.js +1 -0
  25. package/dist/compiler/tir/types/TirNativeType/native/linearMapEntry.d.ts +17 -0
  26. package/dist/compiler/tir/types/TirNativeType/native/linearMapEntry.js +44 -0
  27. package/dist/compiler/tir/types/utils/canAssignTo.js +7 -0
  28. package/dist/compiler/tir/types/utils/canCastTo.js +8 -0
  29. package/dist/compiler/tir/types/utils/getListTypeArg.d.ts +1 -0
  30. package/dist/compiler/tir/types/utils/getListTypeArg.js +8 -0
  31. package/dist/parser/Parser.js +24 -0
  32. package/dist/tokenizer/Tokenizer.js +2 -2
  33. 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 TirLinearMapT)
246
- return IRNative.equalListOf(new TirPairDataT());
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
- // return this.program;
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 { TirElemAccessExpr } from "../../../tir/expressions/TirElemAccessExpr.js";
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): TirElemAccessExpr | 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 litsTypeHint = typeHint ? new TirListT(typeHint) : undefined;
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
- // ...getListMethods( /* to add when adding support for pairs */ ),
90
- lookup: new TirFuncT([kT], new TirSopOptT(vT))
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
  }
@@ -35,6 +35,7 @@ export declare class SourceTypeMap {
35
35
  private listMembers;
36
36
  private bytesMembers;
37
37
  private stringMembers;
38
+ private linearMapEntryMembers;
38
39
  private linearMapMembers;
39
40
  private walkFuncExpr;
40
41
  private walkExpr;
@@ -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
- if (stmt.type instanceof TirSoPStructType) {
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, SourceRange.join(methodIdentifierProp.range, methodCall.range.atEnd()));
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
- return path.startsWith(PATH_DELIMITER);
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);
@@ -5,6 +5,7 @@ export * from "./data.js";
5
5
  export * from "./function.js";
6
6
  export * from "./int.js";
7
7
  export * from "./linearMap.js";
8
+ export * from "./linearMapEntry.js";
8
9
  export * from "./list.js";
9
10
  export * from "./string.js";
10
11
  export * from "./void.js";
@@ -5,6 +5,7 @@ export * from "./data.js";
5
5
  export * from "./function.js";
6
6
  export * from "./int.js";
7
7
  export * from "./linearMap.js";
8
+ export * from "./linearMapEntry.js";
8
9
  export * from "./list.js";
9
10
  export * from "./string.js";
10
11
  export * from "./void.js";
@@ -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,2 +1,3 @@
1
1
  import { TirType } from "../TirType.js";
2
2
  export declare function getListTypeArg(list_t: TirType): TirType | undefined;
3
+ export declare function getLinearMapTypeArgs(map_t: TirType): [key: TirType, value: TirType] | undefined;
@@ -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
+ }
@@ -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 (isHexBase(c)) {
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.4-dev1",
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",