@jhlagado/azm 0.2.7 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/README.md +170 -69
  2. package/dist/src/api-artifacts.d.ts +20 -0
  3. package/dist/src/api-artifacts.js +165 -0
  4. package/dist/src/api-compile.d.ts +8 -2
  5. package/dist/src/api-compile.js +31 -230
  6. package/dist/src/api-register-contracts.d.ts +9 -0
  7. package/dist/src/api-register-contracts.js +77 -0
  8. package/dist/src/api-tooling.d.ts +2 -2
  9. package/dist/src/api-tooling.js +1 -1
  10. package/dist/src/assembly/address-planning.d.ts +1 -2
  11. package/dist/src/assembly/address-planning.js +119 -218
  12. package/dist/src/assembly/address-symbols.d.ts +12 -0
  13. package/dist/src/assembly/address-symbols.js +118 -0
  14. package/dist/src/assembly/fixup-emission.js +30 -48
  15. package/dist/src/assembly/program-emission.js +163 -164
  16. package/dist/src/cli/artifact-files.d.ts +15 -0
  17. package/dist/src/cli/artifact-files.js +86 -0
  18. package/dist/src/cli/parse-args.d.ts +6 -5
  19. package/dist/src/cli/parse-args.js +162 -136
  20. package/dist/src/cli/run.js +4 -1
  21. package/dist/src/cli/usage.d.ts +1 -0
  22. package/dist/src/cli/usage.js +33 -0
  23. package/dist/src/cli/write-artifacts.js +18 -91
  24. package/dist/src/core/compile.js +51 -274
  25. package/dist/src/core/conditional-assembly.d.ts +6 -0
  26. package/dist/src/core/conditional-assembly.js +181 -0
  27. package/dist/src/expansion/op-constant-expression.d.ts +3 -0
  28. package/dist/src/expansion/op-constant-expression.js +52 -0
  29. package/dist/src/expansion/op-expand-selected.d.ts +5 -0
  30. package/dist/src/expansion/op-expand-selected.js +143 -0
  31. package/dist/src/expansion/op-expansion.d.ts +5 -53
  32. package/dist/src/expansion/op-expansion.js +85 -815
  33. package/dist/src/expansion/op-instruction-instantiation.d.ts +3 -0
  34. package/dist/src/expansion/op-instruction-instantiation.js +194 -0
  35. package/dist/src/expansion/op-local-labels.d.ts +8 -0
  36. package/dist/src/expansion/op-local-labels.js +166 -0
  37. package/dist/src/expansion/op-operand-splitting.d.ts +1 -0
  38. package/dist/src/expansion/op-operand-splitting.js +44 -0
  39. package/dist/src/expansion/op-operands.d.ts +53 -0
  40. package/dist/src/expansion/op-operands.js +66 -0
  41. package/dist/src/expansion/op-selection.d.ts +18 -0
  42. package/dist/src/expansion/op-selection.js +172 -0
  43. package/dist/src/index.d.ts +2 -1
  44. package/dist/src/index.js +1 -1
  45. package/dist/src/model/diagnostic.d.ts +4 -0
  46. package/dist/src/model/diagnostic.js +4 -0
  47. package/dist/src/outputs/asm80-expression-evaluation.d.ts +10 -0
  48. package/dist/src/outputs/asm80-expression-evaluation.js +75 -0
  49. package/dist/src/outputs/asm80-expressions.d.ts +5 -0
  50. package/dist/src/outputs/asm80-expressions.js +47 -0
  51. package/dist/src/outputs/asm80-instruction-operands.d.ts +16 -0
  52. package/dist/src/outputs/asm80-instruction-operands.js +38 -0
  53. package/dist/src/outputs/asm80-instructions.d.ts +5 -0
  54. package/dist/src/outputs/asm80-instructions.js +272 -0
  55. package/dist/src/outputs/asm80-ld-operands.d.ts +10 -0
  56. package/dist/src/outputs/asm80-ld-operands.js +157 -0
  57. package/dist/src/outputs/asm80-strings.d.ts +4 -0
  58. package/dist/src/outputs/asm80-strings.js +14 -0
  59. package/dist/src/outputs/d8-files.d.ts +10 -0
  60. package/dist/src/outputs/d8-files.js +103 -0
  61. package/dist/src/outputs/d8-helpers.d.ts +21 -0
  62. package/dist/src/outputs/d8-helpers.js +136 -0
  63. package/dist/src/outputs/hex.js +26 -18
  64. package/dist/src/outputs/types.d.ts +16 -10
  65. package/dist/src/outputs/write-asm80.js +68 -597
  66. package/dist/src/outputs/write-d8.js +6 -216
  67. package/dist/src/register-contracts/accept-output.d.ts +2 -0
  68. package/dist/src/register-contracts/analyze-helpers.d.ts +29 -0
  69. package/dist/src/register-contracts/analyze-helpers.js +162 -0
  70. package/dist/src/{register-care → register-contracts}/analyze.d.ts +6 -6
  71. package/dist/src/register-contracts/analyze.js +73 -0
  72. package/dist/src/register-contracts/annotate.d.ts +11 -0
  73. package/dist/src/{register-care → register-contracts}/annotate.js +3 -3
  74. package/dist/src/register-contracts/annotations.d.ts +8 -0
  75. package/dist/src/{register-care → register-contracts}/annotations.js +3 -3
  76. package/dist/src/register-contracts/boundaryHints.d.ts +3 -0
  77. package/dist/src/register-contracts/boundaryHints.js +24 -0
  78. package/dist/src/register-contracts/carriers.d.ts +2 -0
  79. package/dist/src/register-contracts/constants.d.ts +4 -0
  80. package/dist/src/register-contracts/constants.js +51 -0
  81. package/dist/src/register-contracts/controlFlow.d.ts +5 -0
  82. package/dist/src/register-contracts/controlFlow.js +55 -0
  83. package/dist/src/register-contracts/fix.d.ts +11 -0
  84. package/dist/src/{register-care → register-contracts}/fix.js +47 -30
  85. package/dist/src/register-contracts/instruction-head.d.ts +2 -0
  86. package/dist/src/register-contracts/instruction-head.js +3 -0
  87. package/dist/src/register-contracts/instruction-operands.d.ts +3 -0
  88. package/dist/src/register-contracts/instruction-operands.js +101 -0
  89. package/dist/src/register-contracts/instruction-predicates.d.ts +6 -0
  90. package/dist/src/register-contracts/instruction-predicates.js +44 -0
  91. package/dist/src/register-contracts/interfaceContracts.d.ts +2 -0
  92. package/dist/src/register-contracts/interfaceContracts.js +68 -0
  93. package/dist/src/register-contracts/liveness.d.ts +3 -0
  94. package/dist/src/{register-care → register-contracts}/liveness.js +111 -79
  95. package/dist/src/register-contracts/operand-register-name.d.ts +2 -0
  96. package/dist/src/register-contracts/operand-register-name.js +13 -0
  97. package/dist/src/{register-care → register-contracts}/profiles.d.ts +5 -5
  98. package/dist/src/{register-care → register-contracts}/profiles.js +2 -2
  99. package/dist/src/register-contracts/programModel-boundaries.d.ts +6 -0
  100. package/dist/src/register-contracts/programModel-boundaries.js +64 -0
  101. package/dist/src/register-contracts/programModel-routines.d.ts +7 -0
  102. package/dist/src/register-contracts/programModel-routines.js +128 -0
  103. package/dist/src/register-contracts/programModel.d.ts +3 -0
  104. package/dist/src/register-contracts/programModel.js +14 -0
  105. package/dist/src/register-contracts/report.d.ts +5 -0
  106. package/dist/src/{register-care → register-contracts}/report.js +34 -17
  107. package/dist/src/register-contracts/routine-summaries.d.ts +6 -0
  108. package/dist/src/{register-care → register-contracts}/routine-summaries.js +11 -1
  109. package/dist/src/register-contracts/smartCommentBlocks.d.ts +5 -0
  110. package/dist/src/register-contracts/smartCommentBlocks.js +30 -0
  111. package/dist/src/register-contracts/smartCommentParsing.d.ts +3 -0
  112. package/dist/src/register-contracts/smartCommentParsing.js +80 -0
  113. package/dist/src/register-contracts/smartComments.d.ts +5 -0
  114. package/dist/src/register-contracts/smartComments.js +92 -0
  115. package/dist/src/register-contracts/summaries.d.ts +12 -0
  116. package/dist/src/{register-care → register-contracts}/summaries.js +7 -7
  117. package/dist/src/register-contracts/summary-boundary.d.ts +2 -0
  118. package/dist/src/register-contracts/summary-boundary.js +40 -0
  119. package/dist/src/register-contracts/summary-contract.d.ts +2 -0
  120. package/dist/src/register-contracts/summary-contract.js +45 -0
  121. package/dist/src/register-contracts/summary-result.d.ts +7 -0
  122. package/dist/src/register-contracts/summary-result.js +122 -0
  123. package/dist/src/register-contracts/summary-state.d.ts +23 -0
  124. package/dist/src/register-contracts/summary-state.js +88 -0
  125. package/dist/src/register-contracts/summary-token-transfer.d.ts +3 -0
  126. package/dist/src/register-contracts/summary-token-transfer.js +67 -0
  127. package/dist/src/register-contracts/summary.d.ts +3 -0
  128. package/dist/src/register-contracts/summary.js +266 -0
  129. package/dist/src/register-contracts/tooling.d.ts +57 -0
  130. package/dist/src/{register-care → register-contracts}/tooling.js +8 -6
  131. package/dist/src/register-contracts/types.d.ts +188 -0
  132. package/dist/src/semantics/binary-operators.d.ts +2 -0
  133. package/dist/src/semantics/binary-operators.js +15 -0
  134. package/dist/src/semantics/byte-functions.d.ts +2 -0
  135. package/dist/src/semantics/byte-functions.js +7 -0
  136. package/dist/src/semantics/constant-operator-types.d.ts +10 -0
  137. package/dist/src/semantics/constant-operator-types.js +1 -0
  138. package/dist/src/semantics/constant-operators.d.ts +3 -0
  139. package/dist/src/semantics/constant-operators.js +3 -0
  140. package/dist/src/semantics/diagnostics.d.ts +3 -0
  141. package/dist/src/semantics/diagnostics.js +10 -0
  142. package/dist/src/semantics/expression-evaluation.d.ts +11 -19
  143. package/dist/src/semantics/expression-evaluation.js +22 -334
  144. package/dist/src/semantics/layout-evaluation.d.ts +23 -0
  145. package/dist/src/semantics/layout-evaluation.js +202 -0
  146. package/dist/src/semantics/layout-format.d.ts +5 -0
  147. package/dist/src/semantics/layout-format.js +31 -0
  148. package/dist/src/semantics/layout-path.d.ts +24 -0
  149. package/dist/src/semantics/layout-path.js +58 -0
  150. package/dist/src/semantics/unary-operators.d.ts +2 -0
  151. package/dist/src/semantics/unary-operators.js +8 -0
  152. package/dist/src/source/line-comment-scanner.d.ts +1 -0
  153. package/dist/src/source/line-comment-scanner.js +51 -0
  154. package/dist/src/source/strip-line-comment.js +8 -44
  155. package/dist/src/syntax/directive-aliases.js +36 -22
  156. package/dist/src/syntax/expression-tokenizer.d.ts +30 -0
  157. package/dist/src/syntax/expression-tokenizer.js +310 -0
  158. package/dist/src/syntax/parse-directive-statement.d.ts +14 -0
  159. package/dist/src/syntax/parse-directive-statement.js +307 -0
  160. package/dist/src/syntax/parse-expression.d.ts +2 -2
  161. package/dist/src/syntax/parse-expression.js +7 -568
  162. package/dist/src/syntax/parse-layout-declarations.d.ts +9 -0
  163. package/dist/src/syntax/parse-layout-declarations.js +180 -0
  164. package/dist/src/syntax/parse-layout-expression.d.ts +5 -0
  165. package/dist/src/syntax/parse-layout-expression.js +175 -0
  166. package/dist/src/syntax/parse-line.js +4 -272
  167. package/dist/src/syntax/parse-token-expression.d.ts +3 -0
  168. package/dist/src/syntax/parse-token-expression.js +133 -0
  169. package/dist/src/tooling/case-style.js +47 -30
  170. package/dist/src/z80/effect-groups.d.ts +38 -0
  171. package/dist/src/z80/effect-groups.js +265 -0
  172. package/dist/src/z80/effect-units.d.ts +18 -0
  173. package/dist/src/z80/effect-units.js +165 -0
  174. package/dist/src/z80/effects.d.ts +1 -1
  175. package/dist/src/z80/effects.js +94 -557
  176. package/dist/src/z80/encode-core.d.ts +2 -0
  177. package/dist/src/z80/encode-core.js +42 -0
  178. package/dist/src/z80/encode-ld-helpers.d.ts +25 -0
  179. package/dist/src/z80/encode-ld-helpers.js +172 -0
  180. package/dist/src/z80/encode-ld.d.ts +2 -0
  181. package/dist/src/z80/encode-ld.js +285 -0
  182. package/dist/src/z80/encode.js +190 -542
  183. package/dist/src/z80/ld-support.d.ts +3 -0
  184. package/dist/src/z80/ld-support.js +146 -0
  185. package/dist/src/z80/operand-split-state.d.ts +8 -0
  186. package/dist/src/z80/operand-split-state.js +46 -0
  187. package/dist/src/z80/operand-split.d.ts +1 -0
  188. package/dist/src/z80/operand-split.js +13 -0
  189. package/dist/src/z80/parse-basic.d.ts +4 -0
  190. package/dist/src/z80/parse-basic.js +39 -0
  191. package/dist/src/z80/parse-branch.d.ts +4 -0
  192. package/dist/src/z80/parse-branch.js +218 -0
  193. package/dist/src/z80/parse-conditions.d.ts +6 -0
  194. package/dist/src/z80/parse-conditions.js +10 -0
  195. package/dist/src/z80/parse-exchange.d.ts +2 -0
  196. package/dist/src/z80/parse-exchange.js +30 -0
  197. package/dist/src/z80/parse-instruction.js +224 -1010
  198. package/dist/src/z80/parse-io-control.d.ts +5 -0
  199. package/dist/src/z80/parse-io-control.js +108 -0
  200. package/dist/src/z80/parse-ld.d.ts +2 -0
  201. package/dist/src/z80/parse-ld.js +83 -0
  202. package/dist/src/z80/parse-operands.d.ts +41 -0
  203. package/dist/src/z80/parse-operands.js +259 -0
  204. package/docs/reference/cli.md +42 -35
  205. package/docs/reference/tooling-api.md +20 -16
  206. package/package.json +1 -1
  207. package/dist/src/register-care/accept-output.d.ts +0 -2
  208. package/dist/src/register-care/analyze.js +0 -166
  209. package/dist/src/register-care/annotate.d.ts +0 -11
  210. package/dist/src/register-care/annotations.d.ts +0 -8
  211. package/dist/src/register-care/boundaryHints.d.ts +0 -3
  212. package/dist/src/register-care/boundaryHints.js +0 -80
  213. package/dist/src/register-care/carriers.d.ts +0 -2
  214. package/dist/src/register-care/controlFlow.d.ts +0 -5
  215. package/dist/src/register-care/controlFlow.js +0 -38
  216. package/dist/src/register-care/fix.d.ts +0 -11
  217. package/dist/src/register-care/instruction-shape.d.ts +0 -11
  218. package/dist/src/register-care/instruction-shape.js +0 -129
  219. package/dist/src/register-care/liveness.d.ts +0 -3
  220. package/dist/src/register-care/programModel.d.ts +0 -3
  221. package/dist/src/register-care/programModel.js +0 -266
  222. package/dist/src/register-care/report.d.ts +0 -5
  223. package/dist/src/register-care/routine-summaries.d.ts +0 -6
  224. package/dist/src/register-care/smartComments.d.ts +0 -5
  225. package/dist/src/register-care/smartComments.js +0 -243
  226. package/dist/src/register-care/summaries.d.ts +0 -12
  227. package/dist/src/register-care/summary.d.ts +0 -3
  228. package/dist/src/register-care/summary.js +0 -474
  229. package/dist/src/register-care/tooling.d.ts +0 -43
  230. package/dist/src/register-care/types.d.ts +0 -172
  231. /package/dist/src/{register-care → register-contracts}/accept-output.js +0 -0
  232. /package/dist/src/{register-care → register-contracts}/carriers.js +0 -0
  233. /package/dist/src/{register-care → register-contracts}/sourceText.d.ts +0 -0
  234. /package/dist/src/{register-care → register-contracts}/sourceText.js +0 -0
  235. /package/dist/src/{register-care → register-contracts}/types.js +0 -0
@@ -2,6 +2,24 @@ import { diagnostic, evaluateExpression, lookupEquateRecord, } from '../semantic
2
2
  import { emitAbs16Expression, emitInstruction, patchFixups, } from './fixup-emission.js';
3
3
  import { absoluteCodeAddress, absoluteDataAddress, advanceCodePlacement, advancePlacement, applyOrg, computeResolvedBases, createPlacementState, placementAddress, placementForOrg, } from './placement.js';
4
4
  import { alignmentPadding, stringDirectiveBytes, } from './address-planning.js';
5
+ const EMIT_ITEM_HANDLERS = {
6
+ org: (context, item, items, itemIndex) => emitOrg(context, items, itemIndex, item),
7
+ comment: () => undefined,
8
+ equ: () => undefined,
9
+ label: () => undefined,
10
+ enum: () => undefined,
11
+ type: () => undefined,
12
+ 'type-alias': () => undefined,
13
+ db: (context, item) => emitDb(context, item),
14
+ dw: (context, item) => emitDw(context, item),
15
+ ds: (context, item) => emitDs(context, item),
16
+ align: (context, item) => emitAlign(context, item),
17
+ end: () => true,
18
+ binfrom: (context, item) => emitBinRangeControl(context, item),
19
+ binto: (context, item) => emitBinRangeControl(context, item),
20
+ 'string-data': (context, item) => emitStringData(context, item),
21
+ instruction: (context, item) => emitProgramInstruction(context, item),
22
+ };
5
23
  function toByte(value) {
6
24
  return value & 0xff;
7
25
  }
@@ -91,178 +109,159 @@ function emitDbValue(value, emitAddress, itemSpan, labels, equates, layouts, dia
91
109
  }
92
110
  }
93
111
  export function emitProgramImage(items, addressState, symbols, diagnostics) {
94
- const { labels, equates, layouts, origin } = addressState;
95
- const image = new Map();
96
- const initializedAddresses = new Set();
97
- const reservedAddresses = new Set();
98
- const sourceSegments = [];
99
- const placement = createPlacementState();
112
+ const context = createEmitContext(addressState, symbols, diagnostics);
100
113
  let ended = false;
101
- let binFrom;
102
- let binTo;
103
114
  for (let itemIndex = 0; itemIndex < items.length; itemIndex += 1) {
104
115
  const item = items[itemIndex];
105
- if (ended && item.kind !== 'binfrom' && item.kind !== 'binto') {
116
+ if (shouldSkipAfterEnd(ended, item)) {
106
117
  continue;
107
118
  }
108
- switch (item.kind) {
109
- case 'org': {
110
- placement.activePlacement = placementForOrg(items, itemIndex);
111
- const value = evaluateExpression(item.expression, labels, equates, item.span, diagnostics, {
112
- currentLocation: placementAddress(placement),
113
- layouts,
114
- });
115
- if (value !== undefined) {
116
- applyOrg(placement, value);
117
- }
118
- break;
119
- }
120
- case 'comment':
121
- case 'equ':
122
- case 'label':
123
- case 'enum':
124
- case 'type':
125
- break;
126
- case 'db':
127
- {
128
- const segmentStart = activePlacementAddress(placement);
129
- for (const value of item.values) {
130
- emitDbValue(value, activePlacementAddress(placement), item.span, labels, equates, layouts, diagnostics, image, initializedAddresses, placement);
131
- }
132
- void segmentStart;
133
- }
134
- break;
135
- case 'dw':
136
- {
137
- const segmentStart = activePlacementAddress(placement);
138
- for (const expression of item.values) {
139
- const emitAddress = activePlacementAddress(placement);
140
- const bytes = [];
141
- const fixups = [];
142
- if (emitAbs16Expression(expression, item.span, emitAddress, labels, equates, diagnostics, bytes, fixups, layouts)) {
143
- patchFixups(fixups, symbols, bytes, diagnostics);
144
- writeImageBytes(image, initializedAddresses, emitAddress, bytes);
145
- advancePlacement(placement, 2);
146
- }
147
- }
148
- void segmentStart;
149
- }
150
- break;
151
- case 'ds': {
152
- const emitAddress = activePlacementAddress(placement);
153
- const size = evaluateExpression(item.size, labels, equates, item.span, diagnostics, {
154
- currentLocation: emitAddress,
155
- layouts,
156
- });
157
- if (size !== undefined) {
158
- const fill = item.fill === undefined
159
- ? undefined
160
- : evaluateExpression(item.fill, labels, equates, item.span, diagnostics, {
161
- currentLocation: emitAddress,
162
- layouts,
163
- });
164
- if (item.fill === undefined || fill !== undefined) {
165
- if (fill !== undefined) {
166
- for (let index = 0; index < size; index += 1) {
167
- writeImageByte(image, initializedAddresses, emitAddress + index, fill);
168
- }
169
- }
170
- else {
171
- for (let index = 0; index < size; index += 1) {
172
- reservedAddresses.add(emitAddress + index);
173
- }
174
- }
175
- advancePlacement(placement, size);
176
- }
177
- }
178
- break;
179
- }
180
- case 'align': {
181
- const emitAddress = activePlacementAddress(placement);
182
- const alignment = evaluateExpression(item.alignment, labels, equates, item.span, diagnostics, {
183
- currentLocation: emitAddress,
184
- layouts,
185
- });
186
- if (alignment !== undefined) {
187
- if (alignment <= 0) {
188
- diagnostics.push(diagnostic(item.span, `.align value must be positive: ${alignment}.`));
189
- }
190
- else {
191
- const padding = alignmentPadding(emitAddress, alignment);
192
- for (let index = 0; index < padding; index += 1) {
193
- writeImageByte(image, initializedAddresses, emitAddress + index, 0);
194
- }
195
- advancePlacement(placement, padding);
196
- addSourceSegment(sourceSegments, item.span, emitAddress, emitAddress + padding, 'directive');
197
- }
198
- }
199
- break;
200
- }
201
- case 'end':
202
- ended = true;
203
- break;
204
- case 'binfrom': {
205
- const value = evaluateExpression(item.expression, labels, equates, item.span, diagnostics, {
206
- currentLocation: placementAddress(placement),
207
- layouts,
208
- });
209
- if (value !== undefined) {
210
- binFrom = value;
211
- }
212
- break;
213
- }
214
- case 'binto': {
215
- const value = evaluateExpression(item.expression, labels, equates, item.span, diagnostics, {
216
- currentLocation: placementAddress(placement),
217
- layouts,
218
- });
219
- if (value !== undefined) {
220
- binTo = value;
221
- }
222
- break;
223
- }
224
- case 'string-data':
225
- {
226
- const segmentStart = activePlacementAddress(placement);
227
- for (const value of stringDirectiveBytes(item.directive, item.value)) {
228
- const stringEmitAddress = activePlacementAddress(placement);
229
- writeImageByte(image, initializedAddresses, stringEmitAddress, value);
230
- advancePlacement(placement, 1);
231
- }
232
- void segmentStart;
233
- }
234
- break;
235
- case 'instruction': {
236
- const bases = computeResolvedBases(placement);
237
- const codeAddress = absoluteCodeAddress(placement, bases);
238
- const bytes = [];
239
- const fixups = [];
240
- const size = emitInstruction(item.instruction, item.span, codeAddress, labels, equates, diagnostics, bytes, fixups, layouts);
241
- patchFixups(fixups, symbols, bytes, diagnostics);
242
- writeImageBytes(image, initializedAddresses, codeAddress, bytes);
243
- advanceCodePlacement(placement, size);
244
- addSourceSegment(sourceSegments, item.emittedSource?.span ?? item.span, codeAddress, codeAddress + size, item.emittedSource?.kind ?? 'code');
245
- if (placement.activePlacement === 'data') {
246
- const dataAddress = absoluteDataAddress(placement, bases);
247
- writeImageBytes(image, initializedAddresses, dataAddress, bytes);
248
- advancePlacement(placement, size);
249
- }
250
- break;
251
- }
252
- }
119
+ ended = EMIT_ITEM_HANDLERS[item.kind](context, item, items, itemIndex) === true || ended;
253
120
  }
254
- const range = outputRange(initializedAddresses, reservedAddresses, origin, binFrom, binTo);
255
- const bytes = flattenImage(image, range.start, range.end);
256
- const initializedAddressList = [...initializedAddresses].sort((a, b) => a - b);
257
- const reservedAddressList = [...reservedAddresses].sort((a, b) => a - b);
121
+ return emittedProgramFromContext(context, addressState.origin, diagnostics);
122
+ }
123
+ function shouldSkipAfterEnd(ended, item) {
124
+ return ended && item.kind !== 'binfrom' && item.kind !== 'binto';
125
+ }
126
+ function emittedProgramFromContext(context, defaultOrigin, diagnostics) {
127
+ const range = outputRange(context.initializedAddresses, context.reservedAddresses, defaultOrigin, context.binFrom, context.binTo);
128
+ const bytes = flattenImage(context.image, range.start, range.end);
258
129
  return {
259
130
  origin: range.start,
260
- initializedAddresses: initializedAddressList,
261
- reservedAddresses: reservedAddressList,
262
- sourceSegments: sourceSegments
263
- .map((segment) => clipSourceSegment(segment, range.start, range.end))
264
- .filter((segment) => segment !== undefined)
265
- .sort((a, b) => a.start - b.start || a.end - b.end),
131
+ initializedAddresses: sortedAddresses(context.initializedAddresses),
132
+ reservedAddresses: sortedAddresses(context.reservedAddresses),
133
+ sourceSegments: clippedSourceSegments(context.sourceSegments, range.start, range.end),
266
134
  bytes: diagnostics.length > 0 ? new Uint8Array() : bytes,
267
135
  };
268
136
  }
137
+ function sortedAddresses(addresses) {
138
+ return [...addresses].sort((a, b) => a - b);
139
+ }
140
+ function clippedSourceSegments(sourceSegments, start, end) {
141
+ return sourceSegments
142
+ .map((segment) => clipSourceSegment(segment, start, end))
143
+ .filter((segment) => segment !== undefined)
144
+ .sort((a, b) => a.start - b.start || a.end - b.end);
145
+ }
146
+ function createEmitContext(addressState, symbols, diagnostics) {
147
+ return {
148
+ labels: addressState.labels,
149
+ equates: addressState.equates,
150
+ layouts: addressState.layouts,
151
+ symbols,
152
+ diagnostics,
153
+ image: new Map(),
154
+ initializedAddresses: new Set(),
155
+ reservedAddresses: new Set(),
156
+ sourceSegments: [],
157
+ placement: createPlacementState(),
158
+ binFrom: undefined,
159
+ binTo: undefined,
160
+ };
161
+ }
162
+ function emitOrg(context, items, itemIndex, item) {
163
+ context.placement.activePlacement = placementForOrg(items, itemIndex);
164
+ const value = evaluateEmitExpression(context, item.expression, item.span, placementAddress(context.placement));
165
+ if (value !== undefined) {
166
+ applyOrg(context.placement, value);
167
+ }
168
+ }
169
+ function emitDb(context, item) {
170
+ for (const value of item.values) {
171
+ emitDbValue(value, activePlacementAddress(context.placement), item.span, context.labels, context.equates, context.layouts, context.diagnostics, context.image, context.initializedAddresses, context.placement);
172
+ }
173
+ }
174
+ function emitDw(context, item) {
175
+ for (const expression of item.values) {
176
+ const emitAddress = activePlacementAddress(context.placement);
177
+ const bytes = [];
178
+ const fixups = [];
179
+ if (emitAbs16Expression(expression, item.span, emitAddress, context.labels, context.equates, context.diagnostics, bytes, fixups, context.layouts)) {
180
+ patchFixups(fixups, context.symbols, bytes, context.diagnostics);
181
+ writeImageBytes(context.image, context.initializedAddresses, emitAddress, bytes);
182
+ advancePlacement(context.placement, 2);
183
+ }
184
+ }
185
+ }
186
+ function emitDs(context, item) {
187
+ const emitAddress = activePlacementAddress(context.placement);
188
+ const size = evaluateEmitExpression(context, item.size, item.span, emitAddress);
189
+ if (size === undefined) {
190
+ return;
191
+ }
192
+ const fill = item.fill === undefined
193
+ ? undefined
194
+ : evaluateEmitExpression(context, item.fill, item.span, emitAddress);
195
+ if (item.fill !== undefined && fill === undefined) {
196
+ return;
197
+ }
198
+ if (fill !== undefined) {
199
+ for (let index = 0; index < size; index += 1) {
200
+ writeImageByte(context.image, context.initializedAddresses, emitAddress + index, fill);
201
+ }
202
+ }
203
+ else {
204
+ for (let index = 0; index < size; index += 1) {
205
+ context.reservedAddresses.add(emitAddress + index);
206
+ }
207
+ }
208
+ advancePlacement(context.placement, size);
209
+ }
210
+ function emitAlign(context, item) {
211
+ const emitAddress = activePlacementAddress(context.placement);
212
+ const alignment = evaluateEmitExpression(context, item.alignment, item.span, emitAddress);
213
+ if (alignment === undefined) {
214
+ return;
215
+ }
216
+ if (alignment <= 0) {
217
+ context.diagnostics.push(diagnostic(item.span, `.align value must be positive: ${alignment}.`));
218
+ return;
219
+ }
220
+ const padding = alignmentPadding(emitAddress, alignment);
221
+ for (let index = 0; index < padding; index += 1) {
222
+ writeImageByte(context.image, context.initializedAddresses, emitAddress + index, 0);
223
+ }
224
+ advancePlacement(context.placement, padding);
225
+ addSourceSegment(context.sourceSegments, item.span, emitAddress, emitAddress + padding, 'directive');
226
+ }
227
+ function emitBinRangeControl(context, item) {
228
+ const value = evaluateEmitExpression(context, item.expression, item.span, placementAddress(context.placement));
229
+ if (value === undefined) {
230
+ return;
231
+ }
232
+ if (item.kind === 'binfrom') {
233
+ context.binFrom = value;
234
+ }
235
+ else {
236
+ context.binTo = value;
237
+ }
238
+ }
239
+ function emitStringData(context, item) {
240
+ for (const value of stringDirectiveBytes(item.directive, item.value)) {
241
+ const stringEmitAddress = activePlacementAddress(context.placement);
242
+ writeImageByte(context.image, context.initializedAddresses, stringEmitAddress, value);
243
+ advancePlacement(context.placement, 1);
244
+ }
245
+ }
246
+ function emitProgramInstruction(context, item) {
247
+ const bases = computeResolvedBases(context.placement);
248
+ const codeAddress = absoluteCodeAddress(context.placement, bases);
249
+ const bytes = [];
250
+ const fixups = [];
251
+ const size = emitInstruction(item.instruction, item.span, codeAddress, context.labels, context.equates, context.diagnostics, bytes, fixups, context.layouts);
252
+ patchFixups(fixups, context.symbols, bytes, context.diagnostics);
253
+ writeImageBytes(context.image, context.initializedAddresses, codeAddress, bytes);
254
+ advanceCodePlacement(context.placement, size);
255
+ addSourceSegment(context.sourceSegments, item.emittedSource?.span ?? item.span, codeAddress, codeAddress + size, item.emittedSource?.kind ?? 'code');
256
+ if (context.placement.activePlacement === 'data') {
257
+ const dataAddress = absoluteDataAddress(context.placement, bases);
258
+ writeImageBytes(context.image, context.initializedAddresses, dataAddress, bytes);
259
+ advancePlacement(context.placement, size);
260
+ }
261
+ }
262
+ function evaluateEmitExpression(context, expression, span, currentLocation) {
263
+ return evaluateExpression(expression, context.labels, context.equates, span, context.diagnostics, {
264
+ currentLocation,
265
+ layouts: context.layouts,
266
+ });
267
+ }
@@ -0,0 +1,15 @@
1
+ import type { Artifact } from '../outputs/types.js';
2
+ interface ArtifactPaths {
3
+ readonly hex: string;
4
+ readonly bin: string;
5
+ readonly d8m: string;
6
+ readonly asm80: string;
7
+ readonly registerContractsReport: string;
8
+ readonly registerContractsInterface: string;
9
+ }
10
+ interface ArtifactWriteResult {
11
+ readonly primaryPath?: string;
12
+ readonly registerContractsPath?: string;
13
+ }
14
+ export declare function writeArtifactFiles(artifacts: readonly Artifact[], paths: ArtifactPaths, outputType: 'hex' | 'bin'): Promise<ArtifactWriteResult>;
15
+ export {};
@@ -0,0 +1,86 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+ function artifactByKind(artifacts) {
4
+ const byKind = new Map();
5
+ for (const artifact of artifacts) {
6
+ byKind.set(artifact.kind, artifact);
7
+ }
8
+ return byKind;
9
+ }
10
+ async function ensureDir(path) {
11
+ await mkdir(dirname(path), { recursive: true });
12
+ }
13
+ async function writeTextArtifact(path, text) {
14
+ await ensureDir(path);
15
+ await writeFile(path, text, 'utf8');
16
+ }
17
+ async function writeBinArtifact(path, bytes) {
18
+ await ensureDir(path);
19
+ await writeFile(path, Buffer.from(bytes));
20
+ }
21
+ function queuePrimaryArtifacts(writes, byKind, paths, outputType) {
22
+ let primaryPath;
23
+ const bin = byKind.get('bin');
24
+ if (bin?.kind === 'bin') {
25
+ writes.push(writeBinArtifact(paths.bin, bin.bytes));
26
+ if (outputType === 'bin')
27
+ primaryPath = paths.bin;
28
+ }
29
+ const hex = byKind.get('hex');
30
+ if (hex?.kind === 'hex') {
31
+ writes.push(writeTextArtifact(paths.hex, hex.text));
32
+ if (outputType === 'hex')
33
+ primaryPath = paths.hex;
34
+ }
35
+ return primaryPath;
36
+ }
37
+ function queueDebugArtifacts(writes, byKind, paths) {
38
+ const d8m = byKind.get('d8m');
39
+ if (d8m?.kind === 'd8m') {
40
+ const text = JSON.stringify(d8m.json, null, 2);
41
+ writes.push(writeTextArtifact(paths.d8m, `${text}\n`));
42
+ }
43
+ const asm80 = byKind.get('asm80');
44
+ if (asm80?.kind === 'asm80') {
45
+ writes.push(writeTextArtifact(paths.asm80, asm80.text));
46
+ }
47
+ }
48
+ function queueRegisterContractsArtifacts(writes, byKind, paths) {
49
+ let registerContractsPath;
50
+ const report = byKind.get('register-contracts-report');
51
+ if (report?.kind === 'register-contracts-report') {
52
+ writes.push(writeTextArtifact(paths.registerContractsReport, report.text));
53
+ registerContractsPath = paths.registerContractsReport;
54
+ }
55
+ const iface = byKind.get('register-contracts-interface');
56
+ if (iface?.kind === 'register-contracts-interface') {
57
+ writes.push(writeTextArtifact(paths.registerContractsInterface, iface.text));
58
+ registerContractsPath ??= paths.registerContractsInterface;
59
+ }
60
+ return registerContractsPath;
61
+ }
62
+ function queueRegisterContractsAnnotationArtifacts(writes, byKind) {
63
+ const annotations = byKind.get('register-contracts-annotations');
64
+ if (annotations?.kind !== 'register-contracts-annotations')
65
+ return undefined;
66
+ let firstAnnotationPath;
67
+ for (const item of annotations.files) {
68
+ writes.push(writeTextArtifact(item.path, item.text));
69
+ firstAnnotationPath ??= item.path;
70
+ }
71
+ return firstAnnotationPath;
72
+ }
73
+ export async function writeArtifactFiles(artifacts, paths, outputType) {
74
+ const byKind = artifactByKind(artifacts);
75
+ const writes = [];
76
+ const primaryPath = queuePrimaryArtifacts(writes, byKind, paths, outputType);
77
+ queueDebugArtifacts(writes, byKind, paths);
78
+ const registerContractsPath = queueRegisterContractsArtifacts(writes, byKind, paths);
79
+ const annotationPrimaryPath = queueRegisterContractsAnnotationArtifacts(writes, byKind);
80
+ await Promise.all(writes);
81
+ const selectedPrimaryPath = primaryPath ?? annotationPrimaryPath;
82
+ return {
83
+ ...(selectedPrimaryPath ? { primaryPath: selectedPrimaryPath } : {}),
84
+ ...(registerContractsPath ? { registerContractsPath } : {}),
85
+ };
86
+ }
@@ -1,5 +1,6 @@
1
- import type { RegisterCareMode } from '../register-care/types.js';
1
+ import type { RegisterContractsMode } from '../register-contracts/types.js';
2
2
  import type { CaseStyleMode } from '../tooling/case-style.js';
3
+ import { cliUsage } from './usage.js';
3
4
  export type CliExit = {
4
5
  code: number;
5
6
  };
@@ -13,16 +14,16 @@ export type CliOptions = {
13
14
  emitD8m: boolean;
14
15
  emitAsm80: boolean;
15
16
  caseStyle: CaseStyleMode;
16
- registerCare: RegisterCareMode;
17
+ registerContracts: RegisterContractsMode;
17
18
  emitRegisterReport: boolean;
18
19
  emitRegisterInterface: boolean;
19
20
  emitRegisterAnnotations: boolean;
20
21
  fixRegisterContracts: boolean;
21
22
  acceptRegisterOutputCandidates: string[];
22
- registerCareProfile?: 'mon3';
23
- registerCareInterfaces: string[];
23
+ registerContractsProfile?: 'mon3';
24
+ registerContractsInterfaces: string[];
24
25
  includeDirs: string[];
25
26
  directiveAliasFiles: string[];
26
27
  };
27
- export declare function cliUsage(): string;
28
+ export { cliUsage };
28
29
  export declare function parseCliArgs(argv: string[]): CliOptions | CliExit;