Berry Force left bracket without spaces for calls (#24154)

This commit is contained in:
s-hadinger 2025-11-23 21:59:12 +01:00 committed by GitHub
parent d7b1bb3574
commit dc2ae5078c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 26 additions and 13 deletions

View File

@ -36,7 +36,7 @@ static const char* const kwords_tab[] = {
"^=", "<<=", ">>=", "+", "-", "*", "/", "%", "^=", "<<=", ">>=", "+", "-", "*", "/", "%",
"<", "<=", "==", "!=", ">", ">=", "&", "|", "<", "<=", "==", "!=", ">", ">=", "&", "|",
"^", "<<", ">>", "..", "&&", "||", "!", "~", "^", "<<", ">>", "..", "&&", "||", "!", "~",
"(", ")", "[", "]", "{", "}", ".", ",", ";", "(", "(", ")", "[", "]", "{", "}", ".", ",", ";",
":", "?", "->", "if", "elif", "else", "while", ":", "?", "->", "if", "elif", "else", "while",
"for", "def", "end", "class", "break", "continue", "for", "def", "end", "class", "break", "continue",
"return", "true", "false", "nil", "var", "do", "return", "true", "false", "nil", "var", "do",
@ -686,6 +686,7 @@ static int skip_delimiter(blexer *lexer) {
c = lgetc(lexer); c = lgetc(lexer);
delimeter_present = 1; delimeter_present = 1;
} }
lexer->had_whitespace = delimeter_present;
return delimeter_present; return delimeter_present;
} }
@ -791,12 +792,15 @@ static btokentype lexer_next(blexer *lexer)
switch (lgetc(lexer)) { switch (lgetc(lexer)) {
case '\r': case '\n': /* newline */ case '\r': case '\n': /* newline */
skip_newline(lexer); skip_newline(lexer);
lexer->had_whitespace = 1;
break; break;
case ' ': case '\t': case '\f': case '\v': /* spaces */ case ' ': case '\t': case '\f': case '\v': /* spaces */
next(lexer); next(lexer);
lexer->had_whitespace = 1;
break; break;
case '#': /* comment */ case '#': /* comment */
skip_comment(lexer); skip_comment(lexer);
lexer->had_whitespace = 1;
break; break;
case EOS: return TokenEOS; /* end of source stream */ case EOS: return TokenEOS; /* end of source stream */
/* operator */ /* operator */
@ -805,7 +809,7 @@ static btokentype lexer_next(blexer *lexer)
case '*': return scan_assign(lexer, OptMulAssign, OptMul); case '*': return scan_assign(lexer, OptMulAssign, OptMul);
case '/': return scan_assign(lexer, OptDivAssign, OptDiv); case '/': return scan_assign(lexer, OptDivAssign, OptDiv);
case '%': return scan_assign(lexer, OptModAssign, OptMod); case '%': return scan_assign(lexer, OptModAssign, OptMod);
case '(': next(lexer); return OptLBK; case '(': next(lexer); return lexer->had_whitespace ? OptSpaceLBK : OptCallLBK;
case ')': next(lexer); return OptRBK; case ')': next(lexer); return OptRBK;
case '[': next(lexer); return OptLSB; case '[': next(lexer); return OptLSB;
case ']': next(lexer); return OptRSB; case ']': next(lexer); return OptRSB;
@ -865,6 +869,7 @@ void be_lexer_init(blexer *lexer, bvm *vm,
lexer->reader.readf = reader; lexer->reader.readf = reader;
lexer->reader.data = data; lexer->reader.data = data;
lexer->reader.len = 0; lexer->reader.len = 0;
lexer->had_whitespace = 1; /* start with whitespace state */
lexerbuf_init(lexer); lexerbuf_init(lexer);
keyword_registe(vm); keyword_registe(vm);
lexer->strtab = be_map_new(vm); lexer->strtab = be_map_new(vm);
@ -892,6 +897,7 @@ int be_lexer_scan_next(blexer *lexer)
return 0; return 0;
} }
lexer->lastline = lexer->linenumber; lexer->lastline = lexer->linenumber;
lexer->had_whitespace = 0; /* reset whitespace flag before scanning */
type = lexer_next(lexer); type = lexer_next(lexer);
clear_buf(lexer); clear_buf(lexer);
if (type != TokenNone) { if (type != TokenNone) {

View File

@ -54,7 +54,8 @@ typedef enum {
OptNot, /* operator, ! */ OptNot, /* operator, ! */
OptFlip, /* operator, ~ */ OptFlip, /* operator, ~ */
/* postfix operator or bracket */ /* postfix operator or bracket */
OptLBK, /* operator, ( bracket */ OptSpaceLBK, /* operator, ( bracket (with space/newline before) */
OptCallLBK, /* operator, ( bracket (call - no space before) */
OptRBK, /* operator, ) bracket */ OptRBK, /* operator, ) bracket */
OptLSB, /* operator, [ square bracket */ OptLSB, /* operator, [ square bracket */
OptRSB, /* operator, ] square bracket */ OptRSB, /* operator, ] square bracket */
@ -67,6 +68,7 @@ typedef enum {
OptColon, /* operator, : */ OptColon, /* operator, : */
OptQuestion, /* operator, ? */ OptQuestion, /* operator, ? */
OptArrow, /* operator, -> */ OptArrow, /* operator, -> */
OptWalrus, /* operator, := */
/* keyword */ /* keyword */
KeyIf, /* keyword if */ KeyIf, /* keyword if */
KeyElif, /* keyword elif */ KeyElif, /* keyword elif */
@ -90,8 +92,6 @@ typedef enum {
KeyExcept, /* keyword except */ KeyExcept, /* keyword except */
KeyRaise, /* keyword raise */ KeyRaise, /* keyword raise */
KeyStatic, /* keyword static */ KeyStatic, /* keyword static */
/* Walrus operator */
OptWalrus, /* operator, := */
} btokentype; } btokentype;
struct blexerreader { struct blexerreader {
@ -126,6 +126,7 @@ typedef struct blexer {
struct blexerreader reader; struct blexerreader reader;
bmap *strtab; bmap *strtab;
bvm *vm; bvm *vm;
int had_whitespace; /* track if whitespace/newline preceded current token */
} blexer; } blexer;
void be_lexer_init(blexer *lexer, bvm *vm, void be_lexer_init(blexer *lexer, bvm *vm,

View File

@ -595,7 +595,12 @@ static void func_varlist(bparser *parser)
/* '(' [ ID {',' ID}] ')' or */ /* '(' [ ID {',' ID}] ')' or */
/* '(' '*' ID ')' or */ /* '(' '*' ID ')' or */
/* '(' [ ID {',' ID}] ',' '*' ID ')' */ /* '(' [ ID {',' ID}] ',' '*' ID ')' */
match_token(parser, OptLBK); /* skip '(' */ btokentype type_lbk = next_type(parser);
if ((type_lbk == OptSpaceLBK) || (type_lbk == OptCallLBK)) {
match_token(parser, type_lbk); /* skip '(' */
} else {
match_token(parser, OptCallLBK); /* raise error */
}
if (next_type(parser) == OptMul) { if (next_type(parser) == OptMul) {
func_vararg(parser); func_vararg(parser);
} else if (match_id(parser, str) != NULL) { } else if (match_id(parser, str) != NULL) {
@ -837,8 +842,8 @@ static void member_expr(bparser *parser, bexpdesc *e)
init_exp(&key, ETSTRING, 0); init_exp(&key, ETSTRING, 0);
key.v.s = str; key.v.s = str;
be_code_member(parser->finfo, e, &key); be_code_member(parser->finfo, e, &key);
} else if (next_type(parser) == OptLBK) { } else if (next_type(parser) == OptCallLBK) {
scan_next_token(parser); /* skip '(' */ scan_next_token(parser); /* skip '(' - must be no space before */
bexpdesc key; bexpdesc key;
expr(parser, &key); expr(parser, &key);
check_var(parser, &key); check_var(parser, &key);
@ -897,7 +902,8 @@ static void simple_expr(bparser *parser, bexpdesc *e)
static void primary_expr(bparser *parser, bexpdesc *e) static void primary_expr(bparser *parser, bexpdesc *e)
{ {
switch (next_type(parser)) { switch (next_type(parser)) {
case OptLBK: /* '(' expr ')' */ case OptSpaceLBK: /* '(' expr ')' - grouping parentheses only */
case OptCallLBK: /* '(' expr ')' - following a symbol */
scan_next_token(parser); /* skip '(' */ scan_next_token(parser); /* skip '(' */
expr(parser, e); expr(parser, e);
check_var(parser, e); check_var(parser, e);
@ -926,7 +932,7 @@ static void suffix_expr(bparser *parser, bexpdesc *e)
primary_expr(parser, e); primary_expr(parser, e);
for (;;) { for (;;) {
switch (next_type(parser)) { switch (next_type(parser)) {
case OptLBK: /* '(' function call */ case OptCallLBK: /* '(' function call - no space before */
call_expr(parser, e); call_expr(parser, e);
break; break;
case OptDot: /* '.' member */ case OptDot: /* '.' member */
@ -1355,7 +1361,7 @@ static void continue_stmt(bparser *parser)
static bbool isoverloadable(btokentype type) static bbool isoverloadable(btokentype type)
{ {
return (type >= OptAdd && type <= OptConnect) /* overloaded binary operator */ return (type >= OptAdd && type <= OptConnect) /* overloaded binary operator */
|| type == OptFlip || type == OptLBK; /* '~' and '()' operator */ || type == OptFlip || type == OptSpaceLBK; /* '~' and '()' operator */
} }
static bstring* func_name(bparser* parser, bexpdesc* e, int ismethod) static bstring* func_name(bparser* parser, bexpdesc* e, int ismethod)
@ -1376,7 +1382,7 @@ static bstring* func_name(bparser* parser, bexpdesc* e, int ismethod)
return parser_newstr(parser, "-*"); return parser_newstr(parser, "-*");
} }
/* '()' call operator */ /* '()' call operator */
if (type == OptLBK && next_type(parser) == OptRBK) { if ((type == OptSpaceLBK) && next_type(parser) == OptRBK) {
scan_next_token(parser); /* skip ')' */ scan_next_token(parser); /* skip ')' */
return parser_newstr(parser, "()"); return parser_newstr(parser, "()");
} }

View File

@ -62,7 +62,7 @@ class str_build:
return size return size
def keywords(self): def keywords(self):
opif = 50 opif = 52
tab = { tab = {
"if": opif, "elif": opif + 1 , "if": opif, "elif": opif + 1 ,
"else": opif + 2 , "while": opif + 3 , "else": opif + 2 , "while": opif + 3 ,