c-next 0.1.0
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 +726 -0
- package/bin/cnext.js +5 -0
- package/grammar/C.g4 +1112 -0
- package/grammar/CNext.g4 +817 -0
- package/grammar/CPP14Lexer.g4 +282 -0
- package/grammar/CPP14Parser.g4 +1072 -0
- package/package.json +85 -0
- package/src/analysis/DivisionByZeroAnalyzer.ts +378 -0
- package/src/analysis/FunctionCallAnalyzer.ts +526 -0
- package/src/analysis/InitializationAnalyzer.ts +725 -0
- package/src/analysis/NullCheckAnalyzer.ts +427 -0
- package/src/analysis/types/IDivisionByZeroError.ts +25 -0
- package/src/analysis/types/IFunctionCallError.ts +17 -0
- package/src/analysis/types/IInitializationError.ts +55 -0
- package/src/analysis/types/INullCheckError.ts +25 -0
- package/src/codegen/CodeGenerator.ts +7945 -0
- package/src/codegen/CommentExtractor.ts +240 -0
- package/src/codegen/CommentFormatter.ts +155 -0
- package/src/codegen/HeaderGenerator.ts +265 -0
- package/src/codegen/TypeResolver.ts +365 -0
- package/src/codegen/types/ECommentType.ts +10 -0
- package/src/codegen/types/IComment.ts +21 -0
- package/src/codegen/types/ICommentError.ts +15 -0
- package/src/codegen/types/TOverflowBehavior.ts +6 -0
- package/src/codegen/types/TParameterInfo.ts +13 -0
- package/src/codegen/types/TTypeConstants.ts +94 -0
- package/src/codegen/types/TTypeInfo.ts +22 -0
- package/src/index.ts +518 -0
- package/src/lib/IncludeDiscovery.ts +131 -0
- package/src/lib/InputExpansion.ts +121 -0
- package/src/lib/PlatformIODetector.ts +162 -0
- package/src/lib/transpiler.ts +439 -0
- package/src/lib/types/ITranspileResult.ts +80 -0
- package/src/parser/c/grammar/C.interp +338 -0
- package/src/parser/c/grammar/C.tokens +229 -0
- package/src/parser/c/grammar/CLexer.interp +415 -0
- package/src/parser/c/grammar/CLexer.tokens +229 -0
- package/src/parser/c/grammar/CLexer.ts +750 -0
- package/src/parser/c/grammar/CListener.ts +976 -0
- package/src/parser/c/grammar/CParser.ts +9663 -0
- package/src/parser/c/grammar/CVisitor.ts +626 -0
- package/src/parser/cpp/grammar/CPP14Lexer.interp +478 -0
- package/src/parser/cpp/grammar/CPP14Lexer.tokens +264 -0
- package/src/parser/cpp/grammar/CPP14Lexer.ts +848 -0
- package/src/parser/cpp/grammar/CPP14Parser.interp +492 -0
- package/src/parser/cpp/grammar/CPP14Parser.tokens +264 -0
- package/src/parser/cpp/grammar/CPP14Parser.ts +19961 -0
- package/src/parser/cpp/grammar/CPP14ParserListener.ts +2120 -0
- package/src/parser/cpp/grammar/CPP14ParserVisitor.ts +1354 -0
- package/src/parser/grammar/CNext.interp +340 -0
- package/src/parser/grammar/CNext.tokens +214 -0
- package/src/parser/grammar/CNextLexer.interp +374 -0
- package/src/parser/grammar/CNextLexer.tokens +214 -0
- package/src/parser/grammar/CNextLexer.ts +668 -0
- package/src/parser/grammar/CNextListener.ts +1020 -0
- package/src/parser/grammar/CNextParser.ts +9239 -0
- package/src/parser/grammar/CNextVisitor.ts +654 -0
- package/src/preprocessor/Preprocessor.ts +301 -0
- package/src/preprocessor/ToolchainDetector.ts +225 -0
- package/src/preprocessor/types/IPreprocessResult.ts +39 -0
- package/src/preprocessor/types/IToolchain.ts +27 -0
- package/src/project/FileDiscovery.ts +236 -0
- package/src/project/Project.ts +425 -0
- package/src/project/types/IProjectConfig.ts +64 -0
- package/src/symbols/CNextSymbolCollector.ts +326 -0
- package/src/symbols/CSymbolCollector.ts +457 -0
- package/src/symbols/CppSymbolCollector.ts +362 -0
- package/src/symbols/SymbolTable.ts +312 -0
- package/src/symbols/types/IConflict.ts +20 -0
- package/src/types/ESourceLanguage.ts +10 -0
- package/src/types/ESymbolKind.ts +20 -0
- package/src/types/ISymbol.ts +45 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeResolver - Handles type inference, classification, and validation
|
|
3
|
+
* Extracted from CodeGenerator for better separation of concerns
|
|
4
|
+
*/
|
|
5
|
+
import * as Parser from "../parser/grammar/CNextParser";
|
|
6
|
+
import CodeGenerator from "./CodeGenerator";
|
|
7
|
+
import {
|
|
8
|
+
INTEGER_TYPES,
|
|
9
|
+
FLOAT_TYPES,
|
|
10
|
+
SIGNED_TYPES,
|
|
11
|
+
UNSIGNED_TYPES,
|
|
12
|
+
TYPE_WIDTH,
|
|
13
|
+
TYPE_RANGES,
|
|
14
|
+
} from "./types/TTypeConstants";
|
|
15
|
+
|
|
16
|
+
class TypeResolver {
|
|
17
|
+
private codeGen: CodeGenerator;
|
|
18
|
+
|
|
19
|
+
constructor(codeGen: CodeGenerator) {
|
|
20
|
+
this.codeGen = codeGen;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* ADR-024: Check if a type is any integer (signed or unsigned)
|
|
25
|
+
*/
|
|
26
|
+
isIntegerType(typeName: string): boolean {
|
|
27
|
+
return (INTEGER_TYPES as readonly string[]).includes(typeName);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* ADR-024: Check if a type is a floating point type
|
|
32
|
+
*/
|
|
33
|
+
isFloatType(typeName: string): boolean {
|
|
34
|
+
return (FLOAT_TYPES as readonly string[]).includes(typeName);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* ADR-024: Check if a type is a signed integer
|
|
39
|
+
*/
|
|
40
|
+
isSignedType(typeName: string): boolean {
|
|
41
|
+
return (SIGNED_TYPES as readonly string[]).includes(typeName);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* ADR-024: Check if a type is an unsigned integer
|
|
46
|
+
*/
|
|
47
|
+
isUnsignedType(typeName: string): boolean {
|
|
48
|
+
return (UNSIGNED_TYPES as readonly string[]).includes(typeName);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Check if a type is a user-defined struct
|
|
53
|
+
*/
|
|
54
|
+
isStructType(typeName: string): boolean {
|
|
55
|
+
// Access CodeGenerator's knownStructs set via reference
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
57
|
+
return this.codeGen["knownStructs"].has(typeName);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* ADR-024: Check if conversion from sourceType to targetType is narrowing
|
|
62
|
+
* Narrowing occurs when target type has fewer bits than source type
|
|
63
|
+
*/
|
|
64
|
+
isNarrowingConversion(sourceType: string, targetType: string): boolean {
|
|
65
|
+
const sourceWidth = TYPE_WIDTH[sourceType] || 0;
|
|
66
|
+
const targetWidth = TYPE_WIDTH[targetType] || 0;
|
|
67
|
+
|
|
68
|
+
if (sourceWidth === 0 || targetWidth === 0) {
|
|
69
|
+
return false; // Can't determine for unknown types
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return targetWidth < sourceWidth;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* ADR-024: Check if conversion involves a sign change
|
|
77
|
+
* Sign change occurs when converting between signed and unsigned types
|
|
78
|
+
*/
|
|
79
|
+
isSignConversion(sourceType: string, targetType: string): boolean {
|
|
80
|
+
const sourceIsSigned = this.isSignedType(sourceType);
|
|
81
|
+
const sourceIsUnsigned = this.isUnsignedType(sourceType);
|
|
82
|
+
const targetIsSigned = this.isSignedType(targetType);
|
|
83
|
+
const targetIsUnsigned = this.isUnsignedType(targetType);
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
(sourceIsSigned && targetIsUnsigned) ||
|
|
87
|
+
(sourceIsUnsigned && targetIsSigned)
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* ADR-024: Validate that a literal value fits within the target type's range.
|
|
93
|
+
* Throws an error if the value doesn't fit.
|
|
94
|
+
* @param literalText The literal text (e.g., "256", "-1", "0xFF")
|
|
95
|
+
* @param targetType The target type (e.g., "u8", "i32")
|
|
96
|
+
*/
|
|
97
|
+
validateLiteralFitsType(literalText: string, targetType: string): void {
|
|
98
|
+
const range = TYPE_RANGES[targetType];
|
|
99
|
+
if (!range) {
|
|
100
|
+
return; // No validation for unknown types (floats, bools, etc.)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Parse the literal value
|
|
104
|
+
let value: bigint;
|
|
105
|
+
try {
|
|
106
|
+
const cleanText = literalText.trim();
|
|
107
|
+
|
|
108
|
+
if (cleanText.match(/^-?\d+$/)) {
|
|
109
|
+
// Decimal integer
|
|
110
|
+
value = BigInt(cleanText);
|
|
111
|
+
} else if (cleanText.match(/^0[xX][0-9a-fA-F]+$/)) {
|
|
112
|
+
// Hex literal
|
|
113
|
+
value = BigInt(cleanText);
|
|
114
|
+
} else if (cleanText.match(/^0[bB][01]+$/)) {
|
|
115
|
+
// Binary literal
|
|
116
|
+
value = BigInt(cleanText);
|
|
117
|
+
} else {
|
|
118
|
+
// Not an integer literal we can validate
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
} catch {
|
|
122
|
+
return; // Can't parse, skip validation
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const [min, max] = range;
|
|
126
|
+
|
|
127
|
+
// Check if value is negative for unsigned type
|
|
128
|
+
if (this.isUnsignedType(targetType) && value < 0n) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`Error: Negative value ${literalText} cannot be assigned to unsigned type ${targetType}`,
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Check if value is out of range
|
|
135
|
+
if (value < min || value > max) {
|
|
136
|
+
throw new Error(
|
|
137
|
+
`Error: Value ${literalText} exceeds ${targetType} range (${min} to ${max})`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* ADR-024: Get the type from a literal (suffixed or unsuffixed).
|
|
144
|
+
* Returns the explicit suffix type, or null for unsuffixed literals.
|
|
145
|
+
*/
|
|
146
|
+
getLiteralType(ctx: Parser.LiteralContext): string | null {
|
|
147
|
+
const text = ctx.getText();
|
|
148
|
+
|
|
149
|
+
// Boolean literals
|
|
150
|
+
if (text === "true" || text === "false") return "bool";
|
|
151
|
+
|
|
152
|
+
// Check for type suffix on numeric literals
|
|
153
|
+
const suffixMatch = text.match(/([uUiI])(8|16|32|64)$/);
|
|
154
|
+
if (suffixMatch) {
|
|
155
|
+
const signChar = suffixMatch[1].toLowerCase();
|
|
156
|
+
const width = suffixMatch[2];
|
|
157
|
+
return (signChar === "u" ? "u" : "i") + width;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Float suffix
|
|
161
|
+
const floatMatch = text.match(/[fF](32|64)$/);
|
|
162
|
+
if (floatMatch) {
|
|
163
|
+
return "f" + floatMatch[1];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Unsuffixed literal - type depends on context (handled by caller)
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* ADR-024: Get the type of an expression for type checking.
|
|
172
|
+
* Returns the inferred type or null if type cannot be determined.
|
|
173
|
+
*/
|
|
174
|
+
getExpressionType(ctx: Parser.ExpressionContext): string | null {
|
|
175
|
+
// Navigate through expression tree to get the actual value
|
|
176
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
177
|
+
const postfix = this.codeGen["getPostfixExpression"](ctx);
|
|
178
|
+
if (postfix) {
|
|
179
|
+
return this.getPostfixExpressionType(postfix);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// For more complex expressions (binary ops, etc.), try to infer type
|
|
183
|
+
const ternary = ctx.ternaryExpression();
|
|
184
|
+
const orExprs = ternary.orExpression();
|
|
185
|
+
// If it's a ternary, we can't easily determine the type
|
|
186
|
+
if (orExprs.length > 1) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
const or = orExprs[0];
|
|
190
|
+
if (or.andExpression().length > 1) {
|
|
191
|
+
return "bool"; // Logical OR returns bool
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const and = or.andExpression()[0];
|
|
195
|
+
if (and.equalityExpression().length > 1) {
|
|
196
|
+
return "bool"; // Logical AND returns bool
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const eq = and.equalityExpression()[0];
|
|
200
|
+
if (eq.relationalExpression().length > 1) {
|
|
201
|
+
return "bool"; // Equality comparison returns bool
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const rel = eq.relationalExpression()[0];
|
|
205
|
+
if (rel.bitwiseOrExpression().length > 1) {
|
|
206
|
+
return "bool"; // Relational comparison returns bool
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// For arithmetic expressions, we'd need to track operand types
|
|
210
|
+
// For now, return null for complex expressions
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* ADR-024: Get the type of a postfix expression.
|
|
216
|
+
*/
|
|
217
|
+
getPostfixExpressionType(
|
|
218
|
+
ctx: Parser.PostfixExpressionContext,
|
|
219
|
+
): string | null {
|
|
220
|
+
const primary = ctx.primaryExpression();
|
|
221
|
+
if (!primary) return null;
|
|
222
|
+
|
|
223
|
+
// Get base type from primary expression
|
|
224
|
+
const baseType = this.getPrimaryExpressionType(primary);
|
|
225
|
+
|
|
226
|
+
// Check for postfix operations like bit indexing
|
|
227
|
+
const suffixes = ctx.children?.slice(1) || [];
|
|
228
|
+
for (const suffix of suffixes) {
|
|
229
|
+
const text = suffix.getText();
|
|
230
|
+
// Bit indexing: [start, width] or [index]
|
|
231
|
+
if (text.startsWith("[") && text.endsWith("]")) {
|
|
232
|
+
const inner = text.slice(1, -1);
|
|
233
|
+
if (inner.includes(",")) {
|
|
234
|
+
// Range indexing: [start, width]
|
|
235
|
+
// ADR-024: Return null for bit indexing to skip type conversion validation
|
|
236
|
+
// Bit indexing is the explicit escape hatch for narrowing/sign conversions
|
|
237
|
+
return null;
|
|
238
|
+
} else {
|
|
239
|
+
// Single bit indexing: [index] - returns bool
|
|
240
|
+
return "bool";
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return baseType;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* ADR-024: Get the type of a primary expression.
|
|
250
|
+
*/
|
|
251
|
+
getPrimaryExpressionType(
|
|
252
|
+
ctx: Parser.PrimaryExpressionContext,
|
|
253
|
+
): string | null {
|
|
254
|
+
// Check for identifier
|
|
255
|
+
const id = ctx.IDENTIFIER();
|
|
256
|
+
if (id) {
|
|
257
|
+
const name = id.getText();
|
|
258
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
259
|
+
const scopedName = this.codeGen["resolveIdentifier"](name);
|
|
260
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
261
|
+
const typeInfo = this.codeGen["context"].typeRegistry.get(scopedName);
|
|
262
|
+
if (typeInfo) {
|
|
263
|
+
return typeInfo.baseType;
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Check for literal
|
|
269
|
+
const literal = ctx.literal();
|
|
270
|
+
if (literal) {
|
|
271
|
+
return this.getLiteralType(literal);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Check for parenthesized expression
|
|
275
|
+
const expr = ctx.expression();
|
|
276
|
+
if (expr) {
|
|
277
|
+
return this.getExpressionType(expr);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Check for cast expression
|
|
281
|
+
const cast = ctx.castExpression();
|
|
282
|
+
if (cast) {
|
|
283
|
+
return cast.type().getText();
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* ADR-024: Get the type of a unary expression (for cast validation).
|
|
291
|
+
*/
|
|
292
|
+
getUnaryExpressionType(ctx: Parser.UnaryExpressionContext): string | null {
|
|
293
|
+
// Check for unary operators - type doesn't change for !, ~, -, +
|
|
294
|
+
const postfix = ctx.postfixExpression();
|
|
295
|
+
if (postfix) {
|
|
296
|
+
return this.getPostfixExpressionType(postfix);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Check for recursive unary expression
|
|
300
|
+
const unary = ctx.unaryExpression();
|
|
301
|
+
if (unary) {
|
|
302
|
+
return this.getUnaryExpressionType(unary);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* ADR-024: Validate that a type conversion is allowed.
|
|
310
|
+
* Throws error for narrowing or sign-changing conversions.
|
|
311
|
+
*/
|
|
312
|
+
validateTypeConversion(targetType: string, sourceType: string | null): void {
|
|
313
|
+
// If we can't determine source type, skip validation
|
|
314
|
+
if (!sourceType) return;
|
|
315
|
+
|
|
316
|
+
// Skip if types are the same
|
|
317
|
+
if (sourceType === targetType) return;
|
|
318
|
+
|
|
319
|
+
// Only validate integer-to-integer conversions
|
|
320
|
+
if (!this.isIntegerType(sourceType) || !this.isIntegerType(targetType))
|
|
321
|
+
return;
|
|
322
|
+
|
|
323
|
+
// Check for narrowing conversion
|
|
324
|
+
if (this.isNarrowingConversion(sourceType, targetType)) {
|
|
325
|
+
const targetWidth = TYPE_WIDTH[targetType] || 0;
|
|
326
|
+
throw new Error(
|
|
327
|
+
`Error: Cannot assign ${sourceType} to ${targetType} (narrowing). ` +
|
|
328
|
+
`Use bit indexing: value[0, ${targetWidth}]`,
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Check for sign conversion
|
|
333
|
+
if (this.isSignConversion(sourceType, targetType)) {
|
|
334
|
+
const targetWidth = TYPE_WIDTH[targetType] || 0;
|
|
335
|
+
throw new Error(
|
|
336
|
+
`Error: Cannot assign ${sourceType} to ${targetType} (sign change). ` +
|
|
337
|
+
`Use bit indexing: value[0, ${targetWidth}]`,
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Get type info for a struct member field
|
|
344
|
+
* Used to track types through member access chains like buf.data[0]
|
|
345
|
+
*/
|
|
346
|
+
getMemberTypeInfo(
|
|
347
|
+
structType: string,
|
|
348
|
+
memberName: string,
|
|
349
|
+
): { isArray: boolean; baseType: string } | undefined {
|
|
350
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
351
|
+
const fieldType = this.codeGen["structFields"]
|
|
352
|
+
.get(structType)
|
|
353
|
+
?.get(memberName);
|
|
354
|
+
if (!fieldType) return undefined;
|
|
355
|
+
|
|
356
|
+
// Check if this field is marked as an array
|
|
357
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
358
|
+
const arrayFields = this.codeGen["structFieldArrays"].get(structType);
|
|
359
|
+
const isArray = arrayFields?.has(memberName) ?? false;
|
|
360
|
+
|
|
361
|
+
return { isArray, baseType: fieldType };
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export default TypeResolver;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import ECommentType from "./ECommentType";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a comment extracted from source (ADR-043)
|
|
5
|
+
*/
|
|
6
|
+
interface IComment {
|
|
7
|
+
/** Comment type */
|
|
8
|
+
type: ECommentType;
|
|
9
|
+
/** Raw text including comment markers */
|
|
10
|
+
raw: string;
|
|
11
|
+
/** Text content without markers */
|
|
12
|
+
content: string;
|
|
13
|
+
/** Line number (1-based) */
|
|
14
|
+
line: number;
|
|
15
|
+
/** Column (0-based) */
|
|
16
|
+
column: number;
|
|
17
|
+
/** Token index for positioning relative to code */
|
|
18
|
+
tokenIndex: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default IComment;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MISRA C:2012 comment violation (ADR-043)
|
|
3
|
+
*/
|
|
4
|
+
interface ICommentError {
|
|
5
|
+
/** MISRA rule violated */
|
|
6
|
+
rule: "3.1" | "3.2";
|
|
7
|
+
/** Error message */
|
|
8
|
+
message: string;
|
|
9
|
+
/** Line number (1-based) */
|
|
10
|
+
line: number;
|
|
11
|
+
/** Column (0-based) */
|
|
12
|
+
column: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default ICommentError;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parameter information for function signatures
|
|
3
|
+
*/
|
|
4
|
+
type TParameterInfo = {
|
|
5
|
+
name: string;
|
|
6
|
+
baseType: string; // 'u32', 'f32', 'Point'
|
|
7
|
+
isArray: boolean;
|
|
8
|
+
isStruct: boolean;
|
|
9
|
+
isConst: boolean; // ADR-013
|
|
10
|
+
isCallback: boolean; // ADR-029
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default TParameterInfo;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type classification and validation constants
|
|
3
|
+
* Extracted from CodeGenerator for reuse
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Maps primitive types to their bit widths
|
|
8
|
+
*/
|
|
9
|
+
export const TYPE_WIDTH: Record<string, number> = {
|
|
10
|
+
u8: 8,
|
|
11
|
+
i8: 8,
|
|
12
|
+
u16: 16,
|
|
13
|
+
i16: 16,
|
|
14
|
+
u32: 32,
|
|
15
|
+
i32: 32,
|
|
16
|
+
u64: 64,
|
|
17
|
+
i64: 64,
|
|
18
|
+
f32: 32,
|
|
19
|
+
f64: 64,
|
|
20
|
+
bool: 1,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Maps C standard types to their bit widths
|
|
25
|
+
* Used for type resolution from C headers
|
|
26
|
+
*/
|
|
27
|
+
export const C_TYPE_WIDTH: Record<string, number> = {
|
|
28
|
+
uint8_t: 8,
|
|
29
|
+
int8_t: 8,
|
|
30
|
+
uint16_t: 16,
|
|
31
|
+
int16_t: 16,
|
|
32
|
+
uint32_t: 32,
|
|
33
|
+
int32_t: 32,
|
|
34
|
+
uint64_t: 64,
|
|
35
|
+
int64_t: 64,
|
|
36
|
+
float: 32,
|
|
37
|
+
double: 64,
|
|
38
|
+
_Bool: 1,
|
|
39
|
+
bool: 1,
|
|
40
|
+
char: 8,
|
|
41
|
+
"unsigned char": 8,
|
|
42
|
+
"signed char": 8,
|
|
43
|
+
short: 16,
|
|
44
|
+
"unsigned short": 16,
|
|
45
|
+
int: 32,
|
|
46
|
+
"unsigned int": 32,
|
|
47
|
+
long: 32, // Platform dependent, but commonly 32-bit
|
|
48
|
+
"unsigned long": 32,
|
|
49
|
+
"long long": 64,
|
|
50
|
+
"unsigned long long": 64,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* ADR-034: Bitmap type sizes (total bits)
|
|
55
|
+
*/
|
|
56
|
+
export const BITMAP_SIZE: Record<string, number> = {
|
|
57
|
+
bitmap8: 8,
|
|
58
|
+
bitmap16: 16,
|
|
59
|
+
bitmap24: 24,
|
|
60
|
+
bitmap32: 32,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* ADR-034: Bitmap backing types for C output
|
|
65
|
+
*/
|
|
66
|
+
export const BITMAP_BACKING_TYPE: Record<string, string> = {
|
|
67
|
+
bitmap8: "uint8_t",
|
|
68
|
+
bitmap16: "uint16_t",
|
|
69
|
+
bitmap24: "uint32_t", // 24-bit uses 32-bit backing for simplicity
|
|
70
|
+
bitmap32: "uint32_t",
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* ADR-024: Type classification for safe casting
|
|
75
|
+
*/
|
|
76
|
+
export const UNSIGNED_TYPES = ["u8", "u16", "u32", "u64"] as const;
|
|
77
|
+
export const SIGNED_TYPES = ["i8", "i16", "i32", "i64"] as const;
|
|
78
|
+
export const INTEGER_TYPES = [...UNSIGNED_TYPES, ...SIGNED_TYPES] as const;
|
|
79
|
+
export const FLOAT_TYPES = ["f32", "f64"] as const;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* ADR-024: Type ranges for literal validation
|
|
83
|
+
* Maps type name to [min, max] inclusive range
|
|
84
|
+
*/
|
|
85
|
+
export const TYPE_RANGES: Record<string, [bigint, bigint]> = {
|
|
86
|
+
u8: [0n, 255n],
|
|
87
|
+
u16: [0n, 65535n],
|
|
88
|
+
u32: [0n, 4294967295n],
|
|
89
|
+
u64: [0n, 18446744073709551615n],
|
|
90
|
+
i8: [-128n, 127n],
|
|
91
|
+
i16: [-32768n, 32767n],
|
|
92
|
+
i32: [-2147483648n, 2147483647n],
|
|
93
|
+
i64: [-9223372036854775808n, 9223372036854775807n],
|
|
94
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type information for variables and expressions
|
|
3
|
+
*/
|
|
4
|
+
import TOverflowBehavior from "./TOverflowBehavior";
|
|
5
|
+
|
|
6
|
+
type TTypeInfo = {
|
|
7
|
+
baseType: string;
|
|
8
|
+
bitWidth: number;
|
|
9
|
+
isArray: boolean;
|
|
10
|
+
arrayDimensions?: number[];
|
|
11
|
+
isConst: boolean;
|
|
12
|
+
isEnum?: boolean;
|
|
13
|
+
enumTypeName?: string;
|
|
14
|
+
isBitmap?: boolean;
|
|
15
|
+
bitmapTypeName?: string;
|
|
16
|
+
overflowBehavior?: TOverflowBehavior;
|
|
17
|
+
isString?: boolean;
|
|
18
|
+
stringCapacity?: number;
|
|
19
|
+
isAtomic?: boolean;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default TTypeInfo;
|