c-next 0.2.11 → 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.
- package/README.md +80 -649
- package/dist/index.js +8273 -6357
- package/dist/index.js.map +4 -4
- package/grammar/C.g4 +17 -4
- package/package.json +3 -3
- package/src/__tests__/index.test.ts +1 -1
- package/src/cli/CleanCommand.ts +8 -12
- package/src/cli/Cli.ts +29 -6
- package/src/cli/Runner.ts +42 -62
- package/src/cli/__tests__/CleanCommand.test.ts +10 -10
- package/src/cli/__tests__/Cli.test.ts +59 -7
- package/src/cli/__tests__/ConfigPrinter.test.ts +12 -12
- package/src/cli/__tests__/PathNormalizer.test.ts +5 -5
- package/src/cli/__tests__/Runner.test.ts +108 -82
- package/src/cli/serve/ServeCommand.ts +1 -1
- package/src/cli/types/ICliConfig.ts +2 -2
- package/src/lib/parseWithSymbols.ts +21 -21
- package/src/transpiler/Transpiler.ts +99 -46
- package/src/transpiler/__tests__/DualCodePaths.test.ts +29 -29
- package/src/transpiler/__tests__/Transpiler.coverage.test.ts +244 -72
- package/src/transpiler/__tests__/Transpiler.test.ts +32 -72
- package/src/transpiler/__tests__/determineProjectRoot.test.ts +30 -28
- package/src/transpiler/__tests__/needsConditionalPreprocessing.test.ts +1 -1
- package/src/transpiler/data/CNextMarkerDetector.ts +34 -0
- package/src/transpiler/data/CppEntryPointScanner.ts +174 -0
- package/src/transpiler/data/FileDiscovery.ts +2 -105
- package/src/transpiler/data/InputExpansion.ts +37 -81
- package/src/transpiler/data/__tests__/CNextMarkerDetector.test.ts +62 -0
- package/src/transpiler/data/__tests__/CppEntryPointScanner.test.ts +239 -0
- package/src/transpiler/data/__tests__/FileDiscovery.test.ts +45 -191
- package/src/transpiler/data/__tests__/InputExpansion.test.ts +36 -204
- package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +2 -2
- package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +4 -5
- package/src/transpiler/logic/parser/c/grammar/C.interp +33 -3
- package/src/transpiler/logic/parser/c/grammar/C.tokens +237 -207
- package/src/transpiler/logic/parser/c/grammar/CLexer.interp +48 -3
- package/src/transpiler/logic/parser/c/grammar/CLexer.tokens +237 -207
- package/src/transpiler/logic/parser/c/grammar/CLexer.ts +702 -611
- package/src/transpiler/logic/parser/c/grammar/CParser.ts +1221 -1107
- package/src/transpiler/logic/symbols/SymbolTable.ts +147 -73
- package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +157 -14
- package/src/transpiler/logic/symbols/c/__tests__/CResolver.integration.test.ts +3 -3
- package/src/transpiler/logic/symbols/c/collectors/StructCollector.ts +7 -37
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolInfoAdapter.test.ts +6 -6
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolInfoAdapter.ts +28 -27
- package/src/transpiler/logic/symbols/cnext/index.ts +4 -4
- package/src/transpiler/logic/symbols/cnext/utils/SymbolNameUtils.ts +5 -5
- package/src/transpiler/output/codegen/CodeGenerator.ts +16 -1
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +15 -0
- package/src/transpiler/output/codegen/__tests__/ExpressionWalker.test.ts +3 -3
- package/src/transpiler/output/codegen/__tests__/RequireInclude.test.ts +14 -14
- package/src/transpiler/output/codegen/__tests__/TrackVariableTypeHelpers.test.ts +2 -2
- package/src/transpiler/output/codegen/helpers/FunctionContextManager.ts +15 -3
- package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +14 -6
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +1 -0
- package/src/transpiler/output/codegen/types/IFunctionContextCallbacks.ts +2 -0
- package/src/transpiler/output/codegen/utils/QualifiedNameGenerator.ts +7 -7
- package/src/transpiler/output/codegen/utils/__tests__/QualifiedNameGenerator.test.ts +3 -3
- package/src/transpiler/output/headers/BaseHeaderGenerator.ts +10 -1
- package/src/transpiler/output/headers/HeaderGenerator.ts +3 -0
- package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +6 -2
- package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +16 -0
- package/src/transpiler/output/headers/adapters/HeaderSymbolAdapter.ts +19 -19
- package/src/transpiler/output/headers/adapters/__tests__/HeaderSymbolAdapter.test.ts +5 -5
- package/src/transpiler/state/SymbolRegistry.ts +10 -12
- package/src/transpiler/state/__tests__/SymbolRegistry.test.ts +11 -13
- package/src/transpiler/types/ICachedFileEntry.ts +4 -0
- package/src/transpiler/types/IPipelineFile.ts +3 -0
- package/src/transpiler/types/ITranspilerConfig.ts +2 -2
- package/src/transpiler/types/symbols/IScopeSymbol.ts +1 -1
- package/src/utils/FunctionUtils.ts +3 -3
- package/src/utils/__tests__/FunctionUtils.test.ts +6 -4
- package/src/utils/cache/CacheManager.ts +28 -15
- package/src/utils/cache/__tests__/CacheManager.test.ts +6 -4
- package/src/transpiler/data/types/IDiscoveryOptions.ts +0 -15
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
[](https://sonarcloud.io/summary/overall?id=jlaustill_c-next)
|
|
7
7
|
[](https://jlaustill.github.io/c-next/coverage/)
|
|
8
8
|
[](https://sonarcloud.io/summary/new_code?id=jlaustill_c-next)
|
|
9
|
+
[](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
|
-
##
|
|
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
|
-
|
|
49
|
+
C-Next transpiles to **standard C99**. Your existing toolchain — GCC, Clang, IAR, arm-none-eabi-gcc — compiles the output.
|
|
134
50
|
|
|
135
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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], ×tamp, 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
|
-
|
|
454
|
-
// u32 bad <- (x) ? 1 : 0;
|
|
112
|
+
### From npm (Recommended)
|
|
455
113
|
|
|
456
|
-
|
|
457
|
-
|
|
114
|
+
```bash
|
|
115
|
+
npm install -g c-next
|
|
458
116
|
```
|
|
459
117
|
|
|
460
|
-
|
|
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
|
-
|
|
482
|
-
|
|
120
|
+
```bash
|
|
121
|
+
cnext --version
|
|
483
122
|
```
|
|
484
123
|
|
|
485
|
-
|
|
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
|
-
|
|
516
|
-
|
|
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
|
-
|
|
520
|
-
|
|
521
|
-
```c
|
|
522
|
-
void onReceive(const CAN_Message_T msg) { }
|
|
133
|
+
## Usage
|
|
523
134
|
|
|
524
|
-
|
|
135
|
+
```bash
|
|
136
|
+
# Transpile to C (output alongside input file)
|
|
137
|
+
cnext examples/blink.cnx
|
|
525
138
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
};
|
|
139
|
+
# Explicit output path
|
|
140
|
+
cnext examples/blink.cnx -o blink.c
|
|
529
141
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
return (struct Controller){ ._handler = onReceive };
|
|
533
|
-
}
|
|
534
|
-
```
|
|
142
|
+
# Parse only (syntax check)
|
|
143
|
+
cnext examples/blink.cnx --parse
|
|
535
144
|
|
|
536
|
-
|
|
145
|
+
# Output as C++ (.cpp)
|
|
146
|
+
cnext examples/blink.cnx --cpp
|
|
537
147
|
|
|
538
|
-
|
|
148
|
+
# Target platform for atomic code generation (ADR-049)
|
|
149
|
+
cnext examples/blink.cnx --target teensy41
|
|
539
150
|
|
|
540
|
-
|
|
541
|
-
|
|
151
|
+
# Separate output directories for code and headers
|
|
152
|
+
cnext src/main.cnx -o build/src --header-out build/include
|
|
542
153
|
|
|
543
|
-
|
|
544
|
-
|
|
154
|
+
# Clean generated files
|
|
155
|
+
cnext src/main.cnx -o build/src --header-out build/include --clean
|
|
545
156
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
}
|
|
157
|
+
# Show all options
|
|
158
|
+
cnext --help
|
|
549
159
|
```
|
|
550
160
|
|
|
551
|
-
|
|
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
|
-
|
|
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
|
-
|
|
574
|
-
volatile u32 status_register @ 0x40020000;
|
|
165
|
+
**Step 1:** Convert a leaf file to C-Next and transpile it:
|
|
575
166
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
// Always reads from hardware
|
|
579
|
-
}
|
|
580
|
-
}
|
|
167
|
+
```bash
|
|
168
|
+
cnext led.cnx # Generates led.h and led.c
|
|
581
169
|
```
|
|
582
170
|
|
|
583
|
-
**
|
|
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
|
-
|
|
593
|
-
|
|
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
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
writeIdx +<- 1;
|
|
607
|
-
}
|
|
177
|
+
int main() {
|
|
178
|
+
LED_on();
|
|
179
|
+
return 0;
|
|
608
180
|
}
|
|
609
181
|
```
|
|
610
182
|
|
|
611
|
-
|
|
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
|
-
```
|
|
614
|
-
|
|
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
|
-
|
|
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
|
-
|
|
191
|
+
## VS Code Extension
|
|
645
192
|
|
|
646
|
-
-
|
|
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
|
-
|
|
195
|
+
**Install from:** [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=jlaustill.vscode-c-next) (coming soon)
|
|
652
196
|
|
|
653
|
-
|
|
197
|
+
**Source:** [github.com/jlaustill/vscode-c-next](https://github.com/jlaustill/vscode-c-next)
|
|
654
198
|
|
|
655
|
-
##
|
|
199
|
+
## Getting Started with PlatformIO
|
|
656
200
|
|
|
657
|
-
|
|
201
|
+
C-Next integrates seamlessly with PlatformIO. Quick setup:
|
|
658
202
|
|
|
659
203
|
```bash
|
|
660
|
-
|
|
661
|
-
cd test-teensy
|
|
662
|
-
pio run -t upload
|
|
204
|
+
cnext --pio-install
|
|
663
205
|
```
|
|
664
206
|
|
|
665
|
-
|
|
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.
|