@jhlagado/azm 0.1.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 (301) hide show
  1. package/LICENSE +649 -0
  2. package/README.md +142 -0
  3. package/dist/src/analysis.d.ts +11 -0
  4. package/dist/src/analysis.js +41 -0
  5. package/dist/src/api-compile.d.ts +8 -0
  6. package/dist/src/api-compile.js +3 -0
  7. package/dist/src/api-tooling.d.ts +25 -0
  8. package/dist/src/api-tooling.js +21 -0
  9. package/dist/src/cli.d.ts +30 -0
  10. package/dist/src/cli.js +523 -0
  11. package/dist/src/compile.d.ts +10 -0
  12. package/dist/src/compile.js +175 -0
  13. package/dist/src/compileShared.d.ts +3 -0
  14. package/dist/src/compileShared.js +7 -0
  15. package/dist/src/diagnosticTypes.d.ts +77 -0
  16. package/dist/src/diagnosticTypes.js +53 -0
  17. package/dist/src/formats/index.d.ts +7 -0
  18. package/dist/src/formats/index.js +17 -0
  19. package/dist/src/formats/range.d.ts +17 -0
  20. package/dist/src/formats/range.js +45 -0
  21. package/dist/src/formats/types.d.ts +208 -0
  22. package/dist/src/formats/types.js +1 -0
  23. package/dist/src/formats/writeAsm80.d.ts +6 -0
  24. package/dist/src/formats/writeAsm80.js +86 -0
  25. package/dist/src/formats/writeBin.d.ts +7 -0
  26. package/dist/src/formats/writeBin.js +23 -0
  27. package/dist/src/formats/writeD8m.d.ts +9 -0
  28. package/dist/src/formats/writeD8m.js +239 -0
  29. package/dist/src/formats/writeHex.d.ts +9 -0
  30. package/dist/src/formats/writeHex.js +39 -0
  31. package/dist/src/formats/writeListing.d.ts +8 -0
  32. package/dist/src/formats/writeListing.js +83 -0
  33. package/dist/src/frontend/asm80/asmLine.d.ts +39 -0
  34. package/dist/src/frontend/asm80/asmLine.js +89 -0
  35. package/dist/src/frontend/asm80/parseAsmRawValues.d.ts +4 -0
  36. package/dist/src/frontend/asm80/parseAsmRawValues.js +94 -0
  37. package/dist/src/frontend/asm80/quoteScan.d.ts +10 -0
  38. package/dist/src/frontend/asm80/quoteScan.js +25 -0
  39. package/dist/src/frontend/ast.d.ts +376 -0
  40. package/dist/src/frontend/ast.js +1 -0
  41. package/dist/src/frontend/directiveAliases.d.ts +14 -0
  42. package/dist/src/frontend/directiveAliases.js +189 -0
  43. package/dist/src/frontend/grammarData.d.ts +14 -0
  44. package/dist/src/frontend/grammarData.js +65 -0
  45. package/dist/src/frontend/immExprUtils.d.ts +2 -0
  46. package/dist/src/frontend/immExprUtils.js +12 -0
  47. package/dist/src/frontend/parseAsmFlatDirectiveLine.d.ts +17 -0
  48. package/dist/src/frontend/parseAsmFlatDirectiveLine.js +187 -0
  49. package/dist/src/frontend/parseAsmInstruction.d.ts +3 -0
  50. package/dist/src/frontend/parseAsmInstruction.js +73 -0
  51. package/dist/src/frontend/parseAsmStatements.d.ts +6 -0
  52. package/dist/src/frontend/parseAsmStatements.js +16 -0
  53. package/dist/src/frontend/parseAsmStream.d.ts +10 -0
  54. package/dist/src/frontend/parseAsmStream.js +33 -0
  55. package/dist/src/frontend/parseAsmTopLevel.d.ts +18 -0
  56. package/dist/src/frontend/parseAsmTopLevel.js +34 -0
  57. package/dist/src/frontend/parseDiagnostics.d.ts +9 -0
  58. package/dist/src/frontend/parseDiagnostics.js +16 -0
  59. package/dist/src/frontend/parseEnum.d.ts +12 -0
  60. package/dist/src/frontend/parseEnum.js +70 -0
  61. package/dist/src/frontend/parseImm.d.ts +10 -0
  62. package/dist/src/frontend/parseImm.js +397 -0
  63. package/dist/src/frontend/parseLogicalLines.d.ts +11 -0
  64. package/dist/src/frontend/parseLogicalLines.js +94 -0
  65. package/dist/src/frontend/parseOp.d.ts +25 -0
  66. package/dist/src/frontend/parseOp.js +120 -0
  67. package/dist/src/frontend/parseOpHeader.d.ts +20 -0
  68. package/dist/src/frontend/parseOpHeader.js +32 -0
  69. package/dist/src/frontend/parseOperands.d.ts +4 -0
  70. package/dist/src/frontend/parseOperands.js +290 -0
  71. package/dist/src/frontend/parseParams.d.ts +6 -0
  72. package/dist/src/frontend/parseParams.js +62 -0
  73. package/dist/src/frontend/parseParserRecovery.d.ts +12 -0
  74. package/dist/src/frontend/parseParserRecovery.js +17 -0
  75. package/dist/src/frontend/parseParserShared.d.ts +2 -0
  76. package/dist/src/frontend/parseParserShared.js +8 -0
  77. package/dist/src/frontend/parseRawDataDirectiveStart.d.ts +1 -0
  78. package/dist/src/frontend/parseRawDataDirectiveStart.js +3 -0
  79. package/dist/src/frontend/parseRawDataDirectives.d.ts +7 -0
  80. package/dist/src/frontend/parseRawDataDirectives.js +142 -0
  81. package/dist/src/frontend/parseRecordFieldDecl.d.ts +34 -0
  82. package/dist/src/frontend/parseRecordFieldDecl.js +177 -0
  83. package/dist/src/frontend/parseSourceItemDispatch.d.ts +46 -0
  84. package/dist/src/frontend/parseSourceItemDispatch.js +53 -0
  85. package/dist/src/frontend/parseSourceItemTable.d.ts +16 -0
  86. package/dist/src/frontend/parseSourceItemTable.js +68 -0
  87. package/dist/src/frontend/parseTopLevelCommon.d.ts +11 -0
  88. package/dist/src/frontend/parseTopLevelCommon.js +50 -0
  89. package/dist/src/frontend/parseTypes.d.ts +24 -0
  90. package/dist/src/frontend/parseTypes.js +77 -0
  91. package/dist/src/frontend/parser.d.ts +11 -0
  92. package/dist/src/frontend/parser.js +88 -0
  93. package/dist/src/frontend/source.d.ts +28 -0
  94. package/dist/src/frontend/source.js +58 -0
  95. package/dist/src/frontend/sourceExtensions.d.ts +2 -0
  96. package/dist/src/frontend/sourceExtensions.js +6 -0
  97. package/dist/src/index.d.ts +3 -0
  98. package/dist/src/index.js +2 -0
  99. package/dist/src/lintCaseStyle.d.ts +4 -0
  100. package/dist/src/lintCaseStyle.js +129 -0
  101. package/dist/src/lowering/asmDirectiveLowering.d.ts +4 -0
  102. package/dist/src/lowering/asmDirectiveLowering.js +229 -0
  103. package/dist/src/lowering/asmDirectiveTraversal.d.ts +47 -0
  104. package/dist/src/lowering/asmDirectiveTraversal.js +52 -0
  105. package/dist/src/lowering/asmEquResolution.d.ts +8 -0
  106. package/dist/src/lowering/asmEquResolution.js +69 -0
  107. package/dist/src/lowering/asmInstructionLdHelpers.d.ts +15 -0
  108. package/dist/src/lowering/asmInstructionLdHelpers.js +102 -0
  109. package/dist/src/lowering/asmInstructionLowering.d.ts +5 -0
  110. package/dist/src/lowering/asmInstructionLowering.js +54 -0
  111. package/dist/src/lowering/asmInstructionStream.d.ts +46 -0
  112. package/dist/src/lowering/asmInstructionStream.js +51 -0
  113. package/dist/src/lowering/asmLoweringBranchCall.d.ts +43 -0
  114. package/dist/src/lowering/asmLoweringBranchCall.js +254 -0
  115. package/dist/src/lowering/asmLoweringHost.d.ts +23 -0
  116. package/dist/src/lowering/asmLoweringHost.js +1 -0
  117. package/dist/src/lowering/asmLoweringLd.d.ts +28 -0
  118. package/dist/src/lowering/asmLoweringLd.js +144 -0
  119. package/dist/src/lowering/asmRangeLowering.d.ts +17 -0
  120. package/dist/src/lowering/asmRangeLowering.js +39 -0
  121. package/dist/src/lowering/asmRawDataLowering.d.ts +16 -0
  122. package/dist/src/lowering/asmRawDataLowering.js +209 -0
  123. package/dist/src/lowering/asmSourceEmitter.d.ts +4 -0
  124. package/dist/src/lowering/asmSourceEmitter.js +9 -0
  125. package/dist/src/lowering/asmSourceInstructionLowering.d.ts +4 -0
  126. package/dist/src/lowering/asmSourceInstructionLowering.js +14 -0
  127. package/dist/src/lowering/asmUtils.d.ts +13 -0
  128. package/dist/src/lowering/asmUtils.js +105 -0
  129. package/dist/src/lowering/assemblerFlowSetup.d.ts +54 -0
  130. package/dist/src/lowering/assemblerFlowSetup.js +128 -0
  131. package/dist/src/lowering/assemblerLoweringContext.d.ts +151 -0
  132. package/dist/src/lowering/assemblerLoweringContext.js +16 -0
  133. package/dist/src/lowering/assemblerLoweringContextSplit.d.ts +7 -0
  134. package/dist/src/lowering/assemblerLoweringContextSplit.js +75 -0
  135. package/dist/src/lowering/assemblerLoweringPhases.d.ts +66 -0
  136. package/dist/src/lowering/assemblerLoweringPhases.js +166 -0
  137. package/dist/src/lowering/bytePlacement.d.ts +7 -0
  138. package/dist/src/lowering/bytePlacement.js +37 -0
  139. package/dist/src/lowering/capabilities.d.ts +67 -0
  140. package/dist/src/lowering/capabilities.js +1 -0
  141. package/dist/src/lowering/eaResolution.d.ts +58 -0
  142. package/dist/src/lowering/eaResolution.js +159 -0
  143. package/dist/src/lowering/emissionCore.d.ts +17 -0
  144. package/dist/src/lowering/emissionCore.js +21 -0
  145. package/dist/src/lowering/emit.d.ts +17 -0
  146. package/dist/src/lowering/emit.js +46 -0
  147. package/dist/src/lowering/emitContextBuilder.d.ts +63 -0
  148. package/dist/src/lowering/emitContextBuilder.js +41 -0
  149. package/dist/src/lowering/emitFinalization.d.ts +61 -0
  150. package/dist/src/lowering/emitFinalization.js +66 -0
  151. package/dist/src/lowering/emitFinalizationSetup.d.ts +19 -0
  152. package/dist/src/lowering/emitFinalizationSetup.js +26 -0
  153. package/dist/src/lowering/emitPhase1BuildProgramLoweringContext.d.ts +7 -0
  154. package/dist/src/lowering/emitPhase1BuildProgramLoweringContext.js +119 -0
  155. package/dist/src/lowering/emitPhase1Helpers.d.ts +4 -0
  156. package/dist/src/lowering/emitPhase1Helpers.js +12 -0
  157. package/dist/src/lowering/emitPhase1Types.d.ts +21 -0
  158. package/dist/src/lowering/emitPhase1Types.js +1 -0
  159. package/dist/src/lowering/emitPhase1WirePipeline.d.ts +70 -0
  160. package/dist/src/lowering/emitPhase1WirePipeline.js +203 -0
  161. package/dist/src/lowering/emitPhase1Workspace.d.ts +82 -0
  162. package/dist/src/lowering/emitPhase1Workspace.js +55 -0
  163. package/dist/src/lowering/emitPipeline.d.ts +121 -0
  164. package/dist/src/lowering/emitPipeline.js +57 -0
  165. package/dist/src/lowering/emitProgramContext.d.ts +39 -0
  166. package/dist/src/lowering/emitProgramContext.js +29 -0
  167. package/dist/src/lowering/emitState.d.ts +90 -0
  168. package/dist/src/lowering/emitState.js +124 -0
  169. package/dist/src/lowering/fixupBaseResolution.d.ts +7 -0
  170. package/dist/src/lowering/fixupBaseResolution.js +23 -0
  171. package/dist/src/lowering/fixupEmission.d.ts +64 -0
  172. package/dist/src/lowering/fixupEmission.js +199 -0
  173. package/dist/src/lowering/immMath.d.ts +2 -0
  174. package/dist/src/lowering/immMath.js +34 -0
  175. package/dist/src/lowering/inputAssets.d.ts +7 -0
  176. package/dist/src/lowering/inputAssets.js +106 -0
  177. package/dist/src/lowering/ldEncoding.d.ts +15 -0
  178. package/dist/src/lowering/ldEncoding.js +12 -0
  179. package/dist/src/lowering/ldEncodingRegMemHelpers.d.ts +5 -0
  180. package/dist/src/lowering/ldEncodingRegMemHelpers.js +124 -0
  181. package/dist/src/lowering/ldFormSelection.d.ts +26 -0
  182. package/dist/src/lowering/ldFormSelection.js +92 -0
  183. package/dist/src/lowering/ldLowering.d.ts +7 -0
  184. package/dist/src/lowering/ldLowering.js +13 -0
  185. package/dist/src/lowering/loweredAsmByteEmission.d.ts +23 -0
  186. package/dist/src/lowering/loweredAsmByteEmission.js +185 -0
  187. package/dist/src/lowering/loweredAsmPlacement.d.ts +13 -0
  188. package/dist/src/lowering/loweredAsmPlacement.js +86 -0
  189. package/dist/src/lowering/loweredAsmStreamRecording.d.ts +27 -0
  190. package/dist/src/lowering/loweredAsmStreamRecording.js +215 -0
  191. package/dist/src/lowering/loweredAsmTypes.d.ts +202 -0
  192. package/dist/src/lowering/loweredAsmTypes.js +1 -0
  193. package/dist/src/lowering/loweredFormat.d.ts +3 -0
  194. package/dist/src/lowering/loweredFormat.js +26 -0
  195. package/dist/src/lowering/loweredItemSize.d.ts +4 -0
  196. package/dist/src/lowering/loweredItemSize.js +17 -0
  197. package/dist/src/lowering/loweringDiagnostics.d.ts +9 -0
  198. package/dist/src/lowering/loweringDiagnostics.js +55 -0
  199. package/dist/src/lowering/loweringTypes.d.ts +27 -0
  200. package/dist/src/lowering/loweringTypes.js +1 -0
  201. package/dist/src/lowering/opCandidateRegistry.d.ts +9 -0
  202. package/dist/src/lowering/opCandidateRegistry.js +9 -0
  203. package/dist/src/lowering/opExpansionExecution.d.ts +15 -0
  204. package/dist/src/lowering/opExpansionExecution.js +45 -0
  205. package/dist/src/lowering/opExpansionOrchestration.d.ts +15 -0
  206. package/dist/src/lowering/opExpansionOrchestration.js +88 -0
  207. package/dist/src/lowering/opExpansionStream.d.ts +12 -0
  208. package/dist/src/lowering/opExpansionStream.js +176 -0
  209. package/dist/src/lowering/opMatching.d.ts +52 -0
  210. package/dist/src/lowering/opMatching.js +355 -0
  211. package/dist/src/lowering/opSubstitution.d.ts +13 -0
  212. package/dist/src/lowering/opSubstitution.js +175 -0
  213. package/dist/src/lowering/prescanTypes.d.ts +7 -0
  214. package/dist/src/lowering/prescanTypes.js +1 -0
  215. package/dist/src/lowering/programLowering.d.ts +144 -0
  216. package/dist/src/lowering/programLowering.js +2 -0
  217. package/dist/src/lowering/programLoweringDeclarations.d.ts +5 -0
  218. package/dist/src/lowering/programLoweringDeclarations.js +5 -0
  219. package/dist/src/lowering/programLoweringFinalize.d.ts +18 -0
  220. package/dist/src/lowering/programLoweringFinalize.js +115 -0
  221. package/dist/src/lowering/programLoweringTraversal.d.ts +2 -0
  222. package/dist/src/lowering/programLoweringTraversal.js +93 -0
  223. package/dist/src/lowering/programPrescan.d.ts +3 -0
  224. package/dist/src/lowering/programPrescan.js +37 -0
  225. package/dist/src/lowering/traceFormat.d.ts +13 -0
  226. package/dist/src/lowering/traceFormat.js +211 -0
  227. package/dist/src/pathCompare.d.ts +3 -0
  228. package/dist/src/pathCompare.js +26 -0
  229. package/dist/src/pipeline.d.ts +78 -0
  230. package/dist/src/pipeline.js +1 -0
  231. package/dist/src/registerCare/analyze.d.ts +24 -0
  232. package/dist/src/registerCare/analyze.js +327 -0
  233. package/dist/src/registerCare/annotate.d.ts +11 -0
  234. package/dist/src/registerCare/annotate.js +76 -0
  235. package/dist/src/registerCare/boundaryHints.d.ts +2 -0
  236. package/dist/src/registerCare/boundaryHints.js +10 -0
  237. package/dist/src/registerCare/carriers.d.ts +4 -0
  238. package/dist/src/registerCare/carriers.js +78 -0
  239. package/dist/src/registerCare/controlFlow.d.ts +5 -0
  240. package/dist/src/registerCare/controlFlow.js +35 -0
  241. package/dist/src/registerCare/fix.d.ts +11 -0
  242. package/dist/src/registerCare/fix.js +119 -0
  243. package/dist/src/registerCare/liveness.d.ts +7 -0
  244. package/dist/src/registerCare/liveness.js +227 -0
  245. package/dist/src/registerCare/profiles.d.ts +11 -0
  246. package/dist/src/registerCare/profiles.js +45 -0
  247. package/dist/src/registerCare/programModel.d.ts +3 -0
  248. package/dist/src/registerCare/programModel.js +181 -0
  249. package/dist/src/registerCare/report.d.ts +5 -0
  250. package/dist/src/registerCare/report.js +139 -0
  251. package/dist/src/registerCare/smartComments.d.ts +5 -0
  252. package/dist/src/registerCare/smartComments.js +247 -0
  253. package/dist/src/registerCare/sourceText.d.ts +8 -0
  254. package/dist/src/registerCare/sourceText.js +15 -0
  255. package/dist/src/registerCare/summary.d.ts +3 -0
  256. package/dist/src/registerCare/summary.js +492 -0
  257. package/dist/src/registerCare/tooling.d.ts +42 -0
  258. package/dist/src/registerCare/tooling.js +50 -0
  259. package/dist/src/registerCare/types.d.ts +154 -0
  260. package/dist/src/registerCare/types.js +1 -0
  261. package/dist/src/semantics/declVisitor.d.ts +5 -0
  262. package/dist/src/semantics/declVisitor.js +11 -0
  263. package/dist/src/semantics/env.d.ts +28 -0
  264. package/dist/src/semantics/env.js +432 -0
  265. package/dist/src/semantics/layout.d.ts +21 -0
  266. package/dist/src/semantics/layout.js +226 -0
  267. package/dist/src/semantics/layoutCastFold.d.ts +22 -0
  268. package/dist/src/semantics/layoutCastFold.js +118 -0
  269. package/dist/src/semantics/semanticsDiagnostics.d.ts +2 -0
  270. package/dist/src/semantics/semanticsDiagnostics.js +4 -0
  271. package/dist/src/semantics/typeQueries.d.ts +31 -0
  272. package/dist/src/semantics/typeQueries.js +124 -0
  273. package/dist/src/sourceIncludeExpansion.d.ts +17 -0
  274. package/dist/src/sourceIncludeExpansion.js +124 -0
  275. package/dist/src/sourceIncludePaths.d.ts +1 -0
  276. package/dist/src/sourceIncludePaths.js +12 -0
  277. package/dist/src/sourceLoader.d.ts +15 -0
  278. package/dist/src/sourceLoader.js +118 -0
  279. package/dist/src/z80/effects.d.ts +3 -0
  280. package/dist/src/z80/effects.js +516 -0
  281. package/dist/src/z80/encode.d.ts +10 -0
  282. package/dist/src/z80/encode.js +412 -0
  283. package/dist/src/z80/encodeAlu.d.ts +7 -0
  284. package/dist/src/z80/encodeAlu.js +219 -0
  285. package/dist/src/z80/encodeBitOps.d.ts +7 -0
  286. package/dist/src/z80/encodeBitOps.js +123 -0
  287. package/dist/src/z80/encodeContext.d.ts +29 -0
  288. package/dist/src/z80/encodeContext.js +1 -0
  289. package/dist/src/z80/encodeControl.d.ts +26 -0
  290. package/dist/src/z80/encodeControl.js +180 -0
  291. package/dist/src/z80/encodeCoreOps.d.ts +7 -0
  292. package/dist/src/z80/encodeCoreOps.js +131 -0
  293. package/dist/src/z80/encodeIo.d.ts +9 -0
  294. package/dist/src/z80/encodeIo.js +128 -0
  295. package/dist/src/z80/encodeLd.d.ts +13 -0
  296. package/dist/src/z80/encodeLd.js +273 -0
  297. package/dist/src/z80/encoderRegistry.d.ts +13 -0
  298. package/dist/src/z80/encoderRegistry.js +169 -0
  299. package/docs/reference/cli.md +134 -0
  300. package/docs/reference/tooling-api.md +248 -0
  301. package/package.json +98 -0
@@ -0,0 +1,211 @@
1
+ const toHexByte = (n) => `$${(n & 0xff).toString(16).toUpperCase().padStart(2, '0')}`;
2
+ const toHexWord = (n) => `$${(n & 0xffff).toString(16).toUpperCase().padStart(4, '0')}`;
3
+ export const formatImmExprForAsm = (expr) => {
4
+ switch (expr.kind) {
5
+ case 'ImmLiteral':
6
+ return toHexWord(expr.value);
7
+ case 'ImmName':
8
+ return expr.name;
9
+ case 'ImmSizeof':
10
+ return 'sizeof(...)';
11
+ case 'ImmOffset':
12
+ return 'offset(...)';
13
+ case 'ImmUnary':
14
+ return `${expr.op}${formatImmExprForAsm(expr.expr)}`;
15
+ case 'ImmBinary':
16
+ return `${formatImmExprForAsm(expr.left)} ${expr.op} ${formatImmExprForAsm(expr.right)}`;
17
+ default:
18
+ return 'imm';
19
+ }
20
+ };
21
+ export const formatEaExpr = (ea, { formatImmExpr, wrapImmEa = false }) => {
22
+ switch (ea.kind) {
23
+ case 'EaName':
24
+ return ea.name;
25
+ case 'EaImm':
26
+ return wrapImmEa ? `(${formatImmExpr(ea.expr)})` : formatImmExpr(ea.expr);
27
+ case 'EaField':
28
+ return `${formatEaExpr(ea.base, { formatImmExpr, wrapImmEa })}.${ea.field}`;
29
+ case 'EaAdd':
30
+ return `${formatEaExpr(ea.base, { formatImmExpr, wrapImmEa })} + ${formatImmExpr(ea.offset)}`;
31
+ case 'EaSub':
32
+ return `${formatEaExpr(ea.base, { formatImmExpr, wrapImmEa })} - ${formatImmExpr(ea.offset)}`;
33
+ case 'EaIndex': {
34
+ let idx = '';
35
+ switch (ea.index.kind) {
36
+ case 'IndexImm':
37
+ idx = formatImmExpr(ea.index.value);
38
+ break;
39
+ case 'IndexReg8':
40
+ case 'IndexReg16':
41
+ idx = ea.index.reg;
42
+ break;
43
+ case 'IndexMemHL':
44
+ idx = '(HL)';
45
+ break;
46
+ case 'IndexMemIxIy':
47
+ idx = ea.index.disp
48
+ ? `${ea.index.base}${ea.index.disp.kind === 'ImmUnary' ? '' : '+'}${formatImmExpr(ea.index.disp)}`
49
+ : ea.index.base;
50
+ break;
51
+ case 'IndexEa':
52
+ idx = formatEaExpr(ea.index.expr, { formatImmExpr, wrapImmEa });
53
+ break;
54
+ }
55
+ return `${formatEaExpr(ea.base, { formatImmExpr, wrapImmEa })}[${idx}]`;
56
+ }
57
+ default:
58
+ return 'ea';
59
+ }
60
+ };
61
+ const formatEaExprForAsm = (ea) => formatEaExpr(ea, { formatImmExpr: formatImmExprForAsm });
62
+ const formatAsmOperandForTrace = (operand) => {
63
+ switch (operand.kind) {
64
+ case 'Reg':
65
+ return operand.name;
66
+ case 'Imm':
67
+ return formatImmExprForAsm(operand.expr);
68
+ case 'Ea':
69
+ return formatEaExprForAsm(operand.expr);
70
+ case 'Mem':
71
+ return `(${formatEaExprForAsm(operand.expr)})`;
72
+ case 'PortC':
73
+ return '(C)';
74
+ case 'PortImm8':
75
+ return `(${formatImmExprForAsm(operand.expr)})`;
76
+ default:
77
+ return '?';
78
+ }
79
+ };
80
+ export const formatAsmInstrForTrace = (head, operands) => {
81
+ const lowerHead = head.toLowerCase();
82
+ if (operands.length === 0)
83
+ return lowerHead;
84
+ return `${lowerHead} ${operands.map(formatAsmOperandForTrace).join(', ')}`;
85
+ };
86
+ const formatFixupSymbolExpr = (baseLower, addend) => {
87
+ if (addend === 0)
88
+ return baseLower;
89
+ if (addend > 0)
90
+ return `${baseLower} + ${addend}`;
91
+ return `${baseLower} - ${Math.abs(addend)}`;
92
+ };
93
+ const jpCondFromOpcode = (opcode) => {
94
+ switch (opcode & 0xff) {
95
+ case 0xc2:
96
+ return 'NZ';
97
+ case 0xca:
98
+ return 'Z';
99
+ case 0xd2:
100
+ return 'NC';
101
+ case 0xda:
102
+ return 'C';
103
+ case 0xe2:
104
+ return 'PO';
105
+ case 0xea:
106
+ return 'PE';
107
+ case 0xf2:
108
+ return 'P';
109
+ case 0xfa:
110
+ return 'M';
111
+ default:
112
+ return undefined;
113
+ }
114
+ };
115
+ const callCondFromOpcode = (opcode) => {
116
+ switch (opcode & 0xff) {
117
+ case 0xc4:
118
+ return 'NZ';
119
+ case 0xcc:
120
+ return 'Z';
121
+ case 0xd4:
122
+ return 'NC';
123
+ case 0xdc:
124
+ return 'C';
125
+ case 0xe4:
126
+ return 'PO';
127
+ case 0xec:
128
+ return 'PE';
129
+ case 0xf4:
130
+ return 'P';
131
+ case 0xfc:
132
+ return 'M';
133
+ default:
134
+ return undefined;
135
+ }
136
+ };
137
+ export const formatAbs16FixupAsm = (opcode, baseLower, addend) => {
138
+ const sym = formatFixupSymbolExpr(baseLower, addend);
139
+ switch (opcode & 0xff) {
140
+ case 0x01:
141
+ return `ld BC, ${sym}`;
142
+ case 0x11:
143
+ return `ld DE, ${sym}`;
144
+ case 0x21:
145
+ return `ld HL, ${sym}`;
146
+ case 0x31:
147
+ return `ld SP, ${sym}`;
148
+ case 0x2a:
149
+ return `ld HL, (${sym})`;
150
+ case 0x3a:
151
+ return `ld A, (${sym})`;
152
+ case 0x22:
153
+ return `ld (${sym}), HL`;
154
+ case 0x32:
155
+ return `ld (${sym}), A`;
156
+ case 0xc3:
157
+ return `jp ${sym}`;
158
+ case 0xcd:
159
+ return `call ${sym}`;
160
+ default: {
161
+ const jpCc = jpCondFromOpcode(opcode);
162
+ if (jpCc)
163
+ return `jp ${jpCc}, ${sym}`;
164
+ const callCc = callCondFromOpcode(opcode);
165
+ if (callCc)
166
+ return `call ${callCc}, ${sym}`;
167
+ return `db ${toHexByte(opcode)}, lo(${baseLower}), hi(${baseLower})`;
168
+ }
169
+ }
170
+ };
171
+ export const formatAbs16FixupEdAsm = (opcode2, baseLower, addend) => {
172
+ const sym = formatFixupSymbolExpr(baseLower, addend);
173
+ switch (opcode2 & 0xff) {
174
+ case 0x4b:
175
+ return `ld BC, (${sym})`;
176
+ case 0x5b:
177
+ return `ld DE, (${sym})`;
178
+ case 0x7b:
179
+ return `ld SP, (${sym})`;
180
+ case 0x43:
181
+ return `ld (${sym}), BC`;
182
+ case 0x53:
183
+ return `ld (${sym}), DE`;
184
+ case 0x73:
185
+ return `ld (${sym}), SP`;
186
+ default:
187
+ return `db $ED, ${toHexByte(opcode2)}, lo(${baseLower}), hi(${baseLower})`;
188
+ }
189
+ };
190
+ export const formatAbs16FixupPrefixedAsm = (prefix, opcode2, baseLower, addend) => {
191
+ const sym = formatFixupSymbolExpr(baseLower, addend);
192
+ const reg16 = prefix === 0xdd ? 'IX' : prefix === 0xfd ? 'IY' : undefined;
193
+ if (!reg16) {
194
+ return `db ${toHexByte(prefix)}, ${toHexByte(opcode2)}, lo(${baseLower}), hi(${baseLower})`;
195
+ }
196
+ switch (opcode2 & 0xff) {
197
+ case 0x21:
198
+ return `ld ${reg16}, ${sym}`;
199
+ case 0x2a:
200
+ return `ld ${reg16}, (${sym})`;
201
+ case 0x22:
202
+ return `ld (${sym}), ${reg16}`;
203
+ default:
204
+ return `db ${toHexByte(prefix)}, ${toHexByte(opcode2)}, lo(${baseLower}), hi(${baseLower})`;
205
+ }
206
+ };
207
+ export const formatIxDisp = (disp) => {
208
+ const hex = Math.abs(disp).toString(16).padStart(2, '0');
209
+ const sign = disp >= 0 ? '+' : '-';
210
+ return `${sign}$${hex}`;
211
+ };
@@ -0,0 +1,3 @@
1
+ export declare function normalizePathForCompare(path: string, options?: {
2
+ realpath?: boolean;
3
+ }): string;
@@ -0,0 +1,26 @@
1
+ import { realpathSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ function stripExtendedWindowsPrefix(path) {
4
+ if (path.startsWith('\\\\?\\UNC\\'))
5
+ return `\\\\${path.slice(8)}`;
6
+ if (path.startsWith('\\\\?\\'))
7
+ return path.slice(4);
8
+ return path;
9
+ }
10
+ export function normalizePathForCompare(path, options = {}) {
11
+ const resolved = options.realpath ? resolve(path) : path;
12
+ const canonical = (() => {
13
+ if (!options.realpath)
14
+ return resolved;
15
+ try {
16
+ return realpathSync.native(resolved);
17
+ }
18
+ catch {
19
+ return resolved;
20
+ }
21
+ })();
22
+ const stripped = stripExtendedWindowsPrefix(canonical);
23
+ const normalized = stripped.replace(/\\/g, '/');
24
+ const normalizedDarwin = process.platform === 'darwin' ? normalized.replace(/^\/private\//, '/') : normalized;
25
+ return process.platform === 'win32' ? normalizedDarwin.toLowerCase() : normalizedDarwin;
26
+ }
@@ -0,0 +1,78 @@
1
+ import type { Diagnostic } from './diagnosticTypes.js';
2
+ import type { Artifact, FormatWriters } from './formats/types.js';
3
+ import type { RegisterCareMode } from './registerCare/types.js';
4
+ export type CaseStyleMode = 'off' | 'upper' | 'lower' | 'consistent';
5
+ /**
6
+ * Options that influence compilation behavior and which artifacts are produced.
7
+ *
8
+ * PR1 implementation note: most options are accepted but only a subset is currently honored.
9
+ */
10
+ export interface CompilerOptions {
11
+ /**
12
+ * Additional include/search directories used for textual includes and input assets.
13
+ *
14
+ * These directories are consulted after checking paths relative to the
15
+ * importing source file.
16
+ */
17
+ includeDirs?: string[];
18
+ /** Primary output path used to derive sibling artifacts (future). */
19
+ outputPath?: string;
20
+ /** Primary output type (future). */
21
+ outputType?: 'hex' | 'bin';
22
+ /** Emit flat binary (`.bin`). */
23
+ emitBin?: boolean;
24
+ /** Emit Intel HEX (`.hex`). */
25
+ emitHex?: boolean;
26
+ /** Emit D8 Debug Map (`.d8.json`). */
27
+ emitD8m?: boolean;
28
+ /** Emit listing (`.lst`). */
29
+ emitListing?: boolean;
30
+ /** Emit ASM80-compatible lowered source (`.asm`). */
31
+ emitAsm80?: boolean;
32
+ /** Optional case-style lint mode for asm keywords/register tokens. */
33
+ caseStyle?: CaseStyleMode;
34
+ /** Require a `main` entry label for runnable builds. */
35
+ requireMain?: boolean;
36
+ /** Default code base address. */
37
+ defaultCodeBase?: number;
38
+ /** JSON directive alias files. Later files extend or override earlier aliases. */
39
+ directiveAliasFiles?: string[];
40
+ /** Register-care analysis mode. */
41
+ registerCare?: RegisterCareMode;
42
+ /** Emit a register-care audit report artifact. */
43
+ emitRegisterReport?: boolean;
44
+ /** Emit an inferred register-care interface artifact. */
45
+ emitRegisterInterface?: boolean;
46
+ /** Rewrite source files with inferred register-care contract blocks. */
47
+ emitRegisterAnnotations?: boolean;
48
+ /** Apply conservative register-care source fixes. Implies source annotations. */
49
+ fixRegisterContracts?: boolean;
50
+ /**
51
+ * Promote selected caller-use output candidates while rewriting register-care
52
+ * source annotations. Entries use `ROUTINE:carriers`, for example `MxMask:A`.
53
+ */
54
+ acceptRegisterOutputCandidates?: string[];
55
+ /** Register-care analysis profile. */
56
+ registerCareProfile?: 'mon3';
57
+ /** Register-care contract files that provide contracts for external/library routines. */
58
+ registerCareInterfaces?: string[];
59
+ }
60
+ /**
61
+ * Result of a compilation run: diagnostics plus any produced artifacts.
62
+ */
63
+ export interface CompileResult {
64
+ diagnostics: Diagnostic[];
65
+ artifacts: Artifact[];
66
+ }
67
+ /**
68
+ * Dependency injection surface for the compiler pipeline.
69
+ *
70
+ * Callers provide concrete format writers so the core pipeline can be pure/in-memory.
71
+ */
72
+ export interface PipelineDeps {
73
+ formats: FormatWriters;
74
+ }
75
+ /**
76
+ * Top-level compile function signature used by the pipeline contract.
77
+ */
78
+ export type CompileFn = (entryFile: string, options: CompilerOptions, deps: PipelineDeps) => Promise<CompileResult>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ import { type Diagnostic } from '../diagnosticTypes.js';
2
+ import type { LoadedProgram } from '../sourceLoader.js';
3
+ import { type RegisterCareAnnotatedFile } from './annotate.js';
4
+ import { type RegisterCareProfileName } from './profiles.js';
5
+ import type { RegisterCareMode, RegisterCareReportModel, RoutineContract } from './types.js';
6
+ export interface AnalyzeRegisterCareOptions {
7
+ mode: RegisterCareMode;
8
+ emitReport: boolean;
9
+ emitInterface: boolean;
10
+ emitAnnotations?: boolean;
11
+ fixRegisterContracts?: boolean;
12
+ acceptOutputCandidates?: string[];
13
+ profile?: RegisterCareProfileName;
14
+ interfaceContracts?: RoutineContract[];
15
+ }
16
+ interface AnalyzeRegisterCareResult {
17
+ diagnostics: Diagnostic[];
18
+ outputCandidates?: RegisterCareReportModel['outputCandidates'];
19
+ reportText?: string;
20
+ interfaceText?: string;
21
+ annotatedFiles?: RegisterCareAnnotatedFile[];
22
+ }
23
+ export declare function analyzeRegisterCare(loaded: LoadedProgram, options: AnalyzeRegisterCareOptions): AnalyzeRegisterCareResult;
24
+ export {};
@@ -0,0 +1,327 @@
1
+ import { DiagnosticIds } from '../diagnosticTypes.js';
2
+ import { annotateRegisterCareContracts } from './annotate.js';
3
+ import { expandCarrierList } from './carriers.js';
4
+ import { diagnosticsForRegisterCareConflicts, findAcceptedOutputCandidatesFromHints, findCallerOutputCandidates, findCallerOutputCandidateObservations, findRegisterCareConflicts, } from './liveness.js';
5
+ import { applyExpectOutFixesToSource, findExpectOutFixes } from './fix.js';
6
+ import { getRegisterCareProfile } from './profiles.js';
7
+ import { buildRegisterCareProgramModel } from './programModel.js';
8
+ import { renderRegisterCareInterface, renderRegisterCareReport } from './report.js';
9
+ import { buildRoutineContracts, parseSmartComments } from './smartComments.js';
10
+ import { applyRoutineContract, inferRoutineSummary } from './summary.js';
11
+ function emptyRoutineSummary(name) {
12
+ return {
13
+ name,
14
+ mayRead: [],
15
+ mayWrite: [],
16
+ preserved: [],
17
+ valueRelations: [],
18
+ stackBalanced: true,
19
+ hasUnknownStackEffect: false,
20
+ };
21
+ }
22
+ function unknownBoundaryForCall(call) {
23
+ return {
24
+ ...call,
25
+ message: `Register-care cannot prove ${call.subject}; add a routine body or .asmi extern contract.`,
26
+ };
27
+ }
28
+ function uniqueSortedTargets(boundaries) {
29
+ return Array.from(new Set(boundaries.map((boundary) => boundary.target))).sort();
30
+ }
31
+ function diagnosticsForUnknownBoundaries(boundaries) {
32
+ return boundaries.map((boundary) => ({
33
+ id: DiagnosticIds.RegisterCareUnknownBoundary,
34
+ severity: 'warning',
35
+ message: boundary.message,
36
+ file: boundary.file,
37
+ line: boundary.line,
38
+ column: boundary.column,
39
+ }));
40
+ }
41
+ function isLocalLabel(name) {
42
+ return name.startsWith('.');
43
+ }
44
+ function nonLocalLabels(labels) {
45
+ return labels.filter((label) => !isLocalLabel(label));
46
+ }
47
+ function boundaryLabels(routine) {
48
+ return routine.entryLabels ?? nonLocalLabels(routine.labels);
49
+ }
50
+ function contractForRoutine(routine, contracts) {
51
+ return boundaryLabels(routine)
52
+ .map((label) => contracts.get(label))
53
+ .find((contract) => contract !== undefined);
54
+ }
55
+ function summariesWithExternalContracts(summaries, contracts, routineNames) {
56
+ const out = [...summaries];
57
+ for (const contract of contracts.values()) {
58
+ if (!routineNames.has(contract.name)) {
59
+ out.push(applyRoutineContract(emptyRoutineSummary(contract.name), contract));
60
+ }
61
+ }
62
+ return out;
63
+ }
64
+ function externalContractsOnly(contracts, routineNames) {
65
+ return new Map([...contracts].filter(([name]) => !routineNames.has(name)));
66
+ }
67
+ function buildBoundarySummaryMap(summaries, routineSummaries, profileSummaries) {
68
+ const boundarySummaryMap = new Map(profileSummaries.map((summary) => [summary.name, summary]));
69
+ for (const summary of summaries) {
70
+ boundarySummaryMap.set(summary.name, summary);
71
+ }
72
+ for (const { routine, summary } of routineSummaries) {
73
+ for (const label of boundaryLabels(routine)) {
74
+ boundarySummaryMap.set(label, summary);
75
+ }
76
+ }
77
+ return boundarySummaryMap;
78
+ }
79
+ function summarizeRoutines(routines, contracts, boundarySummaryMap = new Map()) {
80
+ return routines.map((routine) => {
81
+ const inferred = inferRoutineSummary(routine, boundarySummaryMap);
82
+ const contract = contractForRoutine(routine, contracts);
83
+ return { routine, summary: contract ? applyRoutineContract(inferred, contract) : inferred };
84
+ });
85
+ }
86
+ function sortedUnique(values) {
87
+ return Array.from(new Set(values)).sort();
88
+ }
89
+ function appendUniqueUnits(target, units) {
90
+ for (const unit of units) {
91
+ if (!target.includes(unit))
92
+ target.push(unit);
93
+ }
94
+ }
95
+ function summaryFingerprint(summary) {
96
+ const relations = summary.valueRelations
97
+ .map((relation) => `${relation.out.join(',')}<-${relation.from.join(',')}`)
98
+ .sort();
99
+ return JSON.stringify({
100
+ name: summary.name,
101
+ mayRead: sortedUnique(summary.mayRead),
102
+ mayWrite: sortedUnique(summary.mayWrite),
103
+ preserved: sortedUnique(summary.preserved),
104
+ relations,
105
+ stackBalanced: summary.stackBalanced,
106
+ hasUnknownStackEffect: summary.hasUnknownStackEffect,
107
+ });
108
+ }
109
+ function routineSummariesFingerprint(routineSummaries) {
110
+ return routineSummaries.map((item) => summaryFingerprint(item.summary)).join('\n');
111
+ }
112
+ function inferRoutineSummariesToFixedPoint(routines, contracts, routineNames, profileSummaries) {
113
+ let routineSummaries = summarizeRoutines(routines, contracts);
114
+ const maxPasses = Math.max(2, routines.length + 2);
115
+ for (let pass = 0; pass < maxPasses; pass += 1) {
116
+ const summaries = summariesWithExternalContracts(routineSummaries.map((item) => item.summary), contracts, routineNames);
117
+ const boundarySummaryMap = buildBoundarySummaryMap(summaries, routineSummaries, profileSummaries);
118
+ const nextRoutineSummaries = summarizeRoutines(routines, contracts, boundarySummaryMap);
119
+ if (routineSummariesFingerprint(nextRoutineSummaries) ===
120
+ routineSummariesFingerprint(routineSummaries)) {
121
+ return nextRoutineSummaries;
122
+ }
123
+ routineSummaries = nextRoutineSummaries;
124
+ }
125
+ return routineSummaries;
126
+ }
127
+ function withCallerOutputCandidates(routineSummaries, boundarySummaryMap, acceptOutputCandidates = new Map()) {
128
+ const candidates = findCallerOutputCandidates(routineSummaries.map((item) => item.routine), new Map(boundarySummaryMap));
129
+ return routineSummaries.map((item) => {
130
+ const outputCandidates = candidates.get(item.summary.name);
131
+ const written = new Set(item.summary.mayWrite);
132
+ const accepted = (acceptOutputCandidates.get(item.summary.name) ?? []).filter((unit) => written.has(unit));
133
+ const acceptedSet = new Set(accepted);
134
+ const valueRelations = [...item.summary.valueRelations];
135
+ for (const unit of accepted) {
136
+ if (!valueRelations.some((relation) => relation.out.includes(unit))) {
137
+ valueRelations.push({ out: [unit], from: [] });
138
+ }
139
+ }
140
+ const remainingCandidates = outputCandidates?.filter((unit) => !acceptedSet.has(unit));
141
+ return outputCandidates && outputCandidates.length > 0
142
+ ? {
143
+ ...item,
144
+ summary: {
145
+ ...item.summary,
146
+ valueRelations,
147
+ ...(remainingCandidates && remainingCandidates.length > 0
148
+ ? { outputCandidates: remainingCandidates }
149
+ : {}),
150
+ },
151
+ }
152
+ : item;
153
+ });
154
+ }
155
+ function autoAcceptedOutputCandidates(fixes) {
156
+ const out = new Map();
157
+ for (const fix of fixes) {
158
+ const existing = out.get(fix.routine) ?? [];
159
+ appendUniqueUnits(existing, fix.carriers);
160
+ out.set(fix.routine, existing);
161
+ }
162
+ return out;
163
+ }
164
+ function parseAcceptedOutputCandidates(items = []) {
165
+ const out = new Map();
166
+ for (const item of items) {
167
+ const sep = item.indexOf(':');
168
+ if (sep <= 0 || sep === item.length - 1) {
169
+ throw new Error(`Invalid --accept-out value "${item}" (expected ROUTINE:carriers)`);
170
+ }
171
+ const name = item.slice(0, sep).trim();
172
+ if (!name)
173
+ throw new Error(`Invalid --accept-out value "${item}" (missing routine name)`);
174
+ const carrierParts = item.slice(sep + 1).split(',');
175
+ const rawCarriers = carrierParts.map((part) => part.trim());
176
+ if (rawCarriers.length === 0 || rawCarriers.some((part) => part.length === 0)) {
177
+ throw new Error(`Invalid --accept-out value "${item}" (missing carriers)`);
178
+ }
179
+ const carriers = expandCarrierList(rawCarriers);
180
+ if (!carriers) {
181
+ throw new Error(`Invalid --accept-out value "${item}" (unknown carrier)`);
182
+ }
183
+ const existing = out.get(name) ?? [];
184
+ appendUniqueUnits(existing, carriers);
185
+ out.set(name, existing);
186
+ }
187
+ return out;
188
+ }
189
+ function mergeAcceptedOutputCandidates(...maps) {
190
+ const out = new Map();
191
+ for (const map of maps) {
192
+ for (const [name, units] of map) {
193
+ const existing = out.get(name) ?? [];
194
+ appendUniqueUnits(existing, units);
195
+ out.set(name, existing);
196
+ }
197
+ }
198
+ return out;
199
+ }
200
+ function fixedSourceTexts(referenceSourceTexts, workingSourceTexts, fixes) {
201
+ const byFile = new Map();
202
+ for (const fix of fixes) {
203
+ const items = byFile.get(fix.file) ?? [];
204
+ items.push(fix);
205
+ byFile.set(fix.file, items);
206
+ }
207
+ const out = new Map(workingSourceTexts);
208
+ for (const [file, items] of byFile) {
209
+ const source = workingSourceTexts.get(file);
210
+ const referenceSource = referenceSourceTexts.get(file);
211
+ if (source === undefined)
212
+ continue;
213
+ out.set(file, applyExpectOutFixesToSource(source, items, referenceSource));
214
+ }
215
+ return out;
216
+ }
217
+ function annotateAndFixRegisterCareContracts(sourceTexts, routines, fixes) {
218
+ const annotated = annotateRegisterCareContracts(sourceTexts, routines);
219
+ if (fixes.length === 0)
220
+ return annotated;
221
+ const workingTexts = new Map(sourceTexts);
222
+ for (const file of annotated) {
223
+ workingTexts.set(file.path, file.text);
224
+ }
225
+ const fixedTexts = fixedSourceTexts(sourceTexts, workingTexts, fixes);
226
+ const out = [];
227
+ for (const [path, text] of fixedTexts) {
228
+ if (text !== sourceTexts.get(path))
229
+ out.push({ path, text });
230
+ }
231
+ return out.sort((a, b) => a.path.localeCompare(b.path));
232
+ }
233
+ function candidateKey(item) {
234
+ return `${item.file}:${item.line}:${item.column}:${item.routine}`;
235
+ }
236
+ function candidateExpectation(units) {
237
+ const carriers = units.join(',');
238
+ return units.length === 1 ? units[0] : `{${carriers}}`;
239
+ }
240
+ function candidateMessageWithFixability(candidate, autoFixable) {
241
+ const carriers = candidate.carriers.join(',');
242
+ const expectation = candidateExpectation(candidate.carriers);
243
+ const base = `CALL ${candidate.routine} writes ${carriers} and caller reads it later`;
244
+ return autoFixable
245
+ ? `${base}; generated contracts promote this to \`out ${expectation}\` automatically.`
246
+ : `${base}; manual review required before adding \`; expects out ${expectation}\` because the later read is not a simple direct continuation.`;
247
+ }
248
+ function withCandidateFixability(candidates, fixes) {
249
+ const fixable = new Map(fixes.map((fix) => [candidateKey(fix), new Set(fix.carriers)]));
250
+ return candidates.map((candidate) => {
251
+ const fixableCarriers = fixable.get(candidateKey(candidate));
252
+ const autoFixable = fixableCarriers !== undefined &&
253
+ candidate.carriers.every((carrier) => fixableCarriers.has(carrier));
254
+ return {
255
+ ...candidate,
256
+ autoFixable,
257
+ message: candidateMessageWithFixability(candidate, autoFixable),
258
+ };
259
+ });
260
+ }
261
+ function inferenceOnlyOutputFixes(programRoutines, routineSummaries, profileSummaries) {
262
+ const summaries = routineSummaries.map((item) => item.summary);
263
+ const boundarySummaryMap = buildBoundarySummaryMap(summaries, routineSummaries, profileSummaries);
264
+ const candidates = findCallerOutputCandidateObservations(programRoutines, boundarySummaryMap);
265
+ return findExpectOutFixes(programRoutines, candidates);
266
+ }
267
+ export function analyzeRegisterCare(loaded, options) {
268
+ const profile = getRegisterCareProfile(options.profile);
269
+ const programModel = buildRegisterCareProgramModel(loaded.program);
270
+ const smartComments = parseSmartComments(loaded.sourceLineComments);
271
+ const contracts = buildRoutineContracts(smartComments, programModel.routines, loaded.sourceTexts);
272
+ const cliAcceptedOutputCandidates = parseAcceptedOutputCandidates(options.acceptOutputCandidates);
273
+ for (const contract of options.interfaceContracts ?? []) {
274
+ contracts.set(contract.name, contract);
275
+ }
276
+ const routineNames = new Set(programModel.routines.flatMap((routine) => boundaryLabels(routine)));
277
+ const profileSummaries = profile
278
+ ? [...Array.from(profile.rst.values()), ...Array.from(profile.rstServices.values())]
279
+ : [];
280
+ const routineSummaries = inferRoutineSummariesToFixedPoint(programModel.routines, contracts, routineNames, profileSummaries);
281
+ const summaries = routineSummaries.map((item) => item.summary);
282
+ summaries.push(...summariesWithExternalContracts([], contracts, routineNames));
283
+ const boundarySummaryMap = buildBoundarySummaryMap(summaries, routineSummaries, profileSummaries);
284
+ const unknownBoundaries = programModel.directBoundaries
285
+ .filter((boundary) => !boundarySummaryMap.has(boundary.target))
286
+ .map(unknownBoundaryForCall);
287
+ const conflicts = programModel.routines.flatMap((routine) => findRegisterCareConflicts(routine, boundarySummaryMap, smartComments));
288
+ const rawOutputCandidates = findCallerOutputCandidateObservations(programModel.routines, boundarySummaryMap);
289
+ const possibleExpectOutFixes = findExpectOutFixes(programModel.routines, rawOutputCandidates);
290
+ const outputCandidates = withCandidateFixability(rawOutputCandidates, possibleExpectOutFixes);
291
+ const conflictDiagnostics = options.mode === 'warn' || options.mode === 'strict'
292
+ ? diagnosticsForRegisterCareConflicts(conflicts, 'warning')
293
+ : options.mode === 'error'
294
+ ? diagnosticsForRegisterCareConflicts(conflicts, 'error')
295
+ : [];
296
+ const diagnostics = options.mode === 'strict'
297
+ ? [...conflictDiagnostics, ...diagnosticsForUnknownBoundaries(unknownBoundaries)]
298
+ : conflictDiagnostics;
299
+ const reportModel = {
300
+ entryFile: loaded.program.entryFile,
301
+ mode: options.mode,
302
+ ...(profile ? { profile: profile.name } : {}),
303
+ summaries,
304
+ conflicts,
305
+ outputCandidates,
306
+ unknownCalls: uniqueSortedTargets(unknownBoundaries),
307
+ };
308
+ return {
309
+ diagnostics,
310
+ outputCandidates,
311
+ ...(options.emitReport ? { reportText: renderRegisterCareReport(reportModel) } : {}),
312
+ ...(options.emitInterface ? { interfaceText: renderRegisterCareInterface(summaries) } : {}),
313
+ ...(options.emitAnnotations
314
+ ? (() => {
315
+ const annotationRoutineSummaries = inferRoutineSummariesToFixedPoint(programModel.routines, externalContractsOnly(contracts, routineNames), routineNames, profileSummaries);
316
+ const annotationSummaries = annotationRoutineSummaries.map((item) => item.summary);
317
+ const annotationBoundarySummaryMap = buildBoundarySummaryMap(annotationSummaries, annotationRoutineSummaries, profileSummaries);
318
+ const expectOutFixes = options.fixRegisterContracts === true
319
+ ? inferenceOnlyOutputFixes(programModel.routines, annotationRoutineSummaries, profileSummaries)
320
+ : [];
321
+ return {
322
+ annotatedFiles: annotateAndFixRegisterCareContracts(loaded.sourceTexts, withCallerOutputCandidates(annotationRoutineSummaries, annotationBoundarySummaryMap, mergeAcceptedOutputCandidates(cliAcceptedOutputCandidates, findAcceptedOutputCandidatesFromHints(programModel.routines, annotationBoundarySummaryMap, smartComments), autoAcceptedOutputCandidates(expectOutFixes))), []),
323
+ };
324
+ })()
325
+ : {}),
326
+ };
327
+ }
@@ -0,0 +1,11 @@
1
+ import type { RegisterCareRoutine, RoutineSummary } from './types.js';
2
+ export interface RegisterCareAnnotatedFile {
3
+ path: string;
4
+ text: string;
5
+ }
6
+ interface RegisterCareAnnotationInput {
7
+ routine: RegisterCareRoutine;
8
+ summary: RoutineSummary;
9
+ }
10
+ export declare function annotateRegisterCareContracts(sourceTexts: ReadonlyMap<string, string>, routines: RegisterCareAnnotationInput[]): RegisterCareAnnotatedFile[];
11
+ export {};