c-next 0.1.65 → 0.1.67
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/package.json +5 -1
- package/src/transpiler/Transpiler.ts +49 -42
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +129 -0
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +27 -3
- package/src/transpiler/output/codegen/CodeGenerator.ts +131 -186
- package/src/transpiler/output/codegen/TypeResolver.ts +2 -2
- package/src/transpiler/output/codegen/TypeValidator.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +1087 -0
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +665 -1315
- package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +1 -1
- package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +1 -1
- package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +1 -1
- package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +1 -1
- package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +1 -1
- package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +1 -1
- package/src/transpiler/output/codegen/assignment/handlers/AccessPatternHandlers.ts +24 -27
- package/src/transpiler/output/codegen/assignment/handlers/ArrayHandlers.ts +25 -18
- package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +27 -33
- package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +39 -42
- package/src/transpiler/output/codegen/assignment/handlers/RegisterHandlers.ts +39 -97
- package/src/transpiler/output/codegen/assignment/handlers/RegisterUtils.ts +75 -0
- package/src/transpiler/output/codegen/assignment/handlers/SimpleHandler.ts +9 -6
- package/src/transpiler/output/codegen/assignment/handlers/SpecialHandlers.ts +30 -22
- package/src/transpiler/output/codegen/assignment/handlers/StringHandlers.ts +42 -50
- package/src/transpiler/output/codegen/assignment/handlers/TAssignmentHandler.ts +6 -5
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/AccessPatternHandlers.test.ts +81 -134
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/ArrayHandlers.test.ts +85 -124
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts +82 -124
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitmapHandlers.test.ts +135 -297
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterHandlers.test.ts +105 -227
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterUtils.test.ts +214 -1
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/SpecialHandlers.test.ts +66 -127
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/StringHandlers.test.ts +37 -83
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/handlerTestUtils.ts +162 -0
- package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +618 -12
- package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +819 -0
- package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +1 -1
- package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +1 -1
- package/src/transpiler/output/codegen/helpers/CppModeHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +1 -1
- package/src/transpiler/output/codegen/helpers/FloatBitHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +337 -0
- package/src/transpiler/output/codegen/helpers/ParameterSignatureBuilder.ts +135 -0
- package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/VariableDeclarationFormatter.ts +118 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/CppModeHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/FloatBitHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +426 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterSignatureBuilder.test.ts +315 -0
- package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclarationFormatter.test.ts +333 -0
- package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +1 -1
- package/src/transpiler/output/codegen/resolution/ScopeResolver.ts +1 -1
- package/src/transpiler/output/codegen/resolution/SizeofResolver.ts +1 -1
- package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/resolution/__tests__/SizeofResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/types/ICodeGenApi.ts +57 -0
- package/src/transpiler/output/codegen/types/IParameterInput.ts +58 -0
- package/src/transpiler/output/codegen/types/IVariableFormatInput.ts +51 -0
- package/src/transpiler/output/headers/BaseHeaderGenerator.ts +20 -35
- package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +21 -48
- package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +0 -64
- package/src/transpiler/{output/codegen → state}/CodeGenState.ts +46 -26
- package/src/transpiler/{output/codegen → state}/__tests__/CodeGenState.test.ts +12 -2
- package/src/transpiler/output/codegen/assignment/handlers/IHandlerDeps.ts +0 -161
package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterHandlers.test.ts
CHANGED
|
@@ -3,53 +3,12 @@
|
|
|
3
3
|
* Tests register bit assignment handler functions.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { describe, expect, it, vi } from "vitest";
|
|
6
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
7
7
|
import registerHandlers from "../RegisterHandlers";
|
|
8
8
|
import AssignmentKind from "../../AssignmentKind";
|
|
9
9
|
import IAssignmentContext from "../../IAssignmentContext";
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Create mock dependencies for testing.
|
|
14
|
-
*/
|
|
15
|
-
function createMockDeps(overrides: Record<string, unknown> = {}): IHandlerDeps {
|
|
16
|
-
const base = {
|
|
17
|
-
typeRegistry: new Map(),
|
|
18
|
-
symbols: {
|
|
19
|
-
structFields: new Map(),
|
|
20
|
-
structFieldDimensions: new Map(),
|
|
21
|
-
bitmapFields: new Map(),
|
|
22
|
-
registerMemberAccess: new Map(),
|
|
23
|
-
registerBaseAddresses: new Map(),
|
|
24
|
-
registerMemberOffsets: new Map(),
|
|
25
|
-
registerMemberTypes: new Map(),
|
|
26
|
-
},
|
|
27
|
-
currentScope: null,
|
|
28
|
-
currentParameters: new Map(),
|
|
29
|
-
targetCapabilities: { hasLDREX: false },
|
|
30
|
-
generateAssignmentTarget: vi.fn().mockReturnValue("target"),
|
|
31
|
-
generateExpression: vi
|
|
32
|
-
.fn()
|
|
33
|
-
.mockImplementation((ctx) => ctx?.mockValue ?? "0"),
|
|
34
|
-
markNeedsString: vi.fn(),
|
|
35
|
-
markClampOpUsed: vi.fn(),
|
|
36
|
-
isKnownScope: vi.fn().mockReturnValue(false),
|
|
37
|
-
isKnownStruct: vi.fn().mockReturnValue(false),
|
|
38
|
-
validateCrossScopeVisibility: vi.fn(),
|
|
39
|
-
validateBitmapFieldLiteral: vi.fn(),
|
|
40
|
-
checkArrayBounds: vi.fn(),
|
|
41
|
-
analyzeMemberChainForBitAccess: vi
|
|
42
|
-
.fn()
|
|
43
|
-
.mockReturnValue({ isBitAccess: false }),
|
|
44
|
-
tryEvaluateConstant: vi.fn().mockReturnValue(undefined),
|
|
45
|
-
getMemberTypeInfo: vi.fn().mockReturnValue(null),
|
|
46
|
-
generateFloatBitWrite: vi.fn().mockReturnValue(null),
|
|
47
|
-
foldBooleanToInt: vi.fn().mockImplementation((expr) => expr),
|
|
48
|
-
generateAtomicRMW: vi.fn().mockReturnValue("atomic_rmw"),
|
|
49
|
-
...overrides,
|
|
50
|
-
};
|
|
51
|
-
return base as unknown as IHandlerDeps;
|
|
52
|
-
}
|
|
10
|
+
import CodeGenState from "../../../../../state/CodeGenState";
|
|
11
|
+
import HandlerTestUtils from "./handlerTestUtils";
|
|
53
12
|
|
|
54
13
|
/**
|
|
55
14
|
* Create mock context for testing.
|
|
@@ -80,6 +39,12 @@ function createMockContext(
|
|
|
80
39
|
}
|
|
81
40
|
|
|
82
41
|
describe("RegisterHandlers", () => {
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
CodeGenState.reset();
|
|
44
|
+
HandlerTestUtils.setupMockGenerator();
|
|
45
|
+
HandlerTestUtils.setupMockSymbols();
|
|
46
|
+
});
|
|
47
|
+
|
|
83
48
|
describe("handler registration", () => {
|
|
84
49
|
it("registers all expected register assignment kinds", () => {
|
|
85
50
|
const kinds = registerHandlers.map(([kind]) => kind);
|
|
@@ -102,12 +67,12 @@ describe("RegisterHandlers", () => {
|
|
|
102
67
|
)?.[1];
|
|
103
68
|
|
|
104
69
|
it("generates read-modify-write for read-write register", () => {
|
|
105
|
-
|
|
70
|
+
HandlerTestUtils.setupMockGenerator({
|
|
106
71
|
generateExpression: vi.fn().mockReturnValue("LED_BIT"),
|
|
107
72
|
});
|
|
108
73
|
const ctx = createMockContext();
|
|
109
74
|
|
|
110
|
-
const result = getHandler()!(ctx
|
|
75
|
+
const result = getHandler()!(ctx);
|
|
111
76
|
|
|
112
77
|
expect(result).toContain("GPIO7_DR_SET");
|
|
113
78
|
expect(result).toContain("& ~(1 <<");
|
|
@@ -115,87 +80,67 @@ describe("RegisterHandlers", () => {
|
|
|
115
80
|
});
|
|
116
81
|
|
|
117
82
|
it("generates simple write for write-only register", () => {
|
|
118
|
-
|
|
119
|
-
const deps = createMockDeps({
|
|
83
|
+
HandlerTestUtils.setupMockGenerator({
|
|
120
84
|
generateExpression: vi.fn().mockReturnValue("LED_BIT"),
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
bitmapFields: new Map(),
|
|
125
|
-
registerMemberAccess,
|
|
126
|
-
registerBaseAddresses: new Map(),
|
|
127
|
-
registerMemberOffsets: new Map(),
|
|
128
|
-
registerMemberTypes: new Map(),
|
|
129
|
-
},
|
|
85
|
+
});
|
|
86
|
+
HandlerTestUtils.setupMockSymbols({
|
|
87
|
+
registerMemberAccess: new Map([["GPIO7_DR_SET", "wo"]]),
|
|
130
88
|
});
|
|
131
89
|
const ctx = createMockContext();
|
|
132
90
|
|
|
133
|
-
const result = getHandler()!(ctx
|
|
91
|
+
const result = getHandler()!(ctx);
|
|
134
92
|
|
|
135
93
|
expect(result).toBe("GPIO7_DR_SET = (1 << LED_BIT);");
|
|
136
94
|
});
|
|
137
95
|
|
|
138
96
|
it("throws on write-only register with false value", () => {
|
|
139
|
-
|
|
140
|
-
const deps = createMockDeps({
|
|
97
|
+
HandlerTestUtils.setupMockGenerator({
|
|
141
98
|
generateExpression: vi.fn().mockReturnValue("LED_BIT"),
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
bitmapFields: new Map(),
|
|
146
|
-
registerMemberAccess,
|
|
147
|
-
registerBaseAddresses: new Map(),
|
|
148
|
-
registerMemberOffsets: new Map(),
|
|
149
|
-
registerMemberTypes: new Map(),
|
|
150
|
-
},
|
|
99
|
+
});
|
|
100
|
+
HandlerTestUtils.setupMockSymbols({
|
|
101
|
+
registerMemberAccess: new Map([["GPIO7_DR_SET", "wo"]]),
|
|
151
102
|
});
|
|
152
103
|
const ctx = createMockContext({ generatedValue: "false" });
|
|
153
104
|
|
|
154
|
-
expect(() => getHandler()!(ctx
|
|
105
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
155
106
|
"Cannot assign false to write-only register bit",
|
|
156
107
|
);
|
|
157
108
|
});
|
|
158
109
|
|
|
159
110
|
it("throws on write-only register with 0 value", () => {
|
|
160
|
-
|
|
161
|
-
const deps = createMockDeps({
|
|
111
|
+
HandlerTestUtils.setupMockGenerator({
|
|
162
112
|
generateExpression: vi.fn().mockReturnValue("0"),
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
bitmapFields: new Map(),
|
|
167
|
-
registerMemberAccess,
|
|
168
|
-
registerBaseAddresses: new Map(),
|
|
169
|
-
registerMemberOffsets: new Map(),
|
|
170
|
-
registerMemberTypes: new Map(),
|
|
171
|
-
},
|
|
113
|
+
});
|
|
114
|
+
HandlerTestUtils.setupMockSymbols({
|
|
115
|
+
registerMemberAccess: new Map([["GPIO7_DR_SET", "w1s"]]),
|
|
172
116
|
});
|
|
173
117
|
const ctx = createMockContext({ generatedValue: "0" });
|
|
174
118
|
|
|
175
|
-
expect(() => getHandler()!(ctx
|
|
119
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
176
120
|
"Cannot assign false to write-only register bit",
|
|
177
121
|
);
|
|
178
122
|
});
|
|
179
123
|
|
|
180
124
|
it("throws on compound assignment", () => {
|
|
181
|
-
const deps = createMockDeps();
|
|
182
125
|
const ctx = createMockContext({ isCompound: true, cnextOp: "+<-" });
|
|
183
126
|
|
|
184
|
-
expect(() => getHandler()!(ctx
|
|
127
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
185
128
|
"Compound assignment operators not supported for bit field access",
|
|
186
129
|
);
|
|
187
130
|
});
|
|
188
131
|
|
|
189
132
|
it("handles scoped register prefix correctly", () => {
|
|
190
|
-
|
|
133
|
+
HandlerTestUtils.setupMockGenerator({
|
|
191
134
|
generateExpression: vi.fn().mockReturnValue("5"),
|
|
192
|
-
|
|
135
|
+
});
|
|
136
|
+
HandlerTestUtils.setupMockSymbols({
|
|
137
|
+
knownScopes: new Set(["Motor"]),
|
|
193
138
|
});
|
|
194
139
|
const ctx = createMockContext({
|
|
195
140
|
identifiers: ["Motor", "GPIO7", "DR_SET"],
|
|
196
141
|
});
|
|
197
142
|
|
|
198
|
-
const result = getHandler()!(ctx
|
|
143
|
+
const result = getHandler()!(ctx);
|
|
199
144
|
|
|
200
145
|
expect(result).toContain("Motor_GPIO7_DR_SET");
|
|
201
146
|
});
|
|
@@ -208,7 +153,7 @@ describe("RegisterHandlers", () => {
|
|
|
208
153
|
)?.[1];
|
|
209
154
|
|
|
210
155
|
it("generates read-modify-write for bit range", () => {
|
|
211
|
-
|
|
156
|
+
HandlerTestUtils.setupMockGenerator({
|
|
212
157
|
generateExpression: vi
|
|
213
158
|
.fn()
|
|
214
159
|
.mockReturnValueOnce("0")
|
|
@@ -219,7 +164,7 @@ describe("RegisterHandlers", () => {
|
|
|
219
164
|
generatedValue: "value",
|
|
220
165
|
});
|
|
221
166
|
|
|
222
|
-
const result = getHandler()!(ctx
|
|
167
|
+
const result = getHandler()!(ctx);
|
|
223
168
|
|
|
224
169
|
expect(result).toContain("GPIO7_DR_SET");
|
|
225
170
|
expect(result).toContain("& ~(");
|
|
@@ -227,28 +172,21 @@ describe("RegisterHandlers", () => {
|
|
|
227
172
|
});
|
|
228
173
|
|
|
229
174
|
it("generates simple write for write-only bit range", () => {
|
|
230
|
-
|
|
231
|
-
const deps = createMockDeps({
|
|
175
|
+
HandlerTestUtils.setupMockGenerator({
|
|
232
176
|
generateExpression: vi
|
|
233
177
|
.fn()
|
|
234
178
|
.mockReturnValueOnce("0")
|
|
235
179
|
.mockReturnValueOnce("8"),
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
bitmapFields: new Map(),
|
|
240
|
-
registerMemberAccess,
|
|
241
|
-
registerBaseAddresses: new Map(),
|
|
242
|
-
registerMemberOffsets: new Map(),
|
|
243
|
-
registerMemberTypes: new Map(),
|
|
244
|
-
},
|
|
180
|
+
});
|
|
181
|
+
HandlerTestUtils.setupMockSymbols({
|
|
182
|
+
registerMemberAccess: new Map([["GPIO7_DR_SET", "wo"]]),
|
|
245
183
|
});
|
|
246
184
|
const ctx = createMockContext({
|
|
247
185
|
subscripts: [{ mockValue: "0" } as never, { mockValue: "8" } as never],
|
|
248
186
|
generatedValue: "value",
|
|
249
187
|
});
|
|
250
188
|
|
|
251
|
-
const result = getHandler()!(ctx
|
|
189
|
+
const result = getHandler()!(ctx);
|
|
252
190
|
|
|
253
191
|
expect(result).toContain("GPIO7_DR_SET =");
|
|
254
192
|
expect(result).toContain("value");
|
|
@@ -256,38 +194,27 @@ describe("RegisterHandlers", () => {
|
|
|
256
194
|
});
|
|
257
195
|
|
|
258
196
|
it("throws on write-only bit range with 0 value", () => {
|
|
259
|
-
|
|
260
|
-
const deps = createMockDeps({
|
|
197
|
+
HandlerTestUtils.setupMockGenerator({
|
|
261
198
|
generateExpression: vi
|
|
262
199
|
.fn()
|
|
263
200
|
.mockReturnValueOnce("0")
|
|
264
201
|
.mockReturnValueOnce("8"),
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
bitmapFields: new Map(),
|
|
269
|
-
registerMemberAccess,
|
|
270
|
-
registerBaseAddresses: new Map(),
|
|
271
|
-
registerMemberOffsets: new Map(),
|
|
272
|
-
registerMemberTypes: new Map(),
|
|
273
|
-
},
|
|
202
|
+
});
|
|
203
|
+
HandlerTestUtils.setupMockSymbols({
|
|
204
|
+
registerMemberAccess: new Map([["GPIO7_DR_SET", "w1c"]]),
|
|
274
205
|
});
|
|
275
206
|
const ctx = createMockContext({
|
|
276
207
|
subscripts: [{ mockValue: "0" } as never, { mockValue: "8" } as never],
|
|
277
208
|
generatedValue: "0",
|
|
278
209
|
});
|
|
279
210
|
|
|
280
|
-
expect(() => getHandler()!(ctx
|
|
211
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
281
212
|
"Cannot assign 0 to write-only register bits",
|
|
282
213
|
);
|
|
283
214
|
});
|
|
284
215
|
|
|
285
216
|
it("generates MMIO optimization for byte-aligned access", () => {
|
|
286
|
-
|
|
287
|
-
const registerBaseAddresses = new Map([["GPIO7", "0x40000000"]]);
|
|
288
|
-
const registerMemberOffsets = new Map([["GPIO7_DR_SET", "0x04"]]);
|
|
289
|
-
|
|
290
|
-
const deps = createMockDeps({
|
|
217
|
+
HandlerTestUtils.setupMockGenerator({
|
|
291
218
|
generateExpression: vi
|
|
292
219
|
.fn()
|
|
293
220
|
.mockReturnValueOnce("0")
|
|
@@ -296,22 +223,18 @@ describe("RegisterHandlers", () => {
|
|
|
296
223
|
.fn()
|
|
297
224
|
.mockReturnValueOnce(0)
|
|
298
225
|
.mockReturnValueOnce(8),
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
registerBaseAddresses,
|
|
305
|
-
registerMemberOffsets,
|
|
306
|
-
registerMemberTypes: new Map(),
|
|
307
|
-
},
|
|
226
|
+
});
|
|
227
|
+
HandlerTestUtils.setupMockSymbols({
|
|
228
|
+
registerMemberAccess: new Map([["GPIO7_DR_SET", "wo"]]),
|
|
229
|
+
registerBaseAddresses: new Map([["GPIO7", "0x40000000"]]),
|
|
230
|
+
registerMemberOffsets: new Map([["GPIO7_DR_SET", "0x04"]]),
|
|
308
231
|
});
|
|
309
232
|
const ctx = createMockContext({
|
|
310
233
|
subscripts: [{ mockValue: "0" } as never, { mockValue: "8" } as never],
|
|
311
234
|
generatedValue: "value",
|
|
312
235
|
});
|
|
313
236
|
|
|
314
|
-
const result = getHandler()!(ctx
|
|
237
|
+
const result = getHandler()!(ctx);
|
|
315
238
|
|
|
316
239
|
expect(result).toContain("volatile uint8_t*");
|
|
317
240
|
expect(result).toContain("0x40000000");
|
|
@@ -319,11 +242,7 @@ describe("RegisterHandlers", () => {
|
|
|
319
242
|
});
|
|
320
243
|
|
|
321
244
|
it("generates MMIO with byte offset for non-zero start", () => {
|
|
322
|
-
|
|
323
|
-
const registerBaseAddresses = new Map([["GPIO7", "0x40000000"]]);
|
|
324
|
-
const registerMemberOffsets = new Map([["GPIO7_DR_SET", "0x04"]]);
|
|
325
|
-
|
|
326
|
-
const deps = createMockDeps({
|
|
245
|
+
HandlerTestUtils.setupMockGenerator({
|
|
327
246
|
generateExpression: vi
|
|
328
247
|
.fn()
|
|
329
248
|
.mockReturnValueOnce("8")
|
|
@@ -332,36 +251,31 @@ describe("RegisterHandlers", () => {
|
|
|
332
251
|
.fn()
|
|
333
252
|
.mockReturnValueOnce(8)
|
|
334
253
|
.mockReturnValueOnce(16),
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
registerBaseAddresses,
|
|
341
|
-
registerMemberOffsets,
|
|
342
|
-
registerMemberTypes: new Map(),
|
|
343
|
-
},
|
|
254
|
+
});
|
|
255
|
+
HandlerTestUtils.setupMockSymbols({
|
|
256
|
+
registerMemberAccess: new Map([["GPIO7_DR_SET", "wo"]]),
|
|
257
|
+
registerBaseAddresses: new Map([["GPIO7", "0x40000000"]]),
|
|
258
|
+
registerMemberOffsets: new Map([["GPIO7_DR_SET", "0x04"]]),
|
|
344
259
|
});
|
|
345
260
|
const ctx = createMockContext({
|
|
346
261
|
subscripts: [{ mockValue: "8" } as never, { mockValue: "16" } as never],
|
|
347
262
|
generatedValue: "value",
|
|
348
263
|
});
|
|
349
264
|
|
|
350
|
-
const result = getHandler()!(ctx
|
|
265
|
+
const result = getHandler()!(ctx);
|
|
351
266
|
|
|
352
267
|
expect(result).toContain("volatile uint16_t*");
|
|
353
268
|
expect(result).toContain("0x04 + 1");
|
|
354
269
|
});
|
|
355
270
|
|
|
356
271
|
it("throws on compound assignment", () => {
|
|
357
|
-
const deps = createMockDeps();
|
|
358
272
|
const ctx = createMockContext({
|
|
359
273
|
isCompound: true,
|
|
360
274
|
cnextOp: "+<-",
|
|
361
275
|
subscripts: [{ mockValue: "0" } as never, { mockValue: "8" } as never],
|
|
362
276
|
});
|
|
363
277
|
|
|
364
|
-
expect(() => getHandler()!(ctx
|
|
278
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
365
279
|
"Compound assignment operators not supported for bit field access",
|
|
366
280
|
);
|
|
367
281
|
});
|
|
@@ -374,8 +288,8 @@ describe("RegisterHandlers", () => {
|
|
|
374
288
|
)?.[1];
|
|
375
289
|
|
|
376
290
|
it("generates read-modify-write for scoped register bit", () => {
|
|
377
|
-
|
|
378
|
-
|
|
291
|
+
CodeGenState.currentScope = "Motor";
|
|
292
|
+
HandlerTestUtils.setupMockGenerator({
|
|
379
293
|
generateExpression: vi.fn().mockReturnValue("LED_BIT"),
|
|
380
294
|
});
|
|
381
295
|
const ctx = createMockContext({
|
|
@@ -383,69 +297,55 @@ describe("RegisterHandlers", () => {
|
|
|
383
297
|
hasThis: true,
|
|
384
298
|
});
|
|
385
299
|
|
|
386
|
-
const result = getHandler()!(ctx
|
|
300
|
+
const result = getHandler()!(ctx);
|
|
387
301
|
|
|
388
302
|
expect(result).toContain("Motor_GPIO7_DR_SET");
|
|
389
303
|
expect(result).toContain("& ~(1 <<");
|
|
390
304
|
});
|
|
391
305
|
|
|
392
306
|
it("generates simple write for write-only scoped register", () => {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
currentScope: "Motor",
|
|
307
|
+
CodeGenState.currentScope = "Motor";
|
|
308
|
+
HandlerTestUtils.setupMockGenerator({
|
|
396
309
|
generateExpression: vi.fn().mockReturnValue("LED_BIT"),
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
bitmapFields: new Map(),
|
|
401
|
-
registerMemberAccess,
|
|
402
|
-
registerBaseAddresses: new Map(),
|
|
403
|
-
registerMemberOffsets: new Map(),
|
|
404
|
-
registerMemberTypes: new Map(),
|
|
405
|
-
},
|
|
310
|
+
});
|
|
311
|
+
HandlerTestUtils.setupMockSymbols({
|
|
312
|
+
registerMemberAccess: new Map([["Motor_GPIO7_DR_SET", "wo"]]),
|
|
406
313
|
});
|
|
407
314
|
const ctx = createMockContext({
|
|
408
315
|
identifiers: ["GPIO7", "DR_SET"],
|
|
409
316
|
hasThis: true,
|
|
410
317
|
});
|
|
411
318
|
|
|
412
|
-
const result = getHandler()!(ctx
|
|
319
|
+
const result = getHandler()!(ctx);
|
|
413
320
|
|
|
414
321
|
expect(result).toBe("Motor_GPIO7_DR_SET = (1 << LED_BIT);");
|
|
415
322
|
});
|
|
416
323
|
|
|
417
324
|
it("throws when used outside scope", () => {
|
|
418
|
-
|
|
325
|
+
CodeGenState.currentScope = null;
|
|
419
326
|
const ctx = createMockContext({ hasThis: true });
|
|
420
327
|
|
|
421
|
-
expect(() => getHandler()!(ctx
|
|
328
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
422
329
|
"'this' can only be used inside a scope",
|
|
423
330
|
);
|
|
424
331
|
});
|
|
425
332
|
|
|
426
333
|
it("throws on compound assignment", () => {
|
|
427
|
-
|
|
334
|
+
CodeGenState.currentScope = "Motor";
|
|
428
335
|
const ctx = createMockContext({ isCompound: true, cnextOp: "+<-" });
|
|
429
336
|
|
|
430
|
-
expect(() => getHandler()!(ctx
|
|
337
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
431
338
|
"Compound assignment operators not supported for bit field access",
|
|
432
339
|
);
|
|
433
340
|
});
|
|
434
341
|
|
|
435
342
|
it("throws on write-only register with false value", () => {
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
currentScope: "Motor",
|
|
343
|
+
CodeGenState.currentScope = "Motor";
|
|
344
|
+
HandlerTestUtils.setupMockGenerator({
|
|
439
345
|
generateExpression: vi.fn().mockReturnValue("LED_BIT"),
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
bitmapFields: new Map(),
|
|
444
|
-
registerMemberAccess,
|
|
445
|
-
registerBaseAddresses: new Map(),
|
|
446
|
-
registerMemberOffsets: new Map(),
|
|
447
|
-
registerMemberTypes: new Map(),
|
|
448
|
-
},
|
|
346
|
+
});
|
|
347
|
+
HandlerTestUtils.setupMockSymbols({
|
|
348
|
+
registerMemberAccess: new Map([["Motor_GPIO7_DR_SET", "w1s"]]),
|
|
449
349
|
});
|
|
450
350
|
const ctx = createMockContext({
|
|
451
351
|
identifiers: ["GPIO7", "DR_SET"],
|
|
@@ -453,7 +353,7 @@ describe("RegisterHandlers", () => {
|
|
|
453
353
|
generatedValue: "false",
|
|
454
354
|
});
|
|
455
355
|
|
|
456
|
-
expect(() => getHandler()!(ctx
|
|
356
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
457
357
|
"Cannot assign false to write-only register bit",
|
|
458
358
|
);
|
|
459
359
|
});
|
|
@@ -466,8 +366,8 @@ describe("RegisterHandlers", () => {
|
|
|
466
366
|
)?.[1];
|
|
467
367
|
|
|
468
368
|
it("generates read-modify-write for scoped register bit range", () => {
|
|
469
|
-
|
|
470
|
-
|
|
369
|
+
CodeGenState.currentScope = "Motor";
|
|
370
|
+
HandlerTestUtils.setupMockGenerator({
|
|
471
371
|
generateExpression: vi
|
|
472
372
|
.fn()
|
|
473
373
|
.mockReturnValueOnce("6")
|
|
@@ -480,7 +380,7 @@ describe("RegisterHandlers", () => {
|
|
|
480
380
|
generatedValue: "value",
|
|
481
381
|
});
|
|
482
382
|
|
|
483
|
-
const result = getHandler()!(ctx
|
|
383
|
+
const result = getHandler()!(ctx);
|
|
484
384
|
|
|
485
385
|
expect(result).toContain("Motor_GPIO7_ICR1");
|
|
486
386
|
expect(result).toContain("& ~(");
|
|
@@ -488,22 +388,15 @@ describe("RegisterHandlers", () => {
|
|
|
488
388
|
});
|
|
489
389
|
|
|
490
390
|
it("generates simple write for write-only scoped register bit range", () => {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
currentScope: "Motor",
|
|
391
|
+
CodeGenState.currentScope = "Motor";
|
|
392
|
+
HandlerTestUtils.setupMockGenerator({
|
|
494
393
|
generateExpression: vi
|
|
495
394
|
.fn()
|
|
496
395
|
.mockReturnValueOnce("6")
|
|
497
396
|
.mockReturnValueOnce("2"),
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
bitmapFields: new Map(),
|
|
502
|
-
registerMemberAccess,
|
|
503
|
-
registerBaseAddresses: new Map(),
|
|
504
|
-
registerMemberOffsets: new Map(),
|
|
505
|
-
registerMemberTypes: new Map(),
|
|
506
|
-
},
|
|
397
|
+
});
|
|
398
|
+
HandlerTestUtils.setupMockSymbols({
|
|
399
|
+
registerMemberAccess: new Map([["Motor_GPIO7_ICR1", "wo"]]),
|
|
507
400
|
});
|
|
508
401
|
const ctx = createMockContext({
|
|
509
402
|
identifiers: ["GPIO7", "ICR1"],
|
|
@@ -512,19 +405,15 @@ describe("RegisterHandlers", () => {
|
|
|
512
405
|
generatedValue: "value",
|
|
513
406
|
});
|
|
514
407
|
|
|
515
|
-
const result = getHandler()!(ctx
|
|
408
|
+
const result = getHandler()!(ctx);
|
|
516
409
|
|
|
517
410
|
expect(result).toContain("Motor_GPIO7_ICR1 =");
|
|
518
411
|
expect(result).not.toContain("& ~");
|
|
519
412
|
});
|
|
520
413
|
|
|
521
414
|
it("generates MMIO optimization for byte-aligned scoped access", () => {
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
const registerMemberOffsets = new Map([["Motor_GPIO7_ICR1", "0x08"]]);
|
|
525
|
-
|
|
526
|
-
const deps = createMockDeps({
|
|
527
|
-
currentScope: "Motor",
|
|
415
|
+
CodeGenState.currentScope = "Motor";
|
|
416
|
+
HandlerTestUtils.setupMockGenerator({
|
|
528
417
|
generateExpression: vi
|
|
529
418
|
.fn()
|
|
530
419
|
.mockReturnValueOnce("0")
|
|
@@ -533,15 +422,11 @@ describe("RegisterHandlers", () => {
|
|
|
533
422
|
.fn()
|
|
534
423
|
.mockReturnValueOnce(0)
|
|
535
424
|
.mockReturnValueOnce(32),
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
registerBaseAddresses,
|
|
542
|
-
registerMemberOffsets,
|
|
543
|
-
registerMemberTypes: new Map(),
|
|
544
|
-
},
|
|
425
|
+
});
|
|
426
|
+
HandlerTestUtils.setupMockSymbols({
|
|
427
|
+
registerMemberAccess: new Map([["Motor_GPIO7_ICR1", "wo"]]),
|
|
428
|
+
registerBaseAddresses: new Map([["Motor_GPIO7", "0x40000000"]]),
|
|
429
|
+
registerMemberOffsets: new Map([["Motor_GPIO7_ICR1", "0x08"]]),
|
|
545
430
|
});
|
|
546
431
|
const ctx = createMockContext({
|
|
547
432
|
identifiers: ["GPIO7", "ICR1"],
|
|
@@ -550,54 +435,47 @@ describe("RegisterHandlers", () => {
|
|
|
550
435
|
generatedValue: "value",
|
|
551
436
|
});
|
|
552
437
|
|
|
553
|
-
const result = getHandler()!(ctx
|
|
438
|
+
const result = getHandler()!(ctx);
|
|
554
439
|
|
|
555
440
|
expect(result).toContain("volatile uint32_t*");
|
|
556
441
|
expect(result).toContain("0x40000000");
|
|
557
442
|
});
|
|
558
443
|
|
|
559
444
|
it("throws when used outside scope", () => {
|
|
560
|
-
|
|
445
|
+
CodeGenState.currentScope = null;
|
|
561
446
|
const ctx = createMockContext({
|
|
562
447
|
subscripts: [{ mockValue: "6" } as never, { mockValue: "2" } as never],
|
|
563
448
|
hasThis: true,
|
|
564
449
|
});
|
|
565
450
|
|
|
566
|
-
expect(() => getHandler()!(ctx
|
|
451
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
567
452
|
"'this' can only be used inside a scope",
|
|
568
453
|
);
|
|
569
454
|
});
|
|
570
455
|
|
|
571
456
|
it("throws on compound assignment", () => {
|
|
572
|
-
|
|
457
|
+
CodeGenState.currentScope = "Motor";
|
|
573
458
|
const ctx = createMockContext({
|
|
574
459
|
isCompound: true,
|
|
575
460
|
cnextOp: "+<-",
|
|
576
461
|
subscripts: [{ mockValue: "6" } as never, { mockValue: "2" } as never],
|
|
577
462
|
});
|
|
578
463
|
|
|
579
|
-
expect(() => getHandler()!(ctx
|
|
464
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
580
465
|
"Compound assignment operators not supported for bit field access",
|
|
581
466
|
);
|
|
582
467
|
});
|
|
583
468
|
|
|
584
469
|
it("throws on write-only bit range with 0 value", () => {
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
currentScope: "Motor",
|
|
470
|
+
CodeGenState.currentScope = "Motor";
|
|
471
|
+
HandlerTestUtils.setupMockGenerator({
|
|
588
472
|
generateExpression: vi
|
|
589
473
|
.fn()
|
|
590
474
|
.mockReturnValueOnce("6")
|
|
591
475
|
.mockReturnValueOnce("2"),
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
bitmapFields: new Map(),
|
|
596
|
-
registerMemberAccess,
|
|
597
|
-
registerBaseAddresses: new Map(),
|
|
598
|
-
registerMemberOffsets: new Map(),
|
|
599
|
-
registerMemberTypes: new Map(),
|
|
600
|
-
},
|
|
476
|
+
});
|
|
477
|
+
HandlerTestUtils.setupMockSymbols({
|
|
478
|
+
registerMemberAccess: new Map([["Motor_GPIO7_ICR1", "w1c"]]),
|
|
601
479
|
});
|
|
602
480
|
const ctx = createMockContext({
|
|
603
481
|
identifiers: ["GPIO7", "ICR1"],
|
|
@@ -606,7 +484,7 @@ describe("RegisterHandlers", () => {
|
|
|
606
484
|
generatedValue: "0",
|
|
607
485
|
});
|
|
608
486
|
|
|
609
|
-
expect(() => getHandler()!(ctx
|
|
487
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
610
488
|
"Cannot assign 0 to write-only register bits",
|
|
611
489
|
);
|
|
612
490
|
});
|