@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
@@ -0,0 +1,129 @@
1
+ export function instructionHead(item) {
2
+ return item.instruction.mnemonic.toLowerCase();
3
+ }
4
+ export function regName(operand) {
5
+ if (operand === undefined)
6
+ return undefined;
7
+ switch (operand.kind) {
8
+ case 'reg8':
9
+ return operand.register.toUpperCase();
10
+ case 'reg16':
11
+ return operand.register.toUpperCase();
12
+ case 'reg-index16':
13
+ return operand.register.toUpperCase();
14
+ case 'reg-half-index':
15
+ return operand.register.toUpperCase();
16
+ default:
17
+ return undefined;
18
+ }
19
+ }
20
+ function immValue(operand) {
21
+ if (operand?.kind !== 'imm')
22
+ return undefined;
23
+ const expression = operand.expression;
24
+ return expression.kind === 'number' ? expression.value : undefined;
25
+ }
26
+ export function instructionOperandCount(instruction) {
27
+ switch (instruction.mnemonic) {
28
+ case 'ret':
29
+ case 'ret-cc':
30
+ return instruction.mnemonic === 'ret' ? 0 : 1;
31
+ case 'ld':
32
+ return 2;
33
+ case 'ex':
34
+ return 2;
35
+ case 'jp':
36
+ case 'jp-cc':
37
+ case 'jr':
38
+ case 'jr-cc':
39
+ case 'djnz':
40
+ case 'call':
41
+ case 'call-cc':
42
+ return 1;
43
+ case 'add':
44
+ case 'adc':
45
+ case 'sbc':
46
+ return 'target' in instruction ? 2 : 1;
47
+ case 'sub':
48
+ case 'and':
49
+ case 'or':
50
+ case 'xor':
51
+ case 'cp':
52
+ return 1;
53
+ default:
54
+ return 0;
55
+ }
56
+ }
57
+ export function instructionOperand(instruction, index) {
58
+ switch (instruction.mnemonic) {
59
+ case 'ld':
60
+ return index === 0 ? instruction.target : index === 1 ? instruction.source : undefined;
61
+ case 'ex': {
62
+ if (index === 0) {
63
+ return instruction.form === 'de-hl'
64
+ ? { kind: 'reg16', register: 'de' }
65
+ : instruction.form === 'af-af'
66
+ ? { kind: 'reg16', register: 'af' }
67
+ : undefined;
68
+ }
69
+ if (index === 1) {
70
+ return instruction.form === 'de-hl'
71
+ ? { kind: 'reg16', register: 'hl' }
72
+ : undefined;
73
+ }
74
+ return undefined;
75
+ }
76
+ case 'add':
77
+ case 'adc':
78
+ case 'sbc':
79
+ if ('target' in instruction) {
80
+ return index === 0 ? instruction.target : index === 1 ? instruction.source : undefined;
81
+ }
82
+ return index === 0 ? instruction.source : undefined;
83
+ case 'sub':
84
+ case 'and':
85
+ case 'or':
86
+ case 'xor':
87
+ case 'cp':
88
+ return index === 0 ? instruction.source : undefined;
89
+ default:
90
+ return undefined;
91
+ }
92
+ }
93
+ export function isUnconditionalReturnInstruction(item) {
94
+ const head = instructionHead(item);
95
+ if (head === 'ret')
96
+ return item.instruction.mnemonic === 'ret';
97
+ return head === 'retn' || head === 'reti';
98
+ }
99
+ export function isPureTokenTransferInstruction(item) {
100
+ const head = instructionHead(item);
101
+ if (head === 'ex')
102
+ return true;
103
+ if (head !== 'ld' || instructionOperandCount(item.instruction) !== 2)
104
+ return false;
105
+ const dst = instructionOperand(item.instruction, 0);
106
+ const src = instructionOperand(item.instruction, 1);
107
+ if (regName(dst) === undefined)
108
+ return false;
109
+ return regName(src) !== undefined || src?.kind === 'imm';
110
+ }
111
+ export function isAccumulatorSelfOperand(item) {
112
+ const inst = item.instruction;
113
+ if (inst.mnemonic === 'or' || inst.mnemonic === 'and' || inst.mnemonic === 'xor') {
114
+ return inst.source.kind === 'reg8' && inst.source.register === 'a';
115
+ }
116
+ return false;
117
+ }
118
+ export function isImmediateZeroOperand(item) {
119
+ const inst = item.instruction;
120
+ if (inst.mnemonic !== 'cp')
121
+ return false;
122
+ return immValue(inst.source) === 0;
123
+ }
124
+ export function isRegisterOperand(item, index, name) {
125
+ if (item === undefined)
126
+ return false;
127
+ const operand = instructionOperand(item.instruction, index);
128
+ return regName(operand) === name.toUpperCase();
129
+ }
@@ -48,10 +48,7 @@ function hintUnitsForLine(hints, file, callLine) {
48
48
  return prior?.comment.kind === 'expectOut' ? unique(prior.comment.carriers) : [];
49
49
  }
50
50
  function outputUnits(summary) {
51
- return unique([
52
- ...(summary.valueRelations?.flatMap((relation) => relation.out) ?? []),
53
- ...(summary.mayOutput ?? []),
54
- ]);
51
+ return unique(summary.valueRelations.flatMap((relation) => relation.out));
55
52
  }
56
53
  function setEqual(left, right) {
57
54
  if (left.size !== right.size)
@@ -148,7 +145,7 @@ export function findRegisterCareConflicts(routine, summaries, hints) {
148
145
  for (const unit of outputUnits(summary))
149
146
  accepted.add(unit);
150
147
  const carriers = unique(summary.mayWrite.filter((unit) => liveOut[index].has(unit) && !accepted.has(unit)));
151
- if (carriers.length > 0 && !boundary.conditional) {
148
+ if (carriers.length > 0) {
152
149
  conflicts.push({
153
150
  file: item.file,
154
151
  line: item.line,
@@ -171,8 +168,19 @@ export function findCallerOutputCandidateObservations(routines, summaries) {
171
168
  for (const routine of routines) {
172
169
  const { liveOut } = liveSetsForRoutine(routine, summaries);
173
170
  for (const { item, index, boundary, target, summary } of resolvedBoundariesForRoutine(routine, summaries)) {
174
- const alreadyOutput = new Set(outputUnits(summary));
175
- const carriers = unique(summary.mayWrite.filter((unit) => liveOut[index].has(unit) && !alreadyOutput.has(unit)));
171
+ const intentionalOutputs = new Set(outputUnits(summary));
172
+ const carrierSources = [];
173
+ for (const unit of summary.mayWrite) {
174
+ if (liveOut[index].has(unit) && !intentionalOutputs.has(unit)) {
175
+ carrierSources.push(unit);
176
+ }
177
+ }
178
+ for (const unit of intentionalOutputs) {
179
+ if (liveOut[index].has(unit)) {
180
+ carrierSources.push(unit);
181
+ }
182
+ }
183
+ const carriers = unique(carrierSources);
176
184
  if (carriers.length > 0) {
177
185
  out.push({
178
186
  file: item.file,
@@ -23,6 +23,8 @@ export function getRegisterCareProfile(name) {
23
23
  mayOutput: [],
24
24
  preserved: ['B', 'C', 'D', 'E', 'H', 'L'],
25
25
  valueRelations: [],
26
+ stackBalanced: true,
27
+ hasUnknownStackEffect: false,
26
28
  },
27
29
  ],
28
30
  ]),
@@ -36,6 +38,8 @@ export function getRegisterCareProfile(name) {
36
38
  mayOutput: ['A', 'carry', 'zero'],
37
39
  preserved: ['B', 'C', 'D', 'E', 'H', 'L'],
38
40
  valueRelations: [{ out: ['A', 'carry', 'zero'], from: [] }],
41
+ stackBalanced: true,
42
+ hasUnknownStackEffect: false,
39
43
  },
40
44
  ],
41
45
  ]),
@@ -13,6 +13,21 @@ function instructionCallTarget(item) {
13
13
  }
14
14
  return undefined;
15
15
  }
16
+ function instructionTailJumpTarget(item, entryNames) {
17
+ if (item.kind !== 'instruction')
18
+ return undefined;
19
+ const mnemonic = item.instruction.mnemonic;
20
+ if (mnemonic === 'jp-cc' && entryNames === undefined)
21
+ return undefined;
22
+ if (mnemonic !== 'jp' && mnemonic !== 'jp-cc')
23
+ return undefined;
24
+ const target = routineNameFromExpression(item.instruction.expression);
25
+ if (target === undefined || target.startsWith('.'))
26
+ return undefined;
27
+ if (entryNames !== undefined && !entryNames.has(target))
28
+ return undefined;
29
+ return target;
30
+ }
16
31
  function toInstruction(item, labels) {
17
32
  return {
18
33
  instruction: item.instruction,
@@ -22,9 +37,16 @@ function toInstruction(item, labels) {
22
37
  labels: [...labels],
23
38
  };
24
39
  }
40
+ function pushDirectBoundary(boundaries, target, subject, file, line, column) {
41
+ boundaries.push({ target, subject, file, line, column });
42
+ }
25
43
  export function buildRegisterCareProgramModel(items) {
26
44
  const routines = [];
27
45
  const directCalls = [];
46
+ const filesWithEntryLabels = new Set(items
47
+ .filter((item) => item.kind === 'label')
48
+ .filter((item) => item.isEntry === true)
49
+ .map((item) => item.span.sourceName));
28
50
  let routineName;
29
51
  let entryLabels = [];
30
52
  let labels = [];
@@ -35,14 +57,28 @@ export function buildRegisterCareProgramModel(items) {
35
57
  const startRoutine = (item) => {
36
58
  sourceName = item.span.sourceName;
37
59
  routineName = item.name;
38
- entryLabels = [item.name];
60
+ entryLabels = item.isEntry === true ? [item.name] : [];
39
61
  labels = [item.name];
40
62
  routineStartLine = item.span.line;
41
63
  routineStartColumn = item.span.column;
42
64
  instructions = [];
43
65
  };
44
66
  const flushRoutine = () => {
45
- if (routineName === undefined || instructions.length === 0 || routineStartLine === undefined) {
67
+ if (routineName === undefined || routineStartLine === undefined) {
68
+ return;
69
+ }
70
+ if (instructions.length === 0) {
71
+ routines.push({
72
+ name: routineName,
73
+ labels: [...labels],
74
+ entryLabels: [...entryLabels],
75
+ instructions: [],
76
+ span: {
77
+ file: sourceName ?? '',
78
+ start: { line: routineStartLine, column: routineStartColumn ?? 1 },
79
+ end: { line: routineStartLine, column: routineStartColumn ?? 1 },
80
+ },
81
+ });
46
82
  return;
47
83
  }
48
84
  const end = instructions[instructions.length - 1];
@@ -88,12 +124,7 @@ export function buildRegisterCareProgramModel(items) {
88
124
  instructions.push(toInstruction(item, labels));
89
125
  const directTarget = instructionCallTarget(item);
90
126
  if (directTarget !== undefined) {
91
- directCalls.push({
92
- target: directTarget,
93
- file: item.span.sourceName,
94
- line: item.span.line,
95
- column: item.span.column,
96
- });
127
+ pushDirectBoundary(directCalls, directTarget, `CALL ${directTarget}`, item.span.sourceName, item.span.line, item.span.column);
97
128
  }
98
129
  continue;
99
130
  }
@@ -104,19 +135,54 @@ export function buildRegisterCareProgramModel(items) {
104
135
  continue;
105
136
  }
106
137
  if (routineName === undefined) {
138
+ if (filesWithEntryLabels.has(item.span.sourceName) && item.isEntry !== true) {
139
+ continue;
140
+ }
107
141
  startRoutine(item);
108
142
  continue;
109
143
  }
110
- if (instructions.length > 0 ||
111
- sourceName === undefined ||
112
- sourceName !== item.span.sourceName) {
144
+ if (sourceName === undefined || sourceName !== item.span.sourceName) {
145
+ finalizeAndRestart(item);
146
+ continue;
147
+ }
148
+ if (instructions.length > 0) {
149
+ if (filesWithEntryLabels.has(item.span.sourceName) && item.isEntry !== true) {
150
+ labels.push(item.name);
151
+ continue;
152
+ }
113
153
  finalizeAndRestart(item);
114
154
  continue;
115
155
  }
116
156
  // Multiple global labels before body on same routine are coalesced as entry labels.
117
157
  labels.push(item.name);
118
- entryLabels.push(item.name);
158
+ if (item.isEntry === true) {
159
+ entryLabels.push(item.name);
160
+ }
119
161
  }
120
162
  flushRoutine();
121
- return { routines, directCalls };
163
+ const entryNamesByFile = new Map();
164
+ for (const item of items) {
165
+ if (item.kind !== 'label' || item.isEntry !== true)
166
+ continue;
167
+ const names = entryNamesByFile.get(item.span.sourceName) ?? new Set();
168
+ names.add(item.name);
169
+ entryNamesByFile.set(item.span.sourceName, names);
170
+ }
171
+ const directTailJumps = [];
172
+ for (const item of items) {
173
+ if (item.kind !== 'instruction')
174
+ continue;
175
+ const entryNames = filesWithEntryLabels.has(item.span.sourceName)
176
+ ? entryNamesByFile.get(item.span.sourceName)
177
+ : undefined;
178
+ const target = instructionTailJumpTarget(item, entryNames);
179
+ if (target === undefined)
180
+ continue;
181
+ pushDirectBoundary(directTailJumps, target, `JP ${target}`, item.span.sourceName, item.span.line, item.span.column);
182
+ }
183
+ return {
184
+ routines,
185
+ directCalls,
186
+ directBoundaries: [...directCalls, ...directTailJumps],
187
+ };
122
188
  }
@@ -1,4 +1,5 @@
1
1
  import type { RegisterCareReportModel, RegisterCareUnit, RoutineSummary } from './types.js';
2
- export declare function renderRegisterCareReport(model: RegisterCareReportModel): string;
3
2
  export declare function contractCarrierList(units: RegisterCareUnit[]): string;
3
+ export declare function renderRegisterCareReport(model: RegisterCareReportModel): string;
4
4
  export declare function renderRegisterCareInterface(summaries: RoutineSummary[]): string;
5
+ export declare function renderRegisterCareSourceBlock(summary: RoutineSummary): string[];
@@ -1,23 +1,94 @@
1
- function listUnits(units) {
1
+ function list(units) {
2
2
  return units.length === 0 ? '-' : units.join(',');
3
3
  }
4
+ const FLAG_UNITS = new Set(['carry', 'zero', 'sign', 'parity', 'halfCarry']);
5
+ const CONTRACT_CARRIER_PAIRS = [
6
+ { label: 'BC', hi: 'B', lo: 'C' },
7
+ { label: 'DE', hi: 'D', lo: 'E' },
8
+ { label: 'HL', hi: 'H', lo: 'L' },
9
+ { label: 'IX', hi: 'IXH', lo: 'IXL' },
10
+ { label: 'IY', hi: 'IYH', lo: 'IYL' },
11
+ { label: 'SP', hi: 'SPH', lo: 'SPL' },
12
+ ];
13
+ export function contractCarrierList(units) {
14
+ const unique = [...new Set(units)];
15
+ const unitSet = new Set(unique);
16
+ const emitted = new Set();
17
+ const parts = [];
18
+ for (const unit of unique) {
19
+ if (emitted.has(unit))
20
+ continue;
21
+ const pair = CONTRACT_CARRIER_PAIRS.find((candidate) => (candidate.hi === unit || candidate.lo === unit) &&
22
+ unitSet.has(candidate.hi) &&
23
+ unitSet.has(candidate.lo));
24
+ if (pair) {
25
+ parts.push(pair.label);
26
+ emitted.add(pair.hi);
27
+ emitted.add(pair.lo);
28
+ continue;
29
+ }
30
+ parts.push(unit);
31
+ emitted.add(unit);
32
+ }
33
+ return parts.length === 0 ? '-' : parts.join(',');
34
+ }
35
+ function relationOutputUnits(relations) {
36
+ return relations.flatMap((rel) => rel.out);
37
+ }
38
+ function contractEntries(summary) {
39
+ const out = [];
40
+ if (summary.mayRead.length > 0)
41
+ out.push({ keyword: 'in', carriers: contractCarrierList(summary.mayRead) });
42
+ const outputUnits = relationOutputUnits(summary.valueRelations);
43
+ if (outputUnits.length > 0)
44
+ out.push({ keyword: 'out', carriers: contractCarrierList(outputUnits) });
45
+ const relationOut = relationOutUnits(summary);
46
+ const clobbers = summary.mayWrite.filter((unit) => !relationOut.has(unit));
47
+ if (clobbers.length > 0)
48
+ out.push({ keyword: 'clobbers', carriers: contractCarrierList(clobbers) });
49
+ return out;
50
+ }
51
+ function sourceContractEntries(summary) {
52
+ const out = [];
53
+ if (summary.mayRead.length > 0)
54
+ out.push({ keyword: 'in', carriers: contractCarrierList(summary.mayRead) });
55
+ const relationOut = relationOutUnits(summary);
56
+ const candidates = (summary.outputCandidates ?? []).filter((unit) => !relationOut.has(unit));
57
+ if (candidates.length > 0)
58
+ out.push({ keyword: 'maybe-out', carriers: contractCarrierList(candidates) });
59
+ const outputUnits = relationOutputUnits(summary.valueRelations);
60
+ if (outputUnits.length > 0)
61
+ out.push({ keyword: 'out', carriers: contractCarrierList(outputUnits) });
62
+ const clobbers = summary.mayWrite.filter((unit) => !relationOut.has(unit) && !FLAG_UNITS.has(unit));
63
+ if (clobbers.length > 0)
64
+ out.push({ keyword: 'clobbers', carriers: contractCarrierList(clobbers) });
65
+ return out;
66
+ }
67
+ function stackStatus(summary) {
68
+ const balance = summary.stackBalanced ? 'balanced' : 'unbalanced';
69
+ return summary.hasUnknownStackEffect ? `${balance}, unknown effect` : balance;
70
+ }
71
+ function relationOutUnits(summary) {
72
+ return new Set(summary.valueRelations.flatMap((rel) => rel.out));
73
+ }
4
74
  export function renderRegisterCareReport(model) {
5
- const lines = [
6
- 'AZM Register-Care Report',
7
- `Entry: ${model.entryFile}`,
8
- `Mode: ${model.mode}`,
9
- ...(model.profile !== undefined ? [`Profile: ${model.profile}`] : []),
10
- '',
11
- ];
75
+ const lines = ['AZM Register-Care Report', `Entry: ${model.entryFile}`, `Mode: ${model.mode}`];
76
+ if (model.profile)
77
+ lines.push(`Profile: ${model.profile}`);
78
+ lines.push('');
12
79
  if (model.summaries.length === 0) {
13
80
  lines.push('Routines: none', '');
14
81
  }
15
82
  else {
16
83
  for (const summary of model.summaries) {
17
84
  lines.push(`Routine: ${summary.name}`);
18
- lines.push(` reads: ${listUnits(summary.mayRead)}`);
19
- lines.push(` writes: ${listUnits(summary.mayWrite)}`);
20
- lines.push(` preserves: ${listUnits(summary.preserved)}`);
85
+ lines.push(` reads: ${list(summary.mayRead)}`);
86
+ lines.push(` writes: ${list(summary.mayWrite)}`);
87
+ lines.push(` preserves: ${list(summary.preserved)}`);
88
+ lines.push(` stack: ${stackStatus(summary)}`);
89
+ for (const rel of summary.valueRelations) {
90
+ lines.push(` relation: ${list(rel.out)} <= ${list(rel.from)}`);
91
+ }
21
92
  lines.push('');
22
93
  }
23
94
  }
@@ -27,17 +98,17 @@ export function renderRegisterCareReport(model) {
27
98
  }
28
99
  else {
29
100
  for (const conflict of model.conflicts) {
30
- lines.push(` ${conflict.file}:${conflict.line}:${conflict.column}: ${conflict.callTarget}: ${conflict.message}`);
101
+ lines.push(` ${conflict.file}:${conflict.line}:${conflict.column}: ${conflict.callTarget}: ${list(conflict.carriers)}: ${conflict.message}`);
31
102
  }
32
103
  }
33
104
  lines.push('');
34
105
  lines.push('Output candidates:');
35
- if (model.outputCandidates === undefined || model.outputCandidates.length === 0) {
106
+ if (!model.outputCandidates || model.outputCandidates.length === 0) {
36
107
  lines.push(' none');
37
108
  }
38
109
  else {
39
110
  for (const candidate of model.outputCandidates) {
40
- lines.push(` ${candidate.file}:${candidate.line}:${candidate.column}: ${candidate.routine}: ${candidate.carriers.join(',')}: ${candidate.message}`);
111
+ lines.push(` ${candidate.file}:${candidate.line}:${candidate.column}: ${candidate.routine}: ${list(candidate.carriers)}: ${candidate.message}`);
41
112
  }
42
113
  }
43
114
  lines.push('');
@@ -46,37 +117,23 @@ export function renderRegisterCareReport(model) {
46
117
  lines.push(' none');
47
118
  }
48
119
  else {
49
- for (const call of model.unknownCalls) {
120
+ for (const call of model.unknownCalls)
50
121
  lines.push(` ${call}`);
51
- }
52
122
  }
53
123
  lines.push('');
54
124
  return `${lines.join('\n')}\n`;
55
125
  }
56
- export function contractCarrierList(units) {
57
- return units.length === 0 ? '-' : units.join(',');
58
- }
59
126
  export function renderRegisterCareInterface(summaries) {
60
127
  const lines = [];
61
128
  for (const summary of summaries) {
62
- if (summary.mayRead.length === 0 &&
63
- summary.mayWrite.length === 0 &&
64
- summary.preserved.length === 0) {
65
- continue;
66
- }
67
129
  lines.push(`extern ${summary.name}`);
68
- if (summary.mayRead.length > 0) {
69
- lines.push(`in ${contractCarrierList(summary.mayRead)}`);
70
- }
71
- if (summary.mayWrite.length > 0) {
72
- lines.push(`clobbers ${contractCarrierList(summary.mayWrite)}`);
73
- }
74
- if (summary.preserved.length > 0) {
75
- lines.push(`preserves ${contractCarrierList(summary.preserved)}`);
130
+ for (const entry of contractEntries(summary)) {
131
+ lines.push(`${entry.keyword} ${entry.carriers}`);
76
132
  }
77
133
  lines.push('end', '');
78
134
  }
79
- if (lines.length === 0)
80
- lines.push('No inferred contracts were emitted.', '');
81
135
  return `${lines.join('\n')}\n`;
82
136
  }
137
+ export function renderRegisterCareSourceBlock(summary) {
138
+ return sourceContractEntries(summary).map((entry) => `;! ${entry.keyword.padEnd(10)}${entry.carriers}`);
139
+ }
@@ -0,0 +1,6 @@
1
+ import type { RegisterCareRoutine, RoutineContract, RoutineSummary } from './types.js';
2
+ export declare function summariesWithExternalContracts(summaries: RoutineSummary[], contracts: Map<string, RoutineContract>, routineNameSet: Set<string>): RoutineSummary[];
3
+ export declare function inferRoutineSummariesToFixedPoint(routines: RegisterCareRoutine[], contracts: Map<string, RoutineContract>, routineNameSet: Set<string>, profileSummaries: RoutineSummary[]): Array<{
4
+ routine: RegisterCareRoutine;
5
+ summary: RoutineSummary;
6
+ }>;
@@ -0,0 +1,89 @@
1
+ import { applyRoutineContract, inferRoutineSummary } from './summary.js';
2
+ function emptyRoutineSummary(name) {
3
+ return {
4
+ name,
5
+ mayRead: [],
6
+ mayWrite: [],
7
+ preserved: [],
8
+ valueRelations: [],
9
+ stackBalanced: true,
10
+ hasUnknownStackEffect: false,
11
+ };
12
+ }
13
+ function isLocalLabel(name) {
14
+ return name.startsWith('.');
15
+ }
16
+ function nonLocalLabels(labels) {
17
+ return labels.filter((label) => !isLocalLabel(label));
18
+ }
19
+ function boundaryLabels(routine) {
20
+ return routine.entryLabels.length > 0 ? routine.entryLabels : nonLocalLabels(routine.labels);
21
+ }
22
+ function contractForRoutine(routine, contracts) {
23
+ return boundaryLabels(routine)
24
+ .map((label) => contracts.get(label))
25
+ .find((contract) => contract !== undefined);
26
+ }
27
+ export function summariesWithExternalContracts(summaries, contracts, routineNameSet) {
28
+ const out = [...summaries];
29
+ for (const contract of contracts.values()) {
30
+ if (!routineNameSet.has(contract.name)) {
31
+ out.push(applyRoutineContract(emptyRoutineSummary(contract.name), contract));
32
+ }
33
+ }
34
+ return out;
35
+ }
36
+ function buildBoundarySummaryMap(summaries, routineSummaries, profileSummaries) {
37
+ const boundarySummaryMap = new Map(profileSummaries.map((summary) => [summary.name, summary]));
38
+ for (const summary of summaries) {
39
+ boundarySummaryMap.set(summary.name, summary);
40
+ }
41
+ for (const { routine, summary } of routineSummaries) {
42
+ for (const label of boundaryLabels(routine)) {
43
+ boundarySummaryMap.set(label, summary);
44
+ }
45
+ }
46
+ return boundarySummaryMap;
47
+ }
48
+ function summarizeRoutines(routines, contracts, boundarySummaryMap = new Map()) {
49
+ return routines.map((routine) => {
50
+ const inferred = inferRoutineSummary(routine, boundarySummaryMap);
51
+ const contract = contractForRoutine(routine, contracts);
52
+ return { routine, summary: contract ? applyRoutineContract(inferred, contract) : inferred };
53
+ });
54
+ }
55
+ function sortedUnique(values) {
56
+ return Array.from(new Set(values)).sort();
57
+ }
58
+ function summaryFingerprint(summary) {
59
+ const relations = summary.valueRelations
60
+ .map((relation) => `${relation.out.join(',')}<-${relation.from.join(',')}`)
61
+ .sort();
62
+ return JSON.stringify({
63
+ name: summary.name,
64
+ mayRead: sortedUnique(summary.mayRead),
65
+ mayWrite: sortedUnique(summary.mayWrite),
66
+ preserved: sortedUnique(summary.preserved),
67
+ relations,
68
+ stackBalanced: summary.stackBalanced,
69
+ hasUnknownStackEffect: summary.hasUnknownStackEffect,
70
+ });
71
+ }
72
+ function routineSummariesFingerprint(routineSummaries) {
73
+ return routineSummaries.map((item) => summaryFingerprint(item.summary)).join('\n');
74
+ }
75
+ export function inferRoutineSummariesToFixedPoint(routines, contracts, routineNameSet, profileSummaries) {
76
+ let routineSummaries = summarizeRoutines(routines, contracts);
77
+ const maxPasses = Math.max(2, routines.length + 2);
78
+ for (let pass = 0; pass < maxPasses; pass += 1) {
79
+ const summaries = summariesWithExternalContracts(routineSummaries.map((item) => item.summary), contracts, routineNameSet);
80
+ const boundarySummaryMap = buildBoundarySummaryMap(summaries, routineSummaries, profileSummaries);
81
+ const nextRoutineSummaries = summarizeRoutines(routines, contracts, boundarySummaryMap);
82
+ if (routineSummariesFingerprint(nextRoutineSummaries) ===
83
+ routineSummariesFingerprint(routineSummaries)) {
84
+ return nextRoutineSummaries;
85
+ }
86
+ routineSummaries = nextRoutineSummaries;
87
+ }
88
+ return routineSummaries;
89
+ }
@@ -3,10 +3,10 @@ import type { AnalyzeRegisterCareOptions, RegisterCareDirectCall, RegisterCareRo
3
3
  export declare function buildProfileSummaries(profileName: AnalyzeRegisterCareOptions['registerCareProfile']): RoutineSummary[];
4
4
  export declare function buildProfileSummaryLookup(profileName: AnalyzeRegisterCareOptions['registerCareProfile']): Map<string, RoutineSummary>;
5
5
  export declare function routineNames(routines: readonly RegisterCareRoutine[]): string[];
6
- export declare function buildSummaries(routines: readonly RegisterCareRoutine[], contractMap: Map<string, RoutineContract>): RoutineSummary[];
6
+ export declare function buildSummaries(routines: readonly RegisterCareRoutine[], contractMap: Map<string, RoutineContract>, profileSummaries?: readonly RoutineSummary[]): RoutineSummary[];
7
7
  export declare function buildSummaryByName(routines: readonly RegisterCareRoutine[], summaries: readonly RoutineSummary[], profileSummaries?: readonly RoutineSummary[]): Map<string, RoutineSummary>;
8
8
  export declare function withAcceptedOutputs(summaries: readonly RoutineSummary[], acceptedOutputCandidates: ReadonlyMap<string, RegisterCareUnit[]> | undefined): RoutineSummary[];
9
- export declare function unknownBoundaryDiagnostics(directCalls: readonly RegisterCareDirectCall[], knownRoutines: ReadonlySet<string>): Diagnostic[];
10
- export declare function unknownCallList(directCalls: readonly RegisterCareDirectCall[], knownRoutines: ReadonlySet<string>): string[];
9
+ export declare function unknownBoundaryDiagnostics(directBoundaries: readonly RegisterCareDirectCall[], knownRoutines: ReadonlySet<string>): Diagnostic[];
10
+ export declare function unknownCallList(directBoundaries: readonly RegisterCareDirectCall[], knownRoutines: ReadonlySet<string>): string[];
11
11
  export declare function buildOutputCandidateFixability(routines: readonly RegisterCareRoutine[], outputCandidates: readonly RegisterCareOutputCandidate[], autoFixableCandidateKeys: (routines: RegisterCareRoutine[], outputCandidates: RegisterCareOutputCandidate[]) => ReadonlySet<string>): ReadonlyMap<string, boolean>;
12
12
  export declare function outputCandidateKey(file: string, line: number, column: number): string;