@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.
- package/README.md +170 -69
- 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 +31 -230
- 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/fixup-emission.js +30 -48
- 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/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 +68 -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 +128 -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/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 +14 -0
- package/dist/src/syntax/parse-directive-statement.js +307 -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 +180 -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 +4 -272
- 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/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/reference/cli.md +42 -35
- package/docs/reference/tooling-api.md +20 -16
- package/package.json +1 -1
- 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/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/dist/src/api-compile.js
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { dirname, normalize } from 'node:path';
|
|
1
|
+
import { normalize } from 'node:path';
|
|
3
2
|
import { assembleProgram } from './assembly/assemble-program.js';
|
|
3
|
+
import { emitAssemblyArtifacts } from './api-artifacts.js';
|
|
4
|
+
import { runRegisterContracts, shouldAnalyzeRegisterContracts } from './api-register-contracts.js';
|
|
4
5
|
import { analyzeProgramNext, loadProgramNext } from './tooling/api.js';
|
|
5
6
|
import { defaultFormatWriters } from './outputs/index.js';
|
|
6
|
-
import { UnsupportedAsm80LoweringError } from './outputs/write-asm80.js';
|
|
7
7
|
import { writeHex } from './outputs/write-hex.js';
|
|
8
|
-
import {
|
|
9
|
-
import { buildRegisterCareProgramModel } from './register-care/programModel.js';
|
|
10
|
-
import { parseAcceptedOutputCandidates } from './register-care/accept-output.js';
|
|
11
|
-
import { parseInterfaceContracts } from './register-care/smartComments.js';
|
|
8
|
+
import { buildRegisterContractsProgramModel } from './register-contracts/programModel.js';
|
|
12
9
|
function parseUnresolvedSymbolName(message) {
|
|
13
10
|
const match = /^Unresolved symbol "([^"]+)"/.exec(message);
|
|
14
11
|
return match?.[1];
|
|
15
12
|
}
|
|
16
|
-
function
|
|
13
|
+
function isSuppressedUnknownSymbolInRegisterContractsMode(diagnostic, directCalls) {
|
|
17
14
|
if (directCalls === undefined || directCalls.length === 0) {
|
|
18
15
|
return false;
|
|
19
16
|
}
|
|
@@ -33,7 +30,6 @@ function isSuppressedUnknownSymbolInRegisterCareMode(diagnostic, directCalls) {
|
|
|
33
30
|
call.column === diagnostic.column);
|
|
34
31
|
}
|
|
35
32
|
export { writeHex, defaultFormatWriters };
|
|
36
|
-
let cachedPackageVersion;
|
|
37
33
|
/**
|
|
38
34
|
* Compile an AZM/ASM80-style program into in-memory artifacts.
|
|
39
35
|
*/
|
|
@@ -54,219 +50,49 @@ export async function compile(entryFile, options = {}, deps = { formats: default
|
|
|
54
50
|
const analysis = analyzeProgramNext(loaded.loadedProgram, {
|
|
55
51
|
...(options.caseStyle !== undefined ? { caseStyle: options.caseStyle } : {}),
|
|
56
52
|
});
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
options.emitRegisterAnnotations === true ||
|
|
62
|
-
options.fixRegisterContracts === true ||
|
|
63
|
-
(options.acceptRegisterOutputCandidates?.length ?? 0) > 0 ||
|
|
64
|
-
(options.registerCareInterfaces?.length ?? 0) > 0;
|
|
65
|
-
const directCalls = shouldAnalyzeRegisterCare
|
|
66
|
-
? buildRegisterCareProgramModel(loaded.loadedProgram.program.files[0]?.items ?? []).directCalls
|
|
53
|
+
const analyzeRegisterContractsNow = shouldAnalyzeRegisterContracts(options);
|
|
54
|
+
const directCalls = analyzeRegisterContractsNow
|
|
55
|
+
? buildRegisterContractsProgramModel(loaded.loadedProgram.program.files[0]?.items ?? [])
|
|
56
|
+
.directCalls
|
|
67
57
|
: undefined;
|
|
68
|
-
diagnostics.push(...analysis.diagnostics.filter((diagnostic) =>
|
|
69
|
-
? !
|
|
58
|
+
diagnostics.push(...analysis.diagnostics.filter((diagnostic) => analyzeRegisterContractsNow
|
|
59
|
+
? !isSuppressedUnknownSymbolInRegisterContractsMode(diagnostic, directCalls)
|
|
70
60
|
: true));
|
|
71
61
|
const artifacts = [];
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
for (const rawInterface of options.registerCareInterfaces ?? []) {
|
|
77
|
-
const contractPath = normalize(rawInterface);
|
|
78
|
-
if (contractPath.slice(-5).toLowerCase() !== '.asmi') {
|
|
79
|
-
diagnostics.push({
|
|
80
|
-
severity: 'error',
|
|
81
|
-
code: 'AZMN_REGISTER_CARE',
|
|
82
|
-
message: 'Register-care interface files must use the .asmi extension',
|
|
83
|
-
sourceName: contractPath,
|
|
84
|
-
});
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
const interfaceText = await readFile(contractPath, 'utf8');
|
|
88
|
-
for (const contract of parseInterfaceContracts(interfaceText, contractPath).values()) {
|
|
89
|
-
interfaceContracts.push(contract);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
if (hasErrors(diagnostics)) {
|
|
93
|
-
return { diagnostics, artifacts: [] };
|
|
94
|
-
}
|
|
95
|
-
const registerCare = analyzeRegisterCare(loaded.loadedProgram, {
|
|
96
|
-
mode: registerCareMode,
|
|
97
|
-
emitReport: options.emitRegisterReport === true,
|
|
98
|
-
emitInterface: options.emitRegisterInterface === true,
|
|
99
|
-
emitAnnotations: options.emitRegisterAnnotations === true || options.fixRegisterContracts === true,
|
|
100
|
-
fixRegisterContracts: options.fixRegisterContracts === true,
|
|
101
|
-
acceptedOutputCandidates,
|
|
102
|
-
...(options.registerCareProfile !== undefined
|
|
103
|
-
? { registerCareProfile: options.registerCareProfile }
|
|
104
|
-
: {}),
|
|
105
|
-
...(interfaceContracts.length > 0 ? { interfaceContracts } : {}),
|
|
106
|
-
});
|
|
107
|
-
if (registerCare.reportText !== undefined) {
|
|
108
|
-
artifacts.push({ kind: 'register-care-report', text: registerCare.reportText });
|
|
109
|
-
}
|
|
110
|
-
if (registerCare.interfaceText !== undefined) {
|
|
111
|
-
artifacts.push({ kind: 'register-care-interface', text: registerCare.interfaceText });
|
|
112
|
-
}
|
|
113
|
-
if (registerCare.annotations !== undefined && registerCare.annotations.length > 0) {
|
|
114
|
-
const files = registerCare.annotations.map((item) => ({
|
|
115
|
-
path: item.path,
|
|
116
|
-
text: item.text,
|
|
117
|
-
}));
|
|
118
|
-
artifacts.push({ kind: 'register-care-annotations', files });
|
|
119
|
-
}
|
|
120
|
-
diagnostics.push(...registerCare.diagnostics);
|
|
62
|
+
if (analyzeRegisterContractsNow) {
|
|
63
|
+
const registerContracts = await runRegisterContracts(loaded.loadedProgram, options);
|
|
64
|
+
artifacts.push(...registerContracts.artifacts);
|
|
65
|
+
diagnostics.push(...registerContracts.diagnostics);
|
|
121
66
|
if (hasErrors(diagnostics))
|
|
122
|
-
return { diagnostics, artifacts
|
|
67
|
+
return { diagnostics, artifacts };
|
|
123
68
|
}
|
|
124
69
|
if (options.skipAssembly === true) {
|
|
125
70
|
return { diagnostics, artifacts };
|
|
126
71
|
}
|
|
127
72
|
const program = loaded.loadedProgram.program.files[0]?.items ?? [];
|
|
128
73
|
const assembled = assembleProgram(program);
|
|
129
|
-
diagnostics.push(...assembled.diagnostics.filter((diagnostic) =>
|
|
130
|
-
? !
|
|
74
|
+
diagnostics.push(...assembled.diagnostics.filter((diagnostic) => analyzeRegisterContractsNow
|
|
75
|
+
? !isSuppressedUnknownSymbolInRegisterContractsMode(diagnostic, directCalls)
|
|
131
76
|
: true));
|
|
132
77
|
sortDiagnosticsInPlace(diagnostics);
|
|
133
78
|
if (hasErrors(diagnostics)) {
|
|
134
79
|
return { diagnostics, artifacts: [] };
|
|
135
80
|
}
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const main = symbols.find((symbol) => symbol.kind === 'label' && symbol.name.toLowerCase() === 'main');
|
|
150
|
-
const d8mOpts = {
|
|
151
|
-
rootDir: normalize(d8Root),
|
|
152
|
-
packageVersion: await readPackageVersion(),
|
|
153
|
-
inputs: {
|
|
154
|
-
entry: normalizedEntry,
|
|
155
|
-
...(options.d8mInputs?.hex !== undefined ? { hex: options.d8mInputs.hex } : {}),
|
|
156
|
-
...(options.d8mInputs?.bin !== undefined ? { bin: options.d8mInputs.bin } : {}),
|
|
157
|
-
},
|
|
158
|
-
...(main !== undefined ? { entrySymbol: main.name } : {}),
|
|
159
|
-
...(main !== undefined
|
|
160
|
-
? { entryAddress: main.kind === 'constant' ? main.value : main.address }
|
|
161
|
-
: {}),
|
|
162
|
-
};
|
|
163
|
-
artifacts.push(deps.formats.writeD8m(sidecarMap, symbols, d8mOpts));
|
|
164
|
-
}
|
|
165
|
-
if (emit.emitAsm80) {
|
|
166
|
-
if (deps.formats.writeAsm80 !== undefined) {
|
|
167
|
-
try {
|
|
168
|
-
artifacts.push(deps.formats.writeAsm80(program, symbols));
|
|
169
|
-
}
|
|
170
|
-
catch (error) {
|
|
171
|
-
if (error instanceof UnsupportedAsm80LoweringError) {
|
|
172
|
-
diagnostics.push({
|
|
173
|
-
severity: 'error',
|
|
174
|
-
code: 'AZMN_ASM80',
|
|
175
|
-
message: error.message,
|
|
176
|
-
sourceName: error.item.span.sourceName,
|
|
177
|
-
line: error.item.span.line,
|
|
178
|
-
column: error.item.span.column,
|
|
179
|
-
});
|
|
180
|
-
return { diagnostics, artifacts };
|
|
181
|
-
}
|
|
182
|
-
throw error;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
81
|
+
const emittedArtifacts = await emitAssemblyArtifacts({
|
|
82
|
+
entryFile: normalizedEntry,
|
|
83
|
+
options,
|
|
84
|
+
formats: deps.formats,
|
|
85
|
+
program,
|
|
86
|
+
bytes: assembled.bytes,
|
|
87
|
+
origin: assembled.origin,
|
|
88
|
+
sourceSegments: assembled.sourceSegments,
|
|
89
|
+
initializedAddresses: assembled.initializedAddresses,
|
|
90
|
+
symbols: assembled.symbols,
|
|
91
|
+
});
|
|
92
|
+
artifacts.push(...emittedArtifacts.artifacts);
|
|
93
|
+
diagnostics.push(...emittedArtifacts.diagnostics);
|
|
186
94
|
return { diagnostics, artifacts };
|
|
187
95
|
}
|
|
188
|
-
function compileArtifactDefaults(options) {
|
|
189
|
-
const anyPrimary = [options.emitBin, options.emitHex, options.emitD8m].some((value) => value !== undefined);
|
|
190
|
-
const emitBin = anyPrimary ? (options.emitBin ?? false) : true;
|
|
191
|
-
const emitHex = anyPrimary ? (options.emitHex ?? false) : true;
|
|
192
|
-
const emitD8m = anyPrimary ? (options.emitD8m ?? false) : true;
|
|
193
|
-
const emitAsm80 = options.emitAsm80 ?? false;
|
|
194
|
-
return { emitBin, emitHex, emitD8m, emitAsm80 };
|
|
195
|
-
}
|
|
196
|
-
function assembledImageToMap(bytes, origin, sourceSegments = []) {
|
|
197
|
-
const map = new Map();
|
|
198
|
-
for (let offset = 0; offset < bytes.length; offset += 1) {
|
|
199
|
-
map.set(origin + offset, bytes[offset] ?? 0);
|
|
200
|
-
}
|
|
201
|
-
const writtenRange = {
|
|
202
|
-
start: origin,
|
|
203
|
-
end: origin + bytes.length,
|
|
204
|
-
};
|
|
205
|
-
return { bytes: map, writtenRange, sourceSegments };
|
|
206
|
-
}
|
|
207
|
-
function assembledInitializedImageToMap(bytes, origin, initializedAddresses, sourceSegments = []) {
|
|
208
|
-
const map = new Map();
|
|
209
|
-
for (const address of initializedAddresses) {
|
|
210
|
-
const offset = address - origin;
|
|
211
|
-
if (offset >= 0 && offset < bytes.length) {
|
|
212
|
-
map.set(address, bytes[offset] ?? 0);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return { bytes: map, sourceSegments };
|
|
216
|
-
}
|
|
217
|
-
function collectSymbolEntries(items, resolvedSymbols) {
|
|
218
|
-
const map = new Map();
|
|
219
|
-
for (const item of items) {
|
|
220
|
-
switch (item.kind) {
|
|
221
|
-
case 'equ': {
|
|
222
|
-
const value = resolvedSymbols[item.name];
|
|
223
|
-
if (value !== undefined) {
|
|
224
|
-
map.set(item.name, {
|
|
225
|
-
kind: 'constant',
|
|
226
|
-
name: item.name,
|
|
227
|
-
value,
|
|
228
|
-
file: item.span.sourceName,
|
|
229
|
-
line: item.span.line,
|
|
230
|
-
scope: 'global',
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
break;
|
|
234
|
-
}
|
|
235
|
-
case 'label': {
|
|
236
|
-
const address = resolvedSymbols[item.name];
|
|
237
|
-
if (address !== undefined) {
|
|
238
|
-
map.set(item.name, {
|
|
239
|
-
kind: 'label',
|
|
240
|
-
name: item.name,
|
|
241
|
-
address,
|
|
242
|
-
file: item.span.sourceName,
|
|
243
|
-
line: item.span.line,
|
|
244
|
-
scope: 'global',
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
break;
|
|
248
|
-
}
|
|
249
|
-
case 'enum': {
|
|
250
|
-
for (const member of item.members) {
|
|
251
|
-
const fullName = `${item.name}.${member}`;
|
|
252
|
-
const value = resolvedSymbols[fullName];
|
|
253
|
-
if (value !== undefined) {
|
|
254
|
-
map.set(fullName, {
|
|
255
|
-
kind: 'constant',
|
|
256
|
-
name: fullName,
|
|
257
|
-
value,
|
|
258
|
-
file: item.span.sourceName,
|
|
259
|
-
line: item.span.line,
|
|
260
|
-
scope: 'global',
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
break;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
return [...map.values()];
|
|
269
|
-
}
|
|
270
96
|
function hasErrors(diagnostics) {
|
|
271
97
|
return diagnostics.some((diagnostic) => diagnostic.severity === 'error');
|
|
272
98
|
}
|
|
@@ -279,28 +105,3 @@ function sortDiagnosticsInPlace(diagnostics) {
|
|
|
279
105
|
return (left.column ?? 0) - (right.column ?? 0);
|
|
280
106
|
});
|
|
281
107
|
}
|
|
282
|
-
async function readPackageVersion() {
|
|
283
|
-
if (cachedPackageVersion !== undefined) {
|
|
284
|
-
return cachedPackageVersion;
|
|
285
|
-
}
|
|
286
|
-
const packageJsonCandidates = [
|
|
287
|
-
new URL('../package.json', import.meta.url),
|
|
288
|
-
new URL('../../package.json', import.meta.url),
|
|
289
|
-
new URL('../../../package.json', import.meta.url),
|
|
290
|
-
];
|
|
291
|
-
for (const candidate of packageJsonCandidates) {
|
|
292
|
-
try {
|
|
293
|
-
const raw = await readFile(candidate, 'utf8');
|
|
294
|
-
const json = JSON.parse(raw);
|
|
295
|
-
if (json.version !== undefined) {
|
|
296
|
-
cachedPackageVersion = json.version;
|
|
297
|
-
return cachedPackageVersion;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
catch {
|
|
301
|
-
// Continue searching candidates.
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
cachedPackageVersion = '0.0.0';
|
|
305
|
-
return cachedPackageVersion;
|
|
306
|
-
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Diagnostic } from './model/diagnostic.js';
|
|
2
|
+
import type { Artifact } from './outputs/types.js';
|
|
3
|
+
import type { LoadedProgramNext } from './tooling/api.js';
|
|
4
|
+
import type { CompileNextFunctionOptions } from './api-compile.js';
|
|
5
|
+
export declare function shouldAnalyzeRegisterContracts(options: CompileNextFunctionOptions): boolean;
|
|
6
|
+
export declare function runRegisterContracts(loadedProgram: LoadedProgramNext, options: CompileNextFunctionOptions): Promise<{
|
|
7
|
+
readonly artifacts: readonly Artifact[];
|
|
8
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
9
|
+
}>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { normalize } from 'node:path';
|
|
3
|
+
import { analyzeRegisterContracts } from './register-contracts/analyze.js';
|
|
4
|
+
import { parseAcceptedOutputCandidates } from './register-contracts/accept-output.js';
|
|
5
|
+
import { parseInterfaceContracts } from './register-contracts/interfaceContracts.js';
|
|
6
|
+
export function shouldAnalyzeRegisterContracts(options) {
|
|
7
|
+
const registerContractsMode = options.registerContracts ?? options.registerCare ?? 'off';
|
|
8
|
+
return (registerContractsMode !== 'off' ||
|
|
9
|
+
options.emitRegisterReport === true ||
|
|
10
|
+
options.emitRegisterInterface === true ||
|
|
11
|
+
options.emitRegisterAnnotations === true ||
|
|
12
|
+
options.fixRegisterContracts === true ||
|
|
13
|
+
(options.acceptRegisterOutputCandidates?.length ?? 0) > 0 ||
|
|
14
|
+
(options.registerContractsInterfaces?.length ?? options.registerCareInterfaces?.length ?? 0) > 0);
|
|
15
|
+
}
|
|
16
|
+
export async function runRegisterContracts(loadedProgram, options) {
|
|
17
|
+
const diagnostics = [];
|
|
18
|
+
const artifacts = [];
|
|
19
|
+
const interfaceContracts = await loadInterfaceContracts(options.registerContractsInterfaces ?? options.registerCareInterfaces ?? [], diagnostics);
|
|
20
|
+
if (hasErrors(diagnostics)) {
|
|
21
|
+
return { diagnostics, artifacts };
|
|
22
|
+
}
|
|
23
|
+
const registerContracts = analyzeRegisterContracts(loadedProgram, {
|
|
24
|
+
mode: options.registerContracts ?? options.registerCare ?? 'off',
|
|
25
|
+
emitReport: options.emitRegisterReport === true,
|
|
26
|
+
emitInterface: options.emitRegisterInterface === true,
|
|
27
|
+
emitAnnotations: options.emitRegisterAnnotations === true || options.fixRegisterContracts === true,
|
|
28
|
+
fixRegisterContracts: options.fixRegisterContracts === true,
|
|
29
|
+
acceptedOutputCandidates: parseAcceptedOutputCandidates(options.acceptRegisterOutputCandidates ?? []),
|
|
30
|
+
...(options.registerContractsProfile !== undefined || options.registerCareProfile !== undefined
|
|
31
|
+
? {
|
|
32
|
+
registerContractsProfile: options.registerContractsProfile ?? options.registerCareProfile,
|
|
33
|
+
}
|
|
34
|
+
: {}),
|
|
35
|
+
...(interfaceContracts.length > 0 ? { interfaceContracts } : {}),
|
|
36
|
+
});
|
|
37
|
+
if (registerContracts.reportText !== undefined) {
|
|
38
|
+
artifacts.push({ kind: 'register-contracts-report', text: registerContracts.reportText });
|
|
39
|
+
}
|
|
40
|
+
if (registerContracts.interfaceText !== undefined) {
|
|
41
|
+
artifacts.push({ kind: 'register-contracts-interface', text: registerContracts.interfaceText });
|
|
42
|
+
}
|
|
43
|
+
if (registerContracts.annotations !== undefined && registerContracts.annotations.length > 0) {
|
|
44
|
+
artifacts.push({
|
|
45
|
+
kind: 'register-contracts-annotations',
|
|
46
|
+
files: registerContracts.annotations.map((item) => ({
|
|
47
|
+
path: item.path,
|
|
48
|
+
text: item.text,
|
|
49
|
+
})),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
diagnostics.push(...registerContracts.diagnostics);
|
|
53
|
+
return { artifacts, diagnostics };
|
|
54
|
+
}
|
|
55
|
+
async function loadInterfaceContracts(interfaces, diagnostics) {
|
|
56
|
+
const interfaceContracts = [];
|
|
57
|
+
for (const rawInterface of interfaces) {
|
|
58
|
+
const contractPath = normalize(rawInterface);
|
|
59
|
+
if (contractPath.slice(-5).toLowerCase() !== '.asmi') {
|
|
60
|
+
diagnostics.push({
|
|
61
|
+
severity: 'error',
|
|
62
|
+
code: 'AZMN_REGISTER_CONTRACTS',
|
|
63
|
+
message: 'Register contracts interface files must use the .asmi extension',
|
|
64
|
+
sourceName: contractPath,
|
|
65
|
+
});
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const interfaceText = await readFile(contractPath, 'utf8');
|
|
69
|
+
for (const contract of parseInterfaceContracts(interfaceText, contractPath).values()) {
|
|
70
|
+
interfaceContracts.push(contract);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return interfaceContracts;
|
|
74
|
+
}
|
|
75
|
+
function hasErrors(diagnostics) {
|
|
76
|
+
return diagnostics.some((diagnostic) => diagnostic.severity === 'error');
|
|
77
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { analyzeProgram, analyzeProgramNext, loadProgram, loadProgramNext } from './tooling/api.js';
|
|
2
|
-
export { analyzeRegisterCareForTools, codeActionForOutputCandidate, diagnosticForOutputCandidate, type AnalyzeRegisterCareForToolsOptions, type AnalyzeRegisterCareForToolsResult, type RegisterCareCandidateDiagnostic, type RegisterCareCodeAction, type RegisterCareTextEdit, } from './register-
|
|
2
|
+
export { analyzeRegisterCareForTools, analyzeRegisterContractsForTools, codeActionForOutputCandidate, diagnosticForOutputCandidate, type AnalyzeRegisterCareForToolsOptions, type AnalyzeRegisterCareForToolsResult, type AnalyzeRegisterContractsForToolsOptions, type AnalyzeRegisterContractsForToolsResult, type RegisterCareCandidateDiagnostic, type RegisterCareCodeAction, type RegisterCareTextEdit, type RegisterContractsCandidateDiagnostic, type RegisterContractsCodeAction, type RegisterContractsTextEdit, } from './register-contracts/tooling.js';
|
|
3
3
|
export { DiagnosticIds } from './model/diagnostic.js';
|
|
4
4
|
export type { AnalyzeProgramOptions, AnalyzeProgramResult, LoadedProgram, LoadProgramOptions, LoadProgramResult, AnalyzeProgramNextOptions, AnalyzeProgramNextResult, LoadedProgramNext, LoadProgramNextOptions, LoadProgramNextResult, } from './tooling/api.js';
|
|
5
5
|
export type { CaseStyleMode } from './tooling/case-style.js';
|
|
6
6
|
export type { Diagnostic, DiagnosticId, DiagnosticSeverity } from './model/diagnostic.js';
|
|
7
|
-
export type { RegisterCareMode, RegisterCareOutputCandidate, RegisterCareUnit, } from './register-
|
|
7
|
+
export type { RegisterCareMode, RegisterCareOutputCandidate, RegisterCareUnit, RegisterContractsMode, RegisterContractsOutputCandidate, RegisterContractsUnit, } from './register-contracts/types.js';
|
package/dist/src/api-tooling.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { analyzeProgram, analyzeProgramNext, loadProgram, loadProgramNext } from './tooling/api.js';
|
|
2
|
-
export { analyzeRegisterCareForTools, codeActionForOutputCandidate, diagnosticForOutputCandidate, } from './register-
|
|
2
|
+
export { analyzeRegisterCareForTools, analyzeRegisterContractsForTools, codeActionForOutputCandidate, diagnosticForOutputCandidate, } from './register-contracts/tooling.js';
|
|
3
3
|
export { DiagnosticIds } from './model/diagnostic.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Diagnostic } from '../model/diagnostic.js';
|
|
2
2
|
import type { SourceItem } from '../model/source-item.js';
|
|
3
|
-
import type { SymbolTable } from '../model/symbol.js';
|
|
4
3
|
import { type EquateRecord, type LayoutRecord } from '../semantics/expression-evaluation.js';
|
|
4
|
+
export { resolveSymbols } from './address-symbols.js';
|
|
5
5
|
export interface AddressState {
|
|
6
6
|
readonly labels: Record<string, number>;
|
|
7
7
|
readonly equates: Map<string, EquateRecord>;
|
|
@@ -16,4 +16,3 @@ export declare function buildAddressState(items: readonly SourceItem[], diagnost
|
|
|
16
16
|
};
|
|
17
17
|
export declare function stringDirectiveBytes(directive: 'cstr' | 'pstr' | 'istr', value: string): readonly number[];
|
|
18
18
|
export declare function alignmentPadding(address: number, alignment: number): number;
|
|
19
|
-
export declare function resolveSymbols(labels: Readonly<Record<string, number>>, equates: ReadonlyMap<string, EquateRecord>, layouts: ReadonlyMap<string, LayoutRecord>, diagnostics: Diagnostic[]): SymbolTable;
|