Skip to content

Commit 6547ea4

Browse files
author
OpenCode[AI]
committed
No more ; needed
1 parent 898f496 commit 6547ea4

3 files changed

Lines changed: 28 additions & 10 deletions

File tree

AGENTS.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,17 @@
3838
- Some tests need special flags (see `FLAGS =` assignments in `tests/tests2/Makefile`).
3939
- Bound-check tests (`-b` flag) are skipped when `CONFIG_bcheck=no`.
4040
- `.expect` files are generated with gcc by default; some use TCC (flagged with `GEN-TCC`).
41+
42+
## Language Extension: Optional Semicolons
43+
44+
Semicolons are optional after most statements and declarations:
45+
- `return`, `break`, `continue`, `goto`, expression statements
46+
- `do-while` trailing semicolon
47+
- Variable declarations
48+
49+
Semicolons are still **required** for:
50+
- `for()` loop init/condition/increment sections (e.g., `for(i=0; i<n; i++)`)
51+
- Old-style function parameter declarations
52+
- Struct/enum member declarations
53+
54+
The `skip(';')` function in `tccpp.c:100` errors if token doesn't match. Use `if (tok == ';') next();` instead to make semicolons optional.

tccgen.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7205,7 +7205,7 @@ static void block(int flags)
72057205
label_push(&local_label_stack, tok, LABEL_DECLARED);
72067206
next();
72077207
} while (tok == ',');
7208-
skip(';');
7208+
if (tok == ';') next();
72097209
}
72107210

72117211
while (tok != '}') {
@@ -7241,7 +7241,7 @@ static void block(int flags)
72417241
leave_scope(root_scope);
72427242
if (b)
72437243
gfunc_return(&func_vt);
7244-
skip(';');
7244+
if (tok == ';') next();
72457245
/* jump unless last stmt in top-level block */
72467246
if (tok != '}' || local_scope != 1)
72477247
rsym = gjmp(rsym);
@@ -7258,15 +7258,15 @@ static void block(int flags)
72587258
else
72597259
leave_scope(loop_scope);
72607260
*cur_scope->bsym = gjmp(*cur_scope->bsym);
7261-
skip(';');
7261+
if (tok == ';') next();
72627262

72637263
} else if (t == TOK_CONTINUE) {
72647264
/* compute jump */
72657265
if (!cur_scope->csym)
72667266
tcc_error("cannot continue");
72677267
leave_scope(loop_scope);
72687268
*cur_scope->csym = gjmp(*cur_scope->csym);
7269-
skip(';');
7269+
if (tok == ';') next();
72707270

72717271
} else if (t == TOK_FOR) {
72727272
new_scope(&o);
@@ -7314,7 +7314,7 @@ static void block(int flags)
73147314
gexpr();
73157315
c = gvtst(0, 0);
73167316
skip(')');
7317-
skip(';');
7317+
if (tok == ';') next();
73187318
gsym_addr(c, d);
73197319
gsym(a);
73207320
prev_scope_s(&o);
@@ -7426,7 +7426,7 @@ static void block(int flags)
74267426
} else {
74277427
expect("label identifier");
74287428
}
7429-
skip(';');
7429+
if (tok == ';') next();
74307430

74317431
} else if (t == TOK_ASM1 || t == TOK_ASM2 || t == TOK_ASM3) {
74327432
asm_instr();
@@ -7481,7 +7481,7 @@ static void block(int flags)
74817481
gexpr();
74827482
vpop();
74837483
}
7484-
skip(';');
7484+
if (tok == ';') next();
74857485
}
74867486
}
74877487
}
@@ -8637,7 +8637,7 @@ static void do_Static_assert(void)
86378637
skip(')');
86388638
if (c == 0)
86398639
tcc_error("%s", msg);
8640-
skip(';');
8640+
if (tok == ';') next();
86418641
}
86428642

86438643
#ifdef TCC_TARGET_PE
@@ -8718,6 +8718,10 @@ static int decl(int l)
87188718
return 1;
87198719
next();
87208720
continue;
8721+
} else if (l != VT_JMP && l != VT_CMP) {
8722+
/* no semicolon - let caller handle it */
8723+
} else {
8724+
expect(";");
87218725
}
87228726

87238727
while (1) { /* iterate thru each declaration */
@@ -8904,7 +8908,7 @@ static int decl(int l)
89048908
if (tok != ',') {
89058909
if (l == VT_JMP)
89068910
return has_init ? v : 1;
8907-
skip(';');
8911+
if (tok == ';') next();
89088912
break;
89098913
}
89108914
next();

tests/tests2/60_errors_and_warnings.expect

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ bar : 3 ; 3
179179
60_errors_and_warnings.c:372: error: statement expression outside of function
180180

181181
[test_invalid_tokckill]
182-
60_errors_and_warnings.c:375: error: ';' expected (got '3')
182+
60_errors_and_warnings.c:375: warning: function might return no value: 'f'
183183

184184
[test_duplicate_member]
185185
60_errors_and_warnings.c:381: error: duplicate member 'a'

0 commit comments

Comments
 (0)