Browse Source

Make `static` an attribute rather than a keyword prefix

gingerBill 6 years ago
parent
commit
a9ab90bd24
9 changed files with 66 additions and 51 deletions
  1. 2 2
      core/strings/builder.odin
  2. 6 1
      src/check_decl.cpp
  3. 12 5
      src/check_stmt.cpp
  4. 8 12
      src/checker.cpp
  5. 1 0
      src/checker.hpp
  6. 10 1
      src/ir.cpp
  7. 27 28
      src/parser.cpp
  8. 0 1
      src/parser.hpp
  9. 0 1
      src/tokenizer.cpp

+ 2 - 2
core/strings/builder.odin

@@ -61,8 +61,8 @@ write_bytes :: proc(b: ^Builder, x: []byte) {
 	append(&b.buf, ..x);
 }
 
-@(private)
-static DIGITS_LOWER := "0123456789abcdefx";
+@(private, static)
+DIGITS_LOWER := "0123456789abcdefx";
 
 write_quoted_string :: proc(b: ^Builder, s: string, quote: byte = '"') {
 	write_byte(b, quote);

+ 6 - 1
src/check_decl.cpp

@@ -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);
 	}
 
+	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);
-	e->Variable.thread_local_model = ac.thread_local_model;
 
 	String context_name = str_lit("variable declaration");
 

+ 12 - 5
src/check_stmt.cpp

@@ -1665,8 +1665,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 					if (!is_blank_ident(str)) {
 						found = scope_lookup_current(ctx->scope, str);
 						new_name_count += 1;
-					} else if (vd->is_static) {
-						error(name, "'static' is now allowed to be applied to '_'");
 					}
 					if (found == nullptr) {
 						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.foreign_library_ident = fl;
 						}
-						if (vd->is_static) {
-							entity->flags |= EntityFlag_Static;
-						}
 					} else {
 						TokenPos pos = found->token.pos;
 						error(token,
@@ -1744,6 +1739,16 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 				if (ac.link_name.len > 0) {
 					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);
@@ -1751,6 +1756,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 
 			for (isize i = 0; i < entity_count; i++) {
 				Entity *e = entities[i];
+
 				if (e->Variable.is_foreign) {
 					if (vd->values.count > 0) {
 						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 {
 			// constant value declaration
 			// NOTE(bill): Check `_` declarations

+ 8 - 12
src/checker.cpp

@@ -2070,6 +2070,14 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
 DECL_ATTRIBUTE_PROC(var_decl_attribute) {
 	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) {
 		error(elem, "Only a variable at file scope can have a '%.*s'", LIT(name));
 		return true;
@@ -2425,10 +2433,6 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
 				e->flags |= EntityFlag_NotExported;
 			}
 
-			if (vd->is_static) {
-				e->flags |= EntityFlag_Static;
-			}
-
 			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");
@@ -2527,14 +2531,6 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
 				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 (e->kind == Entity_TypeName && init->kind == Ast_EnumType) {
 					d->is_using = true;

+ 1 - 0
src/checker.hpp

@@ -306,6 +306,7 @@ struct DeferredProcedure {
 
 struct AttributeContext {
 	bool    is_export;
+	bool    is_static;
 	String  link_name;
 	String  link_prefix;
 	isize   init_expr_list_count;

+ 10 - 1
src/ir.cpp

@@ -8166,7 +8166,16 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
 		if (vd->is_mutable) {
 			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) {
 					irValue *value = nullptr;
 					if (vd->values.count > 0) {

+ 27 - 28
src/parser.cpp

@@ -1208,7 +1208,6 @@ void fix_advance_to_next_stmt(AstFile *f) {
 		case Token_defer:
 		case Token_asm:
 		case Token_using:
-		case Token_static:
 
 		case Token_break:
 		case Token_continue:
@@ -3751,33 +3750,33 @@ Ast *parse_stmt(AstFile *f) {
 		return s;
 	}
 
-	case Token_static: {
-		CommentGroup *docs = f->lead_comment;
-		Token token = expect_token(f, Token_static);
-
-		Ast *decl = nullptr;
-		Array<Ast *> list = parse_lhs_expr_list(f);
-		if (list.count == 0) {
-			syntax_error(token, "Illegal use of 'static' statement");
-			expect_semicolon(f, nullptr);
-			return ast_bad_stmt(f, token, f->curr_token);
-		}
-
-		expect_token_after(f, Token_Colon, "identifier list");
-		decl = parse_value_decl(f, list, docs);
-
-		if (decl != nullptr && decl->kind == Ast_ValueDecl) {
-			if (decl->ValueDecl.is_mutable) {
-				decl->ValueDecl.is_static = true;
-			} else {
-				error(token, "'static' may only be currently used with variable declaration");
-			}
-			return decl;
-		}
-
-		syntax_error(token, "Illegal use of 'static' statement");
-		return ast_bad_stmt(f, token, f->curr_token);
-	} break;
+	// case Token_static: {
+	// 	CommentGroup *docs = f->lead_comment;
+	// 	Token token = expect_token(f, Token_static);
+
+	// 	Ast *decl = nullptr;
+	// 	Array<Ast *> list = parse_lhs_expr_list(f);
+	// 	if (list.count == 0) {
+	// 		syntax_error(token, "Illegal use of 'static' statement");
+	// 		expect_semicolon(f, nullptr);
+	// 		return ast_bad_stmt(f, token, f->curr_token);
+	// 	}
+
+	// 	expect_token_after(f, Token_Colon, "identifier list");
+	// 	decl = parse_value_decl(f, list, docs);
+
+	// 	if (decl != nullptr && decl->kind == Ast_ValueDecl) {
+	// 		if (decl->ValueDecl.is_mutable) {
+	// 			decl->ValueDecl.is_static = true;
+	// 		} else {
+	// 			error(token, "'static' may only be currently used with variable declaration");
+	// 		}
+	// 		return decl;
+	// 	}
+
+	// 	syntax_error(token, "Illegal use of 'static' statement");
+	// 	return ast_bad_stmt(f, token, f->curr_token);
+	// } break;
 
 	case Token_using: {
 		CommentGroup *docs = f->lead_comment;

+ 0 - 1
src/parser.hpp

@@ -376,7 +376,6 @@ AST_KIND(_DeclBegin,      "", bool) \
 		Array<Ast *> attributes;  \
 		CommentGroup *docs;       \
 		CommentGroup *comment;    \
-		bool          is_static;  \
 		bool          is_using;   \
 		bool          is_mutable; \
 	}) \

+ 0 - 1
src/tokenizer.cpp

@@ -107,7 +107,6 @@ TOKEN_KIND(Token__KeywordBegin, ""), \
 	TOKEN_KIND(Token_bit_field,   "bit_field"),   \
 	TOKEN_KIND(Token_bit_set,     "bit_set"),     \
 	TOKEN_KIND(Token_map,         "map"),         \
-	TOKEN_KIND(Token_static,      "static"),     \
 	TOKEN_KIND(Token_dynamic,     "dynamic"),     \
 	TOKEN_KIND(Token_auto_cast,   "auto_cast"),   \
 	TOKEN_KIND(Token_cast,        "cast"),        \