Skip to content

Commit

Permalink
0.5.5 Disallow multiple _ in a row in digits, e.g. 1__000. #1138
Browse files Browse the repository at this point in the history
  • Loading branch information
lerno committed Feb 17, 2024
1 parent 9a114b3 commit a0f7b50
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 11 deletions.
11 changes: 11 additions & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# C3C Release Notes

## 0.5.5 Change list

### Changes / improvements
- Disallow multiple `_` in a row in digits, e.g. `1__000`.

### Fixes
None

### Stdlib changes
None

## 0.5.4 Change list

### Changes / improvements
Expand Down
8 changes: 4 additions & 4 deletions resources/grammar/c3.l
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ B64 [ \t\v\n\f]?[A-Za-z0-9+/][ \t\v\n\fA-Za-z0-9+/=]+
HEX [ \t\v\n\f]?[A-Fa-f0-9][ \t\v\n\fA-Fa-f0-9]+
INTTYPE ([ui](8|16|32|64|128)|[Uu][Ll]?|[Ll])
REALTYPE ([f](8|16|32|64|128)?)
INT {D}(_*{D})*
HINT {H}(_*{H})*
OINT {O}(_*{O})*
BINT {B}(_*{B})*
INT {D}(_?{D})*
HINT {H}(_?{H})*
OINT {O}(_?{O})*
BINT {B}(_?{B})*

%x COMMENT RAW_STRING

Expand Down
18 changes: 12 additions & 6 deletions src/compiler/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,11 @@ static bool scan_number_suffix(Lexer *lexer, bool *is_float)
}
return true;
}

#define NEXT_AND_CHECK_NO_MULTIPLE_(lexer__) \
do { if (next(lexer__) == '_' && prev(lexer__) == '_') { \
return add_error_token_at_current(lexer__, "Multiple consecutive '_' are not allowed."); \
} } while(0);
/**
* Parsing octals. Here we depart from the (error prone) C style octals with initial zero e.g. 0231
* Instead we only support 0o prefix like 0o231. Note that lexing here doesn't actually parse the
Expand All @@ -429,7 +434,8 @@ static bool scan_oct(Lexer *lexer)
return add_error_token_at_current(lexer, "An expression starting with '0o' should be followed by octal numbers (0-7).");
}
next(lexer);
while (char_is_oct_or_(peek(lexer))) next(lexer);
while (char_is_oct_or_(peek(lexer))) NEXT_AND_CHECK_NO_MULTIPLE_(lexer);

if (char_is_digit(peek(lexer)))
{
return add_error_token_at_current(lexer, "An expression starting with '0o' should be followed by octal numbers (0-7).");
Expand All @@ -453,7 +459,7 @@ static bool scan_binary(Lexer *lexer)
return add_error_token_at_current(lexer, "An expression starting with '0b' should be followed by binary digits (0-1).");
}
next(lexer);
while (char_is_binary_or_(peek(lexer))) next(lexer);
while (char_is_binary_or_(peek(lexer))) NEXT_AND_CHECK_NO_MULTIPLE_(lexer);
if (char_is_digit(peek((lexer))))
{
return add_error_token_at_current(lexer, "An expression starting with '0b' should be followed by binary digits (0-1).");
Expand Down Expand Up @@ -512,7 +518,7 @@ static inline bool scan_hex(Lexer *lexer)
return add_error_token_at_current(lexer, "'0x' starts a hexadecimal number, so the next character should be 0-9, a-f or A-F.");
}
next(lexer);
while (char_is_hex_or_(peek(lexer))) next(lexer);
while (char_is_hex_or_(peek(lexer))) NEXT_AND_CHECK_NO_MULTIPLE_(lexer);
bool is_float = false;
if (peek(lexer) == '.' && peek_next(lexer) != '.')
{
Expand All @@ -521,7 +527,7 @@ static inline bool scan_hex(Lexer *lexer)
char c = peek(lexer);
if (c == '_') return add_error_token_at_current(lexer, "'_' is not allowed directly after decimal point, try removing it.");
if (char_is_hex(c)) next(lexer);
while (char_is_hex_or_(peek(lexer))) next(lexer);
while (char_is_hex_or_(peek(lexer))) NEXT_AND_CHECK_NO_MULTIPLE_(lexer);
}
char c = peek(lexer);
if (c == 'p' || c == 'P')
Expand All @@ -547,7 +553,7 @@ static inline bool scan_dec(Lexer *lexer)

// Walk through the digits, we don't need to worry about
// initial _ because we only call this if we have a digit initially.
while (char_is_digit_or_(peek(lexer))) next(lexer);
while (char_is_digit_or_(peek(lexer))) NEXT_AND_CHECK_NO_MULTIPLE_(lexer);

// Assume no float.
bool is_float = false;
Expand All @@ -565,7 +571,7 @@ static inline bool scan_dec(Lexer *lexer)
if (c == '_') return add_error_token_at_current(lexer, "'_' is not allowed directly after decimal point, try removing it.");
// Now walk until we see no more digits.
// This allows 123. as a floating point number.
while (char_is_digit_or_(peek(lexer))) next(lexer);
while (char_is_digit_or_(peek(lexer))) NEXT_AND_CHECK_NO_MULTIPLE_(lexer);
}
char c = peek(lexer);
// We might have an exponential. We allow 123e1 and 123.e1 as floating point, so
Expand Down
2 changes: 1 addition & 1 deletion src/version.h
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define COMPILER_VERSION "0.5.4"
#define COMPILER_VERSION "0.5.5"
15 changes: 15 additions & 0 deletions test/test_suite/expressions/underscore_errors.c3
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
fn void main()
{
int a = 1___0; // #error: consecutive
int a = 1_0;
float b = 1_0.3__4; // #error: consecutive
float b = 1_0.3_4;
int a2 = 0x1___0; // #error: consecutive
int a2 = 0x1_0;
float b2 = 0x1_0.3__4; // #error: consecutive
float b2 = 0x1_0.3_4;
int a3 = 0b1___0; // #error: consecutive
int a3 = 0b1_0;
int a3 = 0o1___0; // #error: consecutive
int a3 = 0o1_0;
}

0 comments on commit a0f7b50

Please sign in to comment.