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,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C-Next Symbol Collector
|
|
3
|
+
* Extracts symbols from C-Next parse trees for the unified symbol table
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as Parser from "../parser/grammar/CNextParser";
|
|
7
|
+
import ISymbol from "../types/ISymbol";
|
|
8
|
+
import ESymbolKind from "../types/ESymbolKind";
|
|
9
|
+
import ESourceLanguage from "../types/ESourceLanguage";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Collects symbols from a C-Next parse tree
|
|
13
|
+
*/
|
|
14
|
+
class CNextSymbolCollector {
|
|
15
|
+
private sourceFile: string;
|
|
16
|
+
|
|
17
|
+
private symbols: ISymbol[] = [];
|
|
18
|
+
|
|
19
|
+
constructor(sourceFile: string) {
|
|
20
|
+
this.sourceFile = sourceFile;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Collect all symbols from a C-Next program
|
|
25
|
+
*/
|
|
26
|
+
collect(tree: Parser.ProgramContext): ISymbol[] {
|
|
27
|
+
this.symbols = [];
|
|
28
|
+
|
|
29
|
+
for (const decl of tree.declaration()) {
|
|
30
|
+
this.collectDeclaration(decl);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return this.symbols;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private collectDeclaration(decl: Parser.DeclarationContext): void {
|
|
37
|
+
// ADR-016: Handle scope declarations (renamed from namespace)
|
|
38
|
+
if (decl.scopeDeclaration()) {
|
|
39
|
+
this.collectScope(decl.scopeDeclaration()!);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (decl.structDeclaration()) {
|
|
43
|
+
this.collectStruct(decl.structDeclaration()!);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (decl.registerDeclaration()) {
|
|
47
|
+
this.collectRegister(decl.registerDeclaration()!);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (decl.functionDeclaration()) {
|
|
51
|
+
this.collectFunction(decl.functionDeclaration()!, undefined);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (decl.variableDeclaration()) {
|
|
55
|
+
this.collectVariable(decl.variableDeclaration()!, undefined);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ADR-034: Handle bitmap declarations
|
|
59
|
+
if (decl.bitmapDeclaration()) {
|
|
60
|
+
this.collectBitmap(decl.bitmapDeclaration()!, undefined);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ADR-016: Collect scope declarations (renamed from namespace)
|
|
65
|
+
private collectScope(scopeDecl: Parser.ScopeDeclarationContext): void {
|
|
66
|
+
const name = scopeDecl.IDENTIFIER().getText();
|
|
67
|
+
const line = scopeDecl.start?.line ?? 0;
|
|
68
|
+
|
|
69
|
+
this.symbols.push({
|
|
70
|
+
name,
|
|
71
|
+
kind: ESymbolKind.Namespace, // Keep as Namespace kind for backwards compat
|
|
72
|
+
sourceFile: this.sourceFile,
|
|
73
|
+
sourceLine: line,
|
|
74
|
+
sourceLanguage: ESourceLanguage.CNext,
|
|
75
|
+
isExported: true,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Collect scope members
|
|
79
|
+
for (const member of scopeDecl.scopeMember()) {
|
|
80
|
+
if (member.variableDeclaration()) {
|
|
81
|
+
this.collectVariable(member.variableDeclaration()!, name);
|
|
82
|
+
}
|
|
83
|
+
if (member.functionDeclaration()) {
|
|
84
|
+
this.collectFunction(member.functionDeclaration()!, name);
|
|
85
|
+
}
|
|
86
|
+
// ADR-034: Handle bitmap declarations in scopes
|
|
87
|
+
if (member.bitmapDeclaration()) {
|
|
88
|
+
this.collectBitmap(member.bitmapDeclaration()!, name);
|
|
89
|
+
}
|
|
90
|
+
// Handle register declarations in scopes
|
|
91
|
+
if (member.registerDeclaration()) {
|
|
92
|
+
this.collectScopedRegister(member.registerDeclaration()!, name);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Collect scoped register declarations (e.g., scope.register -> Scope_Register)
|
|
98
|
+
private collectScopedRegister(
|
|
99
|
+
reg: Parser.RegisterDeclarationContext,
|
|
100
|
+
scopeName: string,
|
|
101
|
+
): void {
|
|
102
|
+
const regName = reg.IDENTIFIER().getText();
|
|
103
|
+
const fullName = `${scopeName}_${regName}`;
|
|
104
|
+
const line = reg.start?.line ?? 0;
|
|
105
|
+
|
|
106
|
+
this.symbols.push({
|
|
107
|
+
name: fullName,
|
|
108
|
+
kind: ESymbolKind.Register,
|
|
109
|
+
sourceFile: this.sourceFile,
|
|
110
|
+
sourceLine: line,
|
|
111
|
+
sourceLanguage: ESourceLanguage.CNext,
|
|
112
|
+
isExported: true,
|
|
113
|
+
parent: scopeName,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Collect register members with full scoped prefix
|
|
117
|
+
for (const member of reg.registerMember()) {
|
|
118
|
+
const memberName = member.IDENTIFIER().getText();
|
|
119
|
+
const memberLine = member.start?.line ?? 0;
|
|
120
|
+
const accessMod = member.accessModifier().getText();
|
|
121
|
+
const memberType = member.type()?.getText() ?? "u32";
|
|
122
|
+
|
|
123
|
+
this.symbols.push({
|
|
124
|
+
name: `${fullName}_${memberName}`,
|
|
125
|
+
kind: ESymbolKind.RegisterMember,
|
|
126
|
+
type: memberType,
|
|
127
|
+
sourceFile: this.sourceFile,
|
|
128
|
+
sourceLine: memberLine,
|
|
129
|
+
sourceLanguage: ESourceLanguage.CNext,
|
|
130
|
+
isExported: true,
|
|
131
|
+
parent: fullName,
|
|
132
|
+
accessModifier: accessMod,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private collectStruct(struct: Parser.StructDeclarationContext): void {
|
|
138
|
+
const name = struct.IDENTIFIER().getText();
|
|
139
|
+
const line = struct.start?.line ?? 0;
|
|
140
|
+
|
|
141
|
+
this.symbols.push({
|
|
142
|
+
name,
|
|
143
|
+
kind: ESymbolKind.Struct,
|
|
144
|
+
sourceFile: this.sourceFile,
|
|
145
|
+
sourceLine: line,
|
|
146
|
+
sourceLanguage: ESourceLanguage.CNext,
|
|
147
|
+
isExported: true,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
private collectRegister(reg: Parser.RegisterDeclarationContext): void {
|
|
152
|
+
const name = reg.IDENTIFIER().getText();
|
|
153
|
+
const line = reg.start?.line ?? 0;
|
|
154
|
+
|
|
155
|
+
this.symbols.push({
|
|
156
|
+
name,
|
|
157
|
+
kind: ESymbolKind.Register,
|
|
158
|
+
sourceFile: this.sourceFile,
|
|
159
|
+
sourceLine: line,
|
|
160
|
+
sourceLanguage: ESourceLanguage.CNext,
|
|
161
|
+
isExported: true,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Collect register members
|
|
165
|
+
for (const member of reg.registerMember()) {
|
|
166
|
+
const memberName = member.IDENTIFIER().getText();
|
|
167
|
+
const memberLine = member.start?.line ?? 0;
|
|
168
|
+
const accessMod = member.accessModifier().getText();
|
|
169
|
+
const memberType = member.type()?.getText() ?? "u32";
|
|
170
|
+
|
|
171
|
+
this.symbols.push({
|
|
172
|
+
name: `${name}_${memberName}`,
|
|
173
|
+
kind: ESymbolKind.RegisterMember,
|
|
174
|
+
type: memberType,
|
|
175
|
+
sourceFile: this.sourceFile,
|
|
176
|
+
sourceLine: memberLine,
|
|
177
|
+
sourceLanguage: ESourceLanguage.CNext,
|
|
178
|
+
isExported: true,
|
|
179
|
+
parent: name,
|
|
180
|
+
accessModifier: accessMod,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ADR-034: Collect bitmap declarations
|
|
186
|
+
private collectBitmap(
|
|
187
|
+
bitmap: Parser.BitmapDeclarationContext,
|
|
188
|
+
parent: string | undefined,
|
|
189
|
+
): void {
|
|
190
|
+
const name = bitmap.IDENTIFIER().getText();
|
|
191
|
+
const line = bitmap.start?.line ?? 0;
|
|
192
|
+
const bitmapType = bitmap.bitmapType().getText();
|
|
193
|
+
const fullName = parent ? `${parent}_${name}` : name;
|
|
194
|
+
|
|
195
|
+
// Add the bitmap type symbol
|
|
196
|
+
this.symbols.push({
|
|
197
|
+
name: fullName,
|
|
198
|
+
kind: ESymbolKind.Bitmap,
|
|
199
|
+
type: bitmapType,
|
|
200
|
+
sourceFile: this.sourceFile,
|
|
201
|
+
sourceLine: line,
|
|
202
|
+
sourceLanguage: ESourceLanguage.CNext,
|
|
203
|
+
isExported: true,
|
|
204
|
+
parent,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Collect bitmap fields
|
|
208
|
+
let bitOffset = 0;
|
|
209
|
+
for (const member of bitmap.bitmapMember()) {
|
|
210
|
+
const fieldName = member.IDENTIFIER().getText();
|
|
211
|
+
const fieldLine = member.start?.line ?? line;
|
|
212
|
+
|
|
213
|
+
// Get field width: default 1 bit, or explicit [N]
|
|
214
|
+
let width = 1;
|
|
215
|
+
const intLiteral = member.INTEGER_LITERAL();
|
|
216
|
+
if (intLiteral) {
|
|
217
|
+
width = parseInt(intLiteral.getText(), 10);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Calculate bit range for display
|
|
221
|
+
const bitEnd = bitOffset + width - 1;
|
|
222
|
+
const bitRange =
|
|
223
|
+
width === 1 ? `bit ${bitOffset}` : `bits ${bitOffset}-${bitEnd}`;
|
|
224
|
+
|
|
225
|
+
this.symbols.push({
|
|
226
|
+
name: `${fullName}_${fieldName}`,
|
|
227
|
+
kind: ESymbolKind.BitmapField,
|
|
228
|
+
type:
|
|
229
|
+
width === 1 ? "bool" : `u${width <= 8 ? 8 : width <= 16 ? 16 : 32}`,
|
|
230
|
+
sourceFile: this.sourceFile,
|
|
231
|
+
sourceLine: fieldLine,
|
|
232
|
+
sourceLanguage: ESourceLanguage.CNext,
|
|
233
|
+
isExported: true,
|
|
234
|
+
parent: fullName,
|
|
235
|
+
signature: `${bitRange} (${width} bit${width > 1 ? "s" : ""})`,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
bitOffset += width;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
private collectFunction(
|
|
243
|
+
func: Parser.FunctionDeclarationContext,
|
|
244
|
+
parent: string | undefined,
|
|
245
|
+
): void {
|
|
246
|
+
const name = func.IDENTIFIER().getText();
|
|
247
|
+
const line = func.start?.line ?? 0;
|
|
248
|
+
const returnType = func.type()?.getText() ?? "void";
|
|
249
|
+
const fullName = parent ? `${parent}_${name}` : name;
|
|
250
|
+
|
|
251
|
+
// Build signature for overload detection
|
|
252
|
+
const params = func.parameterList()?.parameter() ?? [];
|
|
253
|
+
const paramTypes = params.map((p) => p.type()?.getText() ?? "unknown");
|
|
254
|
+
const signature = `${returnType} ${fullName}(${paramTypes.join(", ")})`;
|
|
255
|
+
|
|
256
|
+
this.symbols.push({
|
|
257
|
+
name: fullName,
|
|
258
|
+
kind: ESymbolKind.Function,
|
|
259
|
+
type: returnType,
|
|
260
|
+
sourceFile: this.sourceFile,
|
|
261
|
+
sourceLine: line,
|
|
262
|
+
sourceLanguage: ESourceLanguage.CNext,
|
|
263
|
+
isExported: true,
|
|
264
|
+
parent,
|
|
265
|
+
signature,
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Collect function parameters as symbols for hover support
|
|
269
|
+
for (const param of params) {
|
|
270
|
+
const paramName = param.IDENTIFIER().getText();
|
|
271
|
+
const paramLine = param.start?.line ?? line;
|
|
272
|
+
const paramType = param.type()?.getText() ?? "unknown";
|
|
273
|
+
const arrayDims = param.arrayDimension();
|
|
274
|
+
const isArray = arrayDims.length > 0;
|
|
275
|
+
const displayType = isArray ? `${paramType}[]` : paramType;
|
|
276
|
+
|
|
277
|
+
this.symbols.push({
|
|
278
|
+
name: paramName,
|
|
279
|
+
kind: ESymbolKind.Variable,
|
|
280
|
+
type: displayType,
|
|
281
|
+
sourceFile: this.sourceFile,
|
|
282
|
+
sourceLine: paramLine,
|
|
283
|
+
sourceLanguage: ESourceLanguage.CNext,
|
|
284
|
+
isExported: false,
|
|
285
|
+
parent: fullName, // Parent is the function
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
private collectVariable(
|
|
291
|
+
varDecl: Parser.VariableDeclarationContext,
|
|
292
|
+
parent: string | undefined,
|
|
293
|
+
): void {
|
|
294
|
+
const name = varDecl.IDENTIFIER().getText();
|
|
295
|
+
const line = varDecl.start?.line ?? 0;
|
|
296
|
+
const typeCtx = varDecl.type();
|
|
297
|
+
const varType = typeCtx ? typeCtx.getText() : "unknown";
|
|
298
|
+
const fullName = parent ? `${parent}_${name}` : name;
|
|
299
|
+
|
|
300
|
+
// Check for array (ADR-036: arrayDimension() now returns array for multi-dim)
|
|
301
|
+
const arrayDims = varDecl.arrayDimension();
|
|
302
|
+
let size: number | undefined;
|
|
303
|
+
if (arrayDims.length > 0) {
|
|
304
|
+
// Get first dimension size for symbol tracking
|
|
305
|
+
const dimText = arrayDims[0].getText();
|
|
306
|
+
const match = dimText.match(/\[(\d+)\]/);
|
|
307
|
+
if (match) {
|
|
308
|
+
size = parseInt(match[1], 10);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
this.symbols.push({
|
|
313
|
+
name: fullName,
|
|
314
|
+
kind: ESymbolKind.Variable,
|
|
315
|
+
type: varType,
|
|
316
|
+
sourceFile: this.sourceFile,
|
|
317
|
+
sourceLine: line,
|
|
318
|
+
sourceLanguage: ESourceLanguage.CNext,
|
|
319
|
+
isExported: true,
|
|
320
|
+
parent,
|
|
321
|
+
size,
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export default CNextSymbolCollector;
|