c-next 0.1.68 → 0.1.70
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 +1 -1
- package/src/transpiler/logic/analysis/FunctionCallAnalyzer.ts +240 -204
- package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +693 -0
- package/src/transpiler/logic/analysis/__tests__/FunctionCallAnalyzer.test.ts +86 -5
- package/src/transpiler/{output/codegen → logic/analysis}/helpers/AssignmentTargetExtractor.ts +1 -1
- package/src/transpiler/{output/codegen → logic/analysis}/helpers/ChildStatementCollector.ts +1 -1
- package/src/transpiler/{output/codegen → logic/analysis}/helpers/StatementExpressionCollector.ts +1 -1
- package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/AssignmentTargetExtractor.test.ts +2 -2
- package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/ChildStatementCollector.test.ts +2 -2
- package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/StatementExpressionCollector.test.ts +2 -2
- package/src/transpiler/output/codegen/CodeGenerator.ts +160 -742
- package/src/transpiler/output/codegen/TypeRegistrationUtils.ts +4 -6
- package/src/transpiler/output/codegen/TypeResolver.ts +2 -2
- package/src/transpiler/output/codegen/TypeValidator.ts +7 -7
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +2 -2
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +29 -1
- package/src/transpiler/output/codegen/__tests__/TypeRegistrationUtils.test.ts +36 -51
- package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +20 -17
- package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +4 -6
- package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +4 -2
- 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 +9 -9
- package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +12 -12
- package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +11 -11
- package/src/transpiler/output/codegen/assignment/AssignmentContextBuilder.ts +49 -0
- package/src/transpiler/output/codegen/assignment/IAssignmentContext.ts +15 -0
- package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +30 -17
- package/src/transpiler/output/codegen/assignment/handlers/ArrayHandlers.ts +25 -18
- package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +19 -8
- package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +3 -3
- package/src/transpiler/output/codegen/assignment/handlers/SpecialHandlers.ts +4 -4
- package/src/transpiler/output/codegen/assignment/handlers/StringHandlers.ts +5 -5
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/AccessPatternHandlers.test.ts +9 -1
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/ArrayHandlers.test.ts +41 -26
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts +29 -37
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitmapHandlers.test.ts +27 -19
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterHandlers.test.ts +10 -1
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/SpecialHandlers.test.ts +51 -33
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/StringHandlers.test.ts +9 -1
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/handlerTestUtils.ts +5 -4
- package/src/transpiler/output/codegen/generators/expressions/CallExprGenerator.ts +14 -6
- package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +19 -16
- package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprGenerator.test.ts +21 -4
- package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +15 -2
- package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +2 -1
- package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +2 -2
- package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +3 -3
- package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +1 -1
- package/src/transpiler/output/codegen/helpers/MemberSeparatorResolver.ts +6 -1
- package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +2 -2
- package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +7 -7
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +7 -7
- package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +2 -2
- package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +4 -4
- package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +2 -2
- package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +5 -5
- package/src/transpiler/state/CodeGenState.ts +157 -5
- package/src/transpiler/state/__tests__/CodeGenState.test.ts +274 -6
- /package/src/transpiler/{output/codegen → logic/analysis}/helpers/TransitiveModificationPropagator.ts +0 -0
- /package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/TransitiveModificationPropagator.test.ts +0 -0
|
@@ -33,13 +33,16 @@ function validateNotCompound(ctx: IAssignmentContext): void {
|
|
|
33
33
|
/**
|
|
34
34
|
* Handle single bit on integer variable: flags[3] <- true
|
|
35
35
|
* Also handles float bit indexing: f32Var[3] <- true
|
|
36
|
+
* Uses resolvedBaseIdentifier for proper scope prefix support.
|
|
36
37
|
*/
|
|
37
38
|
function handleIntegerBit(ctx: IAssignmentContext): string {
|
|
38
39
|
validateNotCompound(ctx);
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
// Use resolvedBaseIdentifier for type lookup and code generation
|
|
42
|
+
// e.g., "ArrayBug_flags" instead of "flags"
|
|
43
|
+
const name = ctx.resolvedBaseIdentifier;
|
|
41
44
|
const bitIndex = gen().generateExpression(ctx.subscripts[0]);
|
|
42
|
-
const typeInfo = CodeGenState.
|
|
45
|
+
const typeInfo = CodeGenState.getVariableTypeInfo(name);
|
|
43
46
|
|
|
44
47
|
// Check for float bit indexing
|
|
45
48
|
if (typeInfo) {
|
|
@@ -67,14 +70,16 @@ function handleIntegerBit(ctx: IAssignmentContext): string {
|
|
|
67
70
|
/**
|
|
68
71
|
* Handle bit range on integer variable: flags[0, 3] <- 5
|
|
69
72
|
* Also handles float bit range: f32Var[0, 8] <- 0xFF
|
|
73
|
+
* Uses resolvedBaseIdentifier for proper scope prefix support.
|
|
70
74
|
*/
|
|
71
75
|
function handleIntegerBitRange(ctx: IAssignmentContext): string {
|
|
72
76
|
validateNotCompound(ctx);
|
|
73
77
|
|
|
74
|
-
|
|
78
|
+
// Use resolvedBaseIdentifier for type lookup and code generation
|
|
79
|
+
const name = ctx.resolvedBaseIdentifier;
|
|
75
80
|
const start = gen().generateExpression(ctx.subscripts[0]);
|
|
76
81
|
const width = gen().generateExpression(ctx.subscripts[1]);
|
|
77
|
-
const typeInfo = CodeGenState.
|
|
82
|
+
const typeInfo = CodeGenState.getVariableTypeInfo(name);
|
|
78
83
|
|
|
79
84
|
// Check for float bit indexing
|
|
80
85
|
if (typeInfo) {
|
|
@@ -126,15 +131,19 @@ function handleStructMemberBit(ctx: IAssignmentContext): string {
|
|
|
126
131
|
|
|
127
132
|
/**
|
|
128
133
|
* Handle bit on multi-dimensional array element: matrix[i][j][FIELD_BIT] <- false
|
|
134
|
+
* Uses resolvedBaseIdentifier for proper scope prefix support.
|
|
129
135
|
*/
|
|
130
136
|
function handleArrayElementBit(ctx: IAssignmentContext): string {
|
|
131
137
|
validateNotCompound(ctx);
|
|
132
138
|
|
|
133
|
-
|
|
134
|
-
const
|
|
139
|
+
// Use resolvedBaseIdentifier for type lookup and code generation
|
|
140
|
+
const arrayName = ctx.resolvedBaseIdentifier;
|
|
141
|
+
const typeInfo = CodeGenState.getVariableTypeInfo(arrayName);
|
|
135
142
|
|
|
136
143
|
if (!typeInfo?.arrayDimensions) {
|
|
137
|
-
|
|
144
|
+
// Use raw identifier in error message for clarity
|
|
145
|
+
const rawName = ctx.identifiers[0];
|
|
146
|
+
throw new Error(`Error: ${rawName} is not an array`);
|
|
138
147
|
}
|
|
139
148
|
|
|
140
149
|
const numDims = typeInfo.arrayDimensions.length;
|
|
@@ -160,12 +169,14 @@ function handleArrayElementBit(ctx: IAssignmentContext): string {
|
|
|
160
169
|
*
|
|
161
170
|
* The target is a chain like array[idx].member or struct.field with a
|
|
162
171
|
* bit range subscript [start, width] at the end.
|
|
172
|
+
* Uses resolvedBaseIdentifier for proper scope prefix support.
|
|
163
173
|
*/
|
|
164
174
|
function handleStructChainBitRange(ctx: IAssignmentContext): string {
|
|
165
175
|
validateNotCompound(ctx);
|
|
166
176
|
|
|
167
177
|
// Build the base target from postfixOps, excluding the last one (the bit range)
|
|
168
|
-
|
|
178
|
+
// Use resolvedBaseIdentifier for the base to include scope prefix
|
|
179
|
+
const baseId = ctx.resolvedBaseIdentifier;
|
|
169
180
|
const opsBeforeLast = ctx.postfixOps.slice(0, -1);
|
|
170
181
|
|
|
171
182
|
let baseTarget = baseId;
|
|
@@ -109,7 +109,7 @@ function generateWriteOnlyBitmapWrite(
|
|
|
109
109
|
function handleBitmapFieldSingleBit(ctx: IAssignmentContext): string {
|
|
110
110
|
const varName = ctx.identifiers[0];
|
|
111
111
|
const fieldName = ctx.identifiers[1];
|
|
112
|
-
const typeInfo = CodeGenState.
|
|
112
|
+
const typeInfo = CodeGenState.getVariableTypeInfo(varName);
|
|
113
113
|
const bitmapType = typeInfo!.bitmapTypeName!;
|
|
114
114
|
|
|
115
115
|
const fieldInfo = getBitmapFieldInfo(bitmapType, fieldName, ctx);
|
|
@@ -130,7 +130,7 @@ function handleBitmapFieldMultiBit(ctx: IAssignmentContext): string {
|
|
|
130
130
|
function handleBitmapArrayElementField(ctx: IAssignmentContext): string {
|
|
131
131
|
const arrayName = ctx.identifiers[0];
|
|
132
132
|
const fieldName = ctx.identifiers[1];
|
|
133
|
-
const typeInfo = CodeGenState.
|
|
133
|
+
const typeInfo = CodeGenState.getVariableTypeInfo(arrayName);
|
|
134
134
|
const bitmapType = typeInfo!.bitmapTypeName!;
|
|
135
135
|
|
|
136
136
|
const fieldInfo = getBitmapFieldInfo(bitmapType, fieldName, ctx);
|
|
@@ -148,7 +148,7 @@ function handleStructMemberBitmapField(ctx: IAssignmentContext): string {
|
|
|
148
148
|
const memberName = ctx.identifiers[1];
|
|
149
149
|
const fieldName = ctx.identifiers[2];
|
|
150
150
|
|
|
151
|
-
const structTypeInfo = CodeGenState.
|
|
151
|
+
const structTypeInfo = CodeGenState.getVariableTypeInfo(structName);
|
|
152
152
|
const memberInfo = CodeGenState.getMemberTypeInfo(
|
|
153
153
|
structTypeInfo!.baseType,
|
|
154
154
|
memberName,
|
|
@@ -36,22 +36,22 @@ function getTargetTypeInfo(ctx: IAssignmentContext): {
|
|
|
36
36
|
|
|
37
37
|
// Simple identifier
|
|
38
38
|
if (ctx.isSimpleIdentifier) {
|
|
39
|
-
return { typeInfo: CodeGenState.
|
|
39
|
+
return { typeInfo: CodeGenState.getVariableTypeInfo(id) };
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
// this.member: lookup using scoped name
|
|
43
43
|
if (ctx.isSimpleThisAccess && CodeGenState.currentScope) {
|
|
44
44
|
const scopedName = `${CodeGenState.currentScope}_${id}`;
|
|
45
|
-
return { typeInfo: CodeGenState.
|
|
45
|
+
return { typeInfo: CodeGenState.getVariableTypeInfo(scopedName) };
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// global.member: lookup using direct name
|
|
49
49
|
if (ctx.isSimpleGlobalAccess) {
|
|
50
|
-
return { typeInfo: CodeGenState.
|
|
50
|
+
return { typeInfo: CodeGenState.getVariableTypeInfo(id) };
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// Fallback to direct lookup
|
|
54
|
-
return { typeInfo: CodeGenState.
|
|
54
|
+
return { typeInfo: CodeGenState.getVariableTypeInfo(id) };
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/**
|
|
@@ -42,7 +42,7 @@ function handleSimpleStringAssignment(ctx: IAssignmentContext): string {
|
|
|
42
42
|
validateNotCompound(ctx);
|
|
43
43
|
|
|
44
44
|
const id = ctx.identifiers[0];
|
|
45
|
-
const typeInfo = CodeGenState.
|
|
45
|
+
const typeInfo = CodeGenState.getVariableTypeInfo(id);
|
|
46
46
|
const capacity = typeInfo!.stringCapacity!;
|
|
47
47
|
|
|
48
48
|
CodeGenState.needsString = true;
|
|
@@ -57,7 +57,7 @@ function handleSimpleStringAssignment(ctx: IAssignmentContext): string {
|
|
|
57
57
|
* Shared helper for struct field string handlers.
|
|
58
58
|
*/
|
|
59
59
|
function getStructFieldType(structName: string, fieldName: string): string {
|
|
60
|
-
const structTypeInfo = CodeGenState.
|
|
60
|
+
const structTypeInfo = CodeGenState.getVariableTypeInfo(structName);
|
|
61
61
|
const structType = structTypeInfo!.baseType;
|
|
62
62
|
const structFields = CodeGenState.symbols!.structFields.get(structType);
|
|
63
63
|
return structFields!.get(fieldName)!;
|
|
@@ -69,7 +69,7 @@ function getStructFieldType(structName: string, fieldName: string): string {
|
|
|
69
69
|
* Shared helper for struct field handlers.
|
|
70
70
|
*/
|
|
71
71
|
function getStructType(structName: string): string {
|
|
72
|
-
const structTypeInfo = CodeGenState.
|
|
72
|
+
const structTypeInfo = CodeGenState.getVariableTypeInfo(structName);
|
|
73
73
|
return structTypeInfo!.baseType;
|
|
74
74
|
}
|
|
75
75
|
|
|
@@ -85,7 +85,7 @@ function handleStringThisMember(ctx: IAssignmentContext): string {
|
|
|
85
85
|
|
|
86
86
|
const memberName = ctx.identifiers[0];
|
|
87
87
|
const scopedName = `${CodeGenState.currentScope}_${memberName}`;
|
|
88
|
-
const typeInfo = CodeGenState.
|
|
88
|
+
const typeInfo = CodeGenState.getVariableTypeInfo(scopedName);
|
|
89
89
|
const capacity = typeInfo!.stringCapacity!;
|
|
90
90
|
|
|
91
91
|
CodeGenState.needsString = true;
|
|
@@ -123,7 +123,7 @@ function handleStringArrayElement(ctx: IAssignmentContext): string {
|
|
|
123
123
|
validateNotCompound(ctx);
|
|
124
124
|
|
|
125
125
|
const name = ctx.identifiers[0];
|
|
126
|
-
const typeInfo = CodeGenState.
|
|
126
|
+
const typeInfo = CodeGenState.getVariableTypeInfo(name);
|
|
127
127
|
const capacity = typeInfo!.stringCapacity!;
|
|
128
128
|
|
|
129
129
|
CodeGenState.needsString = true;
|
package/src/transpiler/output/codegen/assignment/handlers/__tests__/AccessPatternHandlers.test.ts
CHANGED
|
@@ -16,8 +16,14 @@ import HandlerTestUtils from "./handlerTestUtils";
|
|
|
16
16
|
function createMockContext(
|
|
17
17
|
overrides: Partial<IAssignmentContext> = {},
|
|
18
18
|
): IAssignmentContext {
|
|
19
|
+
// Default resolved values based on first identifier
|
|
20
|
+
const identifiers = overrides.identifiers ?? ["Counter", "value"];
|
|
21
|
+
const resolvedTarget = overrides.resolvedTarget ?? `${identifiers.join("_")}`;
|
|
22
|
+
const resolvedBaseIdentifier =
|
|
23
|
+
overrides.resolvedBaseIdentifier ?? identifiers[0];
|
|
24
|
+
|
|
19
25
|
return {
|
|
20
|
-
identifiers
|
|
26
|
+
identifiers,
|
|
21
27
|
subscripts: [],
|
|
22
28
|
isCompound: false,
|
|
23
29
|
cnextOp: "<-",
|
|
@@ -34,6 +40,8 @@ function createMockContext(
|
|
|
34
40
|
isSimpleIdentifier: false,
|
|
35
41
|
isSimpleThisAccess: false,
|
|
36
42
|
isSimpleGlobalAccess: false,
|
|
43
|
+
resolvedTarget,
|
|
44
|
+
resolvedBaseIdentifier,
|
|
37
45
|
...overrides,
|
|
38
46
|
} as IAssignmentContext;
|
|
39
47
|
}
|
|
@@ -28,8 +28,14 @@ import HandlerTestUtils from "./handlerTestUtils";
|
|
|
28
28
|
function createMockContext(
|
|
29
29
|
overrides: Partial<IAssignmentContext> = {},
|
|
30
30
|
): IAssignmentContext {
|
|
31
|
+
// Default resolved values based on first identifier
|
|
32
|
+
const identifiers = overrides.identifiers ?? ["arr"];
|
|
33
|
+
const resolvedTarget = overrides.resolvedTarget ?? `${identifiers[0]}[i]`;
|
|
34
|
+
const resolvedBaseIdentifier =
|
|
35
|
+
overrides.resolvedBaseIdentifier ?? identifiers[0];
|
|
36
|
+
|
|
31
37
|
return {
|
|
32
|
-
identifiers
|
|
38
|
+
identifiers,
|
|
33
39
|
subscripts: [{ mockValue: "i", start: { line: 1 } } as never],
|
|
34
40
|
isCompound: false,
|
|
35
41
|
cnextOp: "<-",
|
|
@@ -46,6 +52,8 @@ function createMockContext(
|
|
|
46
52
|
isSimpleIdentifier: false,
|
|
47
53
|
isSimpleThisAccess: false,
|
|
48
54
|
isSimpleGlobalAccess: false,
|
|
55
|
+
resolvedTarget,
|
|
56
|
+
resolvedBaseIdentifier,
|
|
49
57
|
...overrides,
|
|
50
58
|
} as IAssignmentContext;
|
|
51
59
|
}
|
|
@@ -96,6 +104,7 @@ describe("ArrayHandlers", () => {
|
|
|
96
104
|
isCompound: true,
|
|
97
105
|
cnextOp: "+<-",
|
|
98
106
|
cOp: "+=",
|
|
107
|
+
resolvedTarget: "arr[0]",
|
|
99
108
|
});
|
|
100
109
|
|
|
101
110
|
const result = getHandler()!(ctx);
|
|
@@ -109,6 +118,8 @@ describe("ArrayHandlers", () => {
|
|
|
109
118
|
});
|
|
110
119
|
const ctx = createMockContext({
|
|
111
120
|
identifiers: ["buffer"],
|
|
121
|
+
resolvedTarget: "buffer[idx]",
|
|
122
|
+
resolvedBaseIdentifier: "buffer",
|
|
112
123
|
});
|
|
113
124
|
|
|
114
125
|
const result = getHandler()!(ctx);
|
|
@@ -137,6 +148,8 @@ describe("ArrayHandlers", () => {
|
|
|
137
148
|
{ mockValue: "j", start: { line: 1 } } as never,
|
|
138
149
|
],
|
|
139
150
|
subscriptDepth: 2,
|
|
151
|
+
resolvedTarget: "matrix[i][j]",
|
|
152
|
+
resolvedBaseIdentifier: "matrix",
|
|
140
153
|
});
|
|
141
154
|
|
|
142
155
|
const result = getHandler()!(ctx);
|
|
@@ -160,6 +173,8 @@ describe("ArrayHandlers", () => {
|
|
|
160
173
|
{ mockValue: "z", start: { line: 1 } } as never,
|
|
161
174
|
],
|
|
162
175
|
subscriptDepth: 3,
|
|
176
|
+
resolvedTarget: "cube[x][y][z]",
|
|
177
|
+
resolvedBaseIdentifier: "cube",
|
|
163
178
|
});
|
|
164
179
|
|
|
165
180
|
const result = getHandler()!(ctx);
|
|
@@ -168,9 +183,9 @@ describe("ArrayHandlers", () => {
|
|
|
168
183
|
});
|
|
169
184
|
|
|
170
185
|
it("performs bounds checking when type info available", () => {
|
|
171
|
-
|
|
186
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
172
187
|
["matrix", { arrayDimensions: [10, 10], baseType: "i32" }],
|
|
173
|
-
])
|
|
188
|
+
]);
|
|
174
189
|
mockCheckArrayBounds.mockClear();
|
|
175
190
|
HandlerTestUtils.setupMockGenerator({
|
|
176
191
|
generateExpression: vi
|
|
@@ -212,6 +227,8 @@ describe("ArrayHandlers", () => {
|
|
|
212
227
|
],
|
|
213
228
|
isCompound: true,
|
|
214
229
|
cOp: "-=",
|
|
230
|
+
resolvedTarget: "grid[0][1]",
|
|
231
|
+
resolvedBaseIdentifier: "grid",
|
|
215
232
|
});
|
|
216
233
|
|
|
217
234
|
const result = getHandler()!(ctx);
|
|
@@ -225,9 +242,9 @@ describe("ArrayHandlers", () => {
|
|
|
225
242
|
arrayHandlers.find(([kind]) => kind === AssignmentKind.ARRAY_SLICE)?.[1];
|
|
226
243
|
|
|
227
244
|
it("generates memcpy for valid slice assignment", () => {
|
|
228
|
-
|
|
245
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
229
246
|
["buffer", { arrayDimensions: [100], baseType: "u8" }],
|
|
230
|
-
])
|
|
247
|
+
]);
|
|
231
248
|
HandlerTestUtils.setupMockGenerator({
|
|
232
249
|
tryEvaluateConstant: vi
|
|
233
250
|
.fn()
|
|
@@ -250,7 +267,7 @@ describe("ArrayHandlers", () => {
|
|
|
250
267
|
});
|
|
251
268
|
|
|
252
269
|
it("generates memcpy for string slice", () => {
|
|
253
|
-
|
|
270
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
254
271
|
[
|
|
255
272
|
"str",
|
|
256
273
|
{
|
|
@@ -260,7 +277,7 @@ describe("ArrayHandlers", () => {
|
|
|
260
277
|
baseType: "string",
|
|
261
278
|
},
|
|
262
279
|
],
|
|
263
|
-
])
|
|
280
|
+
]);
|
|
264
281
|
HandlerTestUtils.setupMockGenerator({
|
|
265
282
|
tryEvaluateConstant: vi
|
|
266
283
|
.fn()
|
|
@@ -282,9 +299,9 @@ describe("ArrayHandlers", () => {
|
|
|
282
299
|
});
|
|
283
300
|
|
|
284
301
|
it("throws on compound assignment", () => {
|
|
285
|
-
|
|
302
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
286
303
|
["buffer", { arrayDimensions: [100], baseType: "u8" }],
|
|
287
|
-
])
|
|
304
|
+
]);
|
|
288
305
|
HandlerTestUtils.setupMockGenerator({
|
|
289
306
|
tryEvaluateConstant: vi
|
|
290
307
|
.fn()
|
|
@@ -306,9 +323,9 @@ describe("ArrayHandlers", () => {
|
|
|
306
323
|
});
|
|
307
324
|
|
|
308
325
|
it("throws on multi-dimensional array", () => {
|
|
309
|
-
|
|
326
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
310
327
|
["matrix", { arrayDimensions: [10, 10], baseType: "u8" }],
|
|
311
|
-
])
|
|
328
|
+
]);
|
|
312
329
|
const ctx = createMockContext({
|
|
313
330
|
identifiers: ["matrix"],
|
|
314
331
|
subscripts: [
|
|
@@ -323,9 +340,9 @@ describe("ArrayHandlers", () => {
|
|
|
323
340
|
});
|
|
324
341
|
|
|
325
342
|
it("throws on non-constant offset", () => {
|
|
326
|
-
|
|
343
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
327
344
|
["buffer", { arrayDimensions: [100], baseType: "u8" }],
|
|
328
|
-
])
|
|
345
|
+
]);
|
|
329
346
|
HandlerTestUtils.setupMockGenerator({
|
|
330
347
|
tryEvaluateConstant: vi.fn().mockReturnValue(undefined),
|
|
331
348
|
});
|
|
@@ -342,9 +359,9 @@ describe("ArrayHandlers", () => {
|
|
|
342
359
|
});
|
|
343
360
|
|
|
344
361
|
it("throws on non-constant length", () => {
|
|
345
|
-
|
|
362
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
346
363
|
["buffer", { arrayDimensions: [100], baseType: "u8" }],
|
|
347
|
-
])
|
|
364
|
+
]);
|
|
348
365
|
HandlerTestUtils.setupMockGenerator({
|
|
349
366
|
tryEvaluateConstant: vi
|
|
350
367
|
.fn()
|
|
@@ -364,9 +381,9 @@ describe("ArrayHandlers", () => {
|
|
|
364
381
|
});
|
|
365
382
|
|
|
366
383
|
it("throws on out of bounds access", () => {
|
|
367
|
-
|
|
384
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
368
385
|
["buffer", { arrayDimensions: [50], baseType: "u8" }],
|
|
369
|
-
])
|
|
386
|
+
]);
|
|
370
387
|
HandlerTestUtils.setupMockGenerator({
|
|
371
388
|
tryEvaluateConstant: vi
|
|
372
389
|
.fn()
|
|
@@ -387,9 +404,9 @@ describe("ArrayHandlers", () => {
|
|
|
387
404
|
});
|
|
388
405
|
|
|
389
406
|
it("throws on negative offset", () => {
|
|
390
|
-
|
|
407
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
391
408
|
["buffer", { arrayDimensions: [100], baseType: "u8" }],
|
|
392
|
-
])
|
|
409
|
+
]);
|
|
393
410
|
HandlerTestUtils.setupMockGenerator({
|
|
394
411
|
tryEvaluateConstant: vi
|
|
395
412
|
.fn()
|
|
@@ -410,9 +427,9 @@ describe("ArrayHandlers", () => {
|
|
|
410
427
|
});
|
|
411
428
|
|
|
412
429
|
it("throws on zero length", () => {
|
|
413
|
-
|
|
430
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
414
431
|
["buffer", { arrayDimensions: [100], baseType: "u8" }],
|
|
415
|
-
])
|
|
432
|
+
]);
|
|
416
433
|
HandlerTestUtils.setupMockGenerator({
|
|
417
434
|
tryEvaluateConstant: vi
|
|
418
435
|
.fn()
|
|
@@ -433,9 +450,9 @@ describe("ArrayHandlers", () => {
|
|
|
433
450
|
});
|
|
434
451
|
|
|
435
452
|
it("throws on negative length", () => {
|
|
436
|
-
|
|
453
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
437
454
|
["buffer", { arrayDimensions: [100], baseType: "u8" }],
|
|
438
|
-
])
|
|
455
|
+
]);
|
|
439
456
|
HandlerTestUtils.setupMockGenerator({
|
|
440
457
|
tryEvaluateConstant: vi
|
|
441
458
|
.fn()
|
|
@@ -456,9 +473,7 @@ describe("ArrayHandlers", () => {
|
|
|
456
473
|
});
|
|
457
474
|
|
|
458
475
|
it("throws when buffer size cannot be determined", () => {
|
|
459
|
-
|
|
460
|
-
["unknown", { baseType: "u8" }],
|
|
461
|
-
]) as any;
|
|
476
|
+
HandlerTestUtils.setupMockTypeRegistry([["unknown", { baseType: "u8" }]]);
|
|
462
477
|
HandlerTestUtils.setupMockGenerator({
|
|
463
478
|
tryEvaluateConstant: vi
|
|
464
479
|
.fn()
|
package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts
CHANGED
|
@@ -16,8 +16,14 @@ import HandlerTestUtils from "./handlerTestUtils";
|
|
|
16
16
|
function createMockContext(
|
|
17
17
|
overrides: Partial<IAssignmentContext> = {},
|
|
18
18
|
): IAssignmentContext {
|
|
19
|
+
// Default resolved values based on first identifier
|
|
20
|
+
const identifiers = overrides.identifiers ?? ["flags"];
|
|
21
|
+
const resolvedTarget = overrides.resolvedTarget ?? `${identifiers[0]}[3]`;
|
|
22
|
+
const resolvedBaseIdentifier =
|
|
23
|
+
overrides.resolvedBaseIdentifier ?? identifiers[0];
|
|
24
|
+
|
|
19
25
|
return {
|
|
20
|
-
identifiers
|
|
26
|
+
identifiers,
|
|
21
27
|
subscripts: [{ mockValue: "3" } as never],
|
|
22
28
|
isCompound: false,
|
|
23
29
|
cnextOp: "<-",
|
|
@@ -34,6 +40,8 @@ function createMockContext(
|
|
|
34
40
|
isSimpleIdentifier: false,
|
|
35
41
|
isSimpleThisAccess: false,
|
|
36
42
|
isSimpleGlobalAccess: false,
|
|
43
|
+
resolvedTarget,
|
|
44
|
+
resolvedBaseIdentifier,
|
|
37
45
|
...overrides,
|
|
38
46
|
} as IAssignmentContext;
|
|
39
47
|
}
|
|
@@ -68,9 +76,7 @@ describe("BitAccessHandlers", () => {
|
|
|
68
76
|
)?.[1];
|
|
69
77
|
|
|
70
78
|
it("generates single bit read-modify-write", () => {
|
|
71
|
-
|
|
72
|
-
["flags", { baseType: "u32" }],
|
|
73
|
-
]) as any;
|
|
79
|
+
HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "u32" }]]);
|
|
74
80
|
HandlerTestUtils.setupMockGenerator({
|
|
75
81
|
generateExpression: vi.fn().mockReturnValue("3"),
|
|
76
82
|
});
|
|
@@ -84,9 +90,7 @@ describe("BitAccessHandlers", () => {
|
|
|
84
90
|
});
|
|
85
91
|
|
|
86
92
|
it("uses 1ULL for 64-bit types", () => {
|
|
87
|
-
|
|
88
|
-
["flags", { baseType: "u64" }],
|
|
89
|
-
]) as any;
|
|
93
|
+
HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "u64" }]]);
|
|
90
94
|
HandlerTestUtils.setupMockGenerator({
|
|
91
95
|
generateExpression: vi.fn().mockReturnValue("32"),
|
|
92
96
|
});
|
|
@@ -100,9 +104,7 @@ describe("BitAccessHandlers", () => {
|
|
|
100
104
|
});
|
|
101
105
|
|
|
102
106
|
it("uses 1ULL for signed 64-bit types", () => {
|
|
103
|
-
|
|
104
|
-
["flags", { baseType: "i64" }],
|
|
105
|
-
]) as any;
|
|
107
|
+
HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "i64" }]]);
|
|
106
108
|
HandlerTestUtils.setupMockGenerator({
|
|
107
109
|
generateExpression: vi.fn().mockReturnValue("bit"),
|
|
108
110
|
});
|
|
@@ -115,9 +117,7 @@ describe("BitAccessHandlers", () => {
|
|
|
115
117
|
});
|
|
116
118
|
|
|
117
119
|
it("converts true to 1", () => {
|
|
118
|
-
|
|
119
|
-
["flags", { baseType: "u8" }],
|
|
120
|
-
]) as any;
|
|
120
|
+
HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "u8" }]]);
|
|
121
121
|
HandlerTestUtils.setupMockGenerator({
|
|
122
122
|
generateExpression: vi.fn().mockReturnValue("0"),
|
|
123
123
|
});
|
|
@@ -131,9 +131,7 @@ describe("BitAccessHandlers", () => {
|
|
|
131
131
|
});
|
|
132
132
|
|
|
133
133
|
it("converts false to 0", () => {
|
|
134
|
-
|
|
135
|
-
["flags", { baseType: "u8" }],
|
|
136
|
-
]) as any;
|
|
134
|
+
HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "u8" }]]);
|
|
137
135
|
HandlerTestUtils.setupMockGenerator({
|
|
138
136
|
generateExpression: vi.fn().mockReturnValue("0"),
|
|
139
137
|
});
|
|
@@ -147,7 +145,7 @@ describe("BitAccessHandlers", () => {
|
|
|
147
145
|
});
|
|
148
146
|
|
|
149
147
|
it("delegates to float bit write for float types", () => {
|
|
150
|
-
|
|
148
|
+
HandlerTestUtils.setupMockTypeRegistry([["f", { baseType: "f32" }]]);
|
|
151
149
|
const generateFloatBitWrite = vi
|
|
152
150
|
.fn()
|
|
153
151
|
.mockReturnValue("float_bit_write_result");
|
|
@@ -184,9 +182,7 @@ describe("BitAccessHandlers", () => {
|
|
|
184
182
|
)?.[1];
|
|
185
183
|
|
|
186
184
|
it("generates bit range read-modify-write", () => {
|
|
187
|
-
|
|
188
|
-
["flags", { baseType: "u32" }],
|
|
189
|
-
]) as any;
|
|
185
|
+
HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "u32" }]]);
|
|
190
186
|
HandlerTestUtils.setupMockGenerator({
|
|
191
187
|
generateExpression: vi
|
|
192
188
|
.fn()
|
|
@@ -206,9 +202,7 @@ describe("BitAccessHandlers", () => {
|
|
|
206
202
|
});
|
|
207
203
|
|
|
208
204
|
it("uses correct mask for bit range", () => {
|
|
209
|
-
|
|
210
|
-
["data", { baseType: "u16" }],
|
|
211
|
-
]) as any;
|
|
205
|
+
HandlerTestUtils.setupMockTypeRegistry([["data", { baseType: "u16" }]]);
|
|
212
206
|
HandlerTestUtils.setupMockGenerator({
|
|
213
207
|
generateExpression: vi
|
|
214
208
|
.fn()
|
|
@@ -229,9 +223,7 @@ describe("BitAccessHandlers", () => {
|
|
|
229
223
|
});
|
|
230
224
|
|
|
231
225
|
it("uses ULL suffix for 64-bit bit range mask", () => {
|
|
232
|
-
|
|
233
|
-
["flags", { baseType: "u64" }],
|
|
234
|
-
]) as any;
|
|
226
|
+
HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "u64" }]]);
|
|
235
227
|
HandlerTestUtils.setupMockGenerator({
|
|
236
228
|
generateExpression: vi
|
|
237
229
|
.fn()
|
|
@@ -253,7 +245,7 @@ describe("BitAccessHandlers", () => {
|
|
|
253
245
|
});
|
|
254
246
|
|
|
255
247
|
it("delegates to float bit write for float types", () => {
|
|
256
|
-
|
|
248
|
+
HandlerTestUtils.setupMockTypeRegistry([["f", { baseType: "f32" }]]);
|
|
257
249
|
const generateFloatBitWrite = vi
|
|
258
250
|
.fn()
|
|
259
251
|
.mockReturnValue("float_range_write_result");
|
|
@@ -336,9 +328,9 @@ describe("BitAccessHandlers", () => {
|
|
|
336
328
|
)?.[1];
|
|
337
329
|
|
|
338
330
|
it("generates array element bit assignment for 1D array", () => {
|
|
339
|
-
|
|
331
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
340
332
|
["arr", { baseType: "u32", arrayDimensions: [10] }],
|
|
341
|
-
])
|
|
333
|
+
]);
|
|
342
334
|
HandlerTestUtils.setupMockGenerator({
|
|
343
335
|
generateExpression: vi
|
|
344
336
|
.fn()
|
|
@@ -360,9 +352,9 @@ describe("BitAccessHandlers", () => {
|
|
|
360
352
|
});
|
|
361
353
|
|
|
362
354
|
it("generates array element bit assignment for 2D array", () => {
|
|
363
|
-
|
|
355
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
364
356
|
["matrix", { baseType: "u16", arrayDimensions: [10, 10] }],
|
|
365
|
-
])
|
|
357
|
+
]);
|
|
366
358
|
HandlerTestUtils.setupMockGenerator({
|
|
367
359
|
generateExpression: vi
|
|
368
360
|
.fn()
|
|
@@ -386,9 +378,9 @@ describe("BitAccessHandlers", () => {
|
|
|
386
378
|
});
|
|
387
379
|
|
|
388
380
|
it("uses 1ULL for 64-bit array element", () => {
|
|
389
|
-
|
|
381
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
390
382
|
["arr", { baseType: "u64", arrayDimensions: [5] }],
|
|
391
|
-
])
|
|
383
|
+
]);
|
|
392
384
|
HandlerTestUtils.setupMockGenerator({
|
|
393
385
|
generateExpression: vi
|
|
394
386
|
.fn()
|
|
@@ -406,9 +398,9 @@ describe("BitAccessHandlers", () => {
|
|
|
406
398
|
});
|
|
407
399
|
|
|
408
400
|
it("throws when variable is not an array", () => {
|
|
409
|
-
|
|
401
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
410
402
|
["notArray", { baseType: "u32" }],
|
|
411
|
-
])
|
|
403
|
+
]);
|
|
412
404
|
const ctx = createMockContext({
|
|
413
405
|
identifiers: ["notArray"],
|
|
414
406
|
});
|
|
@@ -417,9 +409,9 @@ describe("BitAccessHandlers", () => {
|
|
|
417
409
|
});
|
|
418
410
|
|
|
419
411
|
it("throws on compound assignment", () => {
|
|
420
|
-
|
|
412
|
+
HandlerTestUtils.setupMockTypeRegistry([
|
|
421
413
|
["arr", { baseType: "u32", arrayDimensions: [10] }],
|
|
422
|
-
])
|
|
414
|
+
]);
|
|
423
415
|
const ctx = createMockContext({
|
|
424
416
|
isCompound: true,
|
|
425
417
|
cnextOp: "+<-",
|