From 220485a2d2cd180e7ff2a15bab66c867c06b05d7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 2 Sep 2018 15:56:36 +0100 Subject: `typeid` as keyword (ready to implement polymorphic name parameters) --- src/checker.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index a4635b215..ff5375a07 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1367,7 +1367,6 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { for_array(i, c->info.definitions) { Entity *e = c->info.definitions[i]; - // if (e->scope->is_global && !is_type_poly_proc(e->type)) { // TODO(bill): is the check enough? if (e->scope == builtin_pkg->scope) { // TODO(bill): is the check enough? if (e->type == nullptr) { add_dependency_to_set(c, e); @@ -1806,6 +1805,14 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) { return false; } +DECL_ATTRIBUTE_PROC(const_decl_attribute) { + if (name == "private") { + // NOTE(bill): Handled elsewhere `check_collect_value_decl` + return true; + } + return false; +} + @@ -2025,6 +2032,49 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { ast_node(vd, ValueDecl, decl); + bool entity_is_private = false; + for_array(i, vd->attributes) { + Ast *attr = vd->attributes[i]; + if (attr->kind != Ast_Attribute) continue; + auto *elems = &attr->Attribute.elems; + for (isize j = 0; j < elems->count; j++) { + Ast *elem = (*elems)[j]; + String name = {}; + Ast *value = nullptr; + switch (elem->kind) { + case_ast_node(i, Ident, elem); + name = i->token.string; + case_end; + case_ast_node(fv, FieldValue, elem); + GB_ASSERT(fv->field->kind == Ast_Ident); + name = fv->field->Ident.token.string; + value = fv->value; + case_end; + default: + continue; + } + + if (name == "private") { + if (value != nullptr) { + error(value, "'%.*s' does not expect a value", LIT(name)); + } + + if (entity_is_private) { + error(elem, "Previous declaration of '%.*s'", LIT(name)); + } else { + entity_is_private = true; + } + array_unordered_remove(elems, j); + j -= 1; + } + } + } + + if (entity_is_private && !(c->scope->flags&ScopeFlag_File)) { + error(decl, "Attribute 'private' is not allowed on a non file scope entity"); + } + + if (vd->is_mutable) { if (!(c->scope->flags&ScopeFlag_File)) { // NOTE(bill): local scope -> handle later and in order @@ -2044,6 +2094,10 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { Entity *e = alloc_entity_variable(c->scope, name->Ident.token, nullptr, false); e->identifier = name; + if (entity_is_private) { + e->flags |= EntityFlag_NotExported; + } + if (vd->is_using) { vd->is_using = false; // NOTE(bill): This error will be only caught once error(name, "'using' is not allowed at the file scope"); @@ -2145,6 +2199,10 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { } e->identifier = name; + if (entity_is_private) { + e->flags |= EntityFlag_NotExported; + } + if (vd->is_using) { if (e->kind == Entity_TypeName && init->kind == Ast_EnumType) { d->is_using = true; -- cgit v1.2.3