@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,31 @@
1
+ import { VarStmt } from "../VarStmt.js";
2
+ import { FuncDecl } from "./FuncDecl.js";
3
+ import { InterfaceDecl } from "./InterfaceDecl.js";
4
+ import { isPebbleTypeDecl } from "./PebbleTypeDecl.js";
5
+ export function isNamespaceMemberStmt(thing) {
6
+ return (thing instanceof VarStmt
7
+ || thing instanceof FuncDecl
8
+ || isPebbleTypeDecl(thing)
9
+ || thing instanceof InterfaceDecl
10
+ || thing instanceof NamespaceDecl);
11
+ }
12
+ export class NamespaceMember {
13
+ isPrivate;
14
+ stmt;
15
+ range;
16
+ constructor(isPrivate, stmt, range) {
17
+ this.isPrivate = isPrivate;
18
+ this.stmt = stmt;
19
+ this.range = range;
20
+ }
21
+ }
22
+ export class NamespaceDecl {
23
+ name;
24
+ members;
25
+ range;
26
+ constructor(name, members, range) {
27
+ this.name = name;
28
+ this.members = members;
29
+ this.range = range;
30
+ }
31
+ }
@@ -86,6 +86,32 @@ export declare class AstCompiler extends DiagnosticEmitter {
86
86
  private _collectInterfaceImplSigs;
87
87
  private _collectTopLevelConst;
88
88
  private _collectTopLevelFuncDeclSig;
89
+ /**
90
+ * Register a generic function template. Compile only the signature in a
91
+ * scope where each type parameter is bound to a `TirTypeParam`; the body
92
+ * is deferred until `monomorphizeGeneric` is invoked at a call site.
93
+ */
94
+ private _registerGenericTemplate;
95
+ /**
96
+ * Resolve a `<T implements I>` constraint clause to a `TypeParamConstraint`.
97
+ *
98
+ * - `decl.constraint` must be a bare `AstNamedTypeExpr` (no type args).
99
+ * - The named interface must be registered in `scope.interfaces`
100
+ * (walking up the parent chain via `resolveInterface`).
101
+ *
102
+ * The returned object captures the AST method signatures verbatim so the
103
+ * monomorphizer doesn't have to re-resolve the interface each time.
104
+ */
105
+ private _resolveTypeParamConstraint;
106
+ /**
107
+ * walks `stmts` for `NamespaceDecl` (optionally wrapped in `ExportStmt`),
108
+ * compiles each one into a `NamespaceSymbol`, and registers it on
109
+ * `enclosingScope` (and `enclosingExports` when exported).
110
+ *
111
+ * removes processed `NamespaceDecl` statements from `stmts`.
112
+ */
113
+ private _collectNamespaceDeclarations;
114
+ private _compileNamespaceDecl;
89
115
  private _collectInterfaceDeclarations;
90
116
  registerInternalTypeDecl(decl: StructDecl | TypeAliasDecl): void;
91
117
  private _collectTypeDeclarations;
@@ -29,14 +29,18 @@ import { CommonFlags } from "../../common.js";
29
29
  import { SimpleVarDecl } from "../../ast/nodes/statements/declarations/VarDecl/SimpleVarDecl.js";
30
30
  import { Identifier } from "../../ast/nodes/common/Identifier.js";
31
31
  import { ArrowKind } from "../../ast/nodes/expr/functions/ArrowKind.js";
32
- import { _compileFuncExpr } from "./internal/exprs/_compileFuncExpr.js";
32
+ import { _compileFuncExpr, getDataFuncSignature } from "./internal/exprs/_compileFuncExpr.js";
33
+ import { TirTypeParam } from "../tir/types/TirTypeParam.js";
33
34
  import { ContractDecl } from "../../ast/nodes/statements/declarations/ContractDecl.js";
34
35
  import { _deriveContractBody } from "./internal/_deriveContractBody/_deriveContractBody.js";
35
36
  import { DiagnosticCategory } from "../../diagnostics/DiagnosticCategory.js";
36
37
  import { VarStmt } from "../../ast/nodes/statements/VarStmt.js";
37
38
  import { _compileSimpleVarDecl } from "./internal/statements/_compileVarStmt.js";
39
+ import { _compileTestStmt } from "./internal/statements/_compileTestStmt.js";
38
40
  import { SourceTypeMap } from "../SourceTypeMap.js";
39
41
  import { isIdentifier } from "../../utils/text.js";
42
+ import { TestStmt } from "../../ast/nodes/statements/TestStmt.js";
43
+ import { NamespaceDecl } from "../../ast/nodes/statements/declarations/NamespaceDecl.js";
40
44
  /*
41
45
  Handling type expressions that depend on other types
42
46
  (such as generics, function return types, and inferred types from complex expressions)
@@ -273,6 +277,9 @@ export class AstCompiler extends DiagnosticEmitter {
273
277
  this._consumeImportsAddSymsInScope(stmts, src.absoluteProjPath, importsScope);
274
278
  const topLevelScope = importsScope.newChildScope({ isFunctionDeclScope: false });
275
279
  const srcExports = this.preludeScope.newChildScope({ isFunctionDeclScope: false });
280
+ // collect namespace declarations (recursively) so that types/interfaces/signatures
281
+ // can refer to symbols defined inside namespaces.
282
+ this._collectNamespaceDeclarations(stmts, src.uid, topLevelScope, srcExports);
276
283
  // collect top level **type** (struct and aliases) declarations
277
284
  this._collectTypeDeclarations(stmts, src.uid, topLevelScope, srcExports);
278
285
  // collect top level **interface** declarations (NOT implementations)
@@ -300,6 +307,17 @@ export class AstCompiler extends DiagnosticEmitter {
300
307
  exportRange = stmt.range;
301
308
  stmt = stmt.stmt;
302
309
  }
310
+ if (stmt instanceof TestStmt) {
311
+ if (isEntryFile) {
312
+ const declContext = AstCompilationCtx.fromScope(this.program, topLevelScope);
313
+ _compileTestStmt(declContext, stmt, srcUid, this.cfg.entry);
314
+ }
315
+ // tests from non-entry files are dropped on the floor:
316
+ // they will be collected when their own file is the entry.
317
+ void stmts.splice(i, 1);
318
+ i--;
319
+ continue;
320
+ }
303
321
  if (!(stmt instanceof FuncDecl
304
322
  || stmt instanceof TypeImplementsStmt
305
323
  || stmt instanceof ContractDecl
@@ -428,6 +446,14 @@ export class AstCompiler extends DiagnosticEmitter {
428
446
  if (this._isExporting && astFuncName === this.program.contractTirFuncName) {
429
447
  this.program.contractTirFuncName = tirFuncName;
430
448
  }
449
+ // Generic function declaration path: do NOT compile the body. Instead,
450
+ // compile the signature in a scope where each type parameter resolves
451
+ // to a fresh `TirTypeParam`, then register a `GenericTemplate` on the
452
+ // program. Call sites instantiate it via `monomorphizeGeneric`.
453
+ if (astFuncExpr.typeParams.length > 0) {
454
+ this._registerGenericTemplate(astFuncExpr, astFuncName, tirFuncName, topLevelScope, srcExports, exportRange);
455
+ return;
456
+ }
431
457
  const declContext = AstCompilationCtx.fromScope(this.program, topLevelScope);
432
458
  const funcExpr = _compileFuncExpr(declContext, astFuncExpr, undefined, // sig
433
459
  false // isMethod
@@ -456,6 +482,160 @@ export class AstCompiler extends DiagnosticEmitter {
456
482
  && this.program.contractTirFuncName === "")
457
483
  this.program.contractTirFuncName = tirFuncName;
458
484
  }
485
+ /**
486
+ * Register a generic function template. Compile only the signature in a
487
+ * scope where each type parameter is bound to a `TirTypeParam`; the body
488
+ * is deferred until `monomorphizeGeneric` is invoked at a call site.
489
+ */
490
+ _registerGenericTemplate(astFuncExpr, astFuncName, tirFuncName, topLevelScope, srcExports, exportRange) {
491
+ if (topLevelScope.functions.has(astFuncName))
492
+ return this.error(DiagnosticCode._0_is_already_defined, astFuncExpr.name.range, astFuncName);
493
+ // Detect duplicate type-param names on the template
494
+ const seenParamNames = new Set();
495
+ const tirTypeParams = [];
496
+ for (const decl of astFuncExpr.typeParams) {
497
+ if (seenParamNames.has(decl.name.text)) {
498
+ return this.error(DiagnosticCode._0_is_already_defined, decl.name.range, decl.name.text);
499
+ }
500
+ seenParamNames.add(decl.name.text);
501
+ tirTypeParams.push(new TirTypeParam(decl.name.text));
502
+ }
503
+ // Build a child scope where each type-param name resolves to its
504
+ // TirTypeParam (via `_compileDataEncodedConcreteType`'s new lookup).
505
+ const templateScope = topLevelScope.newChildScope({
506
+ ...topLevelScope.infos,
507
+ isFunctionDeclScope: false,
508
+ isMethodScope: false
509
+ });
510
+ for (let i = 0; i < astFuncExpr.typeParams.length; i++) {
511
+ templateScope.defineTypeParam(astFuncExpr.typeParams[i].name.text, tirTypeParams[i]);
512
+ }
513
+ // Resolve constraints on each type param (the `implements I` clause).
514
+ // For each constrained param, record the constraint on the template
515
+ // so monomorphizeGeneric can inject the matching dictionary at call
516
+ // sites, and on the template scope so `getPropAccessReturnType` can
517
+ // resolve method calls on `T`-typed values inside the body.
518
+ const constraints = new Array(astFuncExpr.typeParams.length).fill(undefined);
519
+ for (let i = 0; i < astFuncExpr.typeParams.length; i++) {
520
+ const decl = astFuncExpr.typeParams[i];
521
+ if (!decl.constraint)
522
+ continue;
523
+ const con = this._resolveTypeParamConstraint(templateScope, decl);
524
+ if (!con)
525
+ return undefined;
526
+ constraints[i] = con;
527
+ templateScope.defineTypeParamConstraint(decl.name.text, con);
528
+ }
529
+ // Compile only the signature: yields a TirFuncT that may contain
530
+ // TirTypeParams in arg/return positions.
531
+ const templateCtx = AstCompilationCtx.fromScope(this.program, templateScope);
532
+ const placeholderFuncType = getDataFuncSignature(templateCtx, astFuncExpr.signature);
533
+ if (!placeholderFuncType)
534
+ return undefined;
535
+ // Register the template on the program
536
+ this.program.genericTemplates.set(astFuncName, {
537
+ kind: "user",
538
+ astFuncName,
539
+ astFuncExpr,
540
+ typeParams: tirTypeParams,
541
+ definingScope: topLevelScope,
542
+ canonicalTirName: tirFuncName,
543
+ placeholderFuncType,
544
+ constraints,
545
+ });
546
+ // Register the generic placeholder value in the top-level scope so
547
+ // identifier lookup at call sites finds it. The `genericTemplateName`
548
+ // field signals to `_compileCallExpr` that this is a template.
549
+ topLevelScope.functions.set(astFuncName, tirFuncName);
550
+ topLevelScope.defineValue({
551
+ name: astFuncName,
552
+ type: placeholderFuncType,
553
+ isConstant: true,
554
+ genericTemplateName: astFuncName,
555
+ });
556
+ if (exportRange && srcExports) {
557
+ if (srcExports.functions.has(astFuncName)
558
+ || srcExports.variables.has(astFuncName))
559
+ return this.error(DiagnosticCode._0_is_already_exported, exportRange, astFuncName);
560
+ srcExports.functions.set(astFuncName, tirFuncName);
561
+ srcExports.defineValue({
562
+ name: astFuncName,
563
+ type: placeholderFuncType,
564
+ isConstant: true,
565
+ genericTemplateName: astFuncName,
566
+ });
567
+ }
568
+ }
569
+ /**
570
+ * Resolve a `<T implements I>` constraint clause to a `TypeParamConstraint`.
571
+ *
572
+ * - `decl.constraint` must be a bare `AstNamedTypeExpr` (no type args).
573
+ * - The named interface must be registered in `scope.interfaces`
574
+ * (walking up the parent chain via `resolveInterface`).
575
+ *
576
+ * The returned object captures the AST method signatures verbatim so the
577
+ * monomorphizer doesn't have to re-resolve the interface each time.
578
+ */
579
+ _resolveTypeParamConstraint(scope, decl) {
580
+ const constraint = decl.constraint;
581
+ if (!constraint)
582
+ return undefined;
583
+ if (!(constraint instanceof AstNamedTypeExpr))
584
+ return this.error(DiagnosticCode.Type_expected, constraint.range);
585
+ if (constraint.tyArgs.length > 0)
586
+ return this.error(DiagnosticCode.Not_implemented_0, constraint.range, "generic interface as a type-parameter constraint");
587
+ const interfaceName = constraint.name.text;
588
+ const methods = scope.resolveInterface(interfaceName);
589
+ if (!methods)
590
+ return this.error(DiagnosticCode._0_is_not_defined, constraint.name.range, interfaceName);
591
+ return { interfaceName, methods };
592
+ }
593
+ /**
594
+ * walks `stmts` for `NamespaceDecl` (optionally wrapped in `ExportStmt`),
595
+ * compiles each one into a `NamespaceSymbol`, and registers it on
596
+ * `enclosingScope` (and `enclosingExports` when exported).
597
+ *
598
+ * removes processed `NamespaceDecl` statements from `stmts`.
599
+ */
600
+ _collectNamespaceDeclarations(stmts, srcUid, enclosingScope, enclosingExports) {
601
+ for (let i = 0; i < stmts.length; i++) {
602
+ let stmt = stmts[i];
603
+ let exported = false;
604
+ if (stmt instanceof ExportStmt) {
605
+ exported = true;
606
+ stmt = stmt.stmt;
607
+ }
608
+ if (!(stmt instanceof NamespaceDecl))
609
+ continue;
610
+ this._compileNamespaceDecl(stmt, srcUid, enclosingScope, enclosingExports, exported);
611
+ void stmts.splice(i, 1);
612
+ i--;
613
+ }
614
+ }
615
+ _compileNamespaceDecl(decl, srcUid, enclosingScope, enclosingExports, isExported) {
616
+ const nsName = decl.name.text;
617
+ if (enclosingScope.namespaces.has(nsName))
618
+ return this.error(DiagnosticCode._0_is_already_defined, decl.name.range, nsName);
619
+ const compilationScope = enclosingScope.newChildScope({ isFunctionDeclScope: false });
620
+ const publicScope = enclosingScope.newChildScope({ isFunctionDeclScope: false });
621
+ const nsSrcUid = `${srcUid}::${nsName}`;
622
+ // build a synthetic top-level statement list from the namespace's members:
623
+ // wrap public members in ExportStmt so the existing passes route them
624
+ // to `publicScope` automatically; leave private members bare so they only
625
+ // live in `compilationScope`.
626
+ const fakeStmts = decl.members.map((m) => m.isPrivate
627
+ ? m.stmt
628
+ : new ExportStmt(m.stmt, m.range));
629
+ // recurse into nested namespaces first so subsequent passes can
630
+ // resolve `Inner.Member` references.
631
+ this._collectNamespaceDeclarations(fakeStmts, nsSrcUid, compilationScope, publicScope);
632
+ this._collectTypeDeclarations(fakeStmts, nsSrcUid, compilationScope, publicScope);
633
+ this._collectInterfaceDeclarations(fakeStmts, compilationScope, publicScope);
634
+ this._collectAllTopLevelSignatures(fakeStmts, nsSrcUid, compilationScope, publicScope, false);
635
+ enclosingScope.defineNamespace({ name: nsName, publicScope });
636
+ if (isExported)
637
+ enclosingExports.defineNamespace({ name: nsName, publicScope });
638
+ }
459
639
  _collectInterfaceDeclarations(stmts, topLevelScope, srcExports) {
460
640
  for (let i = 0; i < stmts.length; i++) {
461
641
  let stmt = stmts[i];
@@ -603,7 +783,23 @@ export class AstCompiler extends DiagnosticEmitter {
603
783
  for (let i = 0; i < stmts.length; i++) {
604
784
  const stmt = stmts[i];
605
785
  if (stmt instanceof ImportStarStmt) {
606
- this.error(DiagnosticCode.Not_implemented_0, stmt.range, "import *");
786
+ const importAbsPath = getAbsolutePath(stmt.fromPath.string, srcAbsPath) ?? "";
787
+ const importedSymbols = this.program.getExportedSymbols(importAbsPath);
788
+ if (!importedSymbols) {
789
+ this.error(DiagnosticCode.File_0_not_found, stmt.fromPath.range, importAbsPath);
790
+ void stmts.splice(i, 1);
791
+ i--;
792
+ continue;
793
+ }
794
+ const aliasName = stmt.anIdentifier.text;
795
+ const ok = srcImportsScope.defineNamespace({
796
+ name: aliasName,
797
+ publicScope: importedSymbols
798
+ });
799
+ if (!ok)
800
+ this.error(DiagnosticCode._0_is_already_defined, stmt.anIdentifier.range, aliasName);
801
+ void stmts.splice(i, 1);
802
+ i--;
607
803
  continue;
608
804
  }
609
805
  if (!(stmt instanceof ImportStmt))
@@ -620,10 +816,12 @@ export class AstCompiler extends DiagnosticEmitter {
620
816
  const isType = importedSymbols.types.has(declName);
621
817
  const isFunction = importedSymbols.functions.has(declName);
622
818
  const isInterface = importedSymbols.interfaces.has(declName);
819
+ const isNamespace = importedSymbols.namespaces.has(declName);
623
820
  if (!(isValue
624
821
  || isType
625
822
  || isFunction
626
- || isInterface)) {
823
+ || isInterface
824
+ || isNamespace)) {
627
825
  this.error(DiagnosticCode.Module_0_has_no_exported_member_1, importDecl.identifier.range, stmt.fromPath.string, declName);
628
826
  continue;
629
827
  }
@@ -647,6 +845,8 @@ export class AstCompiler extends DiagnosticEmitter {
647
845
  srcImportsScope.types.set(declName, importedSymbols.types.get(declName));
648
846
  if (isInterface)
649
847
  srcImportsScope.interfaces.set(declName, importedSymbols.interfaces.get(declName));
848
+ if (isNamespace)
849
+ srcImportsScope.defineNamespace(importedSymbols.namespaces.get(declName));
650
850
  }
651
851
  // remove from array so we don't process it again
652
852
  void stmts.splice(i, 1);
@@ -14,6 +14,7 @@ import { LitIntExpr } from "../../../../ast/nodes/expr/litteral/LitIntExpr.js";
14
14
  import { LitNamedObjExpr } from "../../../../ast/nodes/expr/litteral/LitNamedObjExpr.js";
15
15
  import { LitObjExpr } from "../../../../ast/nodes/expr/litteral/LitObjExpr.js";
16
16
  import { LitStrExpr } from "../../../../ast/nodes/expr/litteral/LitStrExpr.js";
17
+ import { TemplateStrExpr } from "../../../../ast/nodes/expr/litteral/TemplateStrExpr.js";
17
18
  import { LitThisExpr } from "../../../../ast/nodes/expr/litteral/LitThisExpr.js";
18
19
  import { LitTrueExpr } from "../../../../ast/nodes/expr/litteral/LitTrueExpr.js";
19
20
  import { LitUndefExpr } from "../../../../ast/nodes/expr/litteral/LitUndefExpr.js";
@@ -44,7 +45,7 @@ import { IfStmt } from "../../../../ast/nodes/statements/IfStmt.js";
44
45
  import { MatchStmtCase, MatchStmt, MatchStmtElseCase } from "../../../../ast/nodes/statements/MatchStmt.js";
45
46
  import { ReturnStmt } from "../../../../ast/nodes/statements/ReturnStmt.js";
46
47
  import { TraceStmt } from "../../../../ast/nodes/statements/TraceStmt.js";
47
- import { UsingStmt } from "../../../../ast/nodes/statements/UsingStmt.js";
48
+ import { UsingAliasStmt, UsingStmt } from "../../../../ast/nodes/statements/UsingStmt.js";
48
49
  import { VarStmt } from "../../../../ast/nodes/statements/VarStmt.js";
49
50
  import { WhileStmt } from "../../../../ast/nodes/statements/WhileStmt.js";
50
51
  import { SourceRange } from "../../../../ast/Source/SourceRange.js";
@@ -457,7 +458,8 @@ function _getMatchedRedeemerBlockStatements(compiler, stmts, paramsInternalNames
457
458
  if (stmt instanceof BreakStmt
458
459
  || stmt instanceof ContinueStmt
459
460
  || stmt instanceof EmptyStmt
460
- || stmt instanceof UsingStmt)
461
+ || stmt instanceof UsingStmt
462
+ || stmt instanceof UsingAliasStmt)
461
463
  continue;
462
464
  if (isImplicitAssignmentStmt(stmt))
463
465
  continue;
@@ -766,6 +768,15 @@ function _exprReplaceParamsAndAssertNoLitContext(compiler, expr, paramsInternalN
766
768
  expr.body = new BlockStmt(nextBodyStmts, expr.body.range);
767
769
  return expr;
768
770
  }
771
+ if (expr instanceof TemplateStrExpr) {
772
+ for (let i = 0; i < expr.exprs.length; i++) {
773
+ const newSub = _exprReplaceParamsAndAssertNoLitContext(compiler, expr.exprs[i], paramsInternalNamesMap, renamedVariables);
774
+ if (!newSub)
775
+ return undefined;
776
+ expr.exprs[i] = newSub;
777
+ }
778
+ return expr;
779
+ }
769
780
  const tsEnsureExhaustiveCheck = expr;
770
781
  console.error(expr);
771
782
  throw new Error("unreachable::_exprReplaceParamsAndAssertNoLitContext");
@@ -2,12 +2,13 @@ import { DiagnosticCode } from "../../../../diagnostics/diagnosticMessages.gener
2
2
  import { TirCallExpr } from "../../../tir/expressions/TirCallExpr.js";
3
3
  import { TirFuncT } from "../../../tir/types/TirNativeType/native/function.js";
4
4
  import { canAssignTo } from "../../../tir/types/utils/canAssignTo.js";
5
+ import { inferTypeArgs } from "../../../tir/types/utils/inferTypeArgs.js";
6
+ import { substituteTypeParams } from "../../../tir/types/utils/substituteTypeParams.js";
7
+ import { TirVariableAccessExpr } from "../../../tir/expressions/TirVariableAccessExpr.js";
8
+ import { monomorphizeGeneric } from "../../utils/monomorphizeGeneric.js";
9
+ import { _compileDataEncodedConcreteType } from "../types/_compileDataEncodedConcreteType.js";
5
10
  import { _compileExpr } from "./_compileExpr.js";
6
11
  export function _compileCallExpr(ctx, expr, typeHint) {
7
- // TODO: expr.genericTypeArgs
8
- // expr.funcExpr;
9
- // expr.args;
10
- // expr.range;
11
12
  if (!(typeHint instanceof TirFuncT))
12
13
  typeHint = undefined;
13
14
  const funcExpr = _compileExpr(ctx, expr.funcExpr, typeHint);
@@ -15,7 +16,97 @@ export function _compileCallExpr(ctx, expr, typeHint) {
15
16
  return undefined;
16
17
  if (!(funcExpr.type instanceof TirFuncT))
17
18
  return ctx.error(DiagnosticCode.Expression_is_not_callable, expr.funcExpr.range);
18
- const funcType = funcExpr.type;
19
+ // ---- Generic-callee handling --------------------------------------
20
+ // If the callee resolved to a generic placeholder, the funcExpr is a
21
+ // `TirVariableAccessExpr` whose `variableInfos.genericTemplateName` names
22
+ // a template registered on `program.genericTemplates`. We instantiate it
23
+ // here with explicit or inferred type arguments and replace `funcExpr`
24
+ // with a synthetic access pointing at the concrete monomorphized instance.
25
+ let callee = funcExpr;
26
+ let funcType = funcExpr.type;
27
+ if (funcExpr instanceof TirVariableAccessExpr) {
28
+ const templateName = funcExpr.resolvedValue.variableInfos.genericTemplateName;
29
+ if (typeof templateName === "string") {
30
+ const template = ctx.program.genericTemplates.get(templateName);
31
+ if (!template)
32
+ return ctx.error(DiagnosticCode._0_is_not_defined, expr.funcExpr.range, templateName);
33
+ const nParams = template.typeParams.length;
34
+ // 1) Collect explicit type-args, if any
35
+ const explicitArgs = (Array.isArray(expr.genericTypeArgs)
36
+ ? new Array()
37
+ : undefined);
38
+ if (explicitArgs && expr.genericTypeArgs) {
39
+ for (const tArgExpr of expr.genericTypeArgs) {
40
+ const t = _compileDataEncodedConcreteType(ctx, tArgExpr, true);
41
+ if (!t)
42
+ return undefined;
43
+ explicitArgs.push(t);
44
+ }
45
+ if (explicitArgs.length !== nParams) {
46
+ return ctx.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, expr.funcExpr.range, String(nParams), String(explicitArgs.length));
47
+ }
48
+ }
49
+ // 2) Compile arguments. We need them anyway, and they're used for
50
+ // inference when no explicit args were given.
51
+ const tirArgs = expr.args.map((arg, i) => {
52
+ const expected = explicitArgs
53
+ ? substituteTypeParams(funcType.argTypes[i], new Map(template.typeParams.map((tp, idx) => [tp.symbol, explicitArgs[idx]])))
54
+ : undefined;
55
+ return _compileExpr(ctx, arg, expected);
56
+ });
57
+ for (const a of tirArgs)
58
+ if (!a)
59
+ return undefined;
60
+ // 3) Determine final type arguments
61
+ let resolvedArgs;
62
+ if (explicitArgs) {
63
+ resolvedArgs = explicitArgs;
64
+ }
65
+ else {
66
+ const env = new Map();
67
+ const usable = Math.min(tirArgs.length, funcType.argTypes.length);
68
+ for (let i = 0; i < usable; i++) {
69
+ if (!inferTypeArgs(funcType.argTypes[i], tirArgs[i].type, env)) {
70
+ return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.args[i].range, tirArgs[i].type.toString(), funcType.argTypes[i].toString());
71
+ }
72
+ }
73
+ resolvedArgs = new Array(nParams);
74
+ for (let i = 0; i < nParams; i++) {
75
+ const bound = env.get(template.typeParams[i].symbol);
76
+ if (!bound) {
77
+ return ctx.error(DiagnosticCode.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly, expr.funcExpr.range, template.typeParams[i].name);
78
+ }
79
+ resolvedArgs[i] = bound;
80
+ }
81
+ }
82
+ // 4) Monomorphize
83
+ const mono = monomorphizeGeneric(ctx, template, resolvedArgs, expr.range);
84
+ if (!mono)
85
+ return undefined;
86
+ funcType = mono.concreteFuncType;
87
+ // 5) Synthesize a TirVariableAccessExpr for the concrete instance.
88
+ // The IR layer looks up by name on `program.functions`, so it
89
+ // matches the entry registered by `monomorphizeGeneric`.
90
+ callee = new TirVariableAccessExpr({
91
+ variableInfos: {
92
+ name: mono.tirFuncName,
93
+ type: funcType,
94
+ isConstant: true,
95
+ },
96
+ isDefinedOutsideFuncScope: true,
97
+ }, expr.funcExpr.range);
98
+ // 6) Re-validate argument assignability against concrete signature
99
+ const finalCallExprType = funcType.argTypes.length === tirArgs.length
100
+ ? funcType.returnType
101
+ : new TirFuncT(funcType.argTypes.slice(tirArgs.length), funcType.returnType);
102
+ for (let i = 0; i < tirArgs.length && i < funcType.argTypes.length; i++) {
103
+ if (!canAssignTo(tirArgs[i].type, funcType.argTypes[i]))
104
+ return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.args[i].range, tirArgs[i].type.toString(), funcType.argTypes[i].toString());
105
+ }
106
+ return new TirCallExpr(callee, tirArgs, finalCallExprType, expr.range);
107
+ }
108
+ }
109
+ // ---- End generic-callee handling ----------------------------------
19
110
  for (let i = funcType.argTypes.length; i < expr.args.length; i++) {
20
111
  ctx.warning(DiagnosticCode.Unexpected_argument, expr.args[i].range); // not a big deal
21
112
  }
@@ -32,5 +123,5 @@ export function _compileCallExpr(ctx, expr, typeHint) {
32
123
  if (!canAssignTo(arg.type, funcType.argTypes[i]))
33
124
  return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.args[i].range, arg.type.toString(), funcType.argTypes[i].toString());
34
125
  }
35
- return new TirCallExpr(funcExpr, args, finalCallExprType, expr.range);
126
+ return new TirCallExpr(callee, args, finalCallExprType, expr.range);
36
127
  }
@@ -9,7 +9,6 @@ import { TirReturnStmt } from "../../../tir/statements/TirReturnStmt.js";
9
9
  import { TirSimpleVarDecl } from "../../../tir/statements/TirVarDecl/TirSimpleVarDecl.js";
10
10
  import { TirFuncT } from "../../../tir/types/TirNativeType/native/function.js";
11
11
  import { void_t } from "../../../tir/program/stdScope/stdScope.js";
12
- import { TirTypeParam } from "../../../tir/types/TirTypeParam.js";
13
12
  import { getUnaliased } from "../../../tir/types/utils/getUnaliased.js";
14
13
  import { _compileBlockStmt } from "../statements/_compileBlockStmt.js";
15
14
  import { _compileVarDecl } from "../statements/_compileVarStmt.js";
@@ -91,8 +90,13 @@ export function _compileFuncExpr(ctx, expr, expectedFuncType, isMethod = false)
91
90
  isConstant: true,
92
91
  });
93
92
  // if( _hasDuplicateTypeParams( ctx, expr.typeParams ) ) return undefined;
93
+ // Generic functions are compiled per-instantiation by `monomorphizeGeneric`.
94
+ // The cloned `FuncExpr` it produces has `typeParams = []`, so we only need
95
+ // to refuse the (rare) case where someone directly calls `_compileFuncExpr`
96
+ // on a still-generic AST node (e.g. an anonymous lambda annotated with type
97
+ // params, which is not supported yet).
94
98
  if (expr.typeParams.length > 0)
95
- return ctx.error(DiagnosticCode.Not_implemented_0, expr.typeParams[0].range, "generic functions");
99
+ return ctx.error(DiagnosticCode.Not_implemented_0, expr.typeParams[0].range, "generic lambda expressions (top-level generic functions are supported)");
96
100
  const destructuredParamsResult = _getDestructuredParamsAsVarDecls(funcCtx, expr, expectedFuncType);
97
101
  if (!destructuredParamsResult)
98
102
  return undefined;
@@ -140,8 +144,10 @@ function _compileFuncExprInferReturnType(ctx, expr, isMethod) {
140
144
  type: tempFuncType,
141
145
  isConstant: true,
142
146
  });
147
+ // Inferred-return-type variant: generics are not supported here because
148
+ // signature inference depends on knowing the type-param substitution.
143
149
  if (expr.typeParams.length > 0)
144
- return ctx.error(DiagnosticCode.Not_implemented_0, expr.typeParams[0].range, "generic functions");
150
+ return ctx.error(DiagnosticCode.Not_implemented_0, expr.typeParams[0].range, "generic functions with inferred return type — annotate the return type");
145
151
  const destructuredParamsResult = _getDestructuredParamsAsVarDecls(funcCtx, expr, tempFuncType);
146
152
  if (!destructuredParamsResult)
147
153
  return undefined;
@@ -234,8 +240,9 @@ export function getDataFuncSignature(ctx, signature) {
234
240
  const returnType = signature.returnType instanceof AstFuncType ?
235
241
  getDataFuncSignature(ctx, signature.returnType) :
236
242
  _compileSopEncodedConcreteType(ctx, signature.returnType);
237
- if (!returnType
238
- || returnType instanceof TirTypeParam)
243
+ if (!returnType)
239
244
  return undefined;
245
+ // NOTE: a bare `TirTypeParam` return type is valid here — it marks the
246
+ // template position. `monomorphizeGeneric` substitutes it at call sites.
240
247
  return new TirFuncT(paramTypes, returnType);
241
248
  }
@@ -7,6 +7,7 @@ import { LitIntExpr } from "../../../../ast/nodes/expr/litteral/LitIntExpr.js";
7
7
  import { LitNamedObjExpr } from "../../../../ast/nodes/expr/litteral/LitNamedObjExpr.js";
8
8
  import { LitObjExpr } from "../../../../ast/nodes/expr/litteral/LitObjExpr.js";
9
9
  import { LitStrExpr } from "../../../../ast/nodes/expr/litteral/LitStrExpr.js";
10
+ import { TemplateStrExpr } from "../../../../ast/nodes/expr/litteral/TemplateStrExpr.js";
10
11
  import { LitThisExpr } from "../../../../ast/nodes/expr/litteral/LitThisExpr.js";
11
12
  import { LitTrueExpr } from "../../../../ast/nodes/expr/litteral/LitTrueExpr.js";
12
13
  import { LitUndefExpr } from "../../../../ast/nodes/expr/litteral/LitUndefExpr.js";
@@ -66,6 +67,8 @@ export function _compileLitteralExpr(ctx, expr, typeHint) {
66
67
  return _compileLitteralNamedObjExpr(ctx, expr, typeHint);
67
68
  if (expr instanceof LitFailExpr)
68
69
  return new TirLitFailExpr(expr.range);
70
+ if (expr instanceof TemplateStrExpr)
71
+ return _compileTemplateStrExpr(ctx, expr);
69
72
  if (expr instanceof LitContextExpr)
70
73
  throw new Error("Litteral `context` should have been handled while desugaring.");
71
74
  const tsEnsureExhautstiveCheck = expr;
@@ -226,3 +229,59 @@ export function _compileLitteralArrayExpr(ctx, expr, typeHint) {
226
229
  return undefined;
227
230
  return new TirLitArrExpr([fstCompiledExpr, ...compiledRestElems], listType, expr.range);
228
231
  }
232
+ /**
233
+ * Compile a template string `` `text ${e1} more ${e2} ...` `` into a chain
234
+ * of `appendByteString` calls.
235
+ *
236
+ * Each text fragment becomes a `TirLitHexBytesExpr` containing its UTF-8
237
+ * encoding. Each interpolation is compiled and, if its type is not already
238
+ * `bytes`, wrapped in a `TirShowExpr` so it lowers via the built-in `Show`
239
+ * interface (or the user's `type X implements Show { ... }` override).
240
+ *
241
+ * Empty fragments collapse out — we don't emit `appendByteString("", x)`.
242
+ */
243
+ function _compileTemplateStrExpr(ctx, expr) {
244
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
245
+ const { fromUtf8 } = require("@harmoniclabs/uint8array-utils");
246
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
247
+ const { TirShowExpr } = require("../../../tir/expressions/TirShowExpr.js");
248
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
249
+ const { TirCallExpr } = require("../../../tir/expressions/TirCallExpr.js");
250
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
251
+ const { TirNativeFunc } = require("../../../tir/expressions/TirNativeFunc.js");
252
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
253
+ const { TirBytesT } = require("../../../tir/types/TirNativeType/native/bytes.js");
254
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
255
+ const { bytes_t } = require("../../../tir/program/stdScope/stdScope.js");
256
+ const pieces = [];
257
+ for (let i = 0; i < expr.parts.length; i++) {
258
+ const text = expr.parts[i];
259
+ if (text.length > 0) {
260
+ pieces.push(new TirLitHexBytesExpr(fromUtf8(text), expr.range));
261
+ }
262
+ if (i < expr.exprs.length) {
263
+ const sub = _compileExpr(ctx, expr.exprs[i], undefined);
264
+ if (!sub)
265
+ return undefined;
266
+ const subType = getUnaliased(sub.type);
267
+ if (subType instanceof TirBytesT) {
268
+ // Already valid UTF-8 by convention — pass through.
269
+ pieces.push(sub);
270
+ }
271
+ else {
272
+ // Auto-show via the built-in Show interface dispatch.
273
+ pieces.push(new TirShowExpr(sub, expr.exprs[i].range));
274
+ }
275
+ }
276
+ }
277
+ if (pieces.length === 0) {
278
+ // Empty template — emit empty bytes.
279
+ return new TirLitHexBytesExpr(new Uint8Array(0), expr.range);
280
+ }
281
+ // Left-fold appendByteString.
282
+ let acc = pieces[0];
283
+ for (let i = 1; i < pieces.length; i++) {
284
+ acc = new TirCallExpr(TirNativeFunc.appendByteString, [acc, pieces[i]], bytes_t, expr.range);
285
+ }
286
+ return acc;
287
+ }
@@ -1,9 +1,8 @@
1
1
  import { PropAccessExpr, OptionalPropAccessExpr, NonNullPropAccessExpr, DotPropAccessExpr } from "../../../../ast/nodes/expr/PropAccessExpr.js";
2
2
  import { TirExpr } from "../../../tir/expressions/TirExpr.js";
3
- import { TirPropAccessExpr } from "../../../tir/expressions/TirPropAccessExpr.js";
4
3
  import { TirType } from "../../../tir/types/TirType.js";
5
4
  import { AstCompilationCtx } from "../../AstCompilationCtx.js";
6
5
  export declare function _compilePropAccessExpr(ctx: AstCompilationCtx, expr: PropAccessExpr, typeHint: TirType | undefined): TirExpr | undefined;
7
6
  export declare function _compileOptionalPropAccessExpr(ctx: AstCompilationCtx, expr: OptionalPropAccessExpr, _typeHint: TirType | undefined): TirExpr | undefined;
8
- export declare function _compileNonNullPropAccessExpr(ctx: AstCompilationCtx, expr: NonNullPropAccessExpr, _typeHint: TirType | undefined): TirPropAccessExpr | undefined;
9
- export declare function _compileDotPropAccessExpr(ctx: AstCompilationCtx, expr: DotPropAccessExpr, _typeHint: TirType | undefined): TirPropAccessExpr | undefined;
7
+ export declare function _compileNonNullPropAccessExpr(ctx: AstCompilationCtx, expr: NonNullPropAccessExpr, _typeHint: TirType | undefined): TirExpr | undefined;
8
+ export declare function _compileDotPropAccessExpr(ctx: AstCompilationCtx, expr: DotPropAccessExpr, _typeHint: TirType | undefined): TirExpr | undefined;