mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 16:18:52 +00:00
Make static an attribute rather than a keyword prefix
This commit is contained in:
@@ -61,8 +61,8 @@ write_bytes :: proc(b: ^Builder, x: []byte) {
|
|||||||
append(&b.buf, ..x);
|
append(&b.buf, ..x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private, static)
|
||||||
static DIGITS_LOWER := "0123456789abcdefx";
|
DIGITS_LOWER := "0123456789abcdefx";
|
||||||
|
|
||||||
write_quoted_string :: proc(b: ^Builder, s: string, quote: byte = '"') {
|
write_quoted_string :: proc(b: ^Builder, s: string, quote: byte = '"') {
|
||||||
write_byte(b, quote);
|
write_byte(b, quote);
|
||||||
|
|||||||
+7
-2
@@ -718,9 +718,14 @@ void check_var_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init_ex
|
|||||||
check_decl_attributes(ctx, decl->attributes, var_decl_attribute, &ac);
|
check_decl_attributes(ctx, decl->attributes, var_decl_attribute, &ac);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->Variable.is_export = ac.is_export;
|
|
||||||
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
|
|
||||||
e->Variable.thread_local_model = ac.thread_local_model;
|
e->Variable.thread_local_model = ac.thread_local_model;
|
||||||
|
e->Variable.is_export = ac.is_export;
|
||||||
|
if (ac.is_static) {
|
||||||
|
e->flags |= EntityFlag_Static;
|
||||||
|
} else {
|
||||||
|
e->flags &= ~EntityFlag_Static;
|
||||||
|
}
|
||||||
|
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
|
||||||
|
|
||||||
String context_name = str_lit("variable declaration");
|
String context_name = str_lit("variable declaration");
|
||||||
|
|
||||||
|
|||||||
+12
-5
@@ -1665,8 +1665,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
|||||||
if (!is_blank_ident(str)) {
|
if (!is_blank_ident(str)) {
|
||||||
found = scope_lookup_current(ctx->scope, str);
|
found = scope_lookup_current(ctx->scope, str);
|
||||||
new_name_count += 1;
|
new_name_count += 1;
|
||||||
} else if (vd->is_static) {
|
|
||||||
error(name, "'static' is now allowed to be applied to '_'");
|
|
||||||
}
|
}
|
||||||
if (found == nullptr) {
|
if (found == nullptr) {
|
||||||
entity = alloc_entity_variable(ctx->scope, token, nullptr, false);
|
entity = alloc_entity_variable(ctx->scope, token, nullptr, false);
|
||||||
@@ -1678,9 +1676,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
|||||||
entity->Variable.is_foreign = true;
|
entity->Variable.is_foreign = true;
|
||||||
entity->Variable.foreign_library_ident = fl;
|
entity->Variable.foreign_library_ident = fl;
|
||||||
}
|
}
|
||||||
if (vd->is_static) {
|
|
||||||
entity->flags |= EntityFlag_Static;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
TokenPos pos = found->token.pos;
|
TokenPos pos = found->token.pos;
|
||||||
error(token,
|
error(token,
|
||||||
@@ -1744,6 +1739,16 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
|||||||
if (ac.link_name.len > 0) {
|
if (ac.link_name.len > 0) {
|
||||||
e->Variable.link_name = ac.link_name;
|
e->Variable.link_name = ac.link_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e->flags &= ~EntityFlag_Static;
|
||||||
|
if (ac.is_static) {
|
||||||
|
String name = e->token.string;
|
||||||
|
if (name == "_") {
|
||||||
|
error(e->token, "The 'static' attribute is not allowed to be applied to '_'");
|
||||||
|
} else {
|
||||||
|
e->flags |= EntityFlag_Static;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
check_arity_match(ctx, vd);
|
check_arity_match(ctx, vd);
|
||||||
@@ -1751,6 +1756,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
|||||||
|
|
||||||
for (isize i = 0; i < entity_count; i++) {
|
for (isize i = 0; i < entity_count; i++) {
|
||||||
Entity *e = entities[i];
|
Entity *e = entities[i];
|
||||||
|
|
||||||
if (e->Variable.is_foreign) {
|
if (e->Variable.is_foreign) {
|
||||||
if (vd->values.count > 0) {
|
if (vd->values.count > 0) {
|
||||||
error(e->token, "A foreign variable declaration cannot have a default value");
|
error(e->token, "A foreign variable declaration cannot have a default value");
|
||||||
@@ -1842,6 +1848,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// constant value declaration
|
// constant value declaration
|
||||||
// NOTE(bill): Check `_` declarations
|
// NOTE(bill): Check `_` declarations
|
||||||
|
|||||||
+8
-12
@@ -2070,6 +2070,14 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
|
|||||||
DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
||||||
ExactValue ev = check_decl_attribute_value(c, value);
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
|
|
||||||
|
if (name == "static") {
|
||||||
|
if (value != nullptr) {
|
||||||
|
error(elem, "'static' does not have any parameters");
|
||||||
|
}
|
||||||
|
ac->is_static = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (c->curr_proc_decl != nullptr) {
|
if (c->curr_proc_decl != nullptr) {
|
||||||
error(elem, "Only a variable at file scope can have a '%.*s'", LIT(name));
|
error(elem, "Only a variable at file scope can have a '%.*s'", LIT(name));
|
||||||
return true;
|
return true;
|
||||||
@@ -2425,10 +2433,6 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
|||||||
e->flags |= EntityFlag_NotExported;
|
e->flags |= EntityFlag_NotExported;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vd->is_static) {
|
|
||||||
e->flags |= EntityFlag_Static;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vd->is_using) {
|
if (vd->is_using) {
|
||||||
vd->is_using = false; // NOTE(bill): This error will be only caught once
|
vd->is_using = false; // NOTE(bill): This error will be only caught once
|
||||||
error(name, "'using' is not allowed at the file scope");
|
error(name, "'using' is not allowed at the file scope");
|
||||||
@@ -2527,14 +2531,6 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
|||||||
e->flags |= EntityFlag_NotExported;
|
e->flags |= EntityFlag_NotExported;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vd->is_static) {
|
|
||||||
if (e->kind == Entity_Constant) {
|
|
||||||
e->flags |= EntityFlag_Static;
|
|
||||||
} else {
|
|
||||||
error(name, "'static' is not allowed on this constant value declaration");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vd->is_using) {
|
if (vd->is_using) {
|
||||||
if (e->kind == Entity_TypeName && init->kind == Ast_EnumType) {
|
if (e->kind == Entity_TypeName && init->kind == Ast_EnumType) {
|
||||||
d->is_using = true;
|
d->is_using = true;
|
||||||
|
|||||||
@@ -306,6 +306,7 @@ struct DeferredProcedure {
|
|||||||
|
|
||||||
struct AttributeContext {
|
struct AttributeContext {
|
||||||
bool is_export;
|
bool is_export;
|
||||||
|
bool is_static;
|
||||||
String link_name;
|
String link_name;
|
||||||
String link_prefix;
|
String link_prefix;
|
||||||
isize init_expr_list_count;
|
isize init_expr_list_count;
|
||||||
|
|||||||
+10
-1
@@ -8166,7 +8166,16 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
|
|||||||
if (vd->is_mutable) {
|
if (vd->is_mutable) {
|
||||||
irModule *m = proc->module;
|
irModule *m = proc->module;
|
||||||
|
|
||||||
if (vd->is_static) {
|
bool is_static = false;
|
||||||
|
if (vd->names.count > 0) {
|
||||||
|
Entity *e = entity_of_ident(vd->names[0]);
|
||||||
|
if (e->flags & EntityFlag_Static) {
|
||||||
|
// NOTE(bill): If one of the entities is static, they all are
|
||||||
|
is_static = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_static) {
|
||||||
for_array(i, vd->names) {
|
for_array(i, vd->names) {
|
||||||
irValue *value = nullptr;
|
irValue *value = nullptr;
|
||||||
if (vd->values.count > 0) {
|
if (vd->values.count > 0) {
|
||||||
|
|||||||
+23
-24
@@ -1208,7 +1208,6 @@ void fix_advance_to_next_stmt(AstFile *f) {
|
|||||||
case Token_defer:
|
case Token_defer:
|
||||||
case Token_asm:
|
case Token_asm:
|
||||||
case Token_using:
|
case Token_using:
|
||||||
case Token_static:
|
|
||||||
|
|
||||||
case Token_break:
|
case Token_break:
|
||||||
case Token_continue:
|
case Token_continue:
|
||||||
@@ -3751,33 +3750,33 @@ Ast *parse_stmt(AstFile *f) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Token_static: {
|
// case Token_static: {
|
||||||
CommentGroup *docs = f->lead_comment;
|
// CommentGroup *docs = f->lead_comment;
|
||||||
Token token = expect_token(f, Token_static);
|
// Token token = expect_token(f, Token_static);
|
||||||
|
|
||||||
Ast *decl = nullptr;
|
// Ast *decl = nullptr;
|
||||||
Array<Ast *> list = parse_lhs_expr_list(f);
|
// Array<Ast *> list = parse_lhs_expr_list(f);
|
||||||
if (list.count == 0) {
|
// if (list.count == 0) {
|
||||||
syntax_error(token, "Illegal use of 'static' statement");
|
// syntax_error(token, "Illegal use of 'static' statement");
|
||||||
expect_semicolon(f, nullptr);
|
// expect_semicolon(f, nullptr);
|
||||||
return ast_bad_stmt(f, token, f->curr_token);
|
// return ast_bad_stmt(f, token, f->curr_token);
|
||||||
}
|
// }
|
||||||
|
|
||||||
expect_token_after(f, Token_Colon, "identifier list");
|
// expect_token_after(f, Token_Colon, "identifier list");
|
||||||
decl = parse_value_decl(f, list, docs);
|
// decl = parse_value_decl(f, list, docs);
|
||||||
|
|
||||||
if (decl != nullptr && decl->kind == Ast_ValueDecl) {
|
// if (decl != nullptr && decl->kind == Ast_ValueDecl) {
|
||||||
if (decl->ValueDecl.is_mutable) {
|
// if (decl->ValueDecl.is_mutable) {
|
||||||
decl->ValueDecl.is_static = true;
|
// decl->ValueDecl.is_static = true;
|
||||||
} else {
|
// } else {
|
||||||
error(token, "'static' may only be currently used with variable declaration");
|
// error(token, "'static' may only be currently used with variable declaration");
|
||||||
}
|
// }
|
||||||
return decl;
|
// return decl;
|
||||||
}
|
// }
|
||||||
|
|
||||||
syntax_error(token, "Illegal use of 'static' statement");
|
// syntax_error(token, "Illegal use of 'static' statement");
|
||||||
return ast_bad_stmt(f, token, f->curr_token);
|
// return ast_bad_stmt(f, token, f->curr_token);
|
||||||
} break;
|
// } break;
|
||||||
|
|
||||||
case Token_using: {
|
case Token_using: {
|
||||||
CommentGroup *docs = f->lead_comment;
|
CommentGroup *docs = f->lead_comment;
|
||||||
|
|||||||
@@ -376,7 +376,6 @@ AST_KIND(_DeclBegin, "", bool) \
|
|||||||
Array<Ast *> attributes; \
|
Array<Ast *> attributes; \
|
||||||
CommentGroup *docs; \
|
CommentGroup *docs; \
|
||||||
CommentGroup *comment; \
|
CommentGroup *comment; \
|
||||||
bool is_static; \
|
|
||||||
bool is_using; \
|
bool is_using; \
|
||||||
bool is_mutable; \
|
bool is_mutable; \
|
||||||
}) \
|
}) \
|
||||||
|
|||||||
@@ -107,7 +107,6 @@ TOKEN_KIND(Token__KeywordBegin, ""), \
|
|||||||
TOKEN_KIND(Token_bit_field, "bit_field"), \
|
TOKEN_KIND(Token_bit_field, "bit_field"), \
|
||||||
TOKEN_KIND(Token_bit_set, "bit_set"), \
|
TOKEN_KIND(Token_bit_set, "bit_set"), \
|
||||||
TOKEN_KIND(Token_map, "map"), \
|
TOKEN_KIND(Token_map, "map"), \
|
||||||
TOKEN_KIND(Token_static, "static"), \
|
|
||||||
TOKEN_KIND(Token_dynamic, "dynamic"), \
|
TOKEN_KIND(Token_dynamic, "dynamic"), \
|
||||||
TOKEN_KIND(Token_auto_cast, "auto_cast"), \
|
TOKEN_KIND(Token_auto_cast, "auto_cast"), \
|
||||||
TOKEN_KIND(Token_cast, "cast"), \
|
TOKEN_KIND(Token_cast, "cast"), \
|
||||||
|
|||||||
Reference in New Issue
Block a user