@jhlagado/azm 0.2.7 → 0.2.9
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 +239 -76
- package/dist/src/api-artifacts.d.ts +20 -0
- package/dist/src/api-artifacts.js +165 -0
- package/dist/src/api-compile.d.ts +8 -2
- package/dist/src/api-compile.js +55 -227
- package/dist/src/api-register-contracts.d.ts +9 -0
- package/dist/src/api-register-contracts.js +77 -0
- package/dist/src/api-tooling.d.ts +2 -2
- package/dist/src/api-tooling.js +1 -1
- package/dist/src/assembly/address-planning.d.ts +1 -2
- package/dist/src/assembly/address-planning.js +119 -218
- package/dist/src/assembly/address-symbols.d.ts +12 -0
- package/dist/src/assembly/address-symbols.js +118 -0
- package/dist/src/assembly/assemble-program.js +5 -0
- package/dist/src/assembly/fixup-emission.js +30 -48
- package/dist/src/assembly/import-visibility.d.ts +3 -0
- package/dist/src/assembly/import-visibility.js +204 -0
- package/dist/src/assembly/program-emission.js +163 -164
- package/dist/src/cli/artifact-files.d.ts +15 -0
- package/dist/src/cli/artifact-files.js +86 -0
- package/dist/src/cli/parse-args.d.ts +6 -5
- package/dist/src/cli/parse-args.js +162 -136
- package/dist/src/cli/run.js +4 -1
- package/dist/src/cli/usage.d.ts +1 -0
- package/dist/src/cli/usage.js +33 -0
- package/dist/src/cli/write-artifacts.js +18 -91
- package/dist/src/core/compile.js +51 -274
- package/dist/src/core/conditional-assembly.d.ts +6 -0
- package/dist/src/core/conditional-assembly.js +181 -0
- package/dist/src/expansion/op-constant-expression.d.ts +3 -0
- package/dist/src/expansion/op-constant-expression.js +52 -0
- package/dist/src/expansion/op-expand-selected.d.ts +5 -0
- package/dist/src/expansion/op-expand-selected.js +143 -0
- package/dist/src/expansion/op-expansion.d.ts +5 -53
- package/dist/src/expansion/op-expansion.js +85 -815
- package/dist/src/expansion/op-instruction-instantiation.d.ts +3 -0
- package/dist/src/expansion/op-instruction-instantiation.js +194 -0
- package/dist/src/expansion/op-local-labels.d.ts +8 -0
- package/dist/src/expansion/op-local-labels.js +166 -0
- package/dist/src/expansion/op-operand-splitting.d.ts +1 -0
- package/dist/src/expansion/op-operand-splitting.js +44 -0
- package/dist/src/expansion/op-operands.d.ts +53 -0
- package/dist/src/expansion/op-operands.js +66 -0
- package/dist/src/expansion/op-selection.d.ts +18 -0
- package/dist/src/expansion/op-selection.js +172 -0
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.js +1 -1
- package/dist/src/model/diagnostic.d.ts +4 -0
- package/dist/src/model/diagnostic.js +4 -0
- package/dist/src/node/source-host.js +40 -13
- package/dist/src/outputs/asm80-expression-evaluation.d.ts +10 -0
- package/dist/src/outputs/asm80-expression-evaluation.js +75 -0
- package/dist/src/outputs/asm80-expressions.d.ts +5 -0
- package/dist/src/outputs/asm80-expressions.js +47 -0
- package/dist/src/outputs/asm80-instruction-operands.d.ts +16 -0
- package/dist/src/outputs/asm80-instruction-operands.js +38 -0
- package/dist/src/outputs/asm80-instructions.d.ts +5 -0
- package/dist/src/outputs/asm80-instructions.js +272 -0
- package/dist/src/outputs/asm80-ld-operands.d.ts +10 -0
- package/dist/src/outputs/asm80-ld-operands.js +157 -0
- package/dist/src/outputs/asm80-strings.d.ts +4 -0
- package/dist/src/outputs/asm80-strings.js +14 -0
- package/dist/src/outputs/d8-files.d.ts +10 -0
- package/dist/src/outputs/d8-files.js +103 -0
- package/dist/src/outputs/d8-helpers.d.ts +21 -0
- package/dist/src/outputs/d8-helpers.js +136 -0
- package/dist/src/outputs/hex.js +26 -18
- package/dist/src/outputs/types.d.ts +16 -10
- package/dist/src/outputs/write-asm80.js +72 -597
- package/dist/src/outputs/write-d8.js +6 -216
- package/dist/src/register-contracts/accept-output.d.ts +2 -0
- package/dist/src/register-contracts/analyze-helpers.d.ts +29 -0
- package/dist/src/register-contracts/analyze-helpers.js +162 -0
- package/dist/src/{register-care → register-contracts}/analyze.d.ts +6 -6
- package/dist/src/register-contracts/analyze.js +73 -0
- package/dist/src/register-contracts/annotate.d.ts +11 -0
- package/dist/src/{register-care → register-contracts}/annotate.js +3 -3
- package/dist/src/register-contracts/annotations.d.ts +8 -0
- package/dist/src/{register-care → register-contracts}/annotations.js +3 -3
- package/dist/src/register-contracts/boundaryHints.d.ts +3 -0
- package/dist/src/register-contracts/boundaryHints.js +24 -0
- package/dist/src/register-contracts/carriers.d.ts +2 -0
- package/dist/src/register-contracts/constants.d.ts +4 -0
- package/dist/src/register-contracts/constants.js +51 -0
- package/dist/src/register-contracts/controlFlow.d.ts +5 -0
- package/dist/src/register-contracts/controlFlow.js +55 -0
- package/dist/src/register-contracts/fix.d.ts +11 -0
- package/dist/src/{register-care → register-contracts}/fix.js +47 -30
- package/dist/src/register-contracts/instruction-head.d.ts +2 -0
- package/dist/src/register-contracts/instruction-head.js +3 -0
- package/dist/src/register-contracts/instruction-operands.d.ts +3 -0
- package/dist/src/register-contracts/instruction-operands.js +101 -0
- package/dist/src/register-contracts/instruction-predicates.d.ts +6 -0
- package/dist/src/register-contracts/instruction-predicates.js +44 -0
- package/dist/src/register-contracts/interfaceContracts.d.ts +2 -0
- package/dist/src/register-contracts/interfaceContracts.js +68 -0
- package/dist/src/register-contracts/liveness.d.ts +3 -0
- package/dist/src/{register-care → register-contracts}/liveness.js +111 -79
- package/dist/src/register-contracts/operand-register-name.d.ts +2 -0
- package/dist/src/register-contracts/operand-register-name.js +13 -0
- package/dist/src/{register-care → register-contracts}/profiles.d.ts +5 -5
- package/dist/src/{register-care → register-contracts}/profiles.js +2 -2
- package/dist/src/register-contracts/programModel-boundaries.d.ts +6 -0
- package/dist/src/register-contracts/programModel-boundaries.js +64 -0
- package/dist/src/register-contracts/programModel-routines.d.ts +7 -0
- package/dist/src/register-contracts/programModel-routines.js +144 -0
- package/dist/src/register-contracts/programModel.d.ts +3 -0
- package/dist/src/register-contracts/programModel.js +14 -0
- package/dist/src/register-contracts/report.d.ts +5 -0
- package/dist/src/{register-care → register-contracts}/report.js +34 -17
- package/dist/src/register-contracts/routine-summaries.d.ts +6 -0
- package/dist/src/{register-care → register-contracts}/routine-summaries.js +11 -1
- package/dist/src/register-contracts/smartCommentBlocks.d.ts +5 -0
- package/dist/src/register-contracts/smartCommentBlocks.js +30 -0
- package/dist/src/register-contracts/smartCommentParsing.d.ts +3 -0
- package/dist/src/register-contracts/smartCommentParsing.js +80 -0
- package/dist/src/register-contracts/smartComments.d.ts +5 -0
- package/dist/src/register-contracts/smartComments.js +92 -0
- package/dist/src/register-contracts/summaries.d.ts +12 -0
- package/dist/src/{register-care → register-contracts}/summaries.js +7 -7
- package/dist/src/register-contracts/summary-boundary.d.ts +2 -0
- package/dist/src/register-contracts/summary-boundary.js +40 -0
- package/dist/src/register-contracts/summary-contract.d.ts +2 -0
- package/dist/src/register-contracts/summary-contract.js +45 -0
- package/dist/src/register-contracts/summary-result.d.ts +7 -0
- package/dist/src/register-contracts/summary-result.js +122 -0
- package/dist/src/register-contracts/summary-state.d.ts +23 -0
- package/dist/src/register-contracts/summary-state.js +88 -0
- package/dist/src/register-contracts/summary-token-transfer.d.ts +3 -0
- package/dist/src/register-contracts/summary-token-transfer.js +67 -0
- package/dist/src/register-contracts/summary.d.ts +3 -0
- package/dist/src/register-contracts/summary.js +266 -0
- package/dist/src/register-contracts/tooling.d.ts +57 -0
- package/dist/src/{register-care → register-contracts}/tooling.js +8 -6
- package/dist/src/register-contracts/types.d.ts +188 -0
- package/dist/src/semantics/binary-operators.d.ts +2 -0
- package/dist/src/semantics/binary-operators.js +15 -0
- package/dist/src/semantics/byte-functions.d.ts +2 -0
- package/dist/src/semantics/byte-functions.js +7 -0
- package/dist/src/semantics/constant-operator-types.d.ts +10 -0
- package/dist/src/semantics/constant-operator-types.js +1 -0
- package/dist/src/semantics/constant-operators.d.ts +3 -0
- package/dist/src/semantics/constant-operators.js +3 -0
- package/dist/src/semantics/diagnostics.d.ts +3 -0
- package/dist/src/semantics/diagnostics.js +10 -0
- package/dist/src/semantics/expression-evaluation.d.ts +11 -19
- package/dist/src/semantics/expression-evaluation.js +22 -334
- package/dist/src/semantics/layout-evaluation.d.ts +23 -0
- package/dist/src/semantics/layout-evaluation.js +202 -0
- package/dist/src/semantics/layout-format.d.ts +5 -0
- package/dist/src/semantics/layout-format.js +31 -0
- package/dist/src/semantics/layout-path.d.ts +24 -0
- package/dist/src/semantics/layout-path.js +58 -0
- package/dist/src/semantics/unary-operators.d.ts +2 -0
- package/dist/src/semantics/unary-operators.js +8 -0
- package/dist/src/source/line-comment-scanner.d.ts +1 -0
- package/dist/src/source/line-comment-scanner.js +51 -0
- package/dist/src/source/logical-lines.d.ts +3 -0
- package/dist/src/source/source-span.d.ts +2 -0
- package/dist/src/source/strip-line-comment.js +8 -44
- package/dist/src/syntax/directive-aliases.js +36 -22
- package/dist/src/syntax/expression-tokenizer.d.ts +30 -0
- package/dist/src/syntax/expression-tokenizer.js +310 -0
- package/dist/src/syntax/parse-directive-statement.d.ts +9 -0
- package/dist/src/syntax/parse-directive-statement.js +309 -0
- package/dist/src/syntax/parse-expression.d.ts +2 -2
- package/dist/src/syntax/parse-expression.js +7 -568
- package/dist/src/syntax/parse-layout-declarations.d.ts +9 -0
- package/dist/src/syntax/parse-layout-declarations.js +189 -0
- package/dist/src/syntax/parse-layout-expression.d.ts +5 -0
- package/dist/src/syntax/parse-layout-expression.js +175 -0
- package/dist/src/syntax/parse-line.js +21 -273
- package/dist/src/syntax/parse-token-expression.d.ts +3 -0
- package/dist/src/syntax/parse-token-expression.js +133 -0
- package/dist/src/tooling/api.js +1 -1
- package/dist/src/tooling/case-style.js +47 -30
- package/dist/src/z80/effect-groups.d.ts +38 -0
- package/dist/src/z80/effect-groups.js +265 -0
- package/dist/src/z80/effect-units.d.ts +18 -0
- package/dist/src/z80/effect-units.js +165 -0
- package/dist/src/z80/effects.d.ts +1 -1
- package/dist/src/z80/effects.js +94 -557
- package/dist/src/z80/encode-core.d.ts +2 -0
- package/dist/src/z80/encode-core.js +42 -0
- package/dist/src/z80/encode-ld-helpers.d.ts +25 -0
- package/dist/src/z80/encode-ld-helpers.js +172 -0
- package/dist/src/z80/encode-ld.d.ts +2 -0
- package/dist/src/z80/encode-ld.js +285 -0
- package/dist/src/z80/encode.js +190 -542
- package/dist/src/z80/ld-support.d.ts +3 -0
- package/dist/src/z80/ld-support.js +146 -0
- package/dist/src/z80/operand-split-state.d.ts +8 -0
- package/dist/src/z80/operand-split-state.js +46 -0
- package/dist/src/z80/operand-split.d.ts +1 -0
- package/dist/src/z80/operand-split.js +13 -0
- package/dist/src/z80/parse-basic.d.ts +4 -0
- package/dist/src/z80/parse-basic.js +39 -0
- package/dist/src/z80/parse-branch.d.ts +4 -0
- package/dist/src/z80/parse-branch.js +218 -0
- package/dist/src/z80/parse-conditions.d.ts +6 -0
- package/dist/src/z80/parse-conditions.js +10 -0
- package/dist/src/z80/parse-exchange.d.ts +2 -0
- package/dist/src/z80/parse-exchange.js +30 -0
- package/dist/src/z80/parse-instruction.js +224 -1010
- package/dist/src/z80/parse-io-control.d.ts +5 -0
- package/dist/src/z80/parse-io-control.js +108 -0
- package/dist/src/z80/parse-ld.d.ts +2 -0
- package/dist/src/z80/parse-ld.js +83 -0
- package/dist/src/z80/parse-operands.d.ts +41 -0
- package/dist/src/z80/parse-operands.js +259 -0
- package/docs/codebase/01-orientation-and-repository-layout.md +192 -0
- package/docs/codebase/02-source-loading-and-parsing.md +263 -0
- package/docs/codebase/03-assembly-and-z80-emission.md +251 -0
- package/docs/codebase/04-ops-and-register-contracts.md +237 -0
- package/docs/codebase/05-interfaces-and-output-artifacts.md +253 -0
- package/docs/codebase/06-verification-and-maintenance.md +202 -0
- package/docs/codebase/appendices/a-directory-file-reference.md +253 -0
- package/docs/codebase/appendices/b-compile-flow-reference.md +103 -0
- package/docs/codebase/appendices/c-public-surface-reference.md +106 -0
- package/docs/codebase/appendices/index.md +16 -0
- package/docs/codebase/index.md +46 -0
- package/package.json +2 -3
- package/dist/src/register-care/accept-output.d.ts +0 -2
- package/dist/src/register-care/analyze.js +0 -166
- package/dist/src/register-care/annotate.d.ts +0 -11
- package/dist/src/register-care/annotations.d.ts +0 -8
- package/dist/src/register-care/boundaryHints.d.ts +0 -3
- package/dist/src/register-care/boundaryHints.js +0 -80
- package/dist/src/register-care/carriers.d.ts +0 -2
- package/dist/src/register-care/controlFlow.d.ts +0 -5
- package/dist/src/register-care/controlFlow.js +0 -38
- package/dist/src/register-care/fix.d.ts +0 -11
- package/dist/src/register-care/instruction-shape.d.ts +0 -11
- package/dist/src/register-care/instruction-shape.js +0 -129
- package/dist/src/register-care/liveness.d.ts +0 -3
- package/dist/src/register-care/programModel.d.ts +0 -3
- package/dist/src/register-care/programModel.js +0 -266
- package/dist/src/register-care/report.d.ts +0 -5
- package/dist/src/register-care/routine-summaries.d.ts +0 -6
- package/dist/src/register-care/smartComments.d.ts +0 -5
- package/dist/src/register-care/smartComments.js +0 -243
- package/dist/src/register-care/summaries.d.ts +0 -12
- package/dist/src/register-care/summary.d.ts +0 -3
- package/dist/src/register-care/summary.js +0 -474
- package/dist/src/register-care/tooling.d.ts +0 -43
- package/dist/src/register-care/types.d.ts +0 -172
- package/docs/reference/cli.md +0 -151
- package/docs/reference/tooling-api.md +0 -316
- /package/dist/src/{register-care → register-contracts}/accept-output.js +0 -0
- /package/dist/src/{register-care → register-contracts}/carriers.js +0 -0
- /package/dist/src/{register-care → register-contracts}/sourceText.d.ts +0 -0
- /package/dist/src/{register-care → register-contracts}/sourceText.js +0 -0
- /package/dist/src/{register-care → register-contracts}/types.js +0 -0
package/README.md
CHANGED
|
@@ -4,10 +4,12 @@ AZM is the Z80 assembler used by the Debug80 toolchain. It assembles `.asm`
|
|
|
4
4
|
and `.z80` source into Intel HEX, flat binary and Debug80 map artifacts for
|
|
5
5
|
hardware, emulators and Debug80.
|
|
6
6
|
|
|
7
|
-
This README is the condensed manual. The
|
|
8
|
-
documentation
|
|
7
|
+
This README is the condensed manual. The Debug80 website contains the detailed
|
|
8
|
+
AZM manual and broader Debug80 documentation:
|
|
9
9
|
|
|
10
|
-
[
|
|
10
|
+
- [Debug80 documentation](https://debug80.com/)
|
|
11
|
+
- [AZM Book 0 — Assembler Manual](https://debug80.com/azm-book/book0/)
|
|
12
|
+
- [AZM Book 4](https://jhlagado.github.io/debug80-docs/azm-book/book4/)
|
|
11
13
|
|
|
12
14
|
## Install
|
|
13
15
|
|
|
@@ -43,13 +45,13 @@ azm start.asm
|
|
|
43
45
|
```
|
|
44
46
|
|
|
45
47
|
`.org` means origin. It sets the assembly address for the bytes that follow.
|
|
46
|
-
`@Start:` is an address label and also a public routine entry for register
|
|
48
|
+
`@Start:` is an address label and also a public routine entry for register contracts
|
|
47
49
|
analysis. The Z80 instructions assemble at `$0100`.
|
|
48
50
|
|
|
49
51
|
## Source Style
|
|
50
52
|
|
|
51
53
|
AZM source is built from labels, declarations, directives, Z80 instructions,
|
|
52
|
-
data definitions, layout declarations, register
|
|
54
|
+
data definitions, layout declarations, register contract comments and optional
|
|
53
55
|
inline `op` definitions.
|
|
54
56
|
|
|
55
57
|
Canonical AZM directives are lowercase and dotted:
|
|
@@ -89,16 +91,102 @@ Colour .enum Red, Green, Blue
|
|
|
89
91
|
SpriteArray .typealias Sprite[16]
|
|
90
92
|
```
|
|
91
93
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
### Style Guide
|
|
95
|
+
|
|
96
|
+
AZM is stricter than many older Z80 assemblers. It accepts compatibility aliases
|
|
97
|
+
so existing source can be assembled, but source that you control should use the
|
|
98
|
+
canonical syntax below. These rules are intended to make AZM source predictable
|
|
99
|
+
for people and coding agents.
|
|
100
|
+
|
|
101
|
+
Use lowercase dotted directives, not legacy aliases:
|
|
94
102
|
|
|
95
103
|
```asm
|
|
96
|
-
|
|
104
|
+
.org 0x4000
|
|
105
|
+
.include "../shared/constants.asm"
|
|
97
106
|
|
|
98
|
-
|
|
99
|
-
|
|
107
|
+
MOVE_PERIOD .equ 128
|
|
108
|
+
|
|
109
|
+
Message:
|
|
110
|
+
.db "READY",0
|
|
111
|
+
|
|
112
|
+
StatePtr:
|
|
113
|
+
.dw 0
|
|
114
|
+
|
|
115
|
+
Buffer:
|
|
116
|
+
.ds 32
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Use `@Name:` for callable routine entries. The `@` marks a register contracts
|
|
120
|
+
routine boundary; call sites still write the symbol name without `@`:
|
|
121
|
+
|
|
122
|
+
```asm
|
|
123
|
+
;! in A
|
|
124
|
+
;! out A
|
|
125
|
+
;! clobbers BC
|
|
126
|
+
@MxMask:
|
|
127
|
+
LD C,A
|
|
128
|
+
OR A
|
|
129
|
+
LD A,0x80
|
|
130
|
+
JR Z,MxMaskDone
|
|
131
|
+
MxMaskLp:
|
|
132
|
+
SRL A
|
|
133
|
+
DJNZ MxMaskLp
|
|
134
|
+
MxMaskDone:
|
|
135
|
+
RET
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Use plain labels for data and internal branch targets. Plain labels are global,
|
|
139
|
+
so give branch labels names that stay unique across the whole include tree.
|
|
140
|
+
Prefer descriptive labels such as `MxMaskLoop`, `MxMaskDone`, `SpawnFailed` and
|
|
141
|
+
`HeldDirRateSet` rather than generic names such as `Loop` or `Done`.
|
|
142
|
+
|
|
143
|
+
Use uppercase with underscores for constants, following the usual C-style
|
|
144
|
+
convention. Group related constants with clear prefixes:
|
|
145
|
+
|
|
146
|
+
```asm
|
|
147
|
+
PORT_DIGITS .equ 0x01
|
|
148
|
+
PORT_LCD_DATA .equ 0x84
|
|
149
|
+
|
|
150
|
+
API_SCAN_KEYS .equ 16
|
|
151
|
+
KEY_LEFT .equ 0x11
|
|
152
|
+
KEY_RIGHT .equ 0x10
|
|
153
|
+
|
|
154
|
+
COLOR_RED .equ 0x01
|
|
155
|
+
COLOR_GREEN .equ 0x02
|
|
156
|
+
COLOR_YELLOW .equ COLOR_RED + COLOR_GREEN
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Use PascalCase for routine entries, branch labels, data labels, type names and
|
|
160
|
+
enum names. Use lower camel case for fields and enum members when that makes
|
|
161
|
+
layout expressions easier to read. The assembler enforces uniqueness, not style,
|
|
162
|
+
but symbols are case-sensitive: `ColorRed`, `COLOR_RED` and `colorRed` are
|
|
163
|
+
different names.
|
|
164
|
+
|
|
165
|
+
Put declaration names on the left and do not use a colon for constants, enums,
|
|
166
|
+
types or type aliases:
|
|
167
|
+
|
|
168
|
+
```asm
|
|
169
|
+
MOVE_PERIOD .equ 128
|
|
170
|
+
Colour .enum Red, Green, Blue
|
|
171
|
+
SpriteArray .typealias Sprite[16]
|
|
172
|
+
|
|
173
|
+
Sprite .type
|
|
174
|
+
x .field byte
|
|
175
|
+
y .field byte
|
|
176
|
+
tile .field byte
|
|
177
|
+
flags .field byte
|
|
178
|
+
.endtype
|
|
100
179
|
```
|
|
101
180
|
|
|
181
|
+
Use a colon only for address labels. `COUNT .equ 8` declares a constant;
|
|
182
|
+
`Count:` declares an address label. Do not write `COUNT: .equ 8` in canonical
|
|
183
|
+
AZM.
|
|
184
|
+
|
|
185
|
+
Use indentation to make columns easy to scan. Put labels at the left margin,
|
|
186
|
+
indent instructions and standalone directives, and align operands enough to keep
|
|
187
|
+
dense assembly readable. Exact tab width is less important than keeping one
|
|
188
|
+
source file internally consistent.
|
|
189
|
+
|
|
102
190
|
## Literals
|
|
103
191
|
|
|
104
192
|
AZM accepts the usual Z80 numeric forms:
|
|
@@ -247,12 +335,74 @@ azm -I include -I vendor program.asm
|
|
|
247
335
|
Included source contributes labels, constants, enums, types, ops and routines to
|
|
248
336
|
the same assembly.
|
|
249
337
|
|
|
250
|
-
##
|
|
338
|
+
## Imports
|
|
251
339
|
|
|
252
|
-
|
|
340
|
+
`.import` is AZM's module-style source composition directive:
|
|
341
|
+
|
|
342
|
+
```asm
|
|
343
|
+
; main.asm
|
|
344
|
+
.import "keyboard.asm"
|
|
345
|
+
|
|
346
|
+
@Start:
|
|
347
|
+
call ReadKey
|
|
348
|
+
ret
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
```asm
|
|
352
|
+
; keyboard.asm
|
|
353
|
+
@ReadKey:
|
|
354
|
+
call ScanMatrix
|
|
355
|
+
ret
|
|
356
|
+
|
|
357
|
+
ScanMatrix:
|
|
358
|
+
xor a
|
|
359
|
+
ret
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Imported source assembles at the point where `.import` appears, so native
|
|
363
|
+
`.bin`, `.hex` and `.d8.json` output contain the imported bytes as part of the
|
|
364
|
+
same program. Paths resolve like includes: relative to the importing file first,
|
|
365
|
+
then through `-I` include directories.
|
|
366
|
+
|
|
367
|
+
The difference is visibility. In an imported file, labels written with `@` are
|
|
368
|
+
public exports. Code outside `keyboard.asm` can call `ReadKey`, using the name
|
|
369
|
+
without `@`. Plain labels in an imported file, such as `ScanMatrix`, are private
|
|
370
|
+
to that imported file or import unit. The imported file may call its own private
|
|
371
|
+
helpers, but outside references fail with a direct visibility diagnostic.
|
|
372
|
+
|
|
373
|
+
`.include` remains textual. Included text belongs to the including source unit
|
|
374
|
+
and is intended for shared constants, declarations and compatibility source.
|
|
375
|
+
Use `.import` when a source file should behave like a module with public `@`
|
|
376
|
+
entry points and private implementation labels.
|
|
377
|
+
|
|
378
|
+
Repeated imports of the same resolved file are idempotent: the first import
|
|
379
|
+
loads and emits the module, later imports of that same file are skipped.
|
|
380
|
+
Repeated includes are still textual and repeat every time. Recursive includes or
|
|
381
|
+
imports are rejected with source diagnostics.
|
|
382
|
+
|
|
383
|
+
Register contracts use the same `@` routine boundaries across imported files.
|
|
384
|
+
Imported public routines are analyzed as internal routines under `--rc strict`,
|
|
385
|
+
and private helpers called inside an imported public routine are summarized as
|
|
386
|
+
part of the same program analysis.
|
|
387
|
+
|
|
388
|
+
ASM80-compatible lowered `.z80` output does not yet support imported source
|
|
389
|
+
units. If `--asm80` is requested for a program that uses `.import`, AZM reports
|
|
390
|
+
an explicit `AZMN_ASM80` diagnostic instead of silently flattening the module
|
|
391
|
+
boundary. Use native `.bin`, `.hex` and `.d8.json` output for imported programs.
|
|
392
|
+
|
|
393
|
+
## Register Contracts
|
|
394
|
+
|
|
395
|
+
Register contracts check whether subroutines preserve the register values that their
|
|
253
396
|
callers still need. It is designed to catch register collisions, a common source
|
|
254
397
|
of assembly bugs.
|
|
255
398
|
|
|
399
|
+
The benefit is practical: AZM can stop a plausible-looking routine at compile
|
|
400
|
+
time when it reads a register after calling code that may clobber it. In larger
|
|
401
|
+
Z80 projects this encourages smaller routines, clearer `@` boundaries, explicit
|
|
402
|
+
helper outputs, and proof or test harnesses that stay honest under
|
|
403
|
+
`--rc strict`. The friction is intentional: strict contracts make hidden
|
|
404
|
+
register and stack assumptions visible before they become debugger sessions.
|
|
405
|
+
|
|
256
406
|
Routine entry labels start with `@`:
|
|
257
407
|
|
|
258
408
|
```asm
|
|
@@ -272,7 +422,7 @@ name:
|
|
|
272
422
|
call CheckTile
|
|
273
423
|
```
|
|
274
424
|
|
|
275
|
-
AZMDoc register
|
|
425
|
+
AZMDoc register contract comments use `;!` and may record inputs, outputs,
|
|
276
426
|
clobbered registers and preserved registers. `clobbers B` means the routine may
|
|
277
427
|
change `B`. `preserves B` means the value that enters in `B` is still present
|
|
278
428
|
when the routine returns.
|
|
@@ -280,13 +430,24 @@ when the routine returns.
|
|
|
280
430
|
Run the analysis with:
|
|
281
431
|
|
|
282
432
|
```sh
|
|
283
|
-
azm --rc audit
|
|
433
|
+
azm --rc audit program.asm
|
|
434
|
+
azm --rc warn program.asm
|
|
284
435
|
azm --rc error --interface monitor.asmi program.asm
|
|
436
|
+
azm --rc strict program.asm
|
|
285
437
|
```
|
|
286
438
|
|
|
287
|
-
The main modes are `audit`, `warn`, `error` and `strict`.
|
|
288
|
-
|
|
289
|
-
|
|
439
|
+
The main modes are `audit`, `warn`, `error` and `strict`. Use `audit` for a
|
|
440
|
+
non-blocking check, `warn` for visible diagnostics with a successful compile,
|
|
441
|
+
`error` to fail on proven caller/callee register conflicts, and `strict` to fail
|
|
442
|
+
on any register contracts issue AZM cannot prove safe, including unknown call
|
|
443
|
+
boundaries and unbalanced or unknown stack effects.
|
|
444
|
+
|
|
445
|
+
The normal register contracts interface is compiler diagnostics plus source
|
|
446
|
+
contracts. Use `--contracts` or `--fix` when you want AZM to update compact
|
|
447
|
+
AZMDoc contract comments in source. Use `.asmi` files for externally assembled
|
|
448
|
+
routines or monitor/system APIs. Text report files are available with
|
|
449
|
+
`--reg-report`, but they are an explicit debug/export option and are not part of
|
|
450
|
+
the normal workflow.
|
|
290
451
|
|
|
291
452
|
## Ops and Aliases
|
|
292
453
|
|
|
@@ -316,7 +477,7 @@ azm [options] <entry.asm|entry.z80>
|
|
|
316
477
|
```
|
|
317
478
|
|
|
318
479
|
The entry file is the final argument. Source entries use `.asm` or `.z80`.
|
|
319
|
-
External register
|
|
480
|
+
External register contract interfaces use `.asmi` and are loaded with
|
|
320
481
|
`--interface`.
|
|
321
482
|
|
|
322
483
|
Basic use writes the default artifact set next to the source file:
|
|
@@ -364,55 +525,57 @@ Generate ASM80-compatible lowered source:
|
|
|
364
525
|
azm --asm80 program.asm
|
|
365
526
|
```
|
|
366
527
|
|
|
367
|
-
Run register
|
|
528
|
+
Run register contracts analysis:
|
|
368
529
|
|
|
369
530
|
```sh
|
|
370
|
-
azm --rc audit
|
|
531
|
+
azm --rc audit program.asm
|
|
532
|
+
azm --rc warn program.asm
|
|
371
533
|
azm --rc error --interface monitor.asmi program.asm
|
|
534
|
+
azm --rc strict program.asm
|
|
372
535
|
azm --contracts --rc audit program.asm
|
|
373
536
|
```
|
|
374
537
|
|
|
375
538
|
The main switches are:
|
|
376
539
|
|
|
377
|
-
| Option | Meaning
|
|
378
|
-
| --------------------------------------------- |
|
|
379
|
-
| `-o, --output <file>` | Primary output path. The extension matches `--type`.
|
|
380
|
-
| `-t, --type <hex\|bin>` | Primary output type. Default: `hex`.
|
|
381
|
-
| `--nobin` | Skip `.bin` output.
|
|
382
|
-
| `--nohex` | Skip `.hex` output.
|
|
383
|
-
| `--nod8m` | Skip `.d8.json` output.
|
|
384
|
-
| `--asm80` | Write lowered assembler source as `.z80`.
|
|
385
|
-
| `--source-root <dir>` | Emit project-relative source paths in `.d8.json`.
|
|
386
|
-
| `--case-style <mode>` | Lint mnemonic, register and op-head case style.
|
|
387
|
-
| `--rc, --register-
|
|
388
|
-
| `--reg-report, --emit-register-report` |
|
|
389
|
-
| `--reg-interface, --emit-register-interface` | Write inferred `.asmi` interface metadata.
|
|
390
|
-
| `--contracts, --annotate-register-contracts` | Update AZMDoc contract comments in source.
|
|
391
|
-
| `--fix` | Apply conservative register
|
|
392
|
-
| `--accept-out <routine:carrier>` | Promote an inferred output candidate while annotating.
|
|
393
|
-
| `--interface <file>` | Load external register
|
|
394
|
-
| `--reg-profile, --register-profile <profile>` | Register
|
|
395
|
-
| `--aliases <file>` | Load project directive alias JSON.
|
|
396
|
-
| `-I, --include <dir>` | Add an include search path.
|
|
397
|
-
| `-V, --version` | Print package version.
|
|
398
|
-
| `-h, --help` | Print CLI help.
|
|
399
|
-
|
|
400
|
-
See [
|
|
401
|
-
reference.
|
|
540
|
+
| Option | Meaning |
|
|
541
|
+
| --------------------------------------------- | ------------------------------------------------------------------- |
|
|
542
|
+
| `-o, --output <file>` | Primary output path. The extension matches `--type`. |
|
|
543
|
+
| `-t, --type <hex\|bin>` | Primary output type. Default: `hex`. |
|
|
544
|
+
| `--nobin` | Skip `.bin` output. |
|
|
545
|
+
| `--nohex` | Skip `.hex` output. |
|
|
546
|
+
| `--nod8m` | Skip `.d8.json` output. |
|
|
547
|
+
| `--asm80` | Write lowered assembler source as `.z80`. |
|
|
548
|
+
| `--source-root <dir>` | Emit project-relative source paths in `.d8.json`. |
|
|
549
|
+
| `--case-style <mode>` | Lint mnemonic, register and op-head case style. |
|
|
550
|
+
| `--rc, --register-contracts <mode>` | Register contracts mode: `off`, `audit`, `warn`, `error`, `strict`. |
|
|
551
|
+
| `--reg-report, --emit-register-report` | Opt-in debug report: write `.regcontracts.txt`. |
|
|
552
|
+
| `--reg-interface, --emit-register-interface` | Write inferred `.asmi` interface metadata. |
|
|
553
|
+
| `--contracts, --annotate-register-contracts` | Update AZMDoc contract comments in source. |
|
|
554
|
+
| `--fix` | Apply conservative register contract source fixes. |
|
|
555
|
+
| `--accept-out <routine:carrier>` | Promote an inferred output candidate while annotating. |
|
|
556
|
+
| `--interface <file>` | Load external register contracts from `.asmi`. |
|
|
557
|
+
| `--reg-profile, --register-profile <profile>` | Register contracts profile. Currently `mon3`. |
|
|
558
|
+
| `--aliases <file>` | Load project directive alias JSON. |
|
|
559
|
+
| `-I, --include <dir>` | Add an include search path. |
|
|
560
|
+
| `-V, --version` | Print package version. |
|
|
561
|
+
| `-h, --help` | Print CLI help. |
|
|
562
|
+
|
|
563
|
+
See the [AZM Engineering Manual](docs/codebase/) for the maintained codebase,
|
|
564
|
+
CLI and package-interface reference.
|
|
402
565
|
|
|
403
566
|
## Output Artifacts
|
|
404
567
|
|
|
405
568
|
By default, AZM writes the requested primary output plus useful side artifacts
|
|
406
569
|
using the same base path.
|
|
407
570
|
|
|
408
|
-
| Extension
|
|
409
|
-
|
|
|
410
|
-
| `.hex`
|
|
411
|
-
| `.bin`
|
|
412
|
-
| `.d8.json`
|
|
413
|
-
| `.z80`
|
|
414
|
-
| `.
|
|
415
|
-
| `.asmi`
|
|
571
|
+
| Extension | Contents |
|
|
572
|
+
| ------------------- | -------------------------------------------- |
|
|
573
|
+
| `.hex` | Intel HEX |
|
|
574
|
+
| `.bin` | flat binary |
|
|
575
|
+
| `.d8.json` | Debug80 map |
|
|
576
|
+
| `.z80` | ASM80-compatible lowered source when enabled |
|
|
577
|
+
| `.regcontracts.txt` | opt-in register contracts debug report |
|
|
578
|
+
| `.asmi` | register contracts interface when enabled |
|
|
416
579
|
|
|
417
580
|
## Programmatic API
|
|
418
581
|
|
|
@@ -430,13 +593,13 @@ npm install @jhlagado/azm
|
|
|
430
593
|
```
|
|
431
594
|
|
|
432
595
|
Use `@jhlagado/azm/tooling` when an editor, linter or debugger integration
|
|
433
|
-
needs parsing, diagnostics, symbols, semantic checks or register
|
|
596
|
+
needs parsing, diagnostics, symbols, semantic checks or register contract facts in
|
|
434
597
|
memory:
|
|
435
598
|
|
|
436
599
|
```ts
|
|
437
600
|
import {
|
|
438
601
|
analyzeProgram,
|
|
439
|
-
|
|
602
|
+
analyzeRegisterContractsForTools,
|
|
440
603
|
loadProgram,
|
|
441
604
|
} from '@jhlagado/azm/tooling';
|
|
442
605
|
|
|
@@ -451,13 +614,13 @@ if (loaded.loadedProgram) {
|
|
|
451
614
|
requireMain: false,
|
|
452
615
|
});
|
|
453
616
|
|
|
454
|
-
const
|
|
617
|
+
const registerContracts = analyzeRegisterContractsForTools(loaded.loadedProgram, {
|
|
455
618
|
mode: 'audit',
|
|
456
|
-
|
|
619
|
+
registerContractsProfile: 'mon3',
|
|
457
620
|
});
|
|
458
621
|
|
|
459
622
|
console.log(analysis.diagnostics);
|
|
460
|
-
console.log(
|
|
623
|
+
console.log(registerContracts.candidateDiagnostics);
|
|
461
624
|
}
|
|
462
625
|
```
|
|
463
626
|
|
|
@@ -483,8 +646,8 @@ const result = await compile(
|
|
|
483
646
|
hex: '/abs/path/to/project/build/main.hex',
|
|
484
647
|
bin: '/abs/path/to/project/build/main.bin',
|
|
485
648
|
},
|
|
486
|
-
|
|
487
|
-
|
|
649
|
+
registerContracts: 'audit',
|
|
650
|
+
registerContractsInterfaces: ['/abs/path/to/monitor.asmi'],
|
|
488
651
|
},
|
|
489
652
|
{ formats: defaultFormatWriters },
|
|
490
653
|
);
|
|
@@ -501,24 +664,24 @@ write those artifacts to disk.
|
|
|
501
664
|
|
|
502
665
|
Common programmatic options include:
|
|
503
666
|
|
|
504
|
-
| Option
|
|
505
|
-
|
|
|
506
|
-
| `includeDirs`
|
|
507
|
-
| `directiveAliasFiles`
|
|
508
|
-
| `sourceRoot`
|
|
509
|
-
| `d8mInputs`
|
|
510
|
-
| `outputType`
|
|
511
|
-
| `emitBin`, `emitHex`, `emitD8m` | Select in-memory artifact kinds.
|
|
512
|
-
| `emitAsm80`
|
|
513
|
-
| `
|
|
514
|
-
| `
|
|
667
|
+
| Option | Use |
|
|
668
|
+
| ------------------------------- | --------------------------------------------------------- |
|
|
669
|
+
| `includeDirs` | Include search paths, like repeated `-I`. |
|
|
670
|
+
| `directiveAliasFiles` | Project directive alias JSON files. |
|
|
671
|
+
| `sourceRoot` | Stable project-relative paths in Debug80 maps. |
|
|
672
|
+
| `d8mInputs` | Intended artifact paths recorded in Debug80 map metadata. |
|
|
673
|
+
| `outputType` | Primary output type, `hex` or `bin`. |
|
|
674
|
+
| `emitBin`, `emitHex`, `emitD8m` | Select in-memory artifact kinds. |
|
|
675
|
+
| `emitAsm80` | Request lowered `.z80` artifact. |
|
|
676
|
+
| `registerContracts` | Register contracts mode. |
|
|
677
|
+
| `registerContractsInterfaces` | External `.asmi` contract files. |
|
|
515
678
|
|
|
516
679
|
Public tooling types include `Diagnostic`, `LoadedProgram`,
|
|
517
|
-
`AnalyzeProgramResult`, `LoadProgramResult`, `
|
|
680
|
+
`AnalyzeProgramResult`, `LoadProgramResult`, `RegisterContractsCandidateDiagnostic`
|
|
518
681
|
and the Debug80 map artifact types `D8mArtifact`, `D8mJson` and `D8mSymbol`.
|
|
519
682
|
|
|
520
|
-
See [
|
|
521
|
-
API notes.
|
|
683
|
+
See the [public surface reference](docs/codebase/appendices/c-public-surface-reference.md)
|
|
684
|
+
for current API notes.
|
|
522
685
|
|
|
523
686
|
## Development
|
|
524
687
|
|
|
@@ -533,8 +696,8 @@ npm run test:azm:corpus
|
|
|
533
696
|
npm test
|
|
534
697
|
```
|
|
535
698
|
|
|
536
|
-
The live source map is maintained in
|
|
537
|
-
[
|
|
699
|
+
The live source map is maintained in the
|
|
700
|
+
[AZM Engineering Manual](docs/codebase/).
|
|
538
701
|
|
|
539
702
|
## License
|
|
540
703
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Diagnostic } from './model/diagnostic.js';
|
|
2
|
+
import type { SourceItem } from './model/source-item.js';
|
|
3
|
+
import type { Artifact, EmittedByteMap, FormatWriters } from './outputs/types.js';
|
|
4
|
+
import type { CompileNextFunctionOptions } from './api-compile.js';
|
|
5
|
+
interface EmitAssemblyArtifactsOptions {
|
|
6
|
+
readonly entryFile: string;
|
|
7
|
+
readonly options: CompileNextFunctionOptions;
|
|
8
|
+
readonly formats: FormatWriters;
|
|
9
|
+
readonly program: readonly SourceItem[];
|
|
10
|
+
readonly bytes: Uint8Array;
|
|
11
|
+
readonly origin: number;
|
|
12
|
+
readonly sourceSegments: EmittedByteMap['sourceSegments'];
|
|
13
|
+
readonly initializedAddresses: readonly number[];
|
|
14
|
+
readonly symbols: Readonly<Record<string, number>>;
|
|
15
|
+
}
|
|
16
|
+
export declare function emitAssemblyArtifacts(input: EmitAssemblyArtifactsOptions): Promise<{
|
|
17
|
+
readonly artifacts: readonly Artifact[];
|
|
18
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
19
|
+
}>;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, normalize } from 'node:path';
|
|
3
|
+
import { UnsupportedAsm80LoweringError } from './outputs/write-asm80.js';
|
|
4
|
+
let cachedPackageVersion;
|
|
5
|
+
export async function emitAssemblyArtifacts(input) {
|
|
6
|
+
const artifacts = [];
|
|
7
|
+
const diagnostics = [];
|
|
8
|
+
const map = assembledImageToMap(input.bytes, input.origin, input.sourceSegments);
|
|
9
|
+
const hexMap = assembledInitializedImageToMap(input.bytes, input.origin, input.initializedAddresses);
|
|
10
|
+
const sidecarMap = assembledInitializedImageToMap(input.bytes, input.origin, input.initializedAddresses, input.sourceSegments);
|
|
11
|
+
const symbols = collectSymbolEntries(input.program, input.symbols);
|
|
12
|
+
const emit = compileArtifactDefaults(input.options);
|
|
13
|
+
const d8Root = input.options.sourceRoot ?? dirname(input.entryFile);
|
|
14
|
+
if (emit.emitBin) {
|
|
15
|
+
artifacts.push(input.formats.writeBin(map, symbols));
|
|
16
|
+
}
|
|
17
|
+
if (emit.emitHex) {
|
|
18
|
+
artifacts.push(input.formats.writeHex(hexMap, symbols));
|
|
19
|
+
}
|
|
20
|
+
if (emit.emitD8m) {
|
|
21
|
+
artifacts.push(input.formats.writeD8m(sidecarMap, symbols, await buildD8mOptions(input.entryFile, d8Root, input.options, symbols)));
|
|
22
|
+
}
|
|
23
|
+
if (emit.emitAsm80 && input.formats.writeAsm80 !== undefined) {
|
|
24
|
+
try {
|
|
25
|
+
artifacts.push(input.formats.writeAsm80(input.program, symbols));
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (error instanceof UnsupportedAsm80LoweringError) {
|
|
29
|
+
diagnostics.push({
|
|
30
|
+
severity: 'error',
|
|
31
|
+
code: 'AZMN_ASM80',
|
|
32
|
+
message: error.message,
|
|
33
|
+
sourceName: error.item.span.sourceName,
|
|
34
|
+
line: error.item.span.line,
|
|
35
|
+
column: error.item.span.column,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { artifacts, diagnostics };
|
|
44
|
+
}
|
|
45
|
+
function compileArtifactDefaults(options) {
|
|
46
|
+
const anyPrimary = [options.emitBin, options.emitHex, options.emitD8m].some((value) => value !== undefined);
|
|
47
|
+
const emitBin = anyPrimary ? (options.emitBin ?? false) : true;
|
|
48
|
+
const emitHex = anyPrimary ? (options.emitHex ?? false) : true;
|
|
49
|
+
const emitD8m = anyPrimary ? (options.emitD8m ?? false) : true;
|
|
50
|
+
const emitAsm80 = options.emitAsm80 ?? false;
|
|
51
|
+
return { emitBin, emitHex, emitD8m, emitAsm80 };
|
|
52
|
+
}
|
|
53
|
+
function assembledImageToMap(bytes, origin, sourceSegments = []) {
|
|
54
|
+
const map = new Map();
|
|
55
|
+
for (let offset = 0; offset < bytes.length; offset += 1) {
|
|
56
|
+
map.set(origin + offset, bytes[offset] ?? 0);
|
|
57
|
+
}
|
|
58
|
+
const writtenRange = {
|
|
59
|
+
start: origin,
|
|
60
|
+
end: origin + bytes.length,
|
|
61
|
+
};
|
|
62
|
+
return { bytes: map, writtenRange, sourceSegments };
|
|
63
|
+
}
|
|
64
|
+
function assembledInitializedImageToMap(bytes, origin, initializedAddresses, sourceSegments = []) {
|
|
65
|
+
const map = new Map();
|
|
66
|
+
for (const address of initializedAddresses) {
|
|
67
|
+
const offset = address - origin;
|
|
68
|
+
if (offset >= 0 && offset < bytes.length) {
|
|
69
|
+
map.set(address, bytes[offset] ?? 0);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { bytes: map, sourceSegments };
|
|
73
|
+
}
|
|
74
|
+
function collectSymbolEntries(items, resolvedSymbols) {
|
|
75
|
+
const map = new Map();
|
|
76
|
+
for (const item of items) {
|
|
77
|
+
appendSymbolEntry(map, item, resolvedSymbols);
|
|
78
|
+
}
|
|
79
|
+
return [...map.values()];
|
|
80
|
+
}
|
|
81
|
+
function appendSymbolEntry(map, item, resolvedSymbols) {
|
|
82
|
+
if (item.kind === 'equ') {
|
|
83
|
+
const value = resolvedSymbols[item.name];
|
|
84
|
+
if (value !== undefined) {
|
|
85
|
+
map.set(item.name, {
|
|
86
|
+
kind: 'constant',
|
|
87
|
+
name: item.name,
|
|
88
|
+
value,
|
|
89
|
+
file: item.span.sourceName,
|
|
90
|
+
line: item.span.line,
|
|
91
|
+
scope: 'global',
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (item.kind === 'label') {
|
|
97
|
+
const address = resolvedSymbols[item.name];
|
|
98
|
+
if (address !== undefined) {
|
|
99
|
+
map.set(item.name, {
|
|
100
|
+
kind: 'label',
|
|
101
|
+
name: item.name,
|
|
102
|
+
address,
|
|
103
|
+
file: item.span.sourceName,
|
|
104
|
+
line: item.span.line,
|
|
105
|
+
scope: 'global',
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (item.kind === 'enum') {
|
|
111
|
+
for (const member of item.members) {
|
|
112
|
+
const fullName = `${item.name}.${member}`;
|
|
113
|
+
const value = resolvedSymbols[fullName];
|
|
114
|
+
if (value !== undefined) {
|
|
115
|
+
map.set(fullName, {
|
|
116
|
+
kind: 'constant',
|
|
117
|
+
name: fullName,
|
|
118
|
+
value,
|
|
119
|
+
file: item.span.sourceName,
|
|
120
|
+
line: item.span.line,
|
|
121
|
+
scope: 'global',
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async function buildD8mOptions(entryFile, d8Root, options, symbols) {
|
|
128
|
+
const main = symbols.find((symbol) => symbol.kind === 'label' && symbol.name.toLowerCase() === 'main');
|
|
129
|
+
return {
|
|
130
|
+
rootDir: normalize(d8Root),
|
|
131
|
+
packageVersion: await readPackageVersion(),
|
|
132
|
+
inputs: {
|
|
133
|
+
entry: entryFile,
|
|
134
|
+
...(options.d8mInputs?.hex !== undefined ? { hex: options.d8mInputs.hex } : {}),
|
|
135
|
+
...(options.d8mInputs?.bin !== undefined ? { bin: options.d8mInputs.bin } : {}),
|
|
136
|
+
},
|
|
137
|
+
...(main !== undefined ? { entrySymbol: main.name } : {}),
|
|
138
|
+
...(main !== undefined ? { entryAddress: main.kind === 'constant' ? main.value : main.address } : {}),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
async function readPackageVersion() {
|
|
142
|
+
if (cachedPackageVersion !== undefined) {
|
|
143
|
+
return cachedPackageVersion;
|
|
144
|
+
}
|
|
145
|
+
const packageJsonCandidates = [
|
|
146
|
+
new URL('../package.json', import.meta.url),
|
|
147
|
+
new URL('../../package.json', import.meta.url),
|
|
148
|
+
new URL('../../../package.json', import.meta.url),
|
|
149
|
+
];
|
|
150
|
+
for (const candidate of packageJsonCandidates) {
|
|
151
|
+
try {
|
|
152
|
+
const raw = await readFile(candidate, 'utf8');
|
|
153
|
+
const json = JSON.parse(raw);
|
|
154
|
+
if (json.version !== undefined) {
|
|
155
|
+
cachedPackageVersion = json.version;
|
|
156
|
+
return cachedPackageVersion;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Continue searching candidates.
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
cachedPackageVersion = '0.0.0';
|
|
164
|
+
return cachedPackageVersion;
|
|
165
|
+
}
|
|
@@ -3,7 +3,7 @@ import { writeHex } from './outputs/write-hex.js';
|
|
|
3
3
|
import type { AddressRange, Artifact, D8mArtifact, D8mFileEntry, D8mFileSymbol, D8mGenerator, D8mJson, D8mSegment, D8mSymbol, EmittedByteMap, FormatWriters, SymbolEntry, WriteD8mOptions } from './outputs/types.js';
|
|
4
4
|
import type { Diagnostic } from './model/diagnostic.js';
|
|
5
5
|
import type { CaseStyleMode } from './tooling/case-style.js';
|
|
6
|
-
import type {
|
|
6
|
+
import type { RegisterContractsMode } from './register-contracts/types.js';
|
|
7
7
|
export { writeHex, defaultFormatWriters };
|
|
8
8
|
export type { AddressRange, Artifact, D8mArtifact, D8mFileEntry, D8mFileSymbol, D8mGenerator, D8mJson, D8mSegment, D8mSymbol, EmittedByteMap, FormatWriters, SymbolEntry, WriteD8mOptions, };
|
|
9
9
|
export type CompileDependencies = CompileNextDependencies;
|
|
@@ -27,13 +27,19 @@ export interface CompileNextFunctionOptions {
|
|
|
27
27
|
readonly emitHex?: boolean;
|
|
28
28
|
readonly emitD8m?: boolean;
|
|
29
29
|
readonly emitAsm80?: boolean;
|
|
30
|
-
readonly
|
|
30
|
+
readonly registerContracts?: RegisterContractsMode;
|
|
31
|
+
/** @deprecated Use registerContracts. */
|
|
32
|
+
readonly registerCare?: RegisterContractsMode;
|
|
31
33
|
readonly emitRegisterReport?: boolean;
|
|
32
34
|
readonly emitRegisterInterface?: boolean;
|
|
33
35
|
readonly emitRegisterAnnotations?: boolean;
|
|
34
36
|
readonly fixRegisterContracts?: boolean;
|
|
35
37
|
readonly acceptRegisterOutputCandidates?: string[];
|
|
38
|
+
readonly registerContractsProfile?: 'mon3';
|
|
39
|
+
/** @deprecated Use registerContractsProfile. */
|
|
36
40
|
readonly registerCareProfile?: 'mon3';
|
|
41
|
+
readonly registerContractsInterfaces?: string[];
|
|
42
|
+
/** @deprecated Use registerContractsInterfaces. */
|
|
37
43
|
readonly registerCareInterfaces?: string[];
|
|
38
44
|
readonly skipAssembly?: boolean;
|
|
39
45
|
}
|