@jhlagado/azm 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/dist/{src → legacy-root-azm/src}/formats/index.d.ts +1 -1
- package/dist/{src → legacy-root-azm/src}/formats/index.js +1 -1
- package/dist/{src → legacy-root-azm/src}/formats/types.d.ts +67 -7
- package/dist/{src → legacy-root-azm/src}/formats/writeHex.d.ts +0 -1
- package/dist/{src → legacy-root-azm/src}/formats/writeHex.js +0 -1
- package/dist/{src → legacy-root-azm/src}/pipeline.d.ts +3 -5
- package/dist/legacy-root-azm/src/z80/effects.d.ts +3 -0
- package/dist/legacy-root-azm/src/z80/effects.js +516 -0
- package/dist/legacy-root-azm/src/z80/encode.d.ts +10 -0
- package/dist/legacy-root-azm/src/z80/encode.js +412 -0
- package/dist/src/api-compile.d.ts +49 -8
- package/dist/src/api-compile.js +313 -3
- package/dist/src/api-tooling.d.ts +7 -25
- package/dist/src/api-tooling.js +3 -21
- package/dist/src/assembly/address-planning.d.ts +19 -0
- package/dist/src/assembly/address-planning.js +266 -0
- package/dist/src/assembly/assemble-program.d.ts +13 -0
- package/dist/src/assembly/assemble-program.js +34 -0
- package/dist/src/assembly/fixup-emission.d.ts +10 -0
- package/dist/src/assembly/fixup-emission.js +247 -0
- package/dist/src/assembly/placement.d.ts +26 -0
- package/dist/src/assembly/placement.js +79 -0
- package/dist/src/assembly/program-emission.d.ts +13 -0
- package/dist/src/assembly/program-emission.js +267 -0
- package/dist/src/cli/parse-args.d.ts +29 -0
- package/dist/src/cli/parse-args.js +372 -0
- package/dist/src/cli/run.d.ts +2 -0
- package/dist/src/cli/run.js +35 -0
- package/dist/src/cli/write-artifacts.d.ts +21 -0
- package/dist/src/cli/write-artifacts.js +175 -0
- package/dist/src/cli.d.ts +1 -30
- package/dist/src/cli.js +20 -524
- package/dist/src/core/compile-artifacts.d.ts +26 -0
- package/dist/src/core/compile-artifacts.js +17 -0
- package/dist/src/core/compile.d.ts +26 -0
- package/dist/src/core/compile.js +164 -0
- package/dist/src/diagnostics/format.d.ts +4 -0
- package/dist/src/diagnostics/format.js +9 -0
- package/dist/src/expansion/op-expansion.d.ts +96 -0
- package/dist/src/expansion/op-expansion.js +912 -0
- package/dist/src/index.d.ts +14 -3
- package/dist/src/index.js +7 -2
- package/dist/src/model/diagnostic.d.ts +50 -0
- package/dist/src/model/diagnostic.js +29 -0
- package/dist/src/model/expression.d.ts +51 -0
- package/dist/src/model/expression.js +1 -0
- package/dist/src/model/fixup.d.ts +18 -0
- package/dist/src/model/fixup.js +1 -0
- package/dist/src/model/source-item.d.ts +81 -0
- package/dist/src/model/source-item.js +1 -0
- package/dist/src/model/symbol.d.ts +1 -0
- package/dist/src/model/symbol.js +1 -0
- package/dist/src/node/source-host.d.ts +19 -0
- package/dist/src/node/source-host.js +146 -0
- package/dist/src/outputs/hex.d.ts +1 -0
- package/dist/src/outputs/hex.js +75 -0
- package/dist/src/outputs/index.d.ts +3 -0
- package/dist/src/outputs/index.js +13 -0
- package/dist/src/outputs/range.d.ts +3 -0
- package/dist/src/outputs/range.js +31 -0
- package/dist/src/outputs/types.d.ts +182 -0
- package/dist/src/outputs/types.js +1 -0
- package/dist/src/outputs/write-asm80.d.ts +7 -0
- package/dist/src/outputs/write-asm80.js +549 -0
- package/dist/src/outputs/write-bin.d.ts +2 -0
- package/dist/src/outputs/write-bin.js +27 -0
- package/dist/src/outputs/write-d8.d.ts +2 -0
- package/dist/src/outputs/write-d8.js +257 -0
- package/dist/src/outputs/write-hex.d.ts +2 -0
- package/dist/src/outputs/write-hex.js +53 -0
- package/dist/src/outputs/write-listing.d.ts +2 -0
- package/dist/src/outputs/write-listing.js +79 -0
- package/dist/src/register-care/accept-output.d.ts +2 -0
- package/dist/src/register-care/accept-output.js +35 -0
- package/dist/src/register-care/analyze.d.ts +26 -0
- package/dist/src/register-care/analyze.js +87 -0
- package/dist/src/register-care/annotations.d.ts +8 -0
- package/dist/src/register-care/annotations.js +154 -0
- package/dist/src/register-care/boundaryHints.d.ts +2 -0
- package/dist/src/register-care/boundaryHints.js +11 -0
- package/dist/src/register-care/carriers.d.ts +2 -0
- package/dist/src/register-care/carriers.js +78 -0
- package/dist/src/register-care/controlFlow.d.ts +5 -0
- package/dist/src/register-care/controlFlow.js +38 -0
- package/dist/src/register-care/fix.d.ts +9 -0
- package/dist/src/register-care/fix.js +78 -0
- package/dist/src/register-care/liveness.d.ts +3 -0
- package/dist/src/register-care/liveness.js +189 -0
- package/dist/src/register-care/profiles.d.ts +9 -0
- package/dist/src/register-care/profiles.js +43 -0
- package/dist/src/register-care/programModel.d.ts +3 -0
- package/dist/src/register-care/programModel.js +122 -0
- package/dist/src/register-care/report.d.ts +4 -0
- package/dist/src/register-care/report.js +82 -0
- package/dist/src/register-care/smartComments.d.ts +5 -0
- package/dist/src/register-care/smartComments.js +243 -0
- package/dist/src/register-care/summaries.d.ts +12 -0
- package/dist/src/register-care/summaries.js +154 -0
- package/dist/src/{registerCare → register-care}/tooling.d.ts +7 -6
- package/dist/src/{registerCare → register-care}/tooling.js +17 -6
- package/dist/src/register-care/types.d.ts +165 -0
- package/dist/src/register-care/types.js +1 -0
- package/dist/src/semantics/expression-evaluation.d.ts +29 -0
- package/dist/src/semantics/expression-evaluation.js +409 -0
- package/dist/src/source/logical-lines.d.ts +7 -0
- package/dist/src/source/logical-lines.js +11 -0
- package/dist/src/source/source-file.d.ts +5 -0
- package/dist/src/source/source-file.js +3 -0
- package/dist/src/source/source-span.d.ts +5 -0
- package/dist/src/source/source-span.js +1 -0
- package/dist/src/source/strip-line-comment.d.ts +4 -0
- package/dist/src/source/strip-line-comment.js +27 -0
- package/dist/src/syntax/directive-aliases.d.ts +10 -0
- package/dist/src/syntax/directive-aliases.js +199 -0
- package/dist/src/syntax/parse-expression.d.ts +3 -0
- package/dist/src/syntax/parse-expression.js +551 -0
- package/dist/src/syntax/parse-line.d.ts +12 -0
- package/dist/src/syntax/parse-line.js +329 -0
- package/dist/src/tooling/api.d.ts +42 -0
- package/dist/src/tooling/api.js +42 -0
- package/dist/src/tooling/case-style.d.ts +8 -0
- package/dist/src/tooling/case-style.js +163 -0
- package/dist/src/z80/effects.d.ts +3 -3
- package/dist/src/z80/effects.js +349 -302
- package/dist/src/z80/encode.d.ts +2 -10
- package/dist/src/z80/encode.js +951 -374
- package/dist/src/z80/instruction.d.ts +226 -0
- package/dist/src/z80/instruction.js +1 -0
- package/dist/src/z80/parse-instruction.d.ts +7 -0
- package/dist/src/z80/parse-instruction.js +1068 -0
- package/docs/reference/tooling-api.md +55 -3
- package/package.json +20 -3
- /package/dist/{src → legacy-root-azm/src}/analysis.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/analysis.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/compile.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/compile.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/compileShared.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/compileShared.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/diagnosticTypes.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/diagnosticTypes.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/range.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/range.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/types.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeAsm80.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeAsm80.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeBin.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeBin.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeD8m.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeD8m.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeListing.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/formats/writeListing.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/asm80/asmLine.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/asm80/asmLine.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/asm80/parseAsmRawValues.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/asm80/parseAsmRawValues.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/asm80/quoteScan.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/asm80/quoteScan.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/ast.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/ast.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/directiveAliases.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/directiveAliases.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/grammarData.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/grammarData.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/immExprUtils.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/immExprUtils.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmFlatDirectiveLine.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmFlatDirectiveLine.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmInstruction.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmInstruction.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmStatements.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmStatements.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmStream.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmStream.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmTopLevel.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseAsmTopLevel.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseDiagnostics.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseDiagnostics.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseEnum.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseEnum.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseImm.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseImm.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseLogicalLines.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseLogicalLines.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseOp.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseOp.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseOpHeader.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseOpHeader.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseOperands.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseOperands.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseParams.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseParams.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseParserRecovery.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseParserRecovery.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseParserShared.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseParserShared.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseRawDataDirectiveStart.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseRawDataDirectiveStart.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseRawDataDirectives.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseRawDataDirectives.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseRecordFieldDecl.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseRecordFieldDecl.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseSourceItemDispatch.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseSourceItemDispatch.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseSourceItemTable.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseSourceItemTable.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseTopLevelCommon.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseTopLevelCommon.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseTypes.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parseTypes.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parser.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/parser.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/source.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/source.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/sourceExtensions.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/frontend/sourceExtensions.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lintCaseStyle.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lintCaseStyle.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmDirectiveLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmDirectiveLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmDirectiveTraversal.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmDirectiveTraversal.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmEquResolution.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmEquResolution.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmInstructionLdHelpers.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmInstructionLdHelpers.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmInstructionLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmInstructionLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmInstructionStream.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmInstructionStream.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmLoweringBranchCall.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmLoweringBranchCall.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmLoweringHost.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmLoweringHost.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmLoweringLd.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmLoweringLd.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmRangeLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmRangeLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmRawDataLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmRawDataLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmSourceEmitter.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmSourceEmitter.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmSourceInstructionLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmSourceInstructionLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmUtils.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/asmUtils.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerFlowSetup.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerFlowSetup.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerLoweringContext.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerLoweringContext.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerLoweringContextSplit.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerLoweringContextSplit.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerLoweringPhases.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/assemblerLoweringPhases.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/bytePlacement.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/bytePlacement.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/capabilities.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/capabilities.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/eaResolution.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/eaResolution.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emissionCore.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emissionCore.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emit.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emit.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitContextBuilder.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitContextBuilder.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitFinalization.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitFinalization.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitFinalizationSetup.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitFinalizationSetup.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1BuildProgramLoweringContext.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1BuildProgramLoweringContext.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1Helpers.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1Helpers.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1Types.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1Types.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1WirePipeline.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1WirePipeline.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1Workspace.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPhase1Workspace.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPipeline.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitPipeline.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitProgramContext.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitProgramContext.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitState.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/emitState.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/fixupBaseResolution.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/fixupBaseResolution.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/fixupEmission.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/fixupEmission.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/immMath.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/immMath.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/inputAssets.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/inputAssets.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldEncoding.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldEncoding.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldEncodingRegMemHelpers.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldEncodingRegMemHelpers.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldFormSelection.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldFormSelection.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/ldLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmByteEmission.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmByteEmission.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmPlacement.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmPlacement.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmStreamRecording.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmStreamRecording.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmTypes.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredAsmTypes.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredFormat.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredFormat.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredItemSize.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweredItemSize.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweringDiagnostics.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweringDiagnostics.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweringTypes.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/loweringTypes.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opCandidateRegistry.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opCandidateRegistry.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opExpansionExecution.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opExpansionExecution.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opExpansionOrchestration.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opExpansionOrchestration.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opExpansionStream.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opExpansionStream.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opMatching.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opMatching.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opSubstitution.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/opSubstitution.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/prescanTypes.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/prescanTypes.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLowering.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLowering.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLoweringDeclarations.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLoweringDeclarations.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLoweringFinalize.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLoweringFinalize.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLoweringTraversal.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programLoweringTraversal.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programPrescan.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/programPrescan.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/traceFormat.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/lowering/traceFormat.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/packageInfo.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/packageInfo.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/pathCompare.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/pathCompare.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/pipeline.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/analyze.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/analyze.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/annotate.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/annotate.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/boundaryHints.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/boundaryHints.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/carriers.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/carriers.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/controlFlow.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/controlFlow.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/fix.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/fix.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/liveness.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/liveness.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/profiles.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/profiles.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/programModel.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/programModel.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/report.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/report.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/smartComments.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/smartComments.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/sourceText.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/sourceText.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/summary.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/summary.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/types.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/registerCare/types.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/declVisitor.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/declVisitor.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/env.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/env.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/layout.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/layout.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/layoutCastFold.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/layoutCastFold.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/semanticsDiagnostics.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/semanticsDiagnostics.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/typeQueries.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/semantics/typeQueries.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/sourceIncludeExpansion.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/sourceIncludeExpansion.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/sourceIncludePaths.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/sourceIncludePaths.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/sourceLoader.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/sourceLoader.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeAlu.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeAlu.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeBitOps.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeBitOps.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeContext.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeContext.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeControl.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeControl.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeCoreOps.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeCoreOps.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeIo.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeIo.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeLd.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encodeLd.js +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encoderRegistry.d.ts +0 -0
- /package/dist/{src → legacy-root-azm/src}/z80/encoderRegistry.js +0 -0
|
@@ -0,0 +1,154 @@
|
|
|
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)
|
|
72
|
+
.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
|
+
}
|
|
111
|
+
}
|
|
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
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const out = [];
|
|
133
|
+
for (const [path, routines] of byFile) {
|
|
134
|
+
const sourceText = loaded.sourceTexts.get(path);
|
|
135
|
+
if (sourceText === undefined)
|
|
136
|
+
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
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (text !== sourceText)
|
|
151
|
+
out.push({ path, text });
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function precedingCServiceName(item) {
|
|
2
|
+
const instruction = item?.instruction;
|
|
3
|
+
if (!instruction || instruction.mnemonic !== 'ld')
|
|
4
|
+
return undefined;
|
|
5
|
+
if (instruction.target?.kind !== 'reg8' || instruction.target.register !== 'c')
|
|
6
|
+
return undefined;
|
|
7
|
+
if (instruction.source.kind === 'imm' && instruction.source.expression.kind === 'symbol') {
|
|
8
|
+
return instruction.source.expression.name;
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const FLAG_UNITS = ['carry', 'zero', 'sign', 'parity', 'halfCarry'];
|
|
2
|
+
const SINGLE_UNITS = new Set([
|
|
3
|
+
'A',
|
|
4
|
+
'B',
|
|
5
|
+
'C',
|
|
6
|
+
'D',
|
|
7
|
+
'E',
|
|
8
|
+
'H',
|
|
9
|
+
'L',
|
|
10
|
+
'IXH',
|
|
11
|
+
'IXL',
|
|
12
|
+
'IYH',
|
|
13
|
+
'IYL',
|
|
14
|
+
'SPH',
|
|
15
|
+
'SPL',
|
|
16
|
+
'carry',
|
|
17
|
+
'zero',
|
|
18
|
+
'sign',
|
|
19
|
+
'parity',
|
|
20
|
+
'halfCarry',
|
|
21
|
+
]);
|
|
22
|
+
const PAIRS = {
|
|
23
|
+
AF: ['A', ...FLAG_UNITS],
|
|
24
|
+
BC: ['B', 'C'],
|
|
25
|
+
DE: ['D', 'E'],
|
|
26
|
+
HL: ['H', 'L'],
|
|
27
|
+
IX: ['IXH', 'IXL'],
|
|
28
|
+
IY: ['IYH', 'IYL'],
|
|
29
|
+
SP: ['SPH', 'SPL'],
|
|
30
|
+
};
|
|
31
|
+
const FLAG_ALIASES = {
|
|
32
|
+
CARRY: 'carry',
|
|
33
|
+
ZERO: 'zero',
|
|
34
|
+
Z: 'zero',
|
|
35
|
+
SIGN: 'sign',
|
|
36
|
+
S: 'sign',
|
|
37
|
+
PARITY: 'parity',
|
|
38
|
+
PV: 'parity',
|
|
39
|
+
'P/V': 'parity',
|
|
40
|
+
HALFCARRY: 'halfCarry',
|
|
41
|
+
HFLAG: 'halfCarry',
|
|
42
|
+
};
|
|
43
|
+
function normalizeCarrierName(raw) {
|
|
44
|
+
const trimmed = raw.trim();
|
|
45
|
+
const upper = trimmed.toUpperCase();
|
|
46
|
+
const flag = FLAG_ALIASES[upper];
|
|
47
|
+
if (flag !== undefined)
|
|
48
|
+
return flag;
|
|
49
|
+
if (SINGLE_UNITS.has(upper))
|
|
50
|
+
return upper;
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
function expandCarrier(raw) {
|
|
54
|
+
const upper = raw.trim().toUpperCase();
|
|
55
|
+
if (upper === 'F')
|
|
56
|
+
return FLAG_UNITS;
|
|
57
|
+
const pair = PAIRS[upper];
|
|
58
|
+
if (pair !== undefined)
|
|
59
|
+
return pair;
|
|
60
|
+
const single = normalizeCarrierName(raw);
|
|
61
|
+
return single !== undefined ? [single] : undefined;
|
|
62
|
+
}
|
|
63
|
+
export function expandCarrierList(raw) {
|
|
64
|
+
const out = [];
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
for (const item of raw) {
|
|
67
|
+
const expanded = expandCarrier(item);
|
|
68
|
+
if (expanded === undefined)
|
|
69
|
+
return undefined;
|
|
70
|
+
for (const unit of expanded) {
|
|
71
|
+
if (seen.has(unit))
|
|
72
|
+
continue;
|
|
73
|
+
seen.add(unit);
|
|
74
|
+
out.push(unit);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { InstructionEffect, RegisterCareRoutine } from './types.js';
|
|
2
|
+
export declare function labelIndex(routine: RegisterCareRoutine): Map<string, number>;
|
|
3
|
+
export declare function instructionSuccessors(routine: RegisterCareRoutine, index: number, effect: InstructionEffect, labels: ReadonlyMap<string, number>, options?: {
|
|
4
|
+
boundaryFallthrough?: boolean;
|
|
5
|
+
}): number[];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
function unique(items) {
|
|
2
|
+
return [...new Set(items)];
|
|
3
|
+
}
|
|
4
|
+
export function labelIndex(routine) {
|
|
5
|
+
const out = new Map();
|
|
6
|
+
routine.instructions.forEach((item, index) => {
|
|
7
|
+
for (const label of item.labels)
|
|
8
|
+
out.set(label, index);
|
|
9
|
+
});
|
|
10
|
+
return out;
|
|
11
|
+
}
|
|
12
|
+
function localTargetIndex(labels, target) {
|
|
13
|
+
if (!target)
|
|
14
|
+
return undefined;
|
|
15
|
+
return labels.get(target);
|
|
16
|
+
}
|
|
17
|
+
export function instructionSuccessors(routine, index, effect, labels, options = {}) {
|
|
18
|
+
const next = index + 1 < routine.instructions.length ? index + 1 : undefined;
|
|
19
|
+
if (effect.control.kind === 'fallthrough' ||
|
|
20
|
+
(options.boundaryFallthrough &&
|
|
21
|
+
(effect.control.kind === 'call' || effect.control.kind === 'rst'))) {
|
|
22
|
+
return next === undefined ? [] : [next];
|
|
23
|
+
}
|
|
24
|
+
if (effect.control.kind === 'jump') {
|
|
25
|
+
const target = localTargetIndex(labels, effect.control.target);
|
|
26
|
+
if (effect.control.conditional) {
|
|
27
|
+
return unique([
|
|
28
|
+
...(target === undefined ? [] : [target]),
|
|
29
|
+
...(next === undefined ? [] : [next]),
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
32
|
+
return target === undefined ? [] : [target];
|
|
33
|
+
}
|
|
34
|
+
if (effect.control.kind === 'return') {
|
|
35
|
+
return effect.control.conditional && next !== undefined ? [next] : [];
|
|
36
|
+
}
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RegisterCareOutputCandidate, RegisterCareRoutine, RegisterCareUnit } from './types.js';
|
|
2
|
+
export interface RegisterCareExpectOutFix {
|
|
3
|
+
file: string;
|
|
4
|
+
line: number;
|
|
5
|
+
column: number;
|
|
6
|
+
routine: string;
|
|
7
|
+
carriers: RegisterCareUnit[];
|
|
8
|
+
}
|
|
9
|
+
export declare function autoFixableCandidateKeys(routines: RegisterCareRoutine[], candidates: RegisterCareOutputCandidate[]): Set<string>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { getZ80InstructionEffect } from '../z80/effects.js';
|
|
2
|
+
import { instructionSuccessors, labelIndex } from './controlFlow.js';
|
|
3
|
+
function sameLocation(a, b) {
|
|
4
|
+
return a.file === b.file && a.line === b.line && a.column === b.column;
|
|
5
|
+
}
|
|
6
|
+
function isUnconditionalDirectCall(item) {
|
|
7
|
+
const effect = getZ80InstructionEffect(item.instruction);
|
|
8
|
+
return (effect.control.kind === 'call' &&
|
|
9
|
+
effect.control.target !== undefined &&
|
|
10
|
+
!effect.control.conditional);
|
|
11
|
+
}
|
|
12
|
+
function continuationReads(routine, callIndex, carriers) {
|
|
13
|
+
const labels = labelIndex(routine);
|
|
14
|
+
const confirmed = new Set();
|
|
15
|
+
const work = callIndex + 1 < routine.instructions.length
|
|
16
|
+
? [{ index: callIndex + 1, pending: [...new Set(carriers)] }]
|
|
17
|
+
: [];
|
|
18
|
+
const seen = new Set();
|
|
19
|
+
let steps = 0;
|
|
20
|
+
while (work.length > 0 && steps < 512) {
|
|
21
|
+
steps += 1;
|
|
22
|
+
const state = work.pop();
|
|
23
|
+
const pending = state.pending.filter((unit) => !confirmed.has(unit));
|
|
24
|
+
if (pending.length === 0)
|
|
25
|
+
continue;
|
|
26
|
+
const key = `${state.index}:${pending.join(',')}`;
|
|
27
|
+
if (seen.has(key))
|
|
28
|
+
continue;
|
|
29
|
+
seen.add(key);
|
|
30
|
+
const item = routine.instructions[state.index];
|
|
31
|
+
if (!item)
|
|
32
|
+
continue;
|
|
33
|
+
const effect = getZ80InstructionEffect(item.instruction);
|
|
34
|
+
const reads = new Set(effect.reads);
|
|
35
|
+
const writes = new Set(effect.writes);
|
|
36
|
+
const remaining = [];
|
|
37
|
+
for (const unit of pending) {
|
|
38
|
+
if (reads.has(unit)) {
|
|
39
|
+
confirmed.add(unit);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (!writes.has(unit))
|
|
43
|
+
remaining.push(unit);
|
|
44
|
+
}
|
|
45
|
+
if (remaining.length === 0)
|
|
46
|
+
continue;
|
|
47
|
+
for (const next of instructionSuccessors(routine, state.index, effect, labels)) {
|
|
48
|
+
work.push({ index: next, pending: remaining });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return carriers.filter((unit) => confirmed.has(unit));
|
|
52
|
+
}
|
|
53
|
+
function findExpectOutFixes(routines, candidates) {
|
|
54
|
+
const out = [];
|
|
55
|
+
for (const routine of routines) {
|
|
56
|
+
for (let index = 0; index < routine.instructions.length; index += 1) {
|
|
57
|
+
const item = routine.instructions[index];
|
|
58
|
+
if (!isUnconditionalDirectCall(item))
|
|
59
|
+
continue;
|
|
60
|
+
const candidate = candidates.find((entry) => sameLocation(item, entry));
|
|
61
|
+
if (!candidate)
|
|
62
|
+
continue;
|
|
63
|
+
const carriers = continuationReads(routine, index, candidate.carriers);
|
|
64
|
+
if (carriers.length === 0)
|
|
65
|
+
continue;
|
|
66
|
+
out.push({ ...candidate, carriers });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
export function autoFixableCandidateKeys(routines, candidates) {
|
|
72
|
+
const fixes = findExpectOutFixes(routines, candidates);
|
|
73
|
+
const out = new Set();
|
|
74
|
+
for (const fix of fixes) {
|
|
75
|
+
out.add(`${fix.file}:${fix.line}:${fix.column}`);
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { LocatedSmartComment, RegisterCareConflict, RegisterCareOutputCandidate, RegisterCareRoutine, RoutineSummary } from './types.js';
|
|
2
|
+
export declare function findRegisterCareConflicts(routine: RegisterCareRoutine, summaries: Map<string, RoutineSummary>, hints: LocatedSmartComment[]): RegisterCareConflict[];
|
|
3
|
+
export declare function findCallerOutputCandidateObservations(routines: RegisterCareRoutine[], summaries: Map<string, RoutineSummary>): RegisterCareOutputCandidate[];
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { getZ80InstructionEffect } from '../z80/effects.js';
|
|
2
|
+
import { precedingCServiceName } from './boundaryHints.js';
|
|
3
|
+
import { instructionSuccessors, labelIndex } from './controlFlow.js';
|
|
4
|
+
import { rstServiceTargetName, rstTargetName } from './profiles.js';
|
|
5
|
+
function unique(units) {
|
|
6
|
+
return [...new Set(units)];
|
|
7
|
+
}
|
|
8
|
+
function boundaryTarget(routine, index, effect) {
|
|
9
|
+
const item = routine.instructions[index];
|
|
10
|
+
if (effect.control.kind === 'call' && effect.control.target) {
|
|
11
|
+
return {
|
|
12
|
+
targets: [effect.control.target],
|
|
13
|
+
conditional: effect.control.conditional,
|
|
14
|
+
subject: `CALL ${effect.control.target}`,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if (effect.control.kind === 'jump' &&
|
|
18
|
+
item?.instruction.mnemonic === 'jp' &&
|
|
19
|
+
!effect.control.conditional &&
|
|
20
|
+
effect.control.target &&
|
|
21
|
+
!effect.control.target.startsWith('.')) {
|
|
22
|
+
return {
|
|
23
|
+
targets: [effect.control.target],
|
|
24
|
+
conditional: false,
|
|
25
|
+
subject: `JP ${effect.control.target}`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
if (effect.control.kind === 'rst' && effect.control.vector !== undefined) {
|
|
29
|
+
const target = rstTargetName(effect.control.vector);
|
|
30
|
+
const service = precedingCServiceName(routine.instructions[index - 1]);
|
|
31
|
+
const targets = service
|
|
32
|
+
? [rstServiceTargetName(effect.control.vector, service), target]
|
|
33
|
+
: [target];
|
|
34
|
+
return { targets, conditional: false, subject: target };
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
function summaryForBoundary(boundary, summaries) {
|
|
39
|
+
for (const target of boundary.targets) {
|
|
40
|
+
const summary = summaries.get(target);
|
|
41
|
+
if (summary)
|
|
42
|
+
return { target, summary };
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
function hintUnitsForLine(hints, file, callLine) {
|
|
47
|
+
const prior = hints.find((hint) => hint.file === file && hint.line === callLine - 1 && hint.comment.kind === 'expectOut');
|
|
48
|
+
return prior?.comment.kind === 'expectOut' ? unique(prior.comment.carriers) : [];
|
|
49
|
+
}
|
|
50
|
+
function outputUnits(summary) {
|
|
51
|
+
return unique([
|
|
52
|
+
...(summary.valueRelations?.flatMap((relation) => relation.out) ?? []),
|
|
53
|
+
...(summary.mayOutput ?? []),
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
56
|
+
function setEqual(left, right) {
|
|
57
|
+
if (left.size !== right.size)
|
|
58
|
+
return false;
|
|
59
|
+
for (const item of left)
|
|
60
|
+
if (!right.has(item))
|
|
61
|
+
return false;
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
function unionLive(sets) {
|
|
65
|
+
const out = new Set();
|
|
66
|
+
for (const set of sets) {
|
|
67
|
+
for (const unit of set)
|
|
68
|
+
out.add(unit);
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
function transferLiveBefore(item, effect, boundary, summary, liveAfter, hints) {
|
|
73
|
+
const live = new Set(liveAfter);
|
|
74
|
+
if (boundary && summary) {
|
|
75
|
+
const accepted = new Set();
|
|
76
|
+
for (const unit of hintUnitsForLine(hints, item.file, item.line))
|
|
77
|
+
accepted.add(unit);
|
|
78
|
+
for (const unit of outputUnits(summary))
|
|
79
|
+
accepted.add(unit);
|
|
80
|
+
if (!boundary.conditional) {
|
|
81
|
+
for (const unit of summary.mayWrite)
|
|
82
|
+
live.delete(unit);
|
|
83
|
+
for (const unit of accepted)
|
|
84
|
+
live.delete(unit);
|
|
85
|
+
}
|
|
86
|
+
for (const unit of summary.mayRead)
|
|
87
|
+
live.add(unit);
|
|
88
|
+
}
|
|
89
|
+
const instructionWritesAreConditional = effect.control.kind === 'call' && effect.control.conditional;
|
|
90
|
+
if (!instructionWritesAreConditional) {
|
|
91
|
+
for (const unit of effect.writes)
|
|
92
|
+
live.delete(unit);
|
|
93
|
+
}
|
|
94
|
+
for (const unit of effect.reads)
|
|
95
|
+
live.add(unit);
|
|
96
|
+
return live;
|
|
97
|
+
}
|
|
98
|
+
function liveSetsForRoutine(routine, summaries, hints = []) {
|
|
99
|
+
const labels = labelIndex(routine);
|
|
100
|
+
const effects = routine.instructions.map((item) => getZ80InstructionEffect(item.instruction));
|
|
101
|
+
const boundaries = effects.map((effect, index) => boundaryTarget(routine, index, effect));
|
|
102
|
+
const resolvedSummaries = boundaries.map((boundary) => boundary ? summaryForBoundary(boundary, summaries)?.summary : undefined);
|
|
103
|
+
const successorIndexes = effects.map((effect, index) => instructionSuccessors(routine, index, effect, labels, { boundaryFallthrough: true }));
|
|
104
|
+
const liveIn = routine.instructions.map(() => new Set());
|
|
105
|
+
const liveOut = routine.instructions.map(() => new Set());
|
|
106
|
+
let changed = true;
|
|
107
|
+
let passes = 0;
|
|
108
|
+
while (changed && passes < Math.max(8, routine.instructions.length * 4)) {
|
|
109
|
+
changed = false;
|
|
110
|
+
passes += 1;
|
|
111
|
+
for (let index = routine.instructions.length - 1; index >= 0; index -= 1) {
|
|
112
|
+
const nextOut = unionLive(successorIndexes[index].map((successor) => liveIn[successor]));
|
|
113
|
+
const nextIn = transferLiveBefore(routine.instructions[index], effects[index], boundaries[index], resolvedSummaries[index], nextOut, hints);
|
|
114
|
+
if (!setEqual(nextOut, liveOut[index])) {
|
|
115
|
+
liveOut[index] = nextOut;
|
|
116
|
+
changed = true;
|
|
117
|
+
}
|
|
118
|
+
if (!setEqual(nextIn, liveIn[index])) {
|
|
119
|
+
liveIn[index] = nextIn;
|
|
120
|
+
changed = true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return { liveIn, liveOut };
|
|
125
|
+
}
|
|
126
|
+
function resolvedBoundariesForRoutine(routine, summaries) {
|
|
127
|
+
const out = [];
|
|
128
|
+
for (let index = 0; index < routine.instructions.length; index += 1) {
|
|
129
|
+
const item = routine.instructions[index];
|
|
130
|
+
const effect = getZ80InstructionEffect(item.instruction);
|
|
131
|
+
const boundary = boundaryTarget(routine, index, effect);
|
|
132
|
+
if (!boundary)
|
|
133
|
+
continue;
|
|
134
|
+
const resolved = summaryForBoundary(boundary, summaries);
|
|
135
|
+
if (!resolved)
|
|
136
|
+
continue;
|
|
137
|
+
out.push({ item, index, boundary, target: resolved.target, summary: resolved.summary });
|
|
138
|
+
}
|
|
139
|
+
return out;
|
|
140
|
+
}
|
|
141
|
+
export function findRegisterCareConflicts(routine, summaries, hints) {
|
|
142
|
+
const conflicts = [];
|
|
143
|
+
const { liveOut } = liveSetsForRoutine(routine, summaries, hints);
|
|
144
|
+
for (const { item, index, boundary, target, summary } of resolvedBoundariesForRoutine(routine, summaries)) {
|
|
145
|
+
const accepted = new Set();
|
|
146
|
+
for (const unit of hintUnitsForLine(hints, item.file, item.line))
|
|
147
|
+
accepted.add(unit);
|
|
148
|
+
for (const unit of outputUnits(summary))
|
|
149
|
+
accepted.add(unit);
|
|
150
|
+
const carriers = unique(summary.mayWrite.filter((unit) => liveOut[index].has(unit) && !accepted.has(unit)));
|
|
151
|
+
if (carriers.length > 0 && !boundary.conditional) {
|
|
152
|
+
conflicts.push({
|
|
153
|
+
file: item.file,
|
|
154
|
+
line: item.line,
|
|
155
|
+
column: item.column,
|
|
156
|
+
callTarget: target,
|
|
157
|
+
carriers,
|
|
158
|
+
message: `${boundary.subject} may modify ${carriers.join(',')}, but the pre-call value is used later.`,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return conflicts;
|
|
163
|
+
}
|
|
164
|
+
function candidateMessage(boundary, units) {
|
|
165
|
+
const carriers = units.join(',');
|
|
166
|
+
const expectation = units.length === 1 ? units[0] : `{${carriers}}`;
|
|
167
|
+
return `${boundary.subject} writes ${carriers} and caller reads it later; review the call site and add \`; expects out ${expectation}\` above the call if this is intentional.`;
|
|
168
|
+
}
|
|
169
|
+
export function findCallerOutputCandidateObservations(routines, summaries) {
|
|
170
|
+
const out = [];
|
|
171
|
+
for (const routine of routines) {
|
|
172
|
+
const { liveOut } = liveSetsForRoutine(routine, summaries);
|
|
173
|
+
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)));
|
|
176
|
+
if (carriers.length > 0) {
|
|
177
|
+
out.push({
|
|
178
|
+
file: item.file,
|
|
179
|
+
line: item.line,
|
|
180
|
+
column: item.column,
|
|
181
|
+
routine: target,
|
|
182
|
+
carriers,
|
|
183
|
+
message: candidateMessage(boundary, carriers),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return out;
|
|
189
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RoutineSummary } from './types.js';
|
|
2
|
+
export interface RegisterCareProfileSummary {
|
|
3
|
+
name: 'mon3';
|
|
4
|
+
rst: Map<number, RoutineSummary>;
|
|
5
|
+
rstServices: Map<string, RoutineSummary>;
|
|
6
|
+
}
|
|
7
|
+
export declare function rstTargetName(vector: number): string;
|
|
8
|
+
export declare function rstServiceTargetName(vector: number, service: string): string;
|
|
9
|
+
export declare function getRegisterCareProfile(name: 'mon3' | undefined): RegisterCareProfileSummary | undefined;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const FLAG_UNITS = ['carry', 'zero', 'sign', 'parity', 'halfCarry'];
|
|
2
|
+
export function rstTargetName(vector) {
|
|
3
|
+
return `RST_$${vector.toString(16).toUpperCase().padStart(2, '0')}`;
|
|
4
|
+
}
|
|
5
|
+
function normalizeServiceName(raw) {
|
|
6
|
+
return raw.replace(/[^A-Za-z0-9]/gu, '').toUpperCase();
|
|
7
|
+
}
|
|
8
|
+
export function rstServiceTargetName(vector, service) {
|
|
9
|
+
return `${rstTargetName(vector)}:${normalizeServiceName(service)}`;
|
|
10
|
+
}
|
|
11
|
+
export function getRegisterCareProfile(name) {
|
|
12
|
+
if (name !== 'mon3')
|
|
13
|
+
return undefined;
|
|
14
|
+
return {
|
|
15
|
+
name: 'mon3',
|
|
16
|
+
rst: new Map([
|
|
17
|
+
[
|
|
18
|
+
0x10,
|
|
19
|
+
{
|
|
20
|
+
name: rstTargetName(0x10),
|
|
21
|
+
mayRead: [],
|
|
22
|
+
mayWrite: ['A', ...FLAG_UNITS],
|
|
23
|
+
mayOutput: [],
|
|
24
|
+
preserved: ['B', 'C', 'D', 'E', 'H', 'L'],
|
|
25
|
+
valueRelations: [],
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
]),
|
|
29
|
+
rstServices: new Map([
|
|
30
|
+
[
|
|
31
|
+
rstServiceTargetName(0x10, 'API_SCANKEYS'),
|
|
32
|
+
{
|
|
33
|
+
name: rstServiceTargetName(0x10, 'API_SCANKEYS'),
|
|
34
|
+
mayRead: ['C'],
|
|
35
|
+
mayWrite: ['sign', 'parity', 'halfCarry'],
|
|
36
|
+
mayOutput: ['A', 'carry', 'zero'],
|
|
37
|
+
preserved: ['B', 'C', 'D', 'E', 'H', 'L'],
|
|
38
|
+
valueRelations: [{ out: ['A', 'carry', 'zero'], from: [] }],
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
]),
|
|
42
|
+
};
|
|
43
|
+
}
|