c-next 0.2.12 → 0.2.13

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.
Files changed (66) hide show
  1. package/README.md +80 -649
  2. package/dist/index.js +7387 -6211
  3. package/dist/index.js.map +4 -4
  4. package/grammar/C.g4 +9 -3
  5. package/package.json +1 -2
  6. package/src/__tests__/index.test.ts +1 -1
  7. package/src/cli/CleanCommand.ts +8 -12
  8. package/src/cli/Cli.ts +29 -6
  9. package/src/cli/Runner.ts +42 -62
  10. package/src/cli/__tests__/CleanCommand.test.ts +10 -10
  11. package/src/cli/__tests__/Cli.test.ts +59 -7
  12. package/src/cli/__tests__/ConfigPrinter.test.ts +12 -12
  13. package/src/cli/__tests__/PathNormalizer.test.ts +5 -5
  14. package/src/cli/__tests__/Runner.test.ts +108 -82
  15. package/src/cli/serve/ServeCommand.ts +1 -1
  16. package/src/cli/types/ICliConfig.ts +2 -2
  17. package/src/lib/parseWithSymbols.ts +21 -21
  18. package/src/transpiler/Transpiler.ts +88 -43
  19. package/src/transpiler/__tests__/DualCodePaths.test.ts +29 -29
  20. package/src/transpiler/__tests__/Transpiler.coverage.test.ts +244 -72
  21. package/src/transpiler/__tests__/Transpiler.test.ts +32 -72
  22. package/src/transpiler/__tests__/determineProjectRoot.test.ts +30 -28
  23. package/src/transpiler/__tests__/needsConditionalPreprocessing.test.ts +1 -1
  24. package/src/transpiler/data/CNextMarkerDetector.ts +34 -0
  25. package/src/transpiler/data/CppEntryPointScanner.ts +174 -0
  26. package/src/transpiler/data/FileDiscovery.ts +2 -105
  27. package/src/transpiler/data/InputExpansion.ts +37 -81
  28. package/src/transpiler/data/__tests__/CNextMarkerDetector.test.ts +62 -0
  29. package/src/transpiler/data/__tests__/CppEntryPointScanner.test.ts +239 -0
  30. package/src/transpiler/data/__tests__/FileDiscovery.test.ts +45 -191
  31. package/src/transpiler/data/__tests__/InputExpansion.test.ts +36 -204
  32. package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +2 -2
  33. package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +4 -5
  34. package/src/transpiler/logic/parser/c/grammar/C.interp +19 -1
  35. package/src/transpiler/logic/parser/c/grammar/C.tokens +231 -213
  36. package/src/transpiler/logic/parser/c/grammar/CLexer.interp +28 -1
  37. package/src/transpiler/logic/parser/c/grammar/CLexer.tokens +231 -213
  38. package/src/transpiler/logic/parser/c/grammar/CLexer.ts +654 -600
  39. package/src/transpiler/logic/parser/c/grammar/CParser.ts +1175 -1099
  40. package/src/transpiler/logic/symbols/SymbolTable.ts +19 -7
  41. package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +78 -0
  42. package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolInfoAdapter.test.ts +6 -6
  43. package/src/transpiler/logic/symbols/cnext/adapters/TSymbolInfoAdapter.ts +28 -27
  44. package/src/transpiler/logic/symbols/cnext/index.ts +4 -4
  45. package/src/transpiler/logic/symbols/cnext/utils/SymbolNameUtils.ts +5 -5
  46. package/src/transpiler/output/codegen/CodeGenerator.ts +7 -1
  47. package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +15 -0
  48. package/src/transpiler/output/codegen/__tests__/ExpressionWalker.test.ts +3 -3
  49. package/src/transpiler/output/codegen/__tests__/RequireInclude.test.ts +14 -14
  50. package/src/transpiler/output/codegen/__tests__/TrackVariableTypeHelpers.test.ts +2 -2
  51. package/src/transpiler/output/codegen/utils/QualifiedNameGenerator.ts +7 -7
  52. package/src/transpiler/output/codegen/utils/__tests__/QualifiedNameGenerator.test.ts +3 -3
  53. package/src/transpiler/output/headers/BaseHeaderGenerator.ts +10 -1
  54. package/src/transpiler/output/headers/HeaderGenerator.ts +3 -0
  55. package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +6 -2
  56. package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +16 -0
  57. package/src/transpiler/output/headers/adapters/HeaderSymbolAdapter.ts +19 -19
  58. package/src/transpiler/output/headers/adapters/__tests__/HeaderSymbolAdapter.test.ts +5 -5
  59. package/src/transpiler/state/SymbolRegistry.ts +10 -12
  60. package/src/transpiler/state/__tests__/SymbolRegistry.test.ts +11 -13
  61. package/src/transpiler/types/IPipelineFile.ts +3 -0
  62. package/src/transpiler/types/ITranspilerConfig.ts +2 -2
  63. package/src/transpiler/types/symbols/IScopeSymbol.ts +1 -1
  64. package/src/utils/FunctionUtils.ts +3 -3
  65. package/src/utils/__tests__/FunctionUtils.test.ts +6 -4
  66. package/src/transpiler/data/types/IDiscoveryOptions.ts +0 -15
package/README.md CHANGED
@@ -6,6 +6,7 @@
6
6
  [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=jlaustill_c-next&metric=coverage)](https://sonarcloud.io/summary/overall?id=jlaustill_c-next)
7
7
  [![Coverage Report](https://img.shields.io/badge/Coverage-Report-blue)](https://jlaustill.github.io/c-next/coverage/)
8
8
  [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=jlaustill_c-next&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=jlaustill_c-next)
9
+ [![CI](https://github.com/jlaustill/c-next/actions/workflows/pr-checks.yml/badge.svg)](https://github.com/jlaustill/c-next/actions/workflows/pr-checks.yml)
9
10
 
10
11
  A safer C for embedded systems development. Transpiles to clean, readable C.
11
12
 
@@ -43,178 +44,18 @@ void LED_toggle(void) {
43
44
  }
44
45
  ```
45
46
 
46
- ## Installation
47
-
48
- ### From npm (Recommended)
49
-
50
- ```bash
51
- npm install -g c-next
52
- ```
53
-
54
- Verify the installation:
55
-
56
- ```bash
57
- cnext --version
58
- ```
59
-
60
- ### From Source (Development)
61
-
62
- ```bash
63
- git clone https://github.com/jlaustill/c-next.git
64
- cd c-next
65
- npm install
66
- npm link
67
- ```
68
-
69
- ## Usage
70
-
71
- ```bash
72
- # Transpile to C (output alongside input file)
73
- cnext examples/blink.cnx
74
-
75
- # Explicit output path
76
- cnext examples/blink.cnx -o blink.c
77
-
78
- # Parse only (syntax check)
79
- cnext examples/blink.cnx --parse
80
-
81
- # Output as C++ (.cpp)
82
- cnext examples/blink.cnx --cpp
83
-
84
- # Target platform for atomic code generation (ADR-049)
85
- cnext examples/blink.cnx --target teensy41
86
-
87
- # Separate output directories for code and headers
88
- cnext src/ -o build/src --header-out build/include
89
-
90
- # Clean generated files
91
- cnext src/ -o build/src --header-out build/include --clean
92
-
93
- # Show all options
94
- cnext --help
95
- ```
96
-
97
- ## VS Code Extension
98
-
99
- The C-Next VS Code extension provides syntax highlighting, live C preview, IntelliSense, and error diagnostics.
100
-
101
- **Install from:** [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=jlaustill.vscode-c-next) (coming soon)
102
-
103
- **Source:** [github.com/jlaustill/vscode-c-next](https://github.com/jlaustill/vscode-c-next)
104
-
105
- ## Getting Started with PlatformIO
106
-
107
- C-Next integrates seamlessly with PlatformIO embedded projects. The transpiler automatically converts `.cnx` files to `.c`, `.h`, and `.cpp` as needed before each build.
108
-
109
- ### Quick Setup
110
-
111
- From your PlatformIO project root:
112
-
113
- ```bash
114
- cnext --pio-install
115
- ```
116
-
117
- This command:
118
-
119
- - Creates `cnext_build.py` (pre-build transpilation script)
120
- - Modifies `platformio.ini` to add `extra_scripts = pre:cnext_build.py`
121
-
122
- ### Usage
123
-
124
- 1. **Create `.cnx` files in your `src/` directory** (alongside existing `.c`/`.cpp` files)
125
-
126
- ```bash
127
- src/
128
- ├── main.cpp # Existing C++ code
129
- ├── ConfigStorage.cnx # New c-next code
130
- └── SensorProcessor.cnx # New c-next code
131
- ```
47
+ ## Why C-Next?
132
48
 
133
- 2. **Build as usual** — transpilation happens automatically:
49
+ C-Next transpiles to **standard C99**. Your existing toolchain GCC, Clang, IAR, arm-none-eabi-gcc — compiles the output.
134
50
 
135
- ```bash
136
- pio run
137
- ```
138
-
139
- Output:
140
-
141
- ```
142
- Transpiling 2 c-next files...
143
- ✓ ConfigStorage.cnx
144
- ✓ SensorProcessor.cnx
145
- Building...
146
- ```
147
-
148
- 3. **Commit both `.cnx` and generated `.c|.cpp|.h` files** to version control
149
-
150
- ### Why Commit Generated Files?
151
-
152
- Generated `.c|.cpp|.h` files are **reviewable artifacts** in pull requests:
153
-
154
- ```diff
155
- + // ConfigStorage.cnx
156
- + u8 validate_config() {
157
- + counter +<- 1;
158
- + }
159
-
160
- + // ConfigStorage.c (generated)
161
- + uint8_t validate_config(void) {
162
- + counter = cnx_clamp_add_u8(counter, 1);
163
- + }
164
- ```
165
-
166
- **Benefits**:
167
-
168
- - See exactly what C/CPP code the transpiler generates
169
- - Review safety features (overflow protection, atomic operations)
170
- - Verify transpiler behavior
171
- - Build succeeds even if transpiler isn't available
172
-
173
- This follows the same pattern as TypeScript committing `.js` files or Bison committing generated parsers.
174
-
175
- ### Example Project Structure
176
-
177
- ```
178
- my-teensy-project/
179
- ├── platformio.ini # PlatformIO config
180
- ├── cnext_build.py # Auto-generated transpilation script
181
- ├── src/
182
- │ ├── main.cpp # C++ entry point
183
- │ ├── ConfigStorage.cnx # c-next source
184
- │ ├── ConfigStorage.cpp # Generated (committed)
185
- │ ├── SensorProcessor.cnx # c-next source
186
- │ └── SensorProcessor.cpp # Generated (committed)
187
- └── include/
188
- └── AppConfig.h # Shared types
189
- ```
190
-
191
- ### Uninstall
192
-
193
- To remove c-next integration:
194
-
195
- ```bash
196
- cnext --pio-uninstall
197
- ```
198
-
199
- This removes:
200
-
201
- - `cnext_build.py` script
202
- - `extra_scripts` reference from `platformio.ini`
51
+ This means:
203
52
 
204
- Your `.cnx` files and generated `.c|.cpp|.h` files remain untouched.
53
+ - **50+ years of GCC optimizations** work out of the box
54
+ - **Existing debuggers and profilers** just work (GDB, Ozone, etc.)
55
+ - **No new runtime** — the generated C is what runs on your hardware
56
+ - **Incremental adoption** — drop a single `.cnx` file into an existing project
205
57
 
206
- ### Manual Integration
207
-
208
- If you prefer manual control, you can also run the transpiler explicitly:
209
-
210
- ```bash
211
- # Transpile all .cnx files in a directory (recursive)
212
- cnext src/
213
-
214
- # Or transpile specific files
215
- cnext src/ConfigStorage.cnx
216
- cnext src/SensorProcessor.cnx
217
- ```
58
+ Other memory-safe languages require adopting an entirely new toolchain, build system, and ecosystem. C-Next gives you safety improvements while keeping your investment in C infrastructure.
218
59
 
219
60
  ## Philosophy
220
61
 
@@ -266,412 +107,126 @@ Generated headers automatically include guards:
266
107
 
267
108
  **Guiding Principle:** If Linus Torvalds wouldn't approve of the complexity, it doesn't ship. Safety through removal, not addition.
268
109
 
269
- ## Core Features
270
-
271
- ### Assignment: `<-` vs Equality: `=`
272
-
273
- Eliminates the `if (x = 5)` bug by design:
274
-
275
- ```cnx
276
- x <- 5; // assignment: value flows INTO x
277
- if (x = 5) // comparison: single equals, just like math
278
- ```
279
-
280
- ### Fixed-Width Types
281
-
282
- ```cnx
283
- u8, u16, u32, u64 // unsigned integers
284
- i8, i16, i32, i64 // signed integers
285
- f32, f64 // floating point
286
- bool // boolean
287
- ```
288
-
289
- ### Register Bindings
290
-
291
- Type-safe hardware access with access modifiers:
292
-
293
- ```cnx
294
- register GPIO7 @ 0x42004000 {
295
- DR: u32 rw @ 0x00, // Read-Write
296
- PSR: u32 ro @ 0x08, // Read-Only
297
- DR_SET: u32 wo @ 0x84, // Write-Only (atomic set)
298
- DR_CLEAR: u32 wo @ 0x88, // Write-Only (atomic clear)
299
- DR_TOGGLE: u32 wo @ 0x8C, // Write-Only (atomic toggle)
300
- }
301
- ```
302
-
303
- ### Type-Aware Bit Indexing
304
-
305
- Integers are indexable as bit arrays:
306
-
307
- ```cnx
308
- u8 flags <- 0;
309
- flags[3] <- true; // Set bit 3
310
- flags[0, 3] <- 5; // Set 3 bits starting at bit 0
311
- bool isSet <- flags[3]; // Read bit 3
312
-
313
- // .length property
314
- u8 buffer[16];
315
- buffer.length; // 16 (array element count)
316
- flags.length; // 8 (bit width of u8)
317
- ```
318
-
319
- Write-only registers generate optimized code:
320
-
321
- ```cnx
322
- GPIO7.DR_SET[LED_BIT] <- true; // Generates: GPIO7_DR_SET = (1 << LED_BIT);
323
- ```
324
-
325
- ### Slice Assignment for Memory Operations
326
-
327
- Multi-byte copying with compile-time validated `memcpy` generation (Issue #234):
328
-
329
- ```cnx
330
- u8 buffer[256];
331
- u32 magic <- 0x12345678;
332
-
333
- // Copy 4 bytes from value into buffer at offset 0
334
- buffer[0, 4] <- magic;
335
-
336
- // Named offsets using const variables
337
- const u32 HEADER_OFFSET <- 0;
338
- const u32 DATA_OFFSET <- 8;
339
- buffer[HEADER_OFFSET, 4] <- magic;
340
- buffer[DATA_OFFSET, 8] <- timestamp;
341
- ```
342
-
343
- Transpiles to direct memcpy (bounds validated at compile time):
344
-
345
- ```c
346
- uint8_t buffer[256] = {0};
347
- uint32_t magic = 0x12345678;
348
-
349
- memcpy(&buffer[0], &magic, 4);
350
- memcpy(&buffer[8], &timestamp, 8);
351
- ```
352
-
353
- **Key Features:**
354
-
355
- - **Compile-time bounds checking** prevents buffer overflows at compile time
356
- - Offset and length must be compile-time constants (literals or `const` variables)
357
- - Silent runtime failures are now compile-time errors
358
- - Works with struct fields: `buffer[0, 4] <- config.magic`
359
- - Distinct from bit operations: array slices use `memcpy`, scalar bit ranges use bit manipulation
360
-
361
- ### Scopes (ADR-016)
362
-
363
- Organize code with automatic name prefixing. Inside scopes, explicit qualification is available to avoid naming collisions:
364
-
365
- - `this.X` for scope-local members
366
- - `global.X` for global variables, functions, and registers
367
-
368
- If the same name exists in local, scope, and global levels, the precedence is local, scope, global just like you are used to in other languages.
369
-
370
- ```cnx
371
- const u8 LED_BIT <- 3;
372
-
373
- scope LED {
374
- u8 brightness <- 100;
375
-
376
- void on() { global.GPIO7.DR_SET[global.LED_BIT] <- true; }
377
- void off() { global.GPIO7.DR_CLEAR[global.LED_BIT] <- true; }
378
-
379
- u8 getBrightness() { return this.brightness; }
380
- }
381
-
382
- // Call as:
383
- LED.on();
384
- LED.off();
385
- ```
386
-
387
- Transpiles to:
388
-
389
- ```c
390
- const uint8_t LED_BIT = 3;
391
-
392
- static uint8_t LED_brightness = 100;
393
-
394
- void LED_on(void) { GPIO7_DR_SET = (1 << LED_BIT); }
395
- void LED_off(void) { GPIO7_DR_CLEAR = (1 << LED_BIT); }
396
-
397
- uint8_t LED_getBrightness(void) { return LED_brightness; }
398
- ```
399
-
400
- ### Switch Statements (ADR-025)
401
-
402
- Safe switch with MISRA compliance:
403
-
404
- - Braces replace break (no colons needed)
405
- - No fallthrough allowed
406
- - Multiple cases with `||` syntax
407
- - Counted `default(n)` for enum exhaustiveness
408
-
409
- ```cnx
410
- enum EState { IDLE, RUNNING, STOPPED }
411
-
412
- void handleState(EState state) {
413
- switch (state) {
414
- case EState.IDLE {
415
- startMotor();
416
- }
417
- case EState.RUNNING || EState.STOPPED {
418
- checkSensors();
419
- }
420
- }
421
- }
422
- ```
423
-
424
- Transpiles to:
425
-
426
- ```c
427
- switch (state) {
428
- case EState_IDLE: {
429
- startMotor();
430
- break;
431
- }
432
- case EState_RUNNING:
433
- case EState_STOPPED: {
434
- checkSensors();
435
- break;
436
- }
437
- }
438
- ```
439
-
440
- ### Ternary Operator (ADR-022)
441
-
442
- Safe conditional expressions with MISRA compliance:
443
-
444
- - Parentheses required around condition
445
- - Condition must be boolean (comparison or logical)
446
- - No nesting allowed (use if/else instead)
447
-
448
- ```cnx
449
- u32 max <- (a > b) ? a : b;
450
- u32 abs <- (x < 0) ? -x : x;
451
- u32 result <- (a > 0 && b > 0) ? a : b;
110
+ ## Installation
452
111
 
453
- // ERROR: Condition must be boolean
454
- // u32 bad <- (x) ? 1 : 0;
112
+ ### From npm (Recommended)
455
113
 
456
- // ERROR: Nested ternary not allowed
457
- // i32 sign <- (x > 0) ? 1 : (x < 0) ? -1 : 0;
114
+ ```bash
115
+ npm install -g c-next
458
116
  ```
459
117
 
460
- ### Bounded Strings (ADR-045)
461
-
462
- Safe, statically-allocated strings with compile-time capacity checking:
463
-
464
- ```cnx
465
- string<64> name <- "Hello"; // 64-char capacity, transpiles to char[65]
466
- string<128> message; // Empty string, initialized to ""
467
- const string VERSION <- "1.0.0"; // Auto-sized to string<5>
468
-
469
- // Properties
470
- u32 len <- name.length; // Runtime: strlen(name)
471
- u32 cap <- name.capacity; // Compile-time: 64
472
-
473
- // Comparison - uses strcmp
474
- if (name = "Hello") { } // strcmp(name, "Hello") == 0
475
-
476
- // Concatenation with capacity validation
477
- string<32> first <- "Hello";
478
- string<32> second <- " World";
479
- string<64> result <- first + second; // OK: 64 >= 32 + 32
118
+ Verify the installation:
480
119
 
481
- // Substring extraction with bounds checking
482
- string<5> greeting <- name[0, 5]; // First 5 chars
120
+ ```bash
121
+ cnext --version
483
122
  ```
484
123
 
485
- All operations are validated at compile time:
486
-
487
- - Literal overflow → compile error
488
- - Truncation on assignment → compile error
489
- - Concatenation capacity mismatch → compile error
490
- - Substring out of bounds → compile error
491
-
492
- ### Callbacks (ADR-029)
493
-
494
- Type-safe function pointers with the Function-as-Type pattern:
495
-
496
- - A function definition creates both a callable function AND a type
497
- - Nominal typing: type identity is the function name, not just signature
498
- - Never null: callbacks are always initialized to their default function
499
-
500
- ```cnx
501
- // Define callback type with default behavior
502
- void onReceive(const CAN_Message_T msg) {
503
- // default: no-op
504
- }
505
-
506
- struct Controller {
507
- onReceive _handler; // Type is onReceive, initialized to default
508
- }
509
-
510
- // User implementation must match signature
511
- void myHandler(const CAN_Message_T msg) {
512
- Serial.println(msg.id);
513
- }
124
+ ### From Source (Development)
514
125
 
515
- controller._handler <- myHandler; // OK: signature matches
516
- controller._handler(msg); // Always safe - never null
126
+ ```bash
127
+ git clone https://github.com/jlaustill/c-next.git
128
+ cd c-next
129
+ npm install
130
+ npm link
517
131
  ```
518
132
 
519
- Transpiles to:
520
-
521
- ```c
522
- void onReceive(const CAN_Message_T msg) { }
133
+ ## Usage
523
134
 
524
- typedef void (*onReceive_fp)(const CAN_Message_T);
135
+ ```bash
136
+ # Transpile to C (output alongside input file)
137
+ cnext examples/blink.cnx
525
138
 
526
- struct Controller {
527
- onReceive_fp _handler;
528
- };
139
+ # Explicit output path
140
+ cnext examples/blink.cnx -o blink.c
529
141
 
530
- // Initialization always sets to default
531
- struct Controller Controller_init(void) {
532
- return (struct Controller){ ._handler = onReceive };
533
- }
534
- ```
142
+ # Parse only (syntax check)
143
+ cnext examples/blink.cnx --parse
535
144
 
536
- ### Atomic Variables (ADR-049)
145
+ # Output as C++ (.cpp)
146
+ cnext examples/blink.cnx --cpp
537
147
 
538
- ISR-safe variables with hardware-assisted atomicity:
148
+ # Target platform for atomic code generation (ADR-049)
149
+ cnext examples/blink.cnx --target teensy41
539
150
 
540
- ```cnx
541
- #pragma target teensy41
151
+ # Separate output directories for code and headers
152
+ cnext src/main.cnx -o build/src --header-out build/include
542
153
 
543
- atomic u32 counter <- 0; // ISR-safe with LDREX/STREX
544
- atomic clamp u8 brightness <- 100; // Combines atomic + clamp
154
+ # Clean generated files
155
+ cnext src/main.cnx -o build/src --header-out build/include --clean
545
156
 
546
- void increment() {
547
- counter +<- 1; // Lock-free atomic increment
548
- }
157
+ # Show all options
158
+ cnext --help
549
159
  ```
550
160
 
551
- Generates optimized code based on target platform:
552
-
553
- - **Cortex-M3/M4/M7**: LDREX/STREX retry loops (lock-free)
554
- - **Cortex-M0/M0+**: PRIMASK disable/restore (interrupt masking)
555
-
556
- Target detection priority: `--target` CLI flag > `platformio.ini` > `#pragma target` > default
557
-
558
- ### Volatile Variables (ADR-108)
559
-
560
- Prevent compiler optimization for variables that change outside normal program flow:
161
+ ## Incremental Adoption
561
162
 
562
- ```cnx
563
- // Delay loop - prevent optimization
564
- void delay_ms(const u32 ms) {
565
- volatile u32 i <- 0;
566
- volatile u32 count <- ms * 2000;
567
-
568
- while (i < count) {
569
- i +<- 1; // Compiler cannot optimize away
570
- }
571
- }
163
+ C-Next supports gradual migration from existing C/C++ codebases. Convert files one at a time, starting with leaf modules:
572
164
 
573
- // Hardware register - reads actual memory
574
- volatile u32 status_register @ 0x40020000;
165
+ **Step 1:** Convert a leaf file to C-Next and transpile it:
575
166
 
576
- void waitReady() {
577
- while (status_register & 0x01 = 0) {
578
- // Always reads from hardware
579
- }
580
- }
167
+ ```bash
168
+ cnext led.cnx # Generates led.h and led.c
581
169
  ```
582
170
 
583
- **When to use:**
584
-
585
- - ✅ Delay loops that must not be optimized away
586
- - ✅ Memory-mapped hardware registers
587
- - ✅ Variables polled in tight loops
588
- - ❌ ISR-shared variables (use `atomic` instead for RMW safety)
589
-
590
- **Key difference from `atomic`:**
171
+ **Step 2:** Include the generated header in your existing code:
591
172
 
592
- - `volatile` = prevents optimization only
593
- - `atomic` = prevents optimization + adds synchronization (ISR-safe)
594
-
595
- ### Critical Sections (ADR-050)
596
-
597
- Multi-statement atomic blocks with automatic interrupt masking:
598
-
599
- ```cnx
600
- u8 buffer[64];
601
- u32 writeIdx <- 0;
173
+ ```cpp
174
+ // main.cpp
175
+ #include "led.h"
602
176
 
603
- void enqueue(u8 data) {
604
- critical {
605
- buffer[writeIdx] <- data;
606
- writeIdx +<- 1;
607
- }
177
+ int main() {
178
+ LED_on();
179
+ return 0;
608
180
  }
609
181
  ```
610
182
 
611
- Transpiles to PRIMASK save/restore:
183
+ **Step 3:** Run the transpiler on your C/C++ entry point to auto-discover and re-transpile all C-Next dependencies:
612
184
 
613
- ```c
614
- void enqueue(uint8_t data) {
615
- {
616
- uint32_t __primask = __get_PRIMASK();
617
- __disable_irq();
618
- buffer[writeIdx] = data;
619
- writeIdx += 1;
620
- __set_PRIMASK(__primask);
621
- }
622
- }
185
+ ```bash
186
+ cnext main.cpp # Discovers led.cnx via header marker, transpiles it
623
187
  ```
624
188
 
625
- **Safety**: `return` inside `critical { }` is a compile error (E0853).
626
-
627
- ### NULL for C Library Interop (ADR-047)
628
-
629
- Safe interop with C stream functions that can return NULL:
630
-
631
- ```cnx
632
- #include <stdio.h>
633
-
634
- string<64> buffer;
635
-
636
- void readInput() {
637
- // NULL check is REQUIRED - compiler enforces it
638
- if (fgets(buffer, buffer.size, stdin) != NULL) {
639
- printf("Got: %s", buffer);
640
- }
641
- }
642
- ```
189
+ The transpiler automatically discovers C-Next files by scanning the include tree for headers containing generation markers (e.g., `Generated by C-Next Transpiler from: led.cnx`). When changes are made to any `.cnx` file, running `cnext main.cpp` ensures all generated code is up-to-date.
643
190
 
644
- **Constraints:**
191
+ ## VS Code Extension
645
192
 
646
- - NULL only valid in comparison context (`!= NULL` or `= NULL`)
647
- - Only whitelisted stream functions: `fgets`, `fputs`, `fgetc`, `fputc`
648
- - Cannot store C pointer returns in variables
649
- - `fopen`, `malloc`, etc. are errors (see ADR-103 for future FILE\* support)
193
+ The C-Next VS Code extension provides syntax highlighting, live C preview, IntelliSense, and error diagnostics.
650
194
 
651
- ### Startup Allocation
195
+ **Install from:** [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=jlaustill.vscode-c-next) (coming soon)
652
196
 
653
- Allocate at startup, run with fixed memory. Per MISRA C:2023 Dir 4.12: all memory is allocated during initialization, then forbidden. No runtime allocation means no fragmentation, no OOM, no leaks.
197
+ **Source:** [github.com/jlaustill/vscode-c-next](https://github.com/jlaustill/vscode-c-next)
654
198
 
655
- ## Hardware Testing
199
+ ## Getting Started with PlatformIO
656
200
 
657
- Verified on **Teensy MicroMod**, **Teensy 4.0**, and **STM32** hardware:
201
+ C-Next integrates seamlessly with PlatformIO. Quick setup:
658
202
 
659
203
  ```bash
660
- # Build and flash with PlatformIO
661
- cd test-teensy
662
- pio run -t upload
204
+ cnext --pio-install
663
205
  ```
664
206
 
665
- See `examples/blink.cnx` for the complete LED blink example.
207
+ This creates a pre-build script that automatically transpiles `.cnx` files before each build.
208
+
209
+ **Full guide:** See [PlatformIO Integration](docs/platformio-integration.md) for the complete workflow including why you should commit generated files.
666
210
 
667
211
  ## Projects Using C-Next
668
212
 
669
- | Project | Description |
670
- | ----------------------------------------- | -------------------------------------------------------------------------- |
671
- | [OSSM](https://github.com/jlaustill/ossm) | Open-source stroke machine firmware using C-Next for safe embedded control |
213
+ | Project | Description |
214
+ | ----------------------------------------- | ---------------------------------------------------------------------------------- |
215
+ | [OSSM](https://github.com/jlaustill/ossm) | Open-source stroke machine firmware using C-Next for safe embedded control |
216
+ | [test-teensy](test-teensy/) | Hardware verification project — validates transpiler output on Teensy MicroMod/4.0 |
672
217
 
673
218
  _Using C-Next in your project? Open an issue to get listed!_
674
219
 
220
+ ## Documentation
221
+
222
+ | Resource | Description |
223
+ | ------------------------------------------------------------- | ------------------------------------------ |
224
+ | [Language Guide](docs/language-guide.md) | Complete reference for all C-Next features |
225
+ | [Architecture Decisions](docs/architecture-decisions.md) | 50+ ADRs documenting design choices |
226
+ | [Learn C-Next in Y Minutes](docs/learn-cnext-in-y-minutes.md) | Quick syntax overview |
227
+ | [Error Codes](docs/error-codes.md) | Compiler error reference |
228
+ | [MISRA Compliance](docs/misra-compliance.md) | MISRA C:2012 compliance details |
229
+
675
230
  ## Project Structure
676
231
 
677
232
  ```
@@ -692,110 +247,6 @@ c-next/
692
247
  └── docs/decisions/ # Architecture Decision Records
693
248
  ```
694
249
 
695
- ## Architecture Decision Records
696
-
697
- Decisions are documented in `/docs/decisions/`:
698
-
699
- ### Implemented
700
-
701
- | ADR | Title | Description |
702
- | --------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------ |
703
- | [ADR-001](docs/decisions/adr-001-assignment-operator.md) | Assignment Operator | `<-` for assignment, `=` for comparison |
704
- | [ADR-003](docs/decisions/adr-003-static-allocation.md) | Static Allocation | No dynamic memory after init |
705
- | [ADR-004](docs/decisions/adr-004-register-bindings.md) | Register Bindings | Type-safe hardware access |
706
- | [ADR-006](docs/decisions/adr-006-simplified-references.md) | Simplified References | Pass by reference, no pointer syntax |
707
- | [ADR-007](docs/decisions/adr-007-type-aware-bit-indexing.md) | Type-Aware Bit Indexing | Integers as bit arrays, `.length` property |
708
- | [ADR-010](docs/decisions/adr-010-c-interoperability.md) | C Interoperability | Unified ANTLR parser architecture |
709
- | [ADR-011](docs/decisions/adr-011-vscode-extension.md) | VS Code Extension | Live C preview with syntax highlighting |
710
- | [ADR-012](docs/decisions/adr-012-static-analysis.md) | Static Analysis | cppcheck integration for generated C |
711
- | [ADR-013](docs/decisions/adr-013-const-qualifier.md) | Const Qualifier | Compile-time const enforcement |
712
- | [ADR-014](docs/decisions/adr-014-structs.md) | Structs | Data containers without methods |
713
- | [ADR-015](docs/decisions/adr-015-null-state.md) | Null State | Zero initialization for all variables |
714
- | [ADR-016](docs/decisions/adr-016-scope.md) | Scope | `this.`/`global.` explicit qualification |
715
- | [ADR-017](docs/decisions/adr-017-enums.md) | Enums | Type-safe enums with C-style casting |
716
- | [ADR-030](docs/decisions/adr-030-forward-declarations.md) | Define-Before-Use | Functions must be defined before called |
717
- | [ADR-037](docs/decisions/adr-037-preprocessor.md) | Preprocessor | Flag-only defines, const for values |
718
- | [ADR-043](docs/decisions/adr-043-comments.md) | Comments | Comment preservation with MISRA compliance |
719
- | [ADR-044](docs/decisions/adr-044-primitive-types.md) | Primitive Types | Fixed-width types with `clamp`/`wrap` overflow |
720
- | [ADR-024](docs/decisions/adr-024-type-casting.md) | Type Casting | Widening implicit, narrowing uses bit indexing |
721
- | [ADR-022](docs/decisions/adr-022-conditional-expressions.md) | Conditional Expressions | Ternary with required parens, boolean condition, no nesting |
722
- | [ADR-025](docs/decisions/adr-025-switch-statements.md) | Switch Statements | Safe switch with braces, `\|\|` syntax, counted `default(n)` |
723
- | [ADR-029](docs/decisions/adr-029-function-pointers.md) | Callbacks | Function-as-Type pattern with nominal typing |
724
- | [ADR-045](docs/decisions/adr-045-string-type.md) | Bounded Strings | `string<N>` with compile-time safety |
725
- | [ADR-023](docs/decisions/adr-023-sizeof.md) | Sizeof | Type/value size queries with safety checks |
726
- | [ADR-027](docs/decisions/adr-027-do-while.md) | Do-While | `do { } while ()` with boolean condition (E0701) |
727
- | [ADR-032](docs/decisions/adr-032-nested-structs.md) | Nested Structs | Named nested structs only (no anonymous) |
728
- | [ADR-035](docs/decisions/adr-035-array-initializers.md) | Array Initializers | `[1, 2, 3]` syntax with `[0*]` fill-all |
729
- | [ADR-036](docs/decisions/adr-036-multidimensional-arrays.md) | Multi-dim Arrays | `arr[i][j]` with compile-time bounds enforcement |
730
- | [ADR-040](docs/decisions/adr-040-isr-declaration.md) | ISR Type | Built-in `ISR` type for `void(void)` function pointers |
731
- | [ADR-034](docs/decisions/adr-034-bit-fields.md) | Bitmap Types | `bitmap8`/`bitmap16`/`bitmap32` for portable bit-packed data |
732
- | [ADR-048](docs/decisions/adr-048-cli-executable.md) | CLI Executable | `cnext` command with smart defaults |
733
- | [ADR-049](docs/decisions/adr-049-atomic-types.md) | Atomic Types | `atomic` keyword with LDREX/STREX or PRIMASK fallback |
734
- | [ADR-050](docs/decisions/adr-050-critical-sections.md) | Critical Sections | `critical { }` blocks with PRIMASK save/restore |
735
- | [ADR-108](docs/decisions/adr-108-volatile-keyword.md) | Volatile Variables | `volatile` keyword prevents compiler optimization |
736
- | [ADR-046](docs/decisions/adr-046-nullable-c-interop.md) | Nullable C Interop | `c_` prefix for nullable C pointer types |
737
- | [ADR-053](docs/decisions/adr-053-transpiler-pipeline-architecture.md) | Transpiler Pipeline | Unified multi-pass pipeline with header symbol extraction |
738
- | [ADR-057](docs/decisions/adr-057-implicit-scope-resolution.md) | Implicit Scope Resolution | Bare identifiers resolve local → scope → global |
739
- | [ADR-055](docs/decisions/adr-055-symbol-parser-architecture.md) | Symbol Parser Architecture | Unified symbol resolution with composable collectors |
740
- | [ADR-058](docs/decisions/adr-058-explicit-length-properties.md) | Explicit Length Properties | `.bit_length`/`.byte_length`/`.element_count`/`.char_count` |
741
-
742
- ### Accepted
743
-
744
- | ADR | Title | Description |
745
- | -------------------------------------------------------------------- | --------------------- | ----------------------------------------------------- |
746
- | [ADR-051](docs/decisions/adr-051-division-by-zero.md) | Division by Zero | Compile-time and runtime division-by-zero detection |
747
- | [ADR-052](docs/decisions/adr-052-safe-numeric-literal-generation.md) | Safe Numeric Literals | `type_MIN`/`type_MAX` constants + safe hex conversion |
748
-
749
- ### Superseded
750
-
751
- | ADR | Title | Description |
752
- | --------------------------------------------------- | ------------------ | ----------------------------------------------------------- |
753
- | [ADR-047](docs/decisions/adr-047-nullable-types.md) | NULL for C Interop | `NULL` keyword for C stream functions (replaced by ADR-046) |
754
-
755
- ### Research (v1 Roadmap)
756
-
757
- | ADR | Title | Description |
758
- | ---------------------------------------------------------------- | ----------------------------- | ------------------------------------------------ |
759
- | [ADR-008](docs/decisions/adr-008-language-bug-prevention.md) | Language-Level Bug Prevention | Top 15 embedded bugs and prevention |
760
- | [ADR-009](docs/decisions/adr-009-isr-safety.md) | ISR Safety | Safe interrupts without `unsafe` blocks |
761
- | [ADR-054](docs/decisions/adr-054-array-index-overflow.md) | Array Index Overflow | Overflow semantics for array index expressions |
762
- | [ADR-056](docs/decisions/adr-056-cast-overflow-behavior.md) | Cast Overflow Behavior | Consistent overflow semantics for type casts |
763
- | [ADR-060](docs/decisions/adr-060-vscode-extension-separation.md) | VS Code Extension Separation | Separate repository for VS Code extension |
764
- | [ADR-109](docs/decisions/adr-109-codegenerator-decomposition.md) | CodeGenerator Decomposition | Breaking down CodeGenerator into modules |
765
- | [ADR-110](docs/decisions/adr-110-do178c-compliance.md) | DO-178C Compliance | Safety-critical software certification framework |
766
-
767
- ### Research (v2 Roadmap)
768
-
769
- | ADR | Title | Description |
770
- | --------------------------------------------------------------- | -------------------------- | ----------------------------------------- |
771
- | [ADR-100](docs/decisions/adr-100-multi-core-synchronization.md) | Multi-Core Synchronization | ESP32/RP2040 spinlock patterns |
772
- | [ADR-101](docs/decisions/adr-101-heap-allocation.md) | Heap Allocation | Dynamic memory for desktop targets |
773
- | [ADR-102](docs/decisions/adr-102-critical-section-analysis.md) | Critical Section Analysis | Complexity warnings and cycle analysis |
774
- | [ADR-103](docs/decisions/adr-103-stream-handling.md) | Stream Handling | FILE\* and fopen patterns for file I/O |
775
- | [ADR-104](docs/decisions/adr-104-isr-queues.md) | ISR-Safe Queues | Producer-consumer patterns for ISR/main |
776
- | [ADR-105](docs/decisions/adr-105-prefixed-includes.md) | Prefixed Includes | Namespace control for includes |
777
- | [ADR-106](docs/decisions/adr-106-isr-vector-bindings.md) | Vector Table Bindings | Register bindings for ISR vector tables |
778
- | [ADR-111](docs/decisions/adr-111-safe-hardware-abstraction.md) | Safe Hardware Abstraction | Type-safe hardware abstraction primitives |
779
-
780
- ### Rejected
781
-
782
- | ADR | Title | Description |
783
- | ---------------------------------------------------------------- | ------------------- | ----------------------------------------------------------------------- |
784
- | [ADR-041](docs/decisions/adr-041-inline-assembly.md) | Inline Assembly | Write assembly in C files; C-Next transpiles to C anyway |
785
- | [ADR-042](docs/decisions/adr-042-error-handling.md) | Error Handling | Works with existing features (enums, pass-by-reference, struct returns) |
786
- | [ADR-039](docs/decisions/adr-039-null-safety.md) | Null Safety | Emergent from ADR-003 + ADR-006 + ADR-015; no additional feature needed |
787
- | [ADR-020](docs/decisions/adr-020-size-type.md) | Size Type | Fixed-width types are more predictable than platform-sized |
788
- | [ADR-019](docs/decisions/adr-019-type-aliases.md) | Type Aliases | Fixed-width primitives already solve the problem |
789
- | [ADR-021](docs/decisions/adr-021-increment-decrement.md) | Increment/Decrement | Use `+<- 1` instead; separation of concerns |
790
- | [ADR-002](docs/decisions/adr-002-namespaces.md) | Namespaces | Replaced by `scope` keyword (ADR-016) |
791
- | [ADR-005](docs/decisions/adr-005-classes-without-inheritance.md) | Classes | Use structs + free functions instead (ADR-016) |
792
- | [ADR-018](docs/decisions/adr-018-unions.md) | Unions | Use ADR-004 register bindings or explicit byte manipulation |
793
- | [ADR-038](docs/decisions/adr-038-static-extern.md) | Static/Extern | Use `scope` for visibility; no `static` keyword in v1 |
794
- | [ADR-026](docs/decisions/adr-026-break-continue.md) | Break/Continue | Use structured loop conditions instead |
795
- | [ADR-028](docs/decisions/adr-028-goto.md) | Goto | Permanently rejected; use structured alternatives |
796
- | [ADR-031](docs/decisions/adr-031-inline-functions.md) | Inline Functions | Trust compiler; `inline` is just a hint anyway |
797
- | [ADR-033](docs/decisions/adr-033-packed-structs.md) | Packed Structs | Use ADR-004 register bindings or explicit serialization |
798
-
799
250
  ## Development
800
251
 
801
252
  ### Setup
@@ -831,26 +282,6 @@ npm run coverage:grammar:check # Grammar coverage with threshold check (CI)
831
282
 
832
283
  **Note:** C-Next runs directly via `tsx` without a build step. The `typecheck` command validates types only and does not generate any output files.
833
284
 
834
- ### Formatting C-Next Files
835
-
836
- The project includes a Prettier plugin for formatting `.cnx` files with consistent style (4-space indentation, same-line braces).
837
-
838
- ```bash
839
- # Format a single file
840
- npx prettier --plugin ./prettier-plugin/dist/index.js --write myfile.cnx
841
-
842
- # Format all .cnx files in tests/
843
- npx prettier --plugin ./prettier-plugin/dist/index.js --write "tests/**/*.cnx"
844
- ```
845
-
846
- To build the plugin from source (after making changes):
847
-
848
- ```bash
849
- cd prettier-plugin
850
- npm install
851
- npm run build
852
- ```
853
-
854
285
  ## Contributing
855
286
 
856
287
  See [CONTRIBUTING.md](CONTRIBUTING.md) for the complete development workflow, testing requirements, and PR process.