@harmoniclabs/pebble 0.1.10 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/IR/IRNodes/IRConst.js +14 -3
  2. package/dist/IR/IRNodes/IRNative/index.js +5 -1
  3. package/dist/IR/toUPLC/CompilerOptions.d.ts +22 -7
  4. package/dist/IR/toUPLC/CompilerOptions.js +5 -1
  5. package/dist/IR/tree_utils/bytesToHex.d.ts +8 -0
  6. package/dist/IR/tree_utils/bytesToHex.js +69 -0
  7. package/dist/ast/nodes/expr/functions/FuncExpr.d.ts +16 -2
  8. package/dist/ast/nodes/expr/functions/FuncExpr.js +17 -0
  9. package/dist/ast/nodes/expr/litteral/LitteralExpr.d.ts +2 -1
  10. package/dist/ast/nodes/expr/litteral/LitteralExpr.js +2 -0
  11. package/dist/ast/nodes/expr/litteral/TemplateStrExpr.d.ts +30 -0
  12. package/dist/ast/nodes/expr/litteral/TemplateStrExpr.js +35 -0
  13. package/dist/ast/nodes/statements/ExportStmt.d.ts +3 -3
  14. package/dist/ast/nodes/statements/PebbleStmt.d.ts +4 -3
  15. package/dist/ast/nodes/statements/PebbleStmt.js +6 -2
  16. package/dist/ast/nodes/statements/TestParam.d.ts +18 -0
  17. package/dist/ast/nodes/statements/TestParam.js +18 -0
  18. package/dist/ast/nodes/statements/TestStmt.d.ts +5 -3
  19. package/dist/ast/nodes/statements/TestStmt.js +3 -1
  20. package/dist/ast/nodes/statements/UsingStmt.d.ts +32 -2
  21. package/dist/ast/nodes/statements/UsingStmt.js +39 -3
  22. package/dist/ast/nodes/statements/declarations/NamespaceDecl.d.ts +21 -0
  23. package/dist/ast/nodes/statements/declarations/NamespaceDecl.js +31 -0
  24. package/dist/compiler/AstCompiler/AstCompiler.d.ts +26 -0
  25. package/dist/compiler/AstCompiler/AstCompiler.js +203 -3
  26. package/dist/compiler/AstCompiler/internal/_deriveContractBody/_deriveContractBody.js +13 -2
  27. package/dist/compiler/AstCompiler/internal/exprs/_compileCallExpr.js +97 -6
  28. package/dist/compiler/AstCompiler/internal/exprs/_compileFuncExpr.js +12 -5
  29. package/dist/compiler/AstCompiler/internal/exprs/_compileLitteralExpr.js +59 -0
  30. package/dist/compiler/AstCompiler/internal/exprs/_compilePropAccessExpr.d.ts +2 -3
  31. package/dist/compiler/AstCompiler/internal/exprs/_compilePropAccessExpr.js +28 -0
  32. package/dist/compiler/AstCompiler/internal/exprs/_compileVarAccessExpr.js +2 -0
  33. package/dist/compiler/AstCompiler/internal/statements/_compileStatement.js +4 -1
  34. package/dist/compiler/AstCompiler/internal/statements/_compileTestStmt.d.ts +15 -1
  35. package/dist/compiler/AstCompiler/internal/statements/_compileTestStmt.js +70 -30
  36. package/dist/compiler/AstCompiler/internal/statements/_compileUsingAliasStmt.d.ts +11 -0
  37. package/dist/compiler/AstCompiler/internal/statements/_compileUsingAliasStmt.js +26 -0
  38. package/dist/compiler/AstCompiler/internal/statements/_compileUsingStmt.d.ts +9 -4
  39. package/dist/compiler/AstCompiler/internal/statements/_compileUsingStmt.js +51 -10
  40. package/dist/compiler/AstCompiler/internal/types/_compileDataEncodedConcreteType.js +21 -2
  41. package/dist/compiler/AstCompiler/internal/types/_compileSopEncodedConcreteType.js +17 -2
  42. package/dist/compiler/AstCompiler/scope/AstScope.d.ts +70 -1
  43. package/dist/compiler/AstCompiler/scope/AstScope.js +91 -0
  44. package/dist/compiler/AstCompiler/utils/getPropAccessReturnType.js +25 -1
  45. package/dist/compiler/AstCompiler/utils/monomorphizeGeneric.d.ts +36 -0
  46. package/dist/compiler/AstCompiler/utils/monomorphizeGeneric.js +123 -0
  47. package/dist/compiler/AstCompiler/utils/resolveNamespaceChain.d.ts +28 -0
  48. package/dist/compiler/AstCompiler/utils/resolveNamespaceChain.js +95 -0
  49. package/dist/compiler/AstCompiler/utils/resolveNamespacePath.d.ts +37 -0
  50. package/dist/compiler/AstCompiler/utils/resolveNamespacePath.js +93 -0
  51. package/dist/compiler/Compiler.d.ts +9 -1
  52. package/dist/compiler/Compiler.js +204 -9
  53. package/dist/compiler/TirCompiler/expressify/expressifyVars.js +26 -7
  54. package/dist/compiler/test/TestResult.d.ts +38 -0
  55. package/dist/compiler/test/TestResult.js +6 -0
  56. package/dist/compiler/test/fuzz/PRNG.d.ts +26 -0
  57. package/dist/compiler/test/fuzz/PRNG.js +59 -0
  58. package/dist/compiler/tir/expressions/TirExpr.d.ts +2 -1
  59. package/dist/compiler/tir/expressions/TirExpr.js +2 -0
  60. package/dist/compiler/tir/expressions/TirNativeFunc.d.ts +17 -0
  61. package/dist/compiler/tir/expressions/TirNativeFunc.js +53 -106
  62. package/dist/compiler/tir/expressions/TirShowExpr.d.ts +52 -0
  63. package/dist/compiler/tir/expressions/TirShowExpr.js +199 -0
  64. package/dist/compiler/tir/expressions/TirTraceExpr.js +11 -7
  65. package/dist/compiler/tir/program/TypedProgram.d.ts +101 -0
  66. package/dist/compiler/tir/program/TypedProgram.js +43 -0
  67. package/dist/compiler/tir/program/stdScope/populateBuiltinInterfaces.d.ts +17 -0
  68. package/dist/compiler/tir/program/stdScope/populateBuiltinInterfaces.js +70 -0
  69. package/dist/compiler/tir/program/stdScope/populateStdNamespace.d.ts +22 -0
  70. package/dist/compiler/tir/program/stdScope/populateStdNamespace.js +574 -0
  71. package/dist/compiler/tir/program/stdScope/stdScope.d.ts +1 -0
  72. package/dist/compiler/tir/program/stdScope/stdScope.js +1 -1
  73. package/dist/compiler/tir/statements/TirStmt.js +0 -1
  74. package/dist/compiler/tir/statements/TirTestStmt.d.ts +46 -0
  75. package/dist/compiler/tir/statements/TirTestStmt.js +35 -0
  76. package/dist/compiler/tir/types/TirNativeType/TirNativeType.d.ts +50 -1
  77. package/dist/compiler/tir/types/TirNativeType/TirNativeType.js +53 -1
  78. package/dist/compiler/tir/types/TirType.js +3 -1
  79. package/dist/compiler/tir/types/utils/canAssignTo.js +8 -1
  80. package/dist/compiler/tir/types/utils/inferTypeArgs.d.ts +19 -0
  81. package/dist/compiler/tir/types/utils/inferTypeArgs.js +79 -0
  82. package/dist/compiler/tir/types/utils/substituteTypeParams.d.ts +9 -0
  83. package/dist/compiler/tir/types/utils/substituteTypeParams.js +62 -0
  84. package/dist/diagnostics/diagnosticMessages.generated.d.ts +5 -0
  85. package/dist/diagnostics/diagnosticMessages.generated.js +10 -0
  86. package/dist/index.d.ts +2 -0
  87. package/dist/index.js +2 -0
  88. package/dist/parser/Parser.d.ts +73 -3
  89. package/dist/parser/Parser.js +333 -33
  90. package/dist/tokenizer/Token.d.ts +105 -102
  91. package/dist/tokenizer/Token.js +110 -109
  92. package/dist/tokenizer/utils/tokenFromKeyword.js +9 -6
  93. package/dist/utils/semverSatisfies.d.ts +1 -0
  94. package/dist/utils/semverSatisfies.js +161 -0
  95. package/dist/version.generated.d.ts +1 -0
  96. package/dist/version.generated.js +2 -0
  97. package/package.json +3 -2
@@ -0,0 +1,46 @@
1
+ import { SourceRange } from "../../../ast/Source/SourceRange.js";
2
+ import { ITirStmt } from "./TirStmt.js";
3
+ /**
4
+ * Per-parameter fuzzer descriptor.
5
+ *
6
+ * - `kind: "primitive"`: the runner generates values directly in TS for a
7
+ * supported primitive type (`int`, `bool`, etc.). No Pebble-side fuzzer call.
8
+ * - `kind: "unsupported"`: the parameter type has no default generator and
9
+ * no `via` was supplied; the runner emits a SKIP `TestResult` carrying
10
+ * `reason`.
11
+ * - `kind: "via_not_implemented"`: the user wrote `via <expr>` and the
12
+ * compiler successfully type-checked it, but executing user-defined
13
+ * fuzzers is not wired up yet (Phase 2). Surfaced as SKIP.
14
+ */
15
+ export type FuzzerInfo = {
16
+ kind: "primitive";
17
+ primitive: "int" | "bool";
18
+ } | {
19
+ kind: "unsupported";
20
+ reason: string;
21
+ } | {
22
+ kind: "via_not_implemented";
23
+ };
24
+ /**
25
+ * A `test name( params? ) { body }` block.
26
+ *
27
+ * The compiled body lives in `program.functions` keyed by `tirFuncName`
28
+ * (synthesised as `__pebble_test_<name>_<srcUid>`). The executor
29
+ * (`runTests`) looks up that function, compiles it to UPLC, and evaluates it.
30
+ *
31
+ * `fuzzerInfos` is parallel to the function's params; for unit tests it is
32
+ * empty. For property tests, each entry tells the runner how to source
33
+ * values for that parameter.
34
+ */
35
+ export declare class TirTestStmt implements ITirStmt {
36
+ readonly name: string;
37
+ readonly tirFuncName: string;
38
+ readonly sourceFile: string;
39
+ readonly range: SourceRange;
40
+ readonly fuzzerInfos: FuzzerInfo[];
41
+ constructor(name: string, tirFuncName: string, sourceFile: string, range: SourceRange, fuzzerInfos?: FuzzerInfo[]);
42
+ toString(): string;
43
+ pretty(): string;
44
+ definitelyTerminates(): boolean;
45
+ deps(): string[];
46
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * A `test name( params? ) { body }` block.
3
+ *
4
+ * The compiled body lives in `program.functions` keyed by `tirFuncName`
5
+ * (synthesised as `__pebble_test_<name>_<srcUid>`). The executor
6
+ * (`runTests`) looks up that function, compiles it to UPLC, and evaluates it.
7
+ *
8
+ * `fuzzerInfos` is parallel to the function's params; for unit tests it is
9
+ * empty. For property tests, each entry tells the runner how to source
10
+ * values for that parameter.
11
+ */
12
+ export class TirTestStmt {
13
+ name;
14
+ tirFuncName;
15
+ sourceFile;
16
+ range;
17
+ fuzzerInfos;
18
+ constructor(name, tirFuncName, sourceFile, range, fuzzerInfos = []) {
19
+ this.name = name;
20
+ this.tirFuncName = tirFuncName;
21
+ this.sourceFile = sourceFile;
22
+ this.range = range;
23
+ this.fuzzerInfos = fuzzerInfos;
24
+ }
25
+ toString() {
26
+ return `test ${this.name} -> ${this.tirFuncName}`;
27
+ }
28
+ pretty() {
29
+ return this.toString();
30
+ }
31
+ definitelyTerminates() { return false; }
32
+ deps() {
33
+ return [this.tirFuncName];
34
+ }
35
+ }
@@ -14,7 +14,7 @@ import { TirStringT } from "./native/string.js";
14
14
  import { TirVoidT } from "./native/void.js";
15
15
  export type TirNamedDestructableNativeType = TirDataT | TirDataOptT<TirType> | TirSopOptT<TirType> | TirListT<TirType> | TirLinearMapT<TirType, TirType>;
16
16
  export declare function isTirNamedDestructableNativeType(t: any): t is TirNamedDestructableNativeType;
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
+ export type TirNativeType = TirVoidT | TirBoolT | TirIntT | TirBytesT | TirStringT | TirDataT | TirDataOptT<TirType> | TirSopOptT<TirType> | TirListT<TirType> | TirLinearMapT<TirType, TirType> | TirLinearMapEntryT<TirType, TirType> | TirFuncT | TirUnConstrDataResultT | TirPairDataT | TirBlsG1T | TirBlsG2T | TirMlResultT;
18
18
  export declare function isTirNativeType(t: any): t is TirNativeType;
19
19
  export declare class TirUnConstrDataResultT implements ITirType {
20
20
  constructor();
@@ -40,3 +40,52 @@ export declare class TirPairDataT implements ITirType {
40
40
  clone(): TirPairDataT;
41
41
  toUplcConstType(): ConstType;
42
42
  }
43
+ /**
44
+ * BLS12-381 G1 element. Opaque native scalar; cannot be constructed from
45
+ * Pebble source directly — values are produced by `std.crypto.bls12_381.*`
46
+ * builtins (typically `g1Uncompress` or `g1HashToGroup`).
47
+ */
48
+ export declare class TirBlsG1T implements ITirType {
49
+ constructor();
50
+ hasDataEncoding(): boolean;
51
+ static toTirTypeKey(): string;
52
+ toTirTypeKey(): string;
53
+ toConcreteTirTypeName(): string;
54
+ toString(): string;
55
+ toAstName(): string;
56
+ isConcrete(): boolean;
57
+ clone(): TirBlsG1T;
58
+ toUplcConstType(): ConstType;
59
+ }
60
+ /**
61
+ * BLS12-381 G2 element. Opaque native scalar.
62
+ */
63
+ export declare class TirBlsG2T implements ITirType {
64
+ constructor();
65
+ hasDataEncoding(): boolean;
66
+ static toTirTypeKey(): string;
67
+ toTirTypeKey(): string;
68
+ toConcreteTirTypeName(): string;
69
+ toString(): string;
70
+ toAstName(): string;
71
+ isConcrete(): boolean;
72
+ clone(): TirBlsG2T;
73
+ toUplcConstType(): ConstType;
74
+ }
75
+ /**
76
+ * BLS12-381 Miller-loop result. Opaque native scalar produced by
77
+ * `bls12_381_millerLoop` and consumed by `bls12_381_finalVerify` /
78
+ * `bls12_381_mulMlResult`.
79
+ */
80
+ export declare class TirMlResultT implements ITirType {
81
+ constructor();
82
+ hasDataEncoding(): boolean;
83
+ static toTirTypeKey(): string;
84
+ toTirTypeKey(): string;
85
+ toConcreteTirTypeName(): string;
86
+ toString(): string;
87
+ toAstName(): string;
88
+ isConcrete(): boolean;
89
+ clone(): TirMlResultT;
90
+ toUplcConstType(): ConstType;
91
+ }
@@ -32,7 +32,10 @@ export function isTirNativeType(t) {
32
32
  || t instanceof TirLinearMapEntryT
33
33
  || t instanceof TirFuncT // =>
34
34
  || t instanceof TirUnConstrDataResultT
35
- || t instanceof TirPairDataT);
35
+ || t instanceof TirPairDataT
36
+ || t instanceof TirBlsG1T
37
+ || t instanceof TirBlsG2T
38
+ || t instanceof TirMlResultT);
36
39
  }
37
40
  export class TirUnConstrDataResultT {
38
41
  constructor() { }
@@ -86,3 +89,52 @@ export class TirPairDataT {
86
89
  return constT.pairOf(constT.data, constT.data);
87
90
  }
88
91
  }
92
+ /**
93
+ * BLS12-381 G1 element. Opaque native scalar; cannot be constructed from
94
+ * Pebble source directly — values are produced by `std.crypto.bls12_381.*`
95
+ * builtins (typically `g1Uncompress` or `g1HashToGroup`).
96
+ */
97
+ export class TirBlsG1T {
98
+ constructor() { }
99
+ hasDataEncoding() { return false; }
100
+ static toTirTypeKey() { return "#bls12_381_g1#"; }
101
+ toTirTypeKey() { return TirBlsG1T.toTirTypeKey(); }
102
+ toConcreteTirTypeName() { return this.toTirTypeKey(); }
103
+ toString() { return "G1"; }
104
+ toAstName() { return "G1"; }
105
+ isConcrete() { return true; }
106
+ clone() { return new TirBlsG1T(); }
107
+ toUplcConstType() { return constT.bls12_381_G1_element; }
108
+ }
109
+ /**
110
+ * BLS12-381 G2 element. Opaque native scalar.
111
+ */
112
+ export class TirBlsG2T {
113
+ constructor() { }
114
+ hasDataEncoding() { return false; }
115
+ static toTirTypeKey() { return "#bls12_381_g2#"; }
116
+ toTirTypeKey() { return TirBlsG2T.toTirTypeKey(); }
117
+ toConcreteTirTypeName() { return this.toTirTypeKey(); }
118
+ toString() { return "G2"; }
119
+ toAstName() { return "G2"; }
120
+ isConcrete() { return true; }
121
+ clone() { return new TirBlsG2T(); }
122
+ toUplcConstType() { return constT.bls12_381_G2_element; }
123
+ }
124
+ /**
125
+ * BLS12-381 Miller-loop result. Opaque native scalar produced by
126
+ * `bls12_381_millerLoop` and consumed by `bls12_381_finalVerify` /
127
+ * `bls12_381_mulMlResult`.
128
+ */
129
+ export class TirMlResultT {
130
+ constructor() { }
131
+ hasDataEncoding() { return false; }
132
+ static toTirTypeKey() { return "#bls12_381_ml_result#"; }
133
+ toTirTypeKey() { return TirMlResultT.toTirTypeKey(); }
134
+ toConcreteTirTypeName() { return this.toTirTypeKey(); }
135
+ toString() { return "MlResult"; }
136
+ toAstName() { return "MlResult"; }
137
+ isConcrete() { return true; }
138
+ clone() { return new TirMlResultT(); }
139
+ toUplcConstType() { return constT.bls12_381_MlResult; }
140
+ }
@@ -2,9 +2,11 @@ import { isObject } from "@harmoniclabs/obj-utils";
2
2
  import { TirAliasType } from "./TirAliasType.js";
3
3
  import { isTirStructType } from "./TirStructType.js";
4
4
  import { isTirNamedDestructableNativeType, isTirNativeType } from "./TirNativeType/TirNativeType.js";
5
+ import { TirTypeParam } from "./TirTypeParam.js";
5
6
  export function isTirType(thing) {
6
7
  return isObject(thing) && (isTirNativeType(thing)
7
- || isTirCustomType(thing));
8
+ || isTirCustomType(thing)
9
+ || thing instanceof TirTypeParam);
8
10
  }
9
11
  export function isTirCustomType(thing) {
10
12
  return isObject(thing) && (thing instanceof TirAliasType
@@ -1,5 +1,5 @@
1
1
  import { TirAliasType } from "../TirAliasType.js";
2
- import { TirUnConstrDataResultT, TirPairDataT } from "../TirNativeType/index.js";
2
+ import { TirBlsG1T, TirBlsG2T, TirMlResultT, TirUnConstrDataResultT, TirPairDataT } from "../TirNativeType/index.js";
3
3
  import { TirBoolT } from "../TirNativeType/native/bool.js";
4
4
  import { TirBytesT } from "../TirNativeType/native/bytes.js";
5
5
  import { TirDataT } from "../TirNativeType/native/data.js";
@@ -232,6 +232,13 @@ function uncheckedGetCanAssign(a, b, symbols) {
232
232
  }
233
233
  return currentDecision;
234
234
  }
235
+ // BLS / ML-result are opaque atomic types: assignable only to themselves
236
+ if (b instanceof TirBlsG1T)
237
+ return a instanceof TirBlsG1T ? CanAssign.Yes : CanAssign.No;
238
+ if (b instanceof TirBlsG2T)
239
+ return a instanceof TirBlsG2T ? CanAssign.Yes : CanAssign.No;
240
+ if (b instanceof TirMlResultT)
241
+ return a instanceof TirMlResultT ? CanAssign.Yes : CanAssign.No;
235
242
  const tsEnsureExhautstiveCheck = b;
236
243
  return CanAssign.No;
237
244
  }
@@ -0,0 +1,19 @@
1
+ import { TirType } from "../TirType.js";
2
+ /**
3
+ * Attempt to bind free `TirTypeParam`s in `formal` so that the result matches
4
+ * `actual`. Bindings are accumulated into `env`. Returns `true` on success.
5
+ *
6
+ * - Inconsistent bindings (`T = int` then `T = bytes`) cause failure.
7
+ * - Shape mismatches between concrete containers cause failure.
8
+ * - Unknown type-params in `formal` not yet in `env` are bound to `actual`'s
9
+ * matching position.
10
+ *
11
+ * This is intentionally syntactic — no subtyping, no widening. The caller
12
+ * passes already-unaliased argument types.
13
+ */
14
+ export declare function inferTypeArgs(formal: TirType, actual: TirType, env: Map<symbol, TirType>): boolean;
15
+ /**
16
+ * Cheap structural equality for unaliased TirTypes — compares concrete TIR
17
+ * names. Sufficient for our inference consistency checks.
18
+ */
19
+ export declare function tirTypeStructurallyEqual(a: TirType, b: TirType): boolean;
@@ -0,0 +1,79 @@
1
+ import { TirFuncT } from "../TirNativeType/native/function.js";
2
+ import { TirLinearMapT } from "../TirNativeType/native/linearMap.js";
3
+ import { TirLinearMapEntryT } from "../TirNativeType/native/linearMapEntry.js";
4
+ import { TirListT } from "../TirNativeType/native/list.js";
5
+ import { TirDataOptT } from "../TirNativeType/native/Optional/data.js";
6
+ import { TirSopOptT } from "../TirNativeType/native/Optional/sop.js";
7
+ import { TirTypeParam } from "../TirTypeParam.js";
8
+ import { getUnaliased } from "./getUnaliased.js";
9
+ /**
10
+ * Attempt to bind free `TirTypeParam`s in `formal` so that the result matches
11
+ * `actual`. Bindings are accumulated into `env`. Returns `true` on success.
12
+ *
13
+ * - Inconsistent bindings (`T = int` then `T = bytes`) cause failure.
14
+ * - Shape mismatches between concrete containers cause failure.
15
+ * - Unknown type-params in `formal` not yet in `env` are bound to `actual`'s
16
+ * matching position.
17
+ *
18
+ * This is intentionally syntactic — no subtyping, no widening. The caller
19
+ * passes already-unaliased argument types.
20
+ */
21
+ export function inferTypeArgs(formal, actual, env) {
22
+ formal = getUnaliased(formal);
23
+ actual = getUnaliased(actual);
24
+ if (formal instanceof TirTypeParam) {
25
+ const existing = env.get(formal.symbol);
26
+ if (existing === undefined) {
27
+ env.set(formal.symbol, actual);
28
+ return true;
29
+ }
30
+ // consistency: existing binding must equal actual
31
+ return tirTypeStructurallyEqual(existing, actual);
32
+ }
33
+ // both must be the same shape and equal in arg-positions
34
+ if (formal instanceof TirListT && actual instanceof TirListT) {
35
+ return inferTypeArgs(formal.typeArg, actual.typeArg, env);
36
+ }
37
+ if (formal instanceof TirFuncT && actual instanceof TirFuncT) {
38
+ if (formal.argTypes.length !== actual.argTypes.length)
39
+ return false;
40
+ for (let i = 0; i < formal.argTypes.length; i++) {
41
+ if (!inferTypeArgs(formal.argTypes[i], actual.argTypes[i], env))
42
+ return false;
43
+ }
44
+ return inferTypeArgs(formal.returnType, actual.returnType, env);
45
+ }
46
+ if (formal instanceof TirLinearMapT && actual instanceof TirLinearMapT) {
47
+ return (inferTypeArgs(formal.keyTypeArg, actual.keyTypeArg, env)
48
+ && inferTypeArgs(formal.valTypeArg, actual.valTypeArg, env));
49
+ }
50
+ if (formal instanceof TirLinearMapEntryT && actual instanceof TirLinearMapEntryT) {
51
+ return (inferTypeArgs(formal.keyTypeArg, actual.keyTypeArg, env)
52
+ && inferTypeArgs(formal.valTypeArg, actual.valTypeArg, env));
53
+ }
54
+ if (formal instanceof TirDataOptT && actual instanceof TirDataOptT) {
55
+ return inferTypeArgs(formal.typeArg, actual.typeArg, env);
56
+ }
57
+ if (formal instanceof TirSopOptT && actual instanceof TirSopOptT) {
58
+ return inferTypeArgs(formal.typeArg, actual.typeArg, env);
59
+ }
60
+ // base case: both concrete with no type-vars — must be the same type
61
+ return tirTypeStructurallyEqual(formal, actual);
62
+ }
63
+ /**
64
+ * Cheap structural equality for unaliased TirTypes — compares concrete TIR
65
+ * names. Sufficient for our inference consistency checks.
66
+ */
67
+ export function tirTypeStructurallyEqual(a, b) {
68
+ a = getUnaliased(a);
69
+ b = getUnaliased(b);
70
+ if (a instanceof TirTypeParam && b instanceof TirTypeParam) {
71
+ return a.symbol === b.symbol;
72
+ }
73
+ try {
74
+ return a.toConcreteTirTypeName() === b.toConcreteTirTypeName();
75
+ }
76
+ catch {
77
+ return false;
78
+ }
79
+ }
@@ -0,0 +1,9 @@
1
+ import { TirType } from "../TirType.js";
2
+ /**
3
+ * Walk a TirType tree and replace each `TirTypeParam` whose `symbol` is a key
4
+ * in `subst` with the corresponding concrete type. Containers (`List`, `Func`,
5
+ * `LinearMap`, optionals, aliases) are rebuilt with their substituted children.
6
+ *
7
+ * Returns the input unchanged when no substitution applies.
8
+ */
9
+ export declare function substituteTypeParams(t: TirType, subst: Map<symbol, TirType>): TirType;
@@ -0,0 +1,62 @@
1
+ import { TirAliasType } from "../TirAliasType.js";
2
+ import { TirFuncT } from "../TirNativeType/native/function.js";
3
+ import { TirLinearMapT } from "../TirNativeType/native/linearMap.js";
4
+ import { TirLinearMapEntryT } from "../TirNativeType/native/linearMapEntry.js";
5
+ import { TirListT } from "../TirNativeType/native/list.js";
6
+ import { TirDataOptT } from "../TirNativeType/native/Optional/data.js";
7
+ import { TirSopOptT } from "../TirNativeType/native/Optional/sop.js";
8
+ import { TirTypeParam } from "../TirTypeParam.js";
9
+ /**
10
+ * Walk a TirType tree and replace each `TirTypeParam` whose `symbol` is a key
11
+ * in `subst` with the corresponding concrete type. Containers (`List`, `Func`,
12
+ * `LinearMap`, optionals, aliases) are rebuilt with their substituted children.
13
+ *
14
+ * Returns the input unchanged when no substitution applies.
15
+ */
16
+ export function substituteTypeParams(t, subst) {
17
+ if (subst.size === 0)
18
+ return t;
19
+ if (t instanceof TirTypeParam) {
20
+ return subst.get(t.symbol) ?? t;
21
+ }
22
+ if (t instanceof TirListT) {
23
+ const sub = substituteTypeParams(t.typeArg, subst);
24
+ return sub === t.typeArg ? t : new TirListT(sub);
25
+ }
26
+ if (t instanceof TirFuncT) {
27
+ let changed = false;
28
+ const newArgs = t.argTypes.map(a => {
29
+ const s = substituteTypeParams(a, subst);
30
+ if (s !== a)
31
+ changed = true;
32
+ return s;
33
+ });
34
+ const newRet = substituteTypeParams(t.returnType, subst);
35
+ if (newRet !== t.returnType)
36
+ changed = true;
37
+ return changed ? new TirFuncT(newArgs, newRet) : t;
38
+ }
39
+ if (t instanceof TirLinearMapT) {
40
+ const k = substituteTypeParams(t.keyTypeArg, subst);
41
+ const v = substituteTypeParams(t.valTypeArg, subst);
42
+ return (k === t.keyTypeArg && v === t.valTypeArg) ? t : new TirLinearMapT(k, v);
43
+ }
44
+ if (t instanceof TirLinearMapEntryT) {
45
+ const k = substituteTypeParams(t.keyTypeArg, subst);
46
+ const v = substituteTypeParams(t.valTypeArg, subst);
47
+ return (k === t.keyTypeArg && v === t.valTypeArg) ? t : new TirLinearMapEntryT(k, v);
48
+ }
49
+ if (t instanceof TirDataOptT) {
50
+ const sub = substituteTypeParams(t.typeArg, subst);
51
+ return sub === t.typeArg ? t : new TirDataOptT(sub);
52
+ }
53
+ if (t instanceof TirSopOptT) {
54
+ const sub = substituteTypeParams(t.typeArg, subst);
55
+ return sub === t.typeArg ? t : new TirSopOptT(sub);
56
+ }
57
+ if (t instanceof TirAliasType) {
58
+ const sub = substituteTypeParams(t.aliased, subst);
59
+ return sub === t.aliased ? t : sub;
60
+ }
61
+ return t;
62
+ }
@@ -278,6 +278,11 @@ export declare enum DiagnosticCode {
278
278
  _super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class = 17009,
279
279
  _super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class = 17011,
280
280
  Unkonwn_AST_node = 20000,
281
+ Namespace_0_has_no_exported_member_1 = 30001,
282
+ Namespace_path_is_incomplete_expected_a_value_type_function_or_interface = 30002,
283
+ _private_modifier_is_only_allowed_on_declarations_inside_a_namespace = 30003,
284
+ Namespaces_cannot_be_declared_here = 30004,
285
+ _0_is_not_a_namespace = 30005,
281
286
  Dev_was_too_lazy_to_add_a_prooper_error_message_Something_went_wrong = 42069
282
287
  }
283
288
  /** Translates a diagnostic code to its respective string. */
@@ -280,6 +280,11 @@ export var DiagnosticCode;
280
280
  DiagnosticCode[DiagnosticCode["_super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class"] = 17009] = "_super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class";
281
281
  DiagnosticCode[DiagnosticCode["_super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class"] = 17011] = "_super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class";
282
282
  DiagnosticCode[DiagnosticCode["Unkonwn_AST_node"] = 20000] = "Unkonwn_AST_node";
283
+ DiagnosticCode[DiagnosticCode["Namespace_0_has_no_exported_member_1"] = 30001] = "Namespace_0_has_no_exported_member_1";
284
+ DiagnosticCode[DiagnosticCode["Namespace_path_is_incomplete_expected_a_value_type_function_or_interface"] = 30002] = "Namespace_path_is_incomplete_expected_a_value_type_function_or_interface";
285
+ DiagnosticCode[DiagnosticCode["_private_modifier_is_only_allowed_on_declarations_inside_a_namespace"] = 30003] = "_private_modifier_is_only_allowed_on_declarations_inside_a_namespace";
286
+ DiagnosticCode[DiagnosticCode["Namespaces_cannot_be_declared_here"] = 30004] = "Namespaces_cannot_be_declared_here";
287
+ DiagnosticCode[DiagnosticCode["_0_is_not_a_namespace"] = 30005] = "_0_is_not_a_namespace";
283
288
  DiagnosticCode[DiagnosticCode["Dev_was_too_lazy_to_add_a_prooper_error_message_Something_went_wrong"] = 42069] = "Dev_was_too_lazy_to_add_a_prooper_error_message_Something_went_wrong";
284
289
  })(DiagnosticCode || (DiagnosticCode = {}));
285
290
  /** Translates a diagnostic code to its respective string. */
@@ -563,6 +568,11 @@ export function diagnosticCodeToString(code) {
563
568
  case 17009: return "'super' must be called before accessing 'this' in the constructor of a derived class.";
564
569
  case 17011: return "'super' must be called before accessing a property of 'super' in the constructor of a derived class.";
565
570
  case 20000: return "Unkonwn AST node.";
571
+ case 30001: return "Namespace '{0}' has no exported member '{1}'.";
572
+ case 30002: return "Namespace path is incomplete; expected a value, type, function, or interface.";
573
+ case 30003: return "'private' modifier is only allowed on declarations inside a namespace.";
574
+ case 30004: return "Namespaces cannot be declared here.";
575
+ case 30005: return "'{0}' is not a namespace.";
566
576
  case 42069: return "Dev was too lazy to add a prooper error message. Something went wrong";
567
577
  default: return "";
568
578
  }
package/dist/index.d.ts CHANGED
@@ -8,3 +8,5 @@ export * from "./IR/index.js";
8
8
  export * from "./tokenizer/index.js";
9
9
  export * from "./parser/index.js";
10
10
  export * from "./compiler/index.js";
11
+ export * from "./version.generated.js";
12
+ export * from "./utils/semverSatisfies.js";
package/dist/index.js CHANGED
@@ -8,4 +8,6 @@ export * from "./IR/index.js";
8
8
  export * from "./tokenizer/index.js";
9
9
  export * from "./parser/index.js";
10
10
  export * from "./compiler/index.js";
11
+ export * from "./version.generated.js";
12
+ export * from "./utils/semverSatisfies.js";
11
13
  // export * from "./ast";
@@ -12,7 +12,8 @@ import { SourceRange } from "../ast/Source/SourceRange.js";
12
12
  import { SimpleVarDecl } from "../ast/nodes/statements/declarations/VarDecl/SimpleVarDecl.js";
13
13
  import { ArrayLikeDeconstr } from "../ast/nodes/statements/declarations/VarDecl/ArrayLikeDeconstr.js";
14
14
  import { ParentesizedExpr } from "../ast/nodes/expr/ParentesizedExpr.js";
15
- import { FuncExpr } from "../ast/nodes/expr/functions/FuncExpr.js";
15
+ import { FuncExpr, TypeParamDecl } from "../ast/nodes/expr/functions/FuncExpr.js";
16
+ import { TemplateStrExpr } from "../ast/nodes/expr/litteral/TemplateStrExpr.js";
16
17
  import { BlockStmt } from "../ast/nodes/statements/BlockStmt.js";
17
18
  import { BreakStmt } from "../ast/nodes/statements/BreakStmt.js";
18
19
  import { ContinueStmt } from "../ast/nodes/statements/ContinueStmt.js";
@@ -25,6 +26,7 @@ import { FailStmt } from "../ast/nodes/statements/FailStmt.js";
25
26
  import { TraceStmt } from "../ast/nodes/statements/TraceStmt.js";
26
27
  import { AssertStmt } from "../ast/nodes/statements/AssertStmt.js";
27
28
  import { TestStmt } from "../ast/nodes/statements/TestStmt.js";
29
+ import { TestParam } from "../ast/nodes/statements/TestParam.js";
28
30
  import { MatchStmt } from "../ast/nodes/statements/MatchStmt.js";
29
31
  import { WhileStmt } from "../ast/nodes/statements/WhileStmt.js";
30
32
  import { CaseExpr } from "../ast/nodes/expr/CaseExpr.js";
@@ -39,7 +41,8 @@ import { TypeAliasDecl } from "../ast/nodes/statements/declarations/TypeAliasDec
39
41
  import { EnumDecl, EnumValueDecl } from "../ast/nodes/statements/declarations/EnumDecl.js";
40
42
  import { AssignmentStmt } from "../ast/nodes/statements/AssignmentStmt.js";
41
43
  import { AstTypeExpr } from "../ast/nodes/types/AstTypeExpr.js";
42
- import { UsingStmt } from "../ast/nodes/statements/UsingStmt.js";
44
+ import { UsingAliasStmt, UsingPath, UsingRhs, UsingStmt } from "../ast/nodes/statements/UsingStmt.js";
45
+ import { NamespaceDecl, NamespaceMemberStmt } from "../ast/nodes/statements/declarations/NamespaceDecl.js";
43
46
  import { BodyStmt, TopLevelStmt } from "../ast/nodes/statements/PebbleStmt.js";
44
47
  import { Precedence } from "./Precedence.js";
45
48
  import { ContractDecl } from "../ast/nodes/statements/declarations/ContractDecl.js";
@@ -57,8 +60,50 @@ export declare class Parser extends DiagnosticEmitter {
57
60
  parseTopLevelStatement(): TopLevelStmt | undefined;
58
61
  parseContractDecl(startPos: number): ContractDecl | undefined;
59
62
  parseStateDecl(startPos: number): StateDecl | undefined;
60
- parseUsingDecl(): UsingStmt | undefined;
63
+ parseUsingDecl(): UsingStmt | UsingAliasStmt | undefined;
64
+ /**
65
+ * parse a dotted chain of identifiers: `A`, `A.B`, `A.B.C`, ...
66
+ * used for namespace paths on the RHS of `using` statements.
67
+ */
68
+ parseUsingPath(): UsingPath | undefined;
69
+ /**
70
+ * parse the RHS of `using { ... } = <rhs>;`:
71
+ * - if it begins with a native type keyword (or a generic struct
72
+ * with type args), it's parsed as `AstTypeExpr` (legacy
73
+ * struct-destructure behavior)
74
+ * - if it's a single identifier followed by `<`, it's also parsed as
75
+ * a generic type expression
76
+ * - otherwise, it's parsed as a dotted `UsingPath`
77
+ * (a namespace path; the compiler decides whether it's a struct
78
+ * type or a namespace based on what the head identifier resolves to)
79
+ */
80
+ parseUsingRhs(): UsingRhs | undefined;
81
+ /**
82
+ * parse a namespace body: `{ (private? <member-decl>)* }`
83
+ *
84
+ * called with `namespace` already consumed; `startPos` is the position
85
+ * of the `namespace` keyword.
86
+ */
87
+ parseNamespaceDecl(startPos: number): NamespaceDecl | undefined;
88
+ /**
89
+ * parse a single namespace body member. delegates to the relevant
90
+ * top-level-style parser based on the next token, but rejects
91
+ * declarations that aren't allowed inside a namespace body
92
+ * (no `export`, no `import`, no `using`, no `contract`, no `test`).
93
+ */
94
+ parseNamespaceMember(): NamespaceMemberStmt | undefined;
61
95
  parseTypeParameters(): Identifier[] | undefined;
96
+ /**
97
+ * Parses a function's type-parameter list with optional `implements`
98
+ * interface constraints:
99
+ * `<T, U implements ToData, V implements Foo>`
100
+ *
101
+ * Returns `TypeParamDecl[]` so the compiler can read each param's
102
+ * optional constraint at template-registration time. Struct/interface
103
+ * decls keep using the simpler {@link parseTypeParameters} which
104
+ * returns bare `Identifier[]`.
105
+ */
106
+ parseFuncTypeParameters(): TypeParamDecl[] | undefined;
62
107
  parseTypeArguments(): AstTypeExpr[] | undefined;
63
108
  parseExport(startPos?: number): ExportImportStmt | ExportStarStmt | undefined;
64
109
  parseTypeStmt(flags?: CommonFlags, startPos?: number): TypeAliasDecl | TypeImplementsStmt | undefined;
@@ -132,9 +177,34 @@ export declare class Parser extends DiagnosticEmitter {
132
177
  parseIfStatement(): IfStmt | undefined;
133
178
  parseReturn(): ReturnStmt | undefined;
134
179
  parseTestStatement(): TestStmt | undefined;
180
+ /**
181
+ * Parses the parameter list of a `test` declaration:
182
+ * `( <id>: <type> ('via' <expr>)? (, <id>: <type> ('via' <expr>)? )* )?`
183
+ *
184
+ * Assumes the opening `(` has already been consumed by the caller.
185
+ * Consumes the closing `)` on success.
186
+ *
187
+ * `via` is recognised here ONLY — function/method/contract parameter
188
+ * parsing uses `parseParameters()` which never looks for `Token.Via`.
189
+ */
190
+ parseTestParameters(): TestParam[] | undefined;
135
191
  parseMatchStatement(): MatchStmt | undefined;
136
192
  parseFailStatement(): FailStmt | undefined;
137
193
  parseTraceStatement(): TraceStmt | undefined;
194
+ /**
195
+ * Parse a backtick-delimited template literal:
196
+ *
197
+ * `text ${expr1} more text ${expr2} ...`
198
+ *
199
+ * Tokenizer state: on entry, the current token is
200
+ * `Token.StringTemplateLiteralQuote`; the tokenizer is positioned at
201
+ * the opening backtick. `readString()` (called with no arg) consumes
202
+ * the backtick + the first fragment up to `${` or to the closing
203
+ * backtick; if it stopped at `${` it sets `readingTemplateString = true`
204
+ * and the parser must consume an expression + `}` and then call
205
+ * `readString(CharCode.Backtick)` to read the next fragment.
206
+ */
207
+ parseTemplateLiteral(startPos: number): TemplateStrExpr | undefined;
138
208
  parseAssertStatement(): AssertStmt | undefined;
139
209
  parseWhileStatement(): WhileStmt | undefined;
140
210
  /**