diff --git a/resources/c3.l b/resources/c3.l index f9810f56b..13e5952f6 100644 --- a/resources/c3.l +++ b/resources/c3.l @@ -136,7 +136,8 @@ L?\"(\\.|[^\\"])*\" { count(); return(STRING_LITERAL); } "^" { count(); return('^'); } "|" { count(); return('|'); } "?" { count(); return('?'); } - +"({" { count(); return(FN_BLOCK_BEGIN); } +"{)" { count(); return(FN_BLOCK_END); } [ \t\v\n\f] { count(); } . { /* ignore bad characters */ } diff --git a/resources/grammar.y b/resources/grammar.y index 0beb9a846..caabf1eab 100644 --- a/resources/grammar.y +++ b/resources/grammar.y @@ -24,6 +24,8 @@ void yyerror(char *s); %token TYPE FUNC ERROR MACRO GENERIC CTIF CTELIF CTENDIF CTELSE CTSWITCH CTCASE CTDEFAULT CTFOR %token THROWS THROW TRY CATCH SCOPE PUBLIC DEFER ATTRIBUTE IN +%token FN_BLOCK_START FN_BLOCK_END + %start translation_unit %% @@ -50,6 +52,7 @@ primary_expression | base_type '.' IDENT | TYPE '(' type_expression ')' | '(' expression ')' + | FN_BLOCK_START statement_list FN_BLOCK_END ; postfix_expression diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 22c27dbf5..6d93ea3fd 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -310,6 +310,7 @@ typedef enum TOKEN_EQEQ, // == TOKEN_GREATER_EQ, // >= TOKEN_LESS_EQ, // <= + TOKEN_LPARBRA, // ({ TOKEN_MINUS_ASSIGN, // -= TOKEN_MINUSMINUS, // -- TOKEN_MOD_ASSIGN, // %= @@ -317,6 +318,7 @@ typedef enum TOKEN_NOT_EQUAL, // != TOKEN_PLUS_ASSIGN, // += TOKEN_PLUSPLUS, // ++ + TOKEN_RPARBRA, // }) TOKEN_SCOPE, // :: TOKEN_SHR, // >> TOKEN_SHL, // >> diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 1ec1b5baa..d87066f74 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -619,9 +619,9 @@ Token lexer_scan_token(void) case '{': return make_token(TOKEN_LBRACE); case '}': - return make_token(TOKEN_RBRACE); + return make_token(match(')') ? TOKEN_RPARBRA : TOKEN_RBRACE); case '(': - return make_token(TOKEN_LPAREN); + return make_token(match('{') ? TOKEN_LPARBRA : TOKEN_LPAREN); case ')': return make_token(TOKEN_RPAREN); case '[': diff --git a/src/compiler/parser.c b/src/compiler/parser.c index f8b1753a0..af6f43359 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -200,6 +200,19 @@ static Ast* parse_compound_stmt() return ast; } +static Ast* parse_function_block() +{ + TODO; + CONSUME_OR(TOKEN_LPARBRA, &poisoned_ast); + Ast *ast = AST_NEW(AST_COMPOUND_STMT, tok); + while (!try_consume(TOKEN_RPARBRA)) + { + Ast *stmt = TRY_AST(parse_stmt()); + ast->compound_stmt.stmts = VECADD(ast->compound_stmt.stmts, stmt); + } + return ast; +} + static Path *parse_path(void) { if (tok.type != TOKEN_IDENT || next_tok.type != TOKEN_SCOPE) return NULL; @@ -1210,6 +1223,8 @@ static Ast *parse_stmt(void) { case TOKEN_LBRACE: return parse_compound_stmt(); + case TOKEN_LPARBRA: + return parse_function_block(); case TOKEN_HALF: case TOKEN_QUAD: SEMA_ERROR(next_tok, "Type is unsupported by platform."); @@ -1409,6 +1424,7 @@ static Ast *parse_stmt(void) case TOKEN_CT_ELIF: case TOKEN_CT_ELSE: case TOKEN_CT_DEFAULT: + case TOKEN_RPARBRA: case TOKEN_IN: SEMA_ERROR(tok, "Unexpected '%s' found when expecting a statement.", token_type_to_string(tok.type)); advance(); diff --git a/src/compiler/tokens.c b/src/compiler/tokens.c index baf29cbec..60c60bb08 100644 --- a/src/compiler/tokens.c +++ b/src/compiler/tokens.c @@ -113,6 +113,10 @@ const char *token_type_to_string(TokenType type) return "<<"; case TOKEN_SHR: return ">>"; + case TOKEN_LPARBRA: + return "({"; + case TOKEN_RPARBRA: + return "})"; // Three character tokens case TOKEN_AND_ASSIGN: