@jhlagado/azm 0.2.0 → 0.2.2

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 (334) hide show
  1. package/README.md +110 -78
  2. package/dist/src/api-compile.d.ts +0 -2
  3. package/dist/src/api-compile.js +2 -9
  4. package/dist/src/assembly/address-planning.js +21 -1
  5. package/dist/src/assembly/program-emission.js +1 -0
  6. package/dist/src/cli/parse-args.d.ts +0 -1
  7. package/dist/src/cli/parse-args.js +0 -7
  8. package/dist/src/cli/write-artifacts.js +0 -11
  9. package/dist/src/core/compile.js +192 -9
  10. package/dist/src/expansion/op-expansion.js +2 -0
  11. package/dist/src/model/expression.d.ts +4 -0
  12. package/dist/src/model/source-item.d.ts +11 -0
  13. package/dist/src/outputs/index.js +0 -2
  14. package/dist/src/outputs/types.d.ts +3 -16
  15. package/dist/src/outputs/write-asm80.js +206 -5
  16. package/dist/src/register-care/analyze.js +36 -8
  17. package/dist/src/register-care/annotations.js +33 -146
  18. package/dist/src/register-care/fix.d.ts +2 -0
  19. package/dist/src/register-care/fix.js +52 -0
  20. package/dist/src/register-care/instruction-shape.d.ts +11 -0
  21. package/dist/src/register-care/instruction-shape.js +129 -0
  22. package/dist/src/register-care/liveness.js +15 -7
  23. package/dist/src/register-care/profiles.js +4 -0
  24. package/dist/src/register-care/programModel.js +79 -13
  25. package/dist/src/register-care/report.d.ts +2 -1
  26. package/dist/src/register-care/report.js +91 -34
  27. package/dist/src/register-care/routine-summaries.d.ts +6 -0
  28. package/dist/src/register-care/routine-summaries.js +89 -0
  29. package/dist/src/register-care/summaries.d.ts +3 -3
  30. package/dist/src/register-care/summaries.js +42 -75
  31. package/dist/{legacy-root-azm/src/registerCare → src/register-care}/summary.js +33 -51
  32. package/dist/src/register-care/types.d.ts +6 -1
  33. package/dist/src/semantics/expression-evaluation.d.ts +7 -3
  34. package/dist/src/semantics/expression-evaluation.js +57 -0
  35. package/dist/src/source/strip-line-comment.d.ts +2 -0
  36. package/dist/src/source/strip-line-comment.js +26 -0
  37. package/dist/src/syntax/directive-aliases.js +9 -10
  38. package/dist/src/syntax/parse-diagnostics.d.ts +12 -0
  39. package/dist/src/syntax/parse-diagnostics.js +18 -0
  40. package/dist/src/syntax/parse-expression.js +34 -9
  41. package/dist/src/syntax/parse-line.js +150 -54
  42. package/dist/src/tooling/case-style.js +3 -0
  43. package/docs/reference/cli.md +6 -4
  44. package/docs/reference/tooling-api.md +13 -9
  45. package/package.json +4 -6
  46. package/dist/legacy-root-azm/src/analysis.d.ts +0 -11
  47. package/dist/legacy-root-azm/src/analysis.js +0 -41
  48. package/dist/legacy-root-azm/src/compile.d.ts +0 -10
  49. package/dist/legacy-root-azm/src/compile.js +0 -186
  50. package/dist/legacy-root-azm/src/compileShared.d.ts +0 -3
  51. package/dist/legacy-root-azm/src/compileShared.js +0 -7
  52. package/dist/legacy-root-azm/src/diagnosticTypes.d.ts +0 -77
  53. package/dist/legacy-root-azm/src/diagnosticTypes.js +0 -53
  54. package/dist/legacy-root-azm/src/formats/index.d.ts +0 -7
  55. package/dist/legacy-root-azm/src/formats/index.js +0 -17
  56. package/dist/legacy-root-azm/src/formats/range.d.ts +0 -17
  57. package/dist/legacy-root-azm/src/formats/range.js +0 -45
  58. package/dist/legacy-root-azm/src/formats/types.d.ts +0 -283
  59. package/dist/legacy-root-azm/src/formats/types.js +0 -1
  60. package/dist/legacy-root-azm/src/formats/writeAsm80.d.ts +0 -6
  61. package/dist/legacy-root-azm/src/formats/writeAsm80.js +0 -86
  62. package/dist/legacy-root-azm/src/formats/writeBin.d.ts +0 -7
  63. package/dist/legacy-root-azm/src/formats/writeBin.js +0 -23
  64. package/dist/legacy-root-azm/src/formats/writeD8m.d.ts +0 -9
  65. package/dist/legacy-root-azm/src/formats/writeD8m.js +0 -245
  66. package/dist/legacy-root-azm/src/formats/writeHex.d.ts +0 -8
  67. package/dist/legacy-root-azm/src/formats/writeHex.js +0 -38
  68. package/dist/legacy-root-azm/src/formats/writeListing.d.ts +0 -8
  69. package/dist/legacy-root-azm/src/formats/writeListing.js +0 -83
  70. package/dist/legacy-root-azm/src/frontend/asm80/asmLine.d.ts +0 -39
  71. package/dist/legacy-root-azm/src/frontend/asm80/asmLine.js +0 -89
  72. package/dist/legacy-root-azm/src/frontend/asm80/parseAsmRawValues.d.ts +0 -4
  73. package/dist/legacy-root-azm/src/frontend/asm80/parseAsmRawValues.js +0 -94
  74. package/dist/legacy-root-azm/src/frontend/asm80/quoteScan.d.ts +0 -10
  75. package/dist/legacy-root-azm/src/frontend/asm80/quoteScan.js +0 -25
  76. package/dist/legacy-root-azm/src/frontend/ast.d.ts +0 -376
  77. package/dist/legacy-root-azm/src/frontend/ast.js +0 -1
  78. package/dist/legacy-root-azm/src/frontend/directiveAliases.d.ts +0 -14
  79. package/dist/legacy-root-azm/src/frontend/directiveAliases.js +0 -189
  80. package/dist/legacy-root-azm/src/frontend/grammarData.d.ts +0 -14
  81. package/dist/legacy-root-azm/src/frontend/grammarData.js +0 -65
  82. package/dist/legacy-root-azm/src/frontend/immExprUtils.d.ts +0 -2
  83. package/dist/legacy-root-azm/src/frontend/immExprUtils.js +0 -12
  84. package/dist/legacy-root-azm/src/frontend/parseAsmFlatDirectiveLine.d.ts +0 -17
  85. package/dist/legacy-root-azm/src/frontend/parseAsmFlatDirectiveLine.js +0 -187
  86. package/dist/legacy-root-azm/src/frontend/parseAsmInstruction.d.ts +0 -3
  87. package/dist/legacy-root-azm/src/frontend/parseAsmInstruction.js +0 -73
  88. package/dist/legacy-root-azm/src/frontend/parseAsmStatements.d.ts +0 -6
  89. package/dist/legacy-root-azm/src/frontend/parseAsmStatements.js +0 -16
  90. package/dist/legacy-root-azm/src/frontend/parseAsmStream.d.ts +0 -10
  91. package/dist/legacy-root-azm/src/frontend/parseAsmStream.js +0 -33
  92. package/dist/legacy-root-azm/src/frontend/parseAsmTopLevel.d.ts +0 -18
  93. package/dist/legacy-root-azm/src/frontend/parseAsmTopLevel.js +0 -34
  94. package/dist/legacy-root-azm/src/frontend/parseDiagnostics.d.ts +0 -9
  95. package/dist/legacy-root-azm/src/frontend/parseDiagnostics.js +0 -16
  96. package/dist/legacy-root-azm/src/frontend/parseEnum.d.ts +0 -12
  97. package/dist/legacy-root-azm/src/frontend/parseEnum.js +0 -70
  98. package/dist/legacy-root-azm/src/frontend/parseImm.d.ts +0 -10
  99. package/dist/legacy-root-azm/src/frontend/parseImm.js +0 -397
  100. package/dist/legacy-root-azm/src/frontend/parseLogicalLines.d.ts +0 -11
  101. package/dist/legacy-root-azm/src/frontend/parseLogicalLines.js +0 -94
  102. package/dist/legacy-root-azm/src/frontend/parseOp.d.ts +0 -25
  103. package/dist/legacy-root-azm/src/frontend/parseOp.js +0 -120
  104. package/dist/legacy-root-azm/src/frontend/parseOpHeader.d.ts +0 -20
  105. package/dist/legacy-root-azm/src/frontend/parseOpHeader.js +0 -32
  106. package/dist/legacy-root-azm/src/frontend/parseOperands.d.ts +0 -4
  107. package/dist/legacy-root-azm/src/frontend/parseOperands.js +0 -290
  108. package/dist/legacy-root-azm/src/frontend/parseParams.d.ts +0 -6
  109. package/dist/legacy-root-azm/src/frontend/parseParams.js +0 -62
  110. package/dist/legacy-root-azm/src/frontend/parseParserRecovery.d.ts +0 -12
  111. package/dist/legacy-root-azm/src/frontend/parseParserRecovery.js +0 -17
  112. package/dist/legacy-root-azm/src/frontend/parseParserShared.d.ts +0 -2
  113. package/dist/legacy-root-azm/src/frontend/parseParserShared.js +0 -8
  114. package/dist/legacy-root-azm/src/frontend/parseRawDataDirectiveStart.d.ts +0 -1
  115. package/dist/legacy-root-azm/src/frontend/parseRawDataDirectiveStart.js +0 -3
  116. package/dist/legacy-root-azm/src/frontend/parseRawDataDirectives.d.ts +0 -7
  117. package/dist/legacy-root-azm/src/frontend/parseRawDataDirectives.js +0 -142
  118. package/dist/legacy-root-azm/src/frontend/parseRecordFieldDecl.d.ts +0 -34
  119. package/dist/legacy-root-azm/src/frontend/parseRecordFieldDecl.js +0 -177
  120. package/dist/legacy-root-azm/src/frontend/parseSourceItemDispatch.d.ts +0 -46
  121. package/dist/legacy-root-azm/src/frontend/parseSourceItemDispatch.js +0 -53
  122. package/dist/legacy-root-azm/src/frontend/parseSourceItemTable.d.ts +0 -16
  123. package/dist/legacy-root-azm/src/frontend/parseSourceItemTable.js +0 -68
  124. package/dist/legacy-root-azm/src/frontend/parseTopLevelCommon.d.ts +0 -11
  125. package/dist/legacy-root-azm/src/frontend/parseTopLevelCommon.js +0 -50
  126. package/dist/legacy-root-azm/src/frontend/parseTypes.d.ts +0 -24
  127. package/dist/legacy-root-azm/src/frontend/parseTypes.js +0 -77
  128. package/dist/legacy-root-azm/src/frontend/parser.d.ts +0 -11
  129. package/dist/legacy-root-azm/src/frontend/parser.js +0 -88
  130. package/dist/legacy-root-azm/src/frontend/source.d.ts +0 -28
  131. package/dist/legacy-root-azm/src/frontend/source.js +0 -58
  132. package/dist/legacy-root-azm/src/frontend/sourceExtensions.d.ts +0 -2
  133. package/dist/legacy-root-azm/src/frontend/sourceExtensions.js +0 -6
  134. package/dist/legacy-root-azm/src/lintCaseStyle.d.ts +0 -4
  135. package/dist/legacy-root-azm/src/lintCaseStyle.js +0 -129
  136. package/dist/legacy-root-azm/src/lowering/asmDirectiveLowering.d.ts +0 -4
  137. package/dist/legacy-root-azm/src/lowering/asmDirectiveLowering.js +0 -229
  138. package/dist/legacy-root-azm/src/lowering/asmDirectiveTraversal.d.ts +0 -47
  139. package/dist/legacy-root-azm/src/lowering/asmDirectiveTraversal.js +0 -52
  140. package/dist/legacy-root-azm/src/lowering/asmEquResolution.d.ts +0 -8
  141. package/dist/legacy-root-azm/src/lowering/asmEquResolution.js +0 -69
  142. package/dist/legacy-root-azm/src/lowering/asmInstructionLdHelpers.d.ts +0 -15
  143. package/dist/legacy-root-azm/src/lowering/asmInstructionLdHelpers.js +0 -102
  144. package/dist/legacy-root-azm/src/lowering/asmInstructionLowering.d.ts +0 -5
  145. package/dist/legacy-root-azm/src/lowering/asmInstructionLowering.js +0 -54
  146. package/dist/legacy-root-azm/src/lowering/asmInstructionStream.d.ts +0 -46
  147. package/dist/legacy-root-azm/src/lowering/asmInstructionStream.js +0 -51
  148. package/dist/legacy-root-azm/src/lowering/asmLoweringBranchCall.d.ts +0 -43
  149. package/dist/legacy-root-azm/src/lowering/asmLoweringBranchCall.js +0 -254
  150. package/dist/legacy-root-azm/src/lowering/asmLoweringHost.d.ts +0 -23
  151. package/dist/legacy-root-azm/src/lowering/asmLoweringHost.js +0 -1
  152. package/dist/legacy-root-azm/src/lowering/asmLoweringLd.d.ts +0 -28
  153. package/dist/legacy-root-azm/src/lowering/asmLoweringLd.js +0 -144
  154. package/dist/legacy-root-azm/src/lowering/asmRangeLowering.d.ts +0 -17
  155. package/dist/legacy-root-azm/src/lowering/asmRangeLowering.js +0 -39
  156. package/dist/legacy-root-azm/src/lowering/asmRawDataLowering.d.ts +0 -16
  157. package/dist/legacy-root-azm/src/lowering/asmRawDataLowering.js +0 -209
  158. package/dist/legacy-root-azm/src/lowering/asmSourceEmitter.d.ts +0 -4
  159. package/dist/legacy-root-azm/src/lowering/asmSourceEmitter.js +0 -9
  160. package/dist/legacy-root-azm/src/lowering/asmSourceInstructionLowering.d.ts +0 -4
  161. package/dist/legacy-root-azm/src/lowering/asmSourceInstructionLowering.js +0 -14
  162. package/dist/legacy-root-azm/src/lowering/asmUtils.d.ts +0 -13
  163. package/dist/legacy-root-azm/src/lowering/asmUtils.js +0 -105
  164. package/dist/legacy-root-azm/src/lowering/assemblerFlowSetup.d.ts +0 -54
  165. package/dist/legacy-root-azm/src/lowering/assemblerFlowSetup.js +0 -128
  166. package/dist/legacy-root-azm/src/lowering/assemblerLoweringContext.d.ts +0 -151
  167. package/dist/legacy-root-azm/src/lowering/assemblerLoweringContext.js +0 -16
  168. package/dist/legacy-root-azm/src/lowering/assemblerLoweringContextSplit.d.ts +0 -7
  169. package/dist/legacy-root-azm/src/lowering/assemblerLoweringContextSplit.js +0 -75
  170. package/dist/legacy-root-azm/src/lowering/assemblerLoweringPhases.d.ts +0 -66
  171. package/dist/legacy-root-azm/src/lowering/assemblerLoweringPhases.js +0 -166
  172. package/dist/legacy-root-azm/src/lowering/bytePlacement.d.ts +0 -7
  173. package/dist/legacy-root-azm/src/lowering/bytePlacement.js +0 -37
  174. package/dist/legacy-root-azm/src/lowering/capabilities.d.ts +0 -67
  175. package/dist/legacy-root-azm/src/lowering/capabilities.js +0 -1
  176. package/dist/legacy-root-azm/src/lowering/eaResolution.d.ts +0 -58
  177. package/dist/legacy-root-azm/src/lowering/eaResolution.js +0 -159
  178. package/dist/legacy-root-azm/src/lowering/emissionCore.d.ts +0 -17
  179. package/dist/legacy-root-azm/src/lowering/emissionCore.js +0 -21
  180. package/dist/legacy-root-azm/src/lowering/emit.d.ts +0 -17
  181. package/dist/legacy-root-azm/src/lowering/emit.js +0 -46
  182. package/dist/legacy-root-azm/src/lowering/emitContextBuilder.d.ts +0 -63
  183. package/dist/legacy-root-azm/src/lowering/emitContextBuilder.js +0 -41
  184. package/dist/legacy-root-azm/src/lowering/emitFinalization.d.ts +0 -61
  185. package/dist/legacy-root-azm/src/lowering/emitFinalization.js +0 -66
  186. package/dist/legacy-root-azm/src/lowering/emitFinalizationSetup.d.ts +0 -19
  187. package/dist/legacy-root-azm/src/lowering/emitFinalizationSetup.js +0 -26
  188. package/dist/legacy-root-azm/src/lowering/emitPhase1BuildProgramLoweringContext.d.ts +0 -7
  189. package/dist/legacy-root-azm/src/lowering/emitPhase1BuildProgramLoweringContext.js +0 -119
  190. package/dist/legacy-root-azm/src/lowering/emitPhase1Helpers.d.ts +0 -4
  191. package/dist/legacy-root-azm/src/lowering/emitPhase1Helpers.js +0 -12
  192. package/dist/legacy-root-azm/src/lowering/emitPhase1Types.d.ts +0 -21
  193. package/dist/legacy-root-azm/src/lowering/emitPhase1Types.js +0 -1
  194. package/dist/legacy-root-azm/src/lowering/emitPhase1WirePipeline.d.ts +0 -70
  195. package/dist/legacy-root-azm/src/lowering/emitPhase1WirePipeline.js +0 -203
  196. package/dist/legacy-root-azm/src/lowering/emitPhase1Workspace.d.ts +0 -82
  197. package/dist/legacy-root-azm/src/lowering/emitPhase1Workspace.js +0 -55
  198. package/dist/legacy-root-azm/src/lowering/emitPipeline.d.ts +0 -121
  199. package/dist/legacy-root-azm/src/lowering/emitPipeline.js +0 -57
  200. package/dist/legacy-root-azm/src/lowering/emitProgramContext.d.ts +0 -39
  201. package/dist/legacy-root-azm/src/lowering/emitProgramContext.js +0 -29
  202. package/dist/legacy-root-azm/src/lowering/emitState.d.ts +0 -90
  203. package/dist/legacy-root-azm/src/lowering/emitState.js +0 -124
  204. package/dist/legacy-root-azm/src/lowering/fixupBaseResolution.d.ts +0 -7
  205. package/dist/legacy-root-azm/src/lowering/fixupBaseResolution.js +0 -23
  206. package/dist/legacy-root-azm/src/lowering/fixupEmission.d.ts +0 -64
  207. package/dist/legacy-root-azm/src/lowering/fixupEmission.js +0 -199
  208. package/dist/legacy-root-azm/src/lowering/immMath.d.ts +0 -2
  209. package/dist/legacy-root-azm/src/lowering/immMath.js +0 -34
  210. package/dist/legacy-root-azm/src/lowering/inputAssets.d.ts +0 -7
  211. package/dist/legacy-root-azm/src/lowering/inputAssets.js +0 -106
  212. package/dist/legacy-root-azm/src/lowering/ldEncoding.d.ts +0 -15
  213. package/dist/legacy-root-azm/src/lowering/ldEncoding.js +0 -12
  214. package/dist/legacy-root-azm/src/lowering/ldEncodingRegMemHelpers.d.ts +0 -5
  215. package/dist/legacy-root-azm/src/lowering/ldEncodingRegMemHelpers.js +0 -124
  216. package/dist/legacy-root-azm/src/lowering/ldFormSelection.d.ts +0 -26
  217. package/dist/legacy-root-azm/src/lowering/ldFormSelection.js +0 -92
  218. package/dist/legacy-root-azm/src/lowering/ldLowering.d.ts +0 -7
  219. package/dist/legacy-root-azm/src/lowering/ldLowering.js +0 -13
  220. package/dist/legacy-root-azm/src/lowering/loweredAsmByteEmission.d.ts +0 -23
  221. package/dist/legacy-root-azm/src/lowering/loweredAsmByteEmission.js +0 -185
  222. package/dist/legacy-root-azm/src/lowering/loweredAsmPlacement.d.ts +0 -13
  223. package/dist/legacy-root-azm/src/lowering/loweredAsmPlacement.js +0 -86
  224. package/dist/legacy-root-azm/src/lowering/loweredAsmStreamRecording.d.ts +0 -27
  225. package/dist/legacy-root-azm/src/lowering/loweredAsmStreamRecording.js +0 -215
  226. package/dist/legacy-root-azm/src/lowering/loweredAsmTypes.d.ts +0 -202
  227. package/dist/legacy-root-azm/src/lowering/loweredAsmTypes.js +0 -1
  228. package/dist/legacy-root-azm/src/lowering/loweredFormat.d.ts +0 -3
  229. package/dist/legacy-root-azm/src/lowering/loweredFormat.js +0 -26
  230. package/dist/legacy-root-azm/src/lowering/loweredItemSize.d.ts +0 -4
  231. package/dist/legacy-root-azm/src/lowering/loweredItemSize.js +0 -17
  232. package/dist/legacy-root-azm/src/lowering/loweringDiagnostics.d.ts +0 -9
  233. package/dist/legacy-root-azm/src/lowering/loweringDiagnostics.js +0 -55
  234. package/dist/legacy-root-azm/src/lowering/loweringTypes.d.ts +0 -27
  235. package/dist/legacy-root-azm/src/lowering/loweringTypes.js +0 -1
  236. package/dist/legacy-root-azm/src/lowering/opCandidateRegistry.d.ts +0 -9
  237. package/dist/legacy-root-azm/src/lowering/opCandidateRegistry.js +0 -9
  238. package/dist/legacy-root-azm/src/lowering/opExpansionExecution.d.ts +0 -15
  239. package/dist/legacy-root-azm/src/lowering/opExpansionExecution.js +0 -45
  240. package/dist/legacy-root-azm/src/lowering/opExpansionOrchestration.d.ts +0 -15
  241. package/dist/legacy-root-azm/src/lowering/opExpansionOrchestration.js +0 -88
  242. package/dist/legacy-root-azm/src/lowering/opExpansionStream.d.ts +0 -12
  243. package/dist/legacy-root-azm/src/lowering/opExpansionStream.js +0 -176
  244. package/dist/legacy-root-azm/src/lowering/opMatching.d.ts +0 -52
  245. package/dist/legacy-root-azm/src/lowering/opMatching.js +0 -355
  246. package/dist/legacy-root-azm/src/lowering/opSubstitution.d.ts +0 -13
  247. package/dist/legacy-root-azm/src/lowering/opSubstitution.js +0 -175
  248. package/dist/legacy-root-azm/src/lowering/prescanTypes.d.ts +0 -7
  249. package/dist/legacy-root-azm/src/lowering/prescanTypes.js +0 -1
  250. package/dist/legacy-root-azm/src/lowering/programLowering.d.ts +0 -144
  251. package/dist/legacy-root-azm/src/lowering/programLowering.js +0 -2
  252. package/dist/legacy-root-azm/src/lowering/programLoweringDeclarations.d.ts +0 -5
  253. package/dist/legacy-root-azm/src/lowering/programLoweringDeclarations.js +0 -5
  254. package/dist/legacy-root-azm/src/lowering/programLoweringFinalize.d.ts +0 -18
  255. package/dist/legacy-root-azm/src/lowering/programLoweringFinalize.js +0 -115
  256. package/dist/legacy-root-azm/src/lowering/programLoweringTraversal.d.ts +0 -2
  257. package/dist/legacy-root-azm/src/lowering/programLoweringTraversal.js +0 -93
  258. package/dist/legacy-root-azm/src/lowering/programPrescan.d.ts +0 -3
  259. package/dist/legacy-root-azm/src/lowering/programPrescan.js +0 -37
  260. package/dist/legacy-root-azm/src/lowering/traceFormat.d.ts +0 -13
  261. package/dist/legacy-root-azm/src/lowering/traceFormat.js +0 -211
  262. package/dist/legacy-root-azm/src/packageInfo.d.ts +0 -1
  263. package/dist/legacy-root-azm/src/packageInfo.js +0 -15
  264. package/dist/legacy-root-azm/src/pathCompare.d.ts +0 -3
  265. package/dist/legacy-root-azm/src/pathCompare.js +0 -26
  266. package/dist/legacy-root-azm/src/pipeline.d.ts +0 -91
  267. package/dist/legacy-root-azm/src/pipeline.js +0 -1
  268. package/dist/legacy-root-azm/src/registerCare/analyze.d.ts +0 -24
  269. package/dist/legacy-root-azm/src/registerCare/analyze.js +0 -327
  270. package/dist/legacy-root-azm/src/registerCare/boundaryHints.d.ts +0 -2
  271. package/dist/legacy-root-azm/src/registerCare/boundaryHints.js +0 -10
  272. package/dist/legacy-root-azm/src/registerCare/carriers.d.ts +0 -4
  273. package/dist/legacy-root-azm/src/registerCare/carriers.js +0 -78
  274. package/dist/legacy-root-azm/src/registerCare/controlFlow.d.ts +0 -5
  275. package/dist/legacy-root-azm/src/registerCare/controlFlow.js +0 -35
  276. package/dist/legacy-root-azm/src/registerCare/fix.d.ts +0 -11
  277. package/dist/legacy-root-azm/src/registerCare/fix.js +0 -119
  278. package/dist/legacy-root-azm/src/registerCare/liveness.d.ts +0 -7
  279. package/dist/legacy-root-azm/src/registerCare/liveness.js +0 -227
  280. package/dist/legacy-root-azm/src/registerCare/profiles.d.ts +0 -11
  281. package/dist/legacy-root-azm/src/registerCare/profiles.js +0 -45
  282. package/dist/legacy-root-azm/src/registerCare/programModel.d.ts +0 -3
  283. package/dist/legacy-root-azm/src/registerCare/programModel.js +0 -181
  284. package/dist/legacy-root-azm/src/registerCare/report.d.ts +0 -5
  285. package/dist/legacy-root-azm/src/registerCare/report.js +0 -139
  286. package/dist/legacy-root-azm/src/registerCare/smartComments.d.ts +0 -5
  287. package/dist/legacy-root-azm/src/registerCare/smartComments.js +0 -247
  288. package/dist/legacy-root-azm/src/registerCare/types.d.ts +0 -154
  289. package/dist/legacy-root-azm/src/registerCare/types.js +0 -1
  290. package/dist/legacy-root-azm/src/semantics/declVisitor.d.ts +0 -5
  291. package/dist/legacy-root-azm/src/semantics/declVisitor.js +0 -11
  292. package/dist/legacy-root-azm/src/semantics/env.d.ts +0 -28
  293. package/dist/legacy-root-azm/src/semantics/env.js +0 -432
  294. package/dist/legacy-root-azm/src/semantics/layout.d.ts +0 -21
  295. package/dist/legacy-root-azm/src/semantics/layout.js +0 -226
  296. package/dist/legacy-root-azm/src/semantics/layoutCastFold.d.ts +0 -22
  297. package/dist/legacy-root-azm/src/semantics/layoutCastFold.js +0 -118
  298. package/dist/legacy-root-azm/src/semantics/semanticsDiagnostics.d.ts +0 -2
  299. package/dist/legacy-root-azm/src/semantics/semanticsDiagnostics.js +0 -4
  300. package/dist/legacy-root-azm/src/semantics/typeQueries.d.ts +0 -31
  301. package/dist/legacy-root-azm/src/semantics/typeQueries.js +0 -124
  302. package/dist/legacy-root-azm/src/sourceIncludeExpansion.d.ts +0 -17
  303. package/dist/legacy-root-azm/src/sourceIncludeExpansion.js +0 -124
  304. package/dist/legacy-root-azm/src/sourceIncludePaths.d.ts +0 -1
  305. package/dist/legacy-root-azm/src/sourceIncludePaths.js +0 -12
  306. package/dist/legacy-root-azm/src/sourceLoader.d.ts +0 -15
  307. package/dist/legacy-root-azm/src/sourceLoader.js +0 -118
  308. package/dist/legacy-root-azm/src/z80/effects.d.ts +0 -3
  309. package/dist/legacy-root-azm/src/z80/effects.js +0 -516
  310. package/dist/legacy-root-azm/src/z80/encode.d.ts +0 -10
  311. package/dist/legacy-root-azm/src/z80/encode.js +0 -412
  312. package/dist/legacy-root-azm/src/z80/encodeAlu.d.ts +0 -7
  313. package/dist/legacy-root-azm/src/z80/encodeAlu.js +0 -219
  314. package/dist/legacy-root-azm/src/z80/encodeBitOps.d.ts +0 -7
  315. package/dist/legacy-root-azm/src/z80/encodeBitOps.js +0 -123
  316. package/dist/legacy-root-azm/src/z80/encodeContext.d.ts +0 -29
  317. package/dist/legacy-root-azm/src/z80/encodeContext.js +0 -1
  318. package/dist/legacy-root-azm/src/z80/encodeControl.d.ts +0 -26
  319. package/dist/legacy-root-azm/src/z80/encodeControl.js +0 -180
  320. package/dist/legacy-root-azm/src/z80/encodeCoreOps.d.ts +0 -7
  321. package/dist/legacy-root-azm/src/z80/encodeCoreOps.js +0 -131
  322. package/dist/legacy-root-azm/src/z80/encodeIo.d.ts +0 -9
  323. package/dist/legacy-root-azm/src/z80/encodeIo.js +0 -128
  324. package/dist/legacy-root-azm/src/z80/encodeLd.d.ts +0 -13
  325. package/dist/legacy-root-azm/src/z80/encodeLd.js +0 -273
  326. package/dist/legacy-root-azm/src/z80/encoderRegistry.d.ts +0 -13
  327. package/dist/legacy-root-azm/src/z80/encoderRegistry.js +0 -169
  328. package/dist/src/outputs/write-listing.d.ts +0 -2
  329. package/dist/src/outputs/write-listing.js +0 -79
  330. /package/dist/{legacy-root-azm/src/registerCare → src/register-care}/annotate.d.ts +0 -0
  331. /package/dist/{legacy-root-azm/src/registerCare → src/register-care}/annotate.js +0 -0
  332. /package/dist/{legacy-root-azm/src/registerCare → src/register-care}/sourceText.d.ts +0 -0
  333. /package/dist/{legacy-root-azm/src/registerCare → src/register-care}/sourceText.js +0 -0
  334. /package/dist/{legacy-root-azm/src/registerCare → src/register-care}/summary.d.ts +0 -0
@@ -14,6 +14,7 @@ export function writeAsm80(items, symbols, opts = {}) {
14
14
  void opts;
15
15
  const evalContext = {
16
16
  constants: collectConstants(symbols),
17
+ symbols: collectSymbolValues(symbols),
17
18
  layouts: collectLayouts(items),
18
19
  };
19
20
  const lines = [asm80Header, ''];
@@ -43,6 +44,13 @@ function collectConstants(symbols) {
43
44
  }
44
45
  return constants;
45
46
  }
47
+ function collectSymbolValues(symbols) {
48
+ const values = new Map();
49
+ for (const symbol of symbols) {
50
+ values.set(symbol.name, symbol.kind === 'constant' ? symbol.value : symbol.address);
51
+ }
52
+ return values;
53
+ }
46
54
  function collectLayouts(items) {
47
55
  const layouts = new Map();
48
56
  for (const item of items) {
@@ -53,6 +61,13 @@ function collectLayouts(items) {
53
61
  span: item.span,
54
62
  });
55
63
  }
64
+ else if (item.kind === 'type-alias') {
65
+ layouts.set(item.name, {
66
+ kind: 'alias',
67
+ typeExpr: item.typeExpr,
68
+ span: item.span,
69
+ });
70
+ }
56
71
  }
57
72
  return layouts;
58
73
  }
@@ -74,6 +89,11 @@ function formatItem(item, evalContext, state) {
74
89
  ? undefined
75
90
  : withImplicitOrg(state, `${item.name} EQU ${expression}`, 0);
76
91
  }
92
+ case 'comment':
93
+ return {
94
+ text: item.origin === 'user' ? `; ${item.text}` : `; AZM: ${item.text}`,
95
+ size: 0,
96
+ };
77
97
  case 'label':
78
98
  return withImplicitOrg(state, `${item.name}:`, 0);
79
99
  case 'db':
@@ -90,6 +110,7 @@ function formatItem(item, evalContext, state) {
90
110
  return withImplicitOrg(state, formatInstruction(item.instruction, evalContext)?.text, instructionSize(item.instruction));
91
111
  case 'enum':
92
112
  case 'type':
113
+ case 'type-alias':
93
114
  case 'end':
94
115
  case 'binfrom':
95
116
  case 'binto':
@@ -239,6 +260,16 @@ function formatInstruction(instruction, evalContext) {
239
260
  case 'res':
240
261
  case 'set':
241
262
  return formatBitOp(instruction, evalContext);
263
+ case 'rlc':
264
+ case 'rrc':
265
+ case 'rl':
266
+ case 'rr':
267
+ case 'sla':
268
+ case 'sra':
269
+ case 'sll':
270
+ case 'sls':
271
+ case 'srl':
272
+ return formatRotateShift(instruction, evalContext);
242
273
  case 'in':
243
274
  return formatIn(instruction, evalContext);
244
275
  case 'out':
@@ -264,6 +295,11 @@ function formatInstruction(instruction, evalContext) {
264
295
  return formatBranch(`call ${instruction.condition},`, instruction.expression, evalContext);
265
296
  case 'djnz':
266
297
  return formatBranch('djnz', instruction.expression, evalContext);
298
+ case 'push':
299
+ case 'pop':
300
+ return { text: `${instruction.mnemonic} ${instruction.register}` };
301
+ case 'ret-cc':
302
+ return { text: `ret ${instruction.condition}` };
267
303
  default:
268
304
  return undefined;
269
305
  }
@@ -282,7 +318,7 @@ function formatAlu(mnemonic, source, evalContext) {
282
318
  return { text: `${mnemonic} ${operand}` };
283
319
  }
284
320
  function formatAluOperand(source, evalContext) {
285
- if (source.kind === 'reg8') {
321
+ if (source.kind === 'reg8' || source.kind === 'reg-half-index') {
286
322
  return source.register;
287
323
  }
288
324
  if (source.kind === 'reg-indirect' && source.register === 'hl') {
@@ -330,6 +366,18 @@ function formatLd(target, source, evalContext) {
330
366
  if (target.kind === 'reg8' && source.kind === 'reg8') {
331
367
  return { text: `ld ${target.register}, ${source.register}` };
332
368
  }
369
+ if (target.kind === 'reg8' && source.kind === 'reg-half-index') {
370
+ return { text: `ld ${target.register}, ${source.register}` };
371
+ }
372
+ if (target.kind === 'reg8' && target.register === 'a' && source.kind === 'special8') {
373
+ return { text: `ld a, ${source.register}` };
374
+ }
375
+ if (target.kind === 'special8' && source.kind === 'reg8' && source.register === 'a') {
376
+ return { text: `ld ${target.register}, a` };
377
+ }
378
+ if (target.kind === 'reg-index16' && source.kind === 'imm') {
379
+ return formatLdText(target.register, formatExpression(source.expression, evalContext, 'word'));
380
+ }
333
381
  if (target.kind === 'reg16' && source.kind === 'imm') {
334
382
  return formatLdText(target.register, formatExpression(source.expression, evalContext, 'word'));
335
383
  }
@@ -345,12 +393,44 @@ function formatLd(target, source, evalContext) {
345
393
  source.register === 'a') {
346
394
  return { text: `ld (${target.register}), a` };
347
395
  }
348
- if (target.kind === 'reg8' && target.register === 'a' && source.kind === 'mem-abs') {
349
- return formatLdText('a', formatParenthesizedExpression(source.expression, evalContext, 'auto'));
396
+ if (target.kind === 'reg8' && source.kind === 'reg-indirect' && source.register === 'hl') {
397
+ return { text: `ld ${target.register}, (hl)` };
398
+ }
399
+ if (target.kind === 'reg-indirect' && target.register === 'hl' && source.kind === 'reg8') {
400
+ return { text: `ld (hl), ${source.register}` };
401
+ }
402
+ if (target.kind === 'reg-indirect' && target.register === 'hl' && source.kind === 'imm') {
403
+ const value = formatExpression(source.expression, evalContext, 'byte');
404
+ return value === undefined ? undefined : { text: `ld (hl), ${value}` };
405
+ }
406
+ if (target.kind === 'reg8' && source.kind === 'indexed') {
407
+ const memory = formatIndexedMemory(source.register, source.displacement, evalContext);
408
+ return memory === undefined ? undefined : { text: `ld ${target.register}, ${memory}` };
409
+ }
410
+ if (target.kind === 'indexed' && source.kind === 'reg8') {
411
+ const memory = formatIndexedMemory(target.register, target.displacement, evalContext);
412
+ return memory === undefined ? undefined : { text: `ld ${memory}, ${source.register}` };
413
+ }
414
+ if (target.kind === 'reg8' && source.kind === 'mem-abs') {
415
+ return formatLdText(target.register, formatParenthesizedExpression(source.expression, evalContext, 'auto'));
350
416
  }
351
- if (target.kind === 'mem-abs' && source.kind === 'reg8' && source.register === 'a') {
417
+ if (target.kind === 'mem-abs' && source.kind === 'reg8') {
352
418
  const targetText = formatParenthesizedExpression(target.expression, evalContext, 'auto');
353
- return targetText === undefined ? undefined : { text: `ld ${targetText}, a` };
419
+ return targetText === undefined
420
+ ? undefined
421
+ : { text: `ld ${targetText}, ${source.register}` };
422
+ }
423
+ if (target.kind === 'mem-abs' && source.kind === 'reg16') {
424
+ const targetText = formatParenthesizedExpression(target.expression, evalContext, 'auto');
425
+ return targetText === undefined
426
+ ? undefined
427
+ : { text: `ld ${targetText}, ${source.register}` };
428
+ }
429
+ if (target.kind === 'mem-abs' && source.kind === 'reg-index16') {
430
+ const targetText = formatParenthesizedExpression(target.expression, evalContext, 'auto');
431
+ return targetText === undefined
432
+ ? undefined
433
+ : { text: `ld ${targetText}, ${source.register}` };
354
434
  }
355
435
  return undefined;
356
436
  }
@@ -383,6 +463,37 @@ function formatExpression(expression, evalContext, width) {
383
463
  if (expression.kind === 'symbol') {
384
464
  return expression.name;
385
465
  }
466
+ if (expression.kind === 'type-size') {
467
+ const value = evaluateLoweredConstant(expression, evalContext);
468
+ return value === undefined ? expression.typeExpr.name : formatLoweredNumber(value, width);
469
+ }
470
+ if (expression.kind === 'current-location') {
471
+ return '$';
472
+ }
473
+ if (expression.kind === 'unary') {
474
+ const inner = formatExpression(expression.expression, evalContext, width);
475
+ if (inner === undefined) {
476
+ return undefined;
477
+ }
478
+ switch (expression.operator) {
479
+ case '+':
480
+ return inner;
481
+ case '-':
482
+ return `-${inner}`;
483
+ case '~': {
484
+ const value = evaluateLoweredConstant(expression, evalContext);
485
+ return value === undefined ? undefined : formatLoweredNumber(value, width);
486
+ }
487
+ }
488
+ }
489
+ if (expression.kind === 'binary') {
490
+ const left = formatExpression(expression.left, evalContext, width);
491
+ const right = formatExpression(expression.right, evalContext, width);
492
+ if (left === undefined || right === undefined) {
493
+ return undefined;
494
+ }
495
+ return `${left}${expression.operator}${right}`;
496
+ }
386
497
  return undefined;
387
498
  }
388
499
  function evaluateLoweredConstant(expression, evalContext) {
@@ -391,12 +502,31 @@ function evaluateLoweredConstant(expression, evalContext) {
391
502
  return expression.value;
392
503
  case 'symbol':
393
504
  return evalContext.constants.get(expression.name);
505
+ case 'type-size': {
506
+ const constant = evalContext.constants.get(expression.typeExpr.name);
507
+ if (constant !== undefined) {
508
+ return constant;
509
+ }
510
+ return evaluateExpression(expression, {}, new Map(), silentSpan, [], {
511
+ currentLocation: 0,
512
+ layouts: evalContext.layouts,
513
+ reportUnknown: false,
514
+ });
515
+ }
516
+ case 'offset':
394
517
  case 'sizeof':
395
518
  return evaluateExpression(expression, {}, new Map(), silentSpan, [], {
396
519
  currentLocation: 0,
397
520
  layouts: evalContext.layouts,
398
521
  reportUnknown: false,
399
522
  });
523
+ case 'byte-function': {
524
+ const value = evaluateLoweredResolvedConstant(expression.expression, evalContext);
525
+ if (value === undefined) {
526
+ return undefined;
527
+ }
528
+ return expression.function === 'LSB' ? value & 0xff : (value >> 8) & 0xff;
529
+ }
400
530
  case 'unary': {
401
531
  const value = evaluateLoweredConstant(expression.expression, evalContext);
402
532
  if (value === undefined) {
@@ -446,12 +576,83 @@ function evaluateLoweredConstant(expression, evalContext) {
446
576
  return undefined;
447
577
  }
448
578
  }
579
+ function evaluateLoweredResolvedConstant(expression, evalContext) {
580
+ switch (expression.kind) {
581
+ case 'symbol':
582
+ return evalContext.symbols.get(expression.name);
583
+ case 'unary': {
584
+ const value = evaluateLoweredResolvedConstant(expression.expression, evalContext);
585
+ if (value === undefined) {
586
+ return undefined;
587
+ }
588
+ switch (expression.operator) {
589
+ case '+':
590
+ return value;
591
+ case '-':
592
+ return -value;
593
+ case '~':
594
+ return ~value;
595
+ }
596
+ break;
597
+ }
598
+ case 'binary': {
599
+ const left = evaluateLoweredResolvedConstant(expression.left, evalContext);
600
+ const right = evaluateLoweredResolvedConstant(expression.right, evalContext);
601
+ if (left === undefined || right === undefined) {
602
+ return undefined;
603
+ }
604
+ switch (expression.operator) {
605
+ case '+':
606
+ return left + right;
607
+ case '-':
608
+ return left - right;
609
+ case '*':
610
+ return left * right;
611
+ case '/':
612
+ return right === 0 ? undefined : Math.trunc(left / right);
613
+ case '%':
614
+ return right === 0 ? undefined : left % right;
615
+ case '&':
616
+ return left & right;
617
+ case '^':
618
+ return left ^ right;
619
+ case '|':
620
+ return left | right;
621
+ case '<<':
622
+ return left << right;
623
+ case '>>':
624
+ return left >> right;
625
+ }
626
+ break;
627
+ }
628
+ case 'byte-function': {
629
+ const value = evaluateLoweredResolvedConstant(expression.expression, evalContext);
630
+ if (value === undefined) {
631
+ return undefined;
632
+ }
633
+ return expression.function === 'LSB' ? value & 0xff : (value >> 8) & 0xff;
634
+ }
635
+ default:
636
+ return evaluateLoweredConstant(expression, evalContext);
637
+ }
638
+ }
449
639
  function formatLoweredNumber(value, width) {
450
640
  const normalized = value < 0 ? 0x10000 + (value & 0xffff) : value;
451
641
  const digits = normalized.toString(16).toUpperCase();
452
642
  const minWidth = width === 'word' || (width === 'auto' && normalized > 0xff) ? 4 : 2;
453
643
  return `$${digits.padStart(minWidth, '0')}`;
454
644
  }
645
+ function formatRotateShift(instruction, evalContext) {
646
+ const operand = formatBitOperand(instruction.operand, evalContext);
647
+ if (operand === undefined) {
648
+ return undefined;
649
+ }
650
+ const parts = [operand];
651
+ if (instruction.destination) {
652
+ parts.push(instruction.destination.register);
653
+ }
654
+ return { text: `${instruction.mnemonic} ${parts.join(', ')}` };
655
+ }
455
656
  function formatBitOp(instruction, evalContext) {
456
657
  const bit = formatLoweredNumber(instruction.bit, 'byte');
457
658
  const operand = formatBitOperand(instruction.operand, evalContext);
@@ -5,6 +5,14 @@ import { autoFixableCandidateKeys } from './fix.js';
5
5
  import { findCallerOutputCandidateObservations, findRegisterCareConflicts, } from './liveness.js';
6
6
  import { buildAnnotations } from './annotations.js';
7
7
  import { buildOutputCandidateFixability, buildProfileSummaries, buildProfileSummaryLookup, buildSummaries, buildSummaryByName, outputCandidateKey, routineNames, unknownBoundaryDiagnostics, unknownCallList, withAcceptedOutputs, } from './summaries.js';
8
+ function candidateMessageWithFixability(candidate, autoFixable) {
9
+ const carriers = candidate.carriers.join(',');
10
+ const expectation = candidate.carriers.length === 1 ? candidate.carriers[0] : `{${carriers}}`;
11
+ const base = `CALL ${candidate.routine} writes ${carriers} and caller reads it later`;
12
+ return autoFixable
13
+ ? `${base}; generated contracts promote this to \`out ${expectation}\` automatically.`
14
+ : `${base}; manual review required before adding \`; expects out ${expectation}\` because the later read is not a simple direct continuation.`;
15
+ }
8
16
  export function analyzeRegisterCare(loaded, options) {
9
17
  const file = loaded.program.files[0];
10
18
  const items = file?.items ?? [];
@@ -16,8 +24,8 @@ export function analyzeRegisterCare(loaded, options) {
16
24
  contractMap.set(contract.name, contract);
17
25
  }
18
26
  }
19
- let summaries = buildSummaries(program.routines, contractMap);
20
27
  const profileSummaries = buildProfileSummaries(options.registerCareProfile);
28
+ let summaries = buildSummaries(program.routines, contractMap, profileSummaries);
21
29
  summaries = withAcceptedOutputs(summaries, options.acceptedOutputCandidates);
22
30
  const allSummaries = [...summaries, ...profileSummaries];
23
31
  const summariesByName = buildSummaryByName(program.routines, summaries, profileSummaries);
@@ -41,10 +49,14 @@ export function analyzeRegisterCare(loaded, options) {
41
49
  const conflicts = analyzed.conflicts;
42
50
  const outputCandidates = analyzed.outputCandidates;
43
51
  const outputCandidateFixability = buildOutputCandidateFixability(program.routines, outputCandidates, autoFixableCandidateKeys);
44
- const outputCandidatesWithFixability = outputCandidates.map((candidate) => ({
45
- ...candidate,
46
- autoFixable: outputCandidateFixability.get(outputCandidateKey(candidate.file, candidate.line, candidate.column)) ?? false,
47
- }));
52
+ const outputCandidatesWithFixability = outputCandidates.map((candidate) => {
53
+ const autoFixable = outputCandidateFixability.get(outputCandidateKey(candidate.file, candidate.line, candidate.column)) ?? false;
54
+ return {
55
+ ...candidate,
56
+ autoFixable,
57
+ message: candidateMessageWithFixability(candidate, autoFixable),
58
+ };
59
+ });
48
60
  if (options.mode !== 'audit') {
49
61
  for (const conflict of conflicts) {
50
62
  diagnostics.push({
@@ -58,7 +70,7 @@ export function analyzeRegisterCare(loaded, options) {
58
70
  }
59
71
  }
60
72
  if (options.mode === 'strict') {
61
- diagnostics.push(...unknownBoundaryDiagnostics(program.directCalls, knownRoutines));
73
+ diagnostics.push(...unknownBoundaryDiagnostics(program.directBoundaries, knownRoutines));
62
74
  }
63
75
  const reportModel = {
64
76
  entryFile: loaded.program.entryFile,
@@ -67,10 +79,26 @@ export function analyzeRegisterCare(loaded, options) {
67
79
  conflicts,
68
80
  outputCandidates: outputCandidatesWithFixability,
69
81
  ...(options.registerCareProfile !== undefined ? { profile: options.registerCareProfile } : {}),
70
- unknownCalls: options.mode === 'off' ? [] : unknownCallList(program.directCalls, knownRoutines),
82
+ unknownCalls: options.mode === 'off' ? [] : unknownCallList(program.directBoundaries, knownRoutines),
71
83
  };
84
+ const summariesForAnnotations = new Map(summariesByName);
85
+ const outputCandidatesByRoutine = new Map();
86
+ for (const candidate of outputCandidatesWithFixability) {
87
+ const existing = outputCandidatesByRoutine.get(candidate.routine) ?? [];
88
+ for (const unit of candidate.carriers) {
89
+ if (!existing.includes(unit))
90
+ existing.push(unit);
91
+ }
92
+ outputCandidatesByRoutine.set(candidate.routine, existing);
93
+ }
94
+ for (const [name, summary] of summariesForAnnotations) {
95
+ const candidates = outputCandidatesByRoutine.get(name);
96
+ if (candidates !== undefined && candidates.length > 0) {
97
+ summariesForAnnotations.set(name, { ...summary, outputCandidates: candidates });
98
+ }
99
+ }
72
100
  const annotations = options.emitAnnotations
73
- ? buildAnnotations(loaded, program.routines, summariesByName, outputCandidatesWithFixability, {
101
+ ? buildAnnotations(loaded, program.routines, summariesForAnnotations, outputCandidatesWithFixability, {
74
102
  fixOutputCandidates: options.fixRegisterContracts === true,
75
103
  outputCandidateFixability,
76
104
  outputCandidateKey,
@@ -1,154 +1,41 @@
1
- function formatCarrierLine(tag, units) {
2
- return `;! ${tag.padEnd(10)}${units.join(',')}`;
3
- }
4
- function formatCandidateUnits(units) {
5
- return units.length === 1 ? units[0] : `{${units.join(',')}}`;
6
- }
7
- function formatCarrierLineWithExpectOut(indentation, units) {
8
- return `${indentation}; expects out ${formatCandidateUnits(units)}`;
9
- }
10
- function formatCarrierLineWithMaybeOut(indentation, units) {
11
- return `${indentation};! ${'maybe-out'.padEnd(10)}${formatCandidateUnits(units)}`;
12
- }
13
- function isGeneratedRegisterContractLine(line) {
14
- return /^\s*;!\s*(in|out|clobbers|preserves|maybe-out)\b/i.test(line);
15
- }
16
- function isOutputCandidateHintLine(line) {
17
- return /^\s*;\s*expects\s+out\b/i.test(line) || /^\s*;\s*!\s*maybe-out\b/i.test(line);
18
- }
19
- function normalizeLineEnding(text) {
20
- return text.replace(/\r\n/g, '\n');
21
- }
22
- function splitSourceLines(text) {
23
- return normalizeLineEnding(text).split('\n');
24
- }
25
- function lineDeltaForCandidate(line, deltas) {
26
- let shift = 0;
27
- for (const delta of deltas) {
28
- if (delta.anchorLine < line) {
29
- shift += delta.delta;
30
- }
31
- }
32
- return shift;
33
- }
34
- function applyOutputCandidateHints(sourceText, outputCandidates, candidateFixability, deltas, outputCandidateKey) {
35
- const lines = splitSourceLines(sourceText);
36
- const grouped = new Map();
37
- for (const candidate of outputCandidates) {
38
- const adjustedLine = candidate.line + lineDeltaForCandidate(candidate.line, deltas);
39
- const existing = grouped.get(adjustedLine);
40
- const autoFixable = candidateFixability.get(outputCandidateKey(candidate.file, candidate.line, candidate.column)) ?? false;
41
- if (existing === undefined) {
42
- grouped.set(adjustedLine, { carriers: [...candidate.carriers], autoFixable });
43
- continue;
44
- }
45
- const carriers = existing.carriers;
46
- for (const carrier of candidate.carriers) {
47
- if (!carriers.includes(carrier)) {
48
- carriers.push(carrier);
49
- }
50
- }
51
- existing.autoFixable = existing.autoFixable && autoFixable;
52
- }
53
- const candidates = [...grouped.entries()]
54
- .map(([line, entry]) => ({ line, ...entry }))
55
- .sort((left, right) => right.line - left.line);
56
- for (const candidate of candidates) {
57
- const index = candidate.line - 1;
58
- if (index < 0 || index > lines.length)
59
- continue;
60
- if (index > 0 && isOutputCandidateHintLine(lines[index - 1] ?? ''))
61
- continue;
62
- const indentation = lines[index]?.match(/^\s*/)?.[0] ?? '';
63
- const hint = candidate.autoFixable
64
- ? formatCarrierLineWithExpectOut(indentation, candidate.carriers)
65
- : formatCarrierLineWithMaybeOut(indentation, candidate.carriers);
66
- lines.splice(index, 0, hint);
67
- }
68
- return lines.join('\n');
69
- }
70
- function annotateSourceFile(sourceText, routines, summariesByName) {
71
- const routineLines = Array.from(routines)
1
+ import { annotateRegisterCareContracts } from './annotate.js';
2
+ import { applyExpectOutFixesToSource, findExpectOutFixesForCandidates, } from './fix.js';
3
+ export function buildAnnotations(loaded, programRoutines, summariesByName, outputCandidates, options) {
4
+ const routines = programRoutines
72
5
  .filter((routine) => summariesByName.has(routine.name))
73
- .sort((left, right) => right.span.start.line - left.span.start.line);
74
- if (routineLines.length === 0)
75
- return undefined;
76
- const lines = splitSourceLines(sourceText);
77
- let changed = false;
78
- const deltas = [];
79
- for (const routine of routineLines) {
80
- const summary = summariesByName.get(routine.name);
81
- if (!summary)
82
- continue;
83
- const insertLine = routine.span.start.line - 1;
84
- if (insertLine < 0 || insertLine > lines.length)
85
- continue;
86
- const generatedLines = [
87
- ...(summary.mayRead.length > 0 ? [formatCarrierLine('in', summary.mayRead)] : []),
88
- ...(summary.mayWrite.length > 0 ? [formatCarrierLine('out', summary.mayWrite)] : []),
89
- ...(summary.preserved.length > 0 ? [formatCarrierLine('preserves', summary.preserved)] : []),
90
- ];
91
- if (generatedLines.length === 0)
92
- continue;
93
- let start = insertLine;
94
- for (let index = insertLine - 1; index >= 0 && isGeneratedRegisterContractLine(lines[index] ?? ''); index -= 1) {
95
- start = index;
96
- }
97
- if (start === insertLine ||
98
- lines.slice(start, insertLine).some((line) => line.trim().length === 0)) {
99
- start = insertLine;
100
- }
101
- const existing = lines.slice(start, insertLine);
102
- if (existing.length !== generatedLines.length ||
103
- existing.some((line, index) => line !== generatedLines[index])) {
104
- changed = true;
105
- deltas.push({
106
- anchorLine: routine.span.start.line,
107
- delta: generatedLines.length - (insertLine - start),
108
- });
109
- lines.splice(start, insertLine - start, ...generatedLines);
110
- }
6
+ .map((routine) => ({
7
+ routine,
8
+ summary: summariesByName.get(routine.name),
9
+ }));
10
+ const annotated = annotateRegisterCareContracts(loaded.sourceTexts, routines);
11
+ if (!options.fixOutputCandidates) {
12
+ return annotated.map((file) => ({ path: file.path, text: file.text }));
111
13
  }
112
- if (!changed)
113
- return undefined;
114
- return {
115
- text: lines.join('\n'),
116
- deltas,
117
- };
118
- }
119
- export function buildAnnotations(loaded, programRoutines, summariesByName, outputCandidates, options) {
120
- const byFile = new Map();
121
- for (const routine of programRoutines) {
122
- if (!summariesByName.has(routine.name))
123
- continue;
124
- const file = byFile.get(routine.span.file);
125
- if (file === undefined) {
126
- byFile.set(routine.span.file, [routine]);
127
- }
128
- else {
129
- file.push(routine);
130
- }
14
+ const autoFixableCandidates = outputCandidates.filter((candidate) => options.outputCandidateFixability.get(options.outputCandidateKey(candidate.file, candidate.line, candidate.column)) === true);
15
+ const fixes = findExpectOutFixesForCandidates([...programRoutines], autoFixableCandidates);
16
+ if (fixes.length === 0) {
17
+ return annotated.map((file) => ({ path: file.path, text: file.text }));
18
+ }
19
+ const workingTexts = new Map(loaded.sourceTexts);
20
+ for (const file of annotated) {
21
+ workingTexts.set(file.path, file.text);
131
22
  }
132
23
  const out = [];
133
- for (const [path, routines] of byFile) {
134
- const sourceText = loaded.sourceTexts.get(path);
135
- if (sourceText === undefined)
24
+ const fixesByFile = new Map();
25
+ for (const fix of fixes) {
26
+ const items = fixesByFile.get(fix.file) ?? [];
27
+ items.push(fix);
28
+ fixesByFile.set(fix.file, items);
29
+ }
30
+ for (const [path, text] of workingTexts) {
31
+ const reference = loaded.sourceTexts.get(path);
32
+ if (reference === undefined)
136
33
  continue;
137
- let text = sourceText;
138
- let deltas = [];
139
- const annotation = annotateSourceFile(sourceText, routines, summariesByName);
140
- if (annotation !== undefined) {
141
- text = annotation.text;
142
- deltas = annotation.deltas;
143
- }
144
- if (options.fixOutputCandidates) {
145
- const candidatesForFile = outputCandidates.filter((candidate) => candidate.file === path);
146
- if (candidatesForFile.length > 0) {
147
- text = applyOutputCandidateHints(text, candidatesForFile, options.outputCandidateFixability, deltas, options.outputCandidateKey);
148
- }
34
+ const fileFixes = fixesByFile.get(path) ?? [];
35
+ const nextText = fileFixes.length > 0 ? applyExpectOutFixesToSource(text, fileFixes, reference) : text;
36
+ if (nextText !== reference) {
37
+ out.push({ path, text: nextText });
149
38
  }
150
- if (text !== sourceText)
151
- out.push({ path, text });
152
39
  }
153
- return out;
40
+ return out.sort((left, right) => left.path.localeCompare(right.path));
154
41
  }
@@ -6,4 +6,6 @@ export interface RegisterCareExpectOutFix {
6
6
  routine: string;
7
7
  carriers: RegisterCareUnit[];
8
8
  }
9
+ export declare function findExpectOutFixesForCandidates(routines: RegisterCareRoutine[], candidates: RegisterCareOutputCandidate[]): RegisterCareExpectOutFix[];
9
10
  export declare function autoFixableCandidateKeys(routines: RegisterCareRoutine[], candidates: RegisterCareOutputCandidate[]): Set<string>;
11
+ export declare function applyExpectOutFixesToSource(source: string, fixes: RegisterCareExpectOutFix[], referenceSource?: string): string;
@@ -1,5 +1,7 @@
1
1
  import { getZ80InstructionEffect } from '../z80/effects.js';
2
2
  import { instructionSuccessors, labelIndex } from './controlFlow.js';
3
+ import { contractCarrierList } from './report.js';
4
+ import { joinSourceLines, splitSourceLines } from './sourceText.js';
3
5
  function sameLocation(a, b) {
4
6
  return a.file === b.file && a.line === b.line && a.column === b.column;
5
7
  }
@@ -68,6 +70,9 @@ function findExpectOutFixes(routines, candidates) {
68
70
  }
69
71
  return out;
70
72
  }
73
+ export function findExpectOutFixesForCandidates(routines, candidates) {
74
+ return findExpectOutFixes(routines, candidates);
75
+ }
71
76
  export function autoFixableCandidateKeys(routines, candidates) {
72
77
  const fixes = findExpectOutFixes(routines, candidates);
73
78
  const out = new Set();
@@ -76,3 +81,50 @@ export function autoFixableCandidateKeys(routines, candidates) {
76
81
  }
77
82
  return out;
78
83
  }
84
+ function isExpectOutLine(line) {
85
+ return /^\s*;\s*expects\s+out\b/i.test(line);
86
+ }
87
+ function expectedCallLine(originalLines, fix) {
88
+ return originalLines[fix.line - 1]?.trim();
89
+ }
90
+ function findCallLineIndex(lines, originalLines, fix) {
91
+ const expected = expectedCallLine(originalLines, fix);
92
+ if (!expected)
93
+ return undefined;
94
+ const preferred = fix.line - 1;
95
+ if (lines[preferred]?.trim() === expected)
96
+ return preferred;
97
+ let best;
98
+ let bestDistance = Number.POSITIVE_INFINITY;
99
+ for (let index = 0; index < lines.length; index += 1) {
100
+ if (lines[index]?.trim() !== expected)
101
+ continue;
102
+ const distance = Math.abs(index - preferred);
103
+ if (distance < bestDistance) {
104
+ best = index;
105
+ bestDistance = distance;
106
+ }
107
+ }
108
+ return best;
109
+ }
110
+ function indentation(line) {
111
+ return line.match(/^\s*/)?.[0] ?? '';
112
+ }
113
+ export function applyExpectOutFixesToSource(source, fixes, referenceSource = source) {
114
+ if (fixes.length === 0)
115
+ return source;
116
+ const originalLines = referenceSource.split(/\r?\n/);
117
+ const sourceLines = splitSourceLines(source);
118
+ const { lines } = sourceLines;
119
+ const sorted = [...fixes].sort((a, b) => b.line - a.line || b.column - a.column);
120
+ for (const fix of sorted) {
121
+ const index = findCallLineIndex(lines, originalLines, fix);
122
+ if (index === undefined)
123
+ continue;
124
+ if (index > 0 && isExpectOutLine(lines[index - 1] ?? ''))
125
+ continue;
126
+ const prefix = indentation(lines[index] ?? '');
127
+ lines.splice(index, 0, `${prefix}; expects out ${contractCarrierList(fix.carriers)}`);
128
+ }
129
+ return joinSourceLines(sourceLines);
130
+ }
@@ -0,0 +1,11 @@
1
+ import type { Z80Instruction, Z80Operand } from '../z80/instruction.js';
2
+ import type { RegisterCareInstruction } from './types.js';
3
+ export declare function instructionHead(item: RegisterCareInstruction): string;
4
+ export declare function regName(operand: Z80Operand | undefined): string | undefined;
5
+ export declare function instructionOperandCount(instruction: Z80Instruction): number;
6
+ export declare function instructionOperand(instruction: Z80Instruction, index: number): Z80Operand | undefined;
7
+ export declare function isUnconditionalReturnInstruction(item: RegisterCareInstruction): boolean;
8
+ export declare function isPureTokenTransferInstruction(item: RegisterCareInstruction): boolean;
9
+ export declare function isAccumulatorSelfOperand(item: RegisterCareInstruction): boolean;
10
+ export declare function isImmediateZeroOperand(item: RegisterCareInstruction): boolean;
11
+ export declare function isRegisterOperand(item: RegisterCareInstruction | undefined, index: number, name: string): boolean;