mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
Support #[...] as an alternative attribute syntax
(Experimentation between `@()` and `#[]`)
This commit is contained in:
+48
-41
@@ -3710,6 +3710,47 @@ Ast *parse_foreign_decl(AstFile *f) {
|
|||||||
return ast_bad_decl(f, token, f->curr_token);
|
return ast_bad_decl(f, token, f->curr_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ast *parse_attribute(AstFile *f, Token token, TokenKind open_kind, TokenKind close_kind) {
|
||||||
|
Array<Ast *> elems = {};
|
||||||
|
Token open = expect_token(f, open_kind);
|
||||||
|
f->expr_level++;
|
||||||
|
if (f->curr_token.kind != close_kind) {
|
||||||
|
elems = array_make<Ast *>(heap_allocator());
|
||||||
|
while (f->curr_token.kind != close_kind &&
|
||||||
|
f->curr_token.kind != Token_EOF) {
|
||||||
|
Ast *elem = nullptr;
|
||||||
|
elem = parse_ident(f);
|
||||||
|
if (f->curr_token.kind == Token_Eq) {
|
||||||
|
Token eq = expect_token(f, Token_Eq);
|
||||||
|
Ast *value = parse_value(f);
|
||||||
|
elem = ast_field_value(f, elem, value, eq);
|
||||||
|
}
|
||||||
|
|
||||||
|
array_add(&elems, elem);
|
||||||
|
|
||||||
|
if (!allow_token(f, Token_Comma)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f->expr_level--;
|
||||||
|
Token close = expect_closing(f, close_kind, str_lit("attribute"));
|
||||||
|
|
||||||
|
Ast *attribute = ast_attribute(f, token, open, close, elems);
|
||||||
|
|
||||||
|
Ast *decl = parse_stmt(f);
|
||||||
|
if (decl->kind == Ast_ValueDecl) {
|
||||||
|
array_add(&decl->ValueDecl.attributes, attribute);
|
||||||
|
} else if (decl->kind == Ast_ForeignBlockDecl) {
|
||||||
|
array_add(&decl->ForeignBlockDecl.attributes, attribute);
|
||||||
|
} else {
|
||||||
|
syntax_error(decl, "Expected a value or foreign declaration after an attribute, got %.*s", LIT(ast_strings[decl->kind]));
|
||||||
|
return ast_bad_stmt(f, token, f->curr_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
return decl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Ast *parse_stmt(AstFile *f) {
|
Ast *parse_stmt(AstFile *f) {
|
||||||
Ast *s = nullptr;
|
Ast *s = nullptr;
|
||||||
@@ -3805,51 +3846,16 @@ Ast *parse_stmt(AstFile *f) {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_At: {
|
case Token_At: {
|
||||||
advance_token(f);
|
Token token = expect_token(f, Token_At);
|
||||||
|
return parse_attribute(f, token, Token_OpenParen, Token_CloseParen);
|
||||||
Array<Ast *> elems = {};
|
|
||||||
Token open = expect_token(f, Token_OpenParen);
|
|
||||||
f->expr_level++;
|
|
||||||
if (f->curr_token.kind != Token_CloseParen) {
|
|
||||||
elems = array_make<Ast *>(heap_allocator());
|
|
||||||
while (f->curr_token.kind != Token_CloseParen &&
|
|
||||||
f->curr_token.kind != Token_EOF) {
|
|
||||||
Ast *elem = nullptr;
|
|
||||||
elem = parse_ident(f);
|
|
||||||
if (f->curr_token.kind == Token_Eq) {
|
|
||||||
Token eq = expect_token(f, Token_Eq);
|
|
||||||
Ast *value = parse_value(f);
|
|
||||||
elem = ast_field_value(f, elem, value, eq);
|
|
||||||
}
|
|
||||||
|
|
||||||
array_add(&elems, elem);
|
|
||||||
|
|
||||||
if (!allow_token(f, Token_Comma)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f->expr_level--;
|
|
||||||
Token close = expect_closing(f, Token_CloseParen, str_lit("attribute"));
|
|
||||||
|
|
||||||
Ast *attribute = ast_attribute(f, token, open, close, elems);
|
|
||||||
|
|
||||||
Ast *decl = parse_stmt(f);
|
|
||||||
if (decl->kind == Ast_ValueDecl) {
|
|
||||||
array_add(&decl->ValueDecl.attributes, attribute);
|
|
||||||
} else if (decl->kind == Ast_ForeignBlockDecl) {
|
|
||||||
array_add(&decl->ForeignBlockDecl.attributes, attribute);
|
|
||||||
} else {
|
|
||||||
syntax_error(decl, "Expected a value or foreign declaration after an attribute, got %.*s", LIT(ast_strings[decl->kind]));
|
|
||||||
return ast_bad_stmt(f, token, f->curr_token);
|
|
||||||
}
|
|
||||||
|
|
||||||
return decl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Token_Hash: {
|
case Token_Hash: {
|
||||||
Ast *s = nullptr;
|
|
||||||
Token hash_token = expect_token(f, Token_Hash);
|
Token hash_token = expect_token(f, Token_Hash);
|
||||||
|
if (f->curr_token.kind == Token_OpenBracket) {
|
||||||
|
return parse_attribute(f, hash_token, Token_OpenBracket, Token_CloseBracket);
|
||||||
|
} else {
|
||||||
|
Ast *s = nullptr;
|
||||||
Token name = expect_token(f, Token_Ident);
|
Token name = expect_token(f, Token_Ident);
|
||||||
String tag = name.string;
|
String tag = name.string;
|
||||||
|
|
||||||
@@ -3900,6 +3906,7 @@ Ast *parse_stmt(AstFile *f) {
|
|||||||
fix_advance_to_next_stmt(f);
|
fix_advance_to_next_stmt(f);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_OpenBrace:
|
case Token_OpenBrace:
|
||||||
|
|||||||
@@ -946,7 +946,6 @@ Token tokenizer_get_token(Tokenizer *t) {
|
|||||||
break;
|
break;
|
||||||
case '~': token.kind = token_kind_variant2(t, Token_Xor, Token_XorEq); break;
|
case '~': token.kind = token_kind_variant2(t, Token_Xor, Token_XorEq); break;
|
||||||
case '!': token.kind = token_kind_variant2(t, Token_Not, Token_NotEq); break;
|
case '!': token.kind = token_kind_variant2(t, Token_Not, Token_NotEq); break;
|
||||||
// case '+': token.kind = token_kind_variant3(t, Token_Add, Token_AddEq, '+', Token_Inc); break;
|
|
||||||
case '+': token.kind = token_kind_variant2(t, Token_Add, Token_AddEq); break;
|
case '+': token.kind = token_kind_variant2(t, Token_Add, Token_AddEq); break;
|
||||||
case '-':
|
case '-':
|
||||||
token.kind = Token_Sub;
|
token.kind = Token_Sub;
|
||||||
|
|||||||
Reference in New Issue
Block a user