@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
@@ -2,7 +2,7 @@ import { TirAliasType } from "../../tir/types/TirAliasType.js";
2
2
  import { isTirStructType } from "../../tir/types/TirStructType.js";
3
3
  import { TirTypeParam } from "../../tir/types/TirTypeParam.js";
4
4
  import { int_t, bytes_t, bool_t, string_t } from "../../tir/program/stdScope/stdScope.js";
5
- import { TirUnConstrDataResultT, TirPairDataT } from "../../tir/types/TirNativeType/index.js";
5
+ import { TirBlsG1T, TirBlsG2T, TirMlResultT, TirUnConstrDataResultT, TirPairDataT } from "../../tir/types/TirNativeType/index.js";
6
6
  import { TirBoolT } from "../../tir/types/TirNativeType/native/bool.js";
7
7
  import { TirBytesT } from "../../tir/types/TirNativeType/native/bytes.js";
8
8
  import { TirDataT } from "../../tir/types/TirNativeType/native/data.js";
@@ -27,6 +27,24 @@ export function getPropAccessReturnType(ctx, objType, propId) {
27
27
  objType = objType.aliased;
28
28
  }
29
29
  // if( objType instanceof TirAliasType ) return findPropInImpls( objType.impls, propName ) ?? getPropAccessReturnType( objType.aliased, propId );
30
+ // Universal `.show()` — every (built-in) type implementing the Show
31
+ // interface has signature `(): bytes`. Struct types fall through to
32
+ // `getStructPropAccessReturnType`, which checks user-declared
33
+ // `type X implements Show { ... }` impls first; if absent, the
34
+ // expressify-time fallback emits a TirShowExpr that auto-derives via
35
+ // `_showIR` (e.g. for data-encoded structs).
36
+ if (propName === "show") {
37
+ if (objType instanceof TirVoidT
38
+ || objType instanceof TirBoolT
39
+ || objType instanceof TirIntT
40
+ || objType instanceof TirBytesT
41
+ || objType instanceof TirStringT
42
+ || objType instanceof TirDataT
43
+ || objType instanceof TirListT
44
+ || objType instanceof TirLinearMapT
45
+ || isTirOptType(objType))
46
+ return new TirFuncT([], bytes_t);
47
+ }
30
48
  if (isTirStructType(objType))
31
49
  return getStructPropAccessReturnType(ctx, objType, propName);
32
50
  if (objType instanceof TirVoidT)
@@ -60,6 +78,12 @@ export function getPropAccessReturnType(ctx, objType, propId) {
60
78
  return undefined;
61
79
  if (objType instanceof TirPairDataT)
62
80
  return undefined;
81
+ if (objType instanceof TirBlsG1T)
82
+ return undefined;
83
+ if (objType instanceof TirBlsG2T)
84
+ return undefined;
85
+ if (objType instanceof TirMlResultT)
86
+ return undefined;
63
87
  const tsEnsureExhaustiveCheck = objType;
64
88
  console.error(objType);
65
89
  throw new Error("unreachable::getPropAccessReturnType");
@@ -0,0 +1,36 @@
1
+ import { SourceRange } from "../../../ast/Source/SourceRange.js";
2
+ import { GenericTemplate } from "../../tir/program/TypedProgram.js";
3
+ import { TirFuncT } from "../../tir/types/TirNativeType/native/function.js";
4
+ import { TirType } from "../../tir/types/TirType.js";
5
+ import { AstCompilationCtx } from "../AstCompilationCtx.js";
6
+ export interface MonomorphizationResult {
7
+ /** the canonical TIR function name registered in `program.functions` */
8
+ tirFuncName: string;
9
+ /** the substituted concrete TirFuncT (no remaining type params) */
10
+ concreteFuncType: TirFuncT;
11
+ }
12
+ /**
13
+ * Returns a deterministic instance key for memoization & function-table naming.
14
+ */
15
+ export declare function buildMonomorphizationKey(templateCanonicalName: string, typeArgs: TirType[]): string;
16
+ /**
17
+ * Instantiate a generic function template with the given concrete type
18
+ * arguments, producing (and caching) a fresh concrete TIR function.
19
+ *
20
+ * The strategy is "desugar to a concrete function during AST→TIR":
21
+ *
22
+ * 1. Build a child scope on the template's defining scope where each type
23
+ * parameter name resolves as a type alias for its concrete type. When the
24
+ * cloned FuncExpr is re-compiled, every `AstNamedTypeExpr` mentioning a
25
+ * type parameter resolves to its concrete TIR type.
26
+ * 2. Construct a fresh `FuncExpr` reusing the template's body & signature but
27
+ * with `typeParams = []` (so the "not implemented: generic functions"
28
+ * guard in `_compileFuncExpr` does not trip) and a unique instance name.
29
+ * 3. Compile via `_compileFuncExpr` and register the resulting `TirFuncExpr`
30
+ * in `program.functions` under the instance name.
31
+ *
32
+ * Results are memoized per `(template, type-args)` tuple — repeated calls
33
+ * with the same type arguments return the same instance and do not
34
+ * re-compile.
35
+ */
36
+ export declare function monomorphizeGeneric(ctx: AstCompilationCtx, template: GenericTemplate, typeArgs: TirType[], callRange: SourceRange): MonomorphizationResult | undefined;
@@ -0,0 +1,123 @@
1
+ import { FuncExpr } from "../../../ast/nodes/expr/functions/FuncExpr.js";
2
+ import { Identifier } from "../../../ast/nodes/common/Identifier.js";
3
+ import { ArrowKind } from "../../../ast/nodes/expr/functions/ArrowKind.js";
4
+ import { DiagnosticCode } from "../../../diagnostics/diagnosticMessages.generated.js";
5
+ import { substituteTypeParams } from "../../tir/types/utils/substituteTypeParams.js";
6
+ import { AstCompilationCtx } from "../AstCompilationCtx.js";
7
+ import { _compileFuncExpr } from "../internal/exprs/_compileFuncExpr.js";
8
+ /**
9
+ * Returns a deterministic instance key for memoization & function-table naming.
10
+ */
11
+ export function buildMonomorphizationKey(templateCanonicalName, typeArgs) {
12
+ return templateCanonicalName + "$$" + typeArgs.map(t => t.toConcreteTirTypeName()).join("$$");
13
+ }
14
+ /**
15
+ * Instantiate a generic function template with the given concrete type
16
+ * arguments, producing (and caching) a fresh concrete TIR function.
17
+ *
18
+ * The strategy is "desugar to a concrete function during AST→TIR":
19
+ *
20
+ * 1. Build a child scope on the template's defining scope where each type
21
+ * parameter name resolves as a type alias for its concrete type. When the
22
+ * cloned FuncExpr is re-compiled, every `AstNamedTypeExpr` mentioning a
23
+ * type parameter resolves to its concrete TIR type.
24
+ * 2. Construct a fresh `FuncExpr` reusing the template's body & signature but
25
+ * with `typeParams = []` (so the "not implemented: generic functions"
26
+ * guard in `_compileFuncExpr` does not trip) and a unique instance name.
27
+ * 3. Compile via `_compileFuncExpr` and register the resulting `TirFuncExpr`
28
+ * in `program.functions` under the instance name.
29
+ *
30
+ * Results are memoized per `(template, type-args)` tuple — repeated calls
31
+ * with the same type arguments return the same instance and do not
32
+ * re-compile.
33
+ */
34
+ export function monomorphizeGeneric(ctx, template, typeArgs, callRange) {
35
+ const program = ctx.program;
36
+ if (typeArgs.length !== template.typeParams.length) {
37
+ ctx.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, callRange, String(template.typeParams.length), String(typeArgs.length));
38
+ return undefined;
39
+ }
40
+ // Build the substitution env for substituteTypeParams
41
+ const subst = new Map();
42
+ for (let i = 0; i < template.typeParams.length; i++) {
43
+ subst.set(template.typeParams[i].symbol, typeArgs[i]);
44
+ }
45
+ // Compute concrete signature up-front (used by callers to type the call expr)
46
+ const concreteFuncType = substituteTypeParams(template.placeholderFuncType, subst);
47
+ // Memo key & cache hit
48
+ const instanceName = buildMonomorphizationKey(template.canonicalTirName, typeArgs);
49
+ const cached = program.monomorphizationCache.get(instanceName);
50
+ if (typeof cached === "string") {
51
+ return { tirFuncName: cached, concreteFuncType };
52
+ }
53
+ // Native template path: skip AST cloning entirely.
54
+ if (template.kind === "native") {
55
+ const tirFunc = template.instantiate(typeArgs);
56
+ program.functions.set(instanceName, tirFunc);
57
+ program.monomorphizationCache.set(instanceName, instanceName);
58
+ return { tirFuncName: instanceName, concreteFuncType };
59
+ }
60
+ // Cycle detection: polymorphic recursion (same template + same type args
61
+ // re-entering before the first compile finished) is impossible because
62
+ // recursion at the same type-args hits the memo cache below. Recursion at
63
+ // *different* type-args is allowed and produces a separate instance.
64
+ if (program.monomorphizationInFlight.has(instanceName)) {
65
+ // intentionally rare path; surface as a Not_implemented diagnostic
66
+ ctx.error(DiagnosticCode.Not_implemented_0, callRange, "mutually-recursive monomorphization for " + instanceName);
67
+ return undefined;
68
+ }
69
+ program.monomorphizationInFlight.add(instanceName);
70
+ // Pre-register memo so recursive same-args call resolves to the same name
71
+ program.monomorphizationCache.set(instanceName, instanceName);
72
+ try {
73
+ // Build child scope where each type-param name aliases its concrete type
74
+ const monoScope = template.definingScope.newChildScope({
75
+ ...template.definingScope.infos,
76
+ isFunctionDeclScope: false,
77
+ isMethodScope: false
78
+ });
79
+ for (let i = 0; i < template.typeParams.length; i++) {
80
+ const tparam = template.typeParams[i];
81
+ const concrete = typeArgs[i];
82
+ const concreteKey = concrete.toConcreteTirTypeName();
83
+ if (!program.types.has(concreteKey)) {
84
+ program.types.set(concreteKey, concrete);
85
+ }
86
+ monoScope.defineUnambigousType(tparam.name, concreteKey, concrete.hasDataEncoding(), new Map() // no methods on a bare type alias
87
+ );
88
+ }
89
+ // Register the instance in the parent (defining) scope under the
90
+ // instance name so the body's own recursive `id(...)` call (which
91
+ // resolves through the parent chain) sees a concrete value of the
92
+ // already-substituted type. Without this, recursive calls would
93
+ // re-trigger the generic placeholder path and infinite-loop the
94
+ // monomorphizer.
95
+ // Use the mono scope (not the defining scope) so the entry is local
96
+ // to this instantiation.
97
+ monoScope.defineValue({
98
+ name: instanceName,
99
+ type: concreteFuncType,
100
+ isConstant: true,
101
+ });
102
+ const cloneExpr = new FuncExpr(new Identifier(instanceName, template.astFuncExpr.name.range), template.astFuncExpr.flags, [], // intentionally empty: this clone is the monomorphized concrete fn
103
+ template.astFuncExpr.signature, template.astFuncExpr.body, template.astFuncExpr.arrowKind ?? ArrowKind.None, template.astFuncExpr.range);
104
+ // Pre-seed program.functions with the concrete signature so
105
+ // `_compileFuncExpr` picks it up via `program.functions.get(...).sig()`.
106
+ // We will replace this with the real TirFuncExpr after compile.
107
+ // (placeholder is not strictly required; _compileFuncExpr falls back to
108
+ // inferring from the signature if not present — leaving this out for
109
+ // simplicity)
110
+ const monoCtx = AstCompilationCtx.fromScope(program, monoScope);
111
+ const tirFuncExpr = _compileFuncExpr(monoCtx, cloneExpr, undefined, false // isMethod
112
+ );
113
+ if (!tirFuncExpr) {
114
+ program.monomorphizationCache.delete(instanceName);
115
+ return undefined;
116
+ }
117
+ program.functions.set(instanceName, tirFuncExpr);
118
+ return { tirFuncName: instanceName, concreteFuncType };
119
+ }
120
+ finally {
121
+ program.monomorphizationInFlight.delete(instanceName);
122
+ }
123
+ }
@@ -0,0 +1,28 @@
1
+ import { PebbleExpr } from "../../../ast/nodes/expr/PebbleExpr.js";
2
+ import { TirExpr } from "../../tir/expressions/TirExpr.js";
3
+ import { AstCompilationCtx } from "../AstCompilationCtx.js";
4
+ import { NamespaceSymbol } from "../scope/AstScope.js";
5
+ export type NamespaceChainResolution = {
6
+ kind: "namespace";
7
+ namespace: NamespaceSymbol;
8
+ } | {
9
+ kind: "value";
10
+ expr: TirExpr;
11
+ }
12
+ /** the chain points to a non-value (type / interface / nested ns
13
+ * used in non-expression position). callers should typically error. */
14
+ | {
15
+ kind: "incomplete";
16
+ } | undefined;
17
+ /**
18
+ * if `expr` is `Identifier` or a chain of `DotPropAccessExpr` ending in an
19
+ * `Identifier`, AND the head identifier resolves to a namespace in scope,
20
+ * walks the chain through namespace `publicScope`s and returns the resolved
21
+ * member. otherwise returns `undefined` so the caller can fall back to
22
+ * normal value/property-access compilation.
23
+ *
24
+ * the resolution does NOT emit diagnostics on plain "not a namespace"
25
+ * outcomes — those are silent failures so the caller can choose another
26
+ * resolution strategy.
27
+ */
28
+ export declare function tryResolveNamespaceChain(ctx: AstCompilationCtx, expr: PebbleExpr): NamespaceChainResolution;
@@ -0,0 +1,95 @@
1
+ import { Identifier } from "../../../ast/nodes/common/Identifier.js";
2
+ import { DotPropAccessExpr } from "../../../ast/nodes/expr/PropAccessExpr.js";
3
+ import { DiagnosticCode } from "../../../diagnostics/diagnosticMessages.generated.js";
4
+ import { TirVariableAccessExpr } from "../../tir/expressions/TirVariableAccessExpr.js";
5
+ /**
6
+ * if `expr` is `Identifier` or a chain of `DotPropAccessExpr` ending in an
7
+ * `Identifier`, AND the head identifier resolves to a namespace in scope,
8
+ * walks the chain through namespace `publicScope`s and returns the resolved
9
+ * member. otherwise returns `undefined` so the caller can fall back to
10
+ * normal value/property-access compilation.
11
+ *
12
+ * the resolution does NOT emit diagnostics on plain "not a namespace"
13
+ * outcomes — those are silent failures so the caller can choose another
14
+ * resolution strategy.
15
+ */
16
+ export function tryResolveNamespaceChain(ctx, expr) {
17
+ const segments = _collectChainSegments(expr);
18
+ if (!segments)
19
+ return undefined;
20
+ const head = ctx.scope.resolveNamespace(segments[0].text);
21
+ if (!head)
22
+ return undefined;
23
+ // head is a namespace; from here on, any failure emits a diagnostic
24
+ let current = head;
25
+ for (let i = 1; i < segments.length; i++) {
26
+ const seg = segments[i];
27
+ const name = seg.text;
28
+ const pub = current.publicScope;
29
+ const nested = pub.namespaces.get(name);
30
+ if (nested) {
31
+ current = nested;
32
+ continue;
33
+ }
34
+ const variable = pub.variables.get(name);
35
+ if (variable) {
36
+ // last segment must end here; if not, the chain is invalid
37
+ if (i !== segments.length - 1) {
38
+ ctx.error(DiagnosticCode.Property_0_does_not_exist_on_type_1, seg.range, segments[i + 1].text, variable.type.toString());
39
+ return { kind: "incomplete" };
40
+ }
41
+ return {
42
+ kind: "value",
43
+ expr: new TirVariableAccessExpr({ variableInfos: variable, isDefinedOutsideFuncScope: true }, seg.range)
44
+ };
45
+ }
46
+ const tirFuncName = pub.functions.get(name);
47
+ if (tirFuncName) {
48
+ if (i !== segments.length - 1) {
49
+ // function-typed member can't be further dotted
50
+ ctx.error(DiagnosticCode.Namespace_path_is_incomplete_expected_a_value_type_function_or_interface, seg.range);
51
+ return { kind: "incomplete" };
52
+ }
53
+ const funcExpr = pub.program.functions.get(tirFuncName);
54
+ if (!funcExpr) {
55
+ ctx.error(DiagnosticCode.Namespace_0_has_no_exported_member_1, seg.range, current.name, name);
56
+ return { kind: "incomplete" };
57
+ }
58
+ return {
59
+ kind: "value",
60
+ expr: new TirVariableAccessExpr({
61
+ variableInfos: {
62
+ isConstant: true,
63
+ name: tirFuncName,
64
+ type: funcExpr.type,
65
+ },
66
+ isDefinedOutsideFuncScope: true,
67
+ }, seg.range)
68
+ };
69
+ }
70
+ // not a namespace, not a value, not a function — likely a type or
71
+ // interface. either way it can't be used as a value here.
72
+ if (pub.types.has(name) || pub.interfaces.has(name)) {
73
+ ctx.error(DiagnosticCode.Namespace_path_is_incomplete_expected_a_value_type_function_or_interface, seg.range);
74
+ return { kind: "incomplete" };
75
+ }
76
+ ctx.error(DiagnosticCode.Namespace_0_has_no_exported_member_1, seg.range, current.name, name);
77
+ return { kind: "incomplete" };
78
+ }
79
+ // chain consumed entirely as namespaces (no leaf member)
80
+ return { kind: "namespace", namespace: current };
81
+ }
82
+ function _collectChainSegments(expr) {
83
+ if (expr instanceof Identifier)
84
+ return [expr];
85
+ if (expr instanceof DotPropAccessExpr) {
86
+ const inner = _collectChainSegments(expr.object);
87
+ if (!inner)
88
+ return undefined;
89
+ inner.push(expr.prop);
90
+ return inner;
91
+ }
92
+ // anything other than a plain dotted-identifier chain disqualifies
93
+ // namespace resolution.
94
+ return undefined;
95
+ }
@@ -0,0 +1,37 @@
1
+ import { Identifier } from "../../../ast/nodes/common/Identifier.js";
2
+ import { UsingPath } from "../../../ast/nodes/statements/UsingStmt.js";
3
+ import { AstScope, NamespaceSymbol } from "../scope/AstScope.js";
4
+ import { AstCompilationCtx } from "../AstCompilationCtx.js";
5
+ export interface ResolvedNamespacePath {
6
+ /** the namespace the path resolves to */
7
+ namespace: NamespaceSymbol;
8
+ /** the chain of resolved namespaces (one per segment of the path) */
9
+ chain: NamespaceSymbol[];
10
+ }
11
+ /**
12
+ * walks a dotted namespace path against the given scope.
13
+ *
14
+ * - returns the final `NamespaceSymbol` if every segment resolves to a namespace.
15
+ * - if the first segment is not a namespace, returns `undefined`
16
+ * (no diagnostic emitted; the caller can fall back to a different
17
+ * resolution strategy, e.g. struct lookup).
18
+ * - if a later segment is missing or is not a namespace, emits a
19
+ * diagnostic and returns `undefined`.
20
+ */
21
+ export declare function resolveNamespacePath(ctx: AstCompilationCtx, path: UsingPath): ResolvedNamespacePath | undefined;
22
+ /**
23
+ * looks up a member name in a namespace's public scope.
24
+ *
25
+ * the member can be any of:
26
+ * - a value (variable)
27
+ * - a function
28
+ * - a type
29
+ * - an interface
30
+ * - a nested namespace
31
+ *
32
+ * binds the resolved member into `target` (under either `originalName`
33
+ * or `aliasName` if provided). emits a diagnostic and returns `false`
34
+ * if no such member is exported, or if a conflicting binding already
35
+ * exists in `target`.
36
+ */
37
+ export declare function bindNamespaceMember(ctx: AstCompilationCtx, ns: NamespaceSymbol, originalName: Identifier, aliasName: Identifier | undefined, target: AstScope): boolean;
@@ -0,0 +1,93 @@
1
+ import { DiagnosticCode } from "../../../diagnostics/diagnosticMessages.generated.js";
2
+ /**
3
+ * walks a dotted namespace path against the given scope.
4
+ *
5
+ * - returns the final `NamespaceSymbol` if every segment resolves to a namespace.
6
+ * - if the first segment is not a namespace, returns `undefined`
7
+ * (no diagnostic emitted; the caller can fall back to a different
8
+ * resolution strategy, e.g. struct lookup).
9
+ * - if a later segment is missing or is not a namespace, emits a
10
+ * diagnostic and returns `undefined`.
11
+ */
12
+ export function resolveNamespacePath(ctx, path) {
13
+ const segments = path.segments;
14
+ if (segments.length === 0)
15
+ return undefined;
16
+ const head = segments[0];
17
+ const first = ctx.scope.resolveNamespace(head.text);
18
+ if (!first)
19
+ return undefined;
20
+ const chain = [first];
21
+ let current = first;
22
+ for (let i = 1; i < segments.length; i++) {
23
+ const seg = segments[i];
24
+ const inner = current.publicScope.namespaces.get(seg.text);
25
+ if (!inner) {
26
+ ctx.error(DiagnosticCode.Namespace_0_has_no_exported_member_1, seg.range, current.name, seg.text);
27
+ return undefined;
28
+ }
29
+ chain.push(inner);
30
+ current = inner;
31
+ }
32
+ return { namespace: current, chain };
33
+ }
34
+ /**
35
+ * looks up a member name in a namespace's public scope.
36
+ *
37
+ * the member can be any of:
38
+ * - a value (variable)
39
+ * - a function
40
+ * - a type
41
+ * - an interface
42
+ * - a nested namespace
43
+ *
44
+ * binds the resolved member into `target` (under either `originalName`
45
+ * or `aliasName` if provided). emits a diagnostic and returns `false`
46
+ * if no such member is exported, or if a conflicting binding already
47
+ * exists in `target`.
48
+ */
49
+ export function bindNamespaceMember(ctx, ns, originalName, aliasName, target) {
50
+ const pub = ns.publicScope;
51
+ const name = originalName.text;
52
+ const localName = aliasName?.text ?? name;
53
+ const variable = pub.variables.get(name);
54
+ const fn = pub.functions.get(name);
55
+ const tirFunc = fn ? pub.program.functions.get(fn) : undefined;
56
+ const ty = pub.types.get(name);
57
+ const iface = pub.interfaces.get(name);
58
+ const nested = pub.namespaces.get(name);
59
+ if (!variable && !fn && !ty && !iface && !nested) {
60
+ ctx.error(DiagnosticCode.Namespace_0_has_no_exported_member_1, originalName.range, ns.name, name);
61
+ return false;
62
+ }
63
+ let ok = true;
64
+ if (variable) {
65
+ ok = target.defineValue({ ...variable, name: localName }) && ok;
66
+ }
67
+ if (fn) {
68
+ target.functions.set(localName, fn);
69
+ if (tirFunc) {
70
+ target.defineValue({
71
+ isConstant: true,
72
+ name: localName,
73
+ type: tirFunc.type,
74
+ });
75
+ }
76
+ }
77
+ if (ty) {
78
+ ok = target.defineType(localName, ty) && ok;
79
+ }
80
+ if (iface) {
81
+ if (target.interfaces.has(localName))
82
+ ok = false;
83
+ else
84
+ target.interfaces.set(localName, iface);
85
+ }
86
+ if (nested) {
87
+ ok = target.defineNamespace({
88
+ name: localName,
89
+ publicScope: nested.publicScope
90
+ }) && ok;
91
+ }
92
+ return ok;
93
+ }
@@ -3,11 +3,13 @@ import { DiagnosticMessage } from "../diagnostics/DiagnosticMessage.js";
3
3
  import { CompilerOptions } from "../IR/toUPLC/CompilerOptions.js";
4
4
  import { CompilerIoApi } from "./io/CompilerIoApi.js";
5
5
  import { CheckResult } from "./SourceTypeMap.js";
6
+ import { TestResult } from "./test/TestResult.js";
6
7
  export { CheckResult, SourceTypeMap, TypeEntry, MemberInfo } from "./SourceTypeMap.js";
8
+ export { TestBudget, TestIterationResult, TestResult, TestKind, } from "./test/TestResult.js";
7
9
  export declare class Compiler extends DiagnosticEmitter {
8
10
  readonly io: CompilerIoApi;
9
11
  readonly cfg: CompilerOptions;
10
- constructor(io?: CompilerIoApi, cfg?: CompilerOptions, diagnostics?: DiagnosticMessage[]);
12
+ constructor(io: CompilerIoApi, cfg: CompilerOptions, diagnostics?: DiagnosticMessage[]);
11
13
  check(config?: Partial<CompilerOptions>): Promise<CheckResult>;
12
14
  compile(config?: Partial<CompilerOptions>): Promise<Uint8Array>;
13
15
  export(config: Partial<ExportOptions> & HasFuncitonName): Promise<Uint8Array>;
@@ -16,6 +18,12 @@ export declare class Compiler extends DiagnosticEmitter {
16
18
  budgetSpent: import("@harmoniclabs/plutus-machine").ExBudget;
17
19
  logs: string[];
18
20
  }>;
21
+ test(config?: Partial<CompilerOptions> & {
22
+ nameFilter?: string | RegExp;
23
+ propertyIterations?: number;
24
+ seed?: number;
25
+ }): Promise<TestResult[]>;
26
+ private _runOneTest;
19
27
  runRepl(config?: Partial<CompilerOptions>): Promise<{
20
28
  result: import("@harmoniclabs/plutus-machine").CEKValueObj;
21
29
  budgetSpent: import("@harmoniclabs/plutus-machine").ExBudget;