Ver Fonte

Foreign context cleanup

gingerBill há 7 anos atrás
pai
commit
e7999f8450
4 ficheiros alterados com 32 adições e 68 exclusões
  1. 4 4
      src/check_stmt.cpp
  2. 3 3
      src/check_type.cpp
  3. 23 22
      src/checker.cpp
  4. 2 39
      src/parser.cpp

+ 4 - 4
src/check_stmt.cpp

@@ -1669,8 +1669,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 
 		CheckerContext prev_context = c->context;
 		if (ok) {
-			c->context.curr_foreign_library = foreign_library;
-			c->context.default_foreign_cc = ProcCC_CDecl;
+			c->context.foreign_context.curr_library = foreign_library;
+			c->context.foreign_context.default_cc = ProcCC_CDecl;
 		}
 
 		check_foreign_block_decl_attributes(c, fb);
@@ -1763,7 +1763,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 					entity = make_entity_variable(c->allocator, c->context.scope, token, nullptr, false);
 					entity->identifier = name;
 
-					AstNode *fl = c->context.curr_foreign_library;
+					AstNode *fl = c->context.foreign_context.curr_library;
 					if (fl != nullptr) {
 						GB_ASSERT(fl->kind == AstNode_Ident);
 						entity->Variable.is_foreign = true;
@@ -1850,7 +1850,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 			add_entity(c, c->context.scope, e->identifier, e);
 		}
 
-		if ((vd->flags & VarDeclFlag_using) != 0) {
+		if (vd->is_using != 0) {
 			Token token = ast_node_token(node);
 			if (vd->type != nullptr && entity_count > 1) {
 				error(token, "`using` can only be applied to one variable of the same type");

+ 3 - 3
src/check_type.cpp

@@ -82,7 +82,7 @@ void check_struct_field_decl(Checker *c, AstNode *decl, Array<Entity *> *fields,
 
 	if (!vd->is_mutable) return;
 
-	bool is_using = (vd->flags&VarDeclFlag_using) != 0;
+	bool is_using = vd->is_using;
 
 	if (is_using && vd->names.count > 1) {
 		error(vd->names[0], "Cannot apply `using` to more than one of the same type");
@@ -1891,8 +1891,8 @@ bool check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node, Array
 	ProcCallingConvention cc = pt->calling_convention;
 	if (cc == ProcCC_ForeignBlockDefault) {
 		cc = ProcCC_CDecl;
-		if (c->context.default_foreign_cc > 0) {
-			cc = c->context.default_foreign_cc;
+		if (c->context.foreign_context.default_cc > 0) {
+			cc = c->context.foreign_context.default_cc;
 		}
 	}
 	GB_ASSERT(cc > 0);

+ 23 - 22
src/checker.cpp

@@ -411,7 +411,12 @@ GB_COMPARE_PROC(ast_node_cmp) {
 	return token_pos_cmp(i.pos, j.pos);
 }
 
-
+struct ForeignContext {
+	AstNode *             curr_library;
+	ProcCallingConvention default_cc;
+	String                link_prefix;
+	bool                  in_export;
+};
 
 struct CheckerContext {
 	Scope *    file_scope;
@@ -422,11 +427,8 @@ struct CheckerContext {
 	String     proc_name;
 	Type *     type_hint;
 	DeclInfo * curr_proc_decl;
-	AstNode *  curr_foreign_library;
-	ProcCallingConvention default_foreign_cc;
-	String                foreign_link_prefix;
+	ForeignContext foreign_context;
 
-	bool       in_foreign_export;
 	bool       collect_delayed_decls;
 	bool       allow_polymorphic_types;
 	bool       no_polymorphic_errors;
@@ -1916,7 +1918,7 @@ void check_foreign_block_decl_attributes(Checker *c, AstNodeForeignBlockDecl *fb
 					if (cc == ProcCC_Invalid) {
 						error(elem, "Unknown procedure calling convention: `%.*s`\n", LIT(ev.value_string));
 					} else {
-						c->context.default_foreign_cc = cc;
+						c->context.foreign_context.default_cc = cc;
 					}
 				} else {
 					error(elem, "Expected a string value for `%.*s`", LIT(name));
@@ -1927,7 +1929,7 @@ void check_foreign_block_decl_attributes(Checker *c, AstNodeForeignBlockDecl *fb
 					if (!is_foreign_name_valid(link_prefix)) {
 						error(elem, "Invalid link prefix: `%.*s`\n", LIT(link_prefix));
 					} else {
-						c->context.foreign_link_prefix = link_prefix;
+						c->context.foreign_context.link_prefix = link_prefix;
 					}
 				} else {
 					error(elem, "Expected a string value for `%.*s`", LIT(name));
@@ -2053,20 +2055,20 @@ void check_collect_value_decl(Checker *c, AstNode *decl) {
 			Entity *e = make_entity_variable(c->allocator, c->context.scope, name->Ident.token, nullptr, false);
 			e->identifier = name;
 
-			if (vd->flags & VarDeclFlag_using) {
-				vd->flags &= ~VarDeclFlag_using; // NOTE(bill): This error will be only caught once
+			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");
 			}
 
-			AstNode *fl = c->context.curr_foreign_library;
+			AstNode *fl = c->context.foreign_context.curr_library;
 			if (fl != nullptr) {
 				GB_ASSERT(fl->kind == AstNode_Ident);
 				e->Variable.is_foreign = true;
 				e->Variable.foreign_library_ident = fl;
 
-				e->Variable.link_prefix = c->context.foreign_link_prefix;
+				e->Variable.link_prefix = c->context.foreign_context.link_prefix;
 
-			} else if (c->context.in_foreign_export) {
+			} else if (c->context.foreign_context.in_export) {
 				e->Variable.is_export = true;
 			}
 
@@ -2105,7 +2107,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) {
 
 			Token token = name->Ident.token;
 
-			AstNode *fl = c->context.curr_foreign_library;
+			AstNode *fl = c->context.foreign_context.curr_library;
 			DeclInfo *d = make_declaration_info(c->allocator, c->context.scope, c->context.decl);
 			Entity *e = nullptr;
 
@@ -2135,16 +2137,16 @@ void check_collect_value_decl(Checker *c, AstNode *decl) {
 					auto cc = pl->type->ProcType.calling_convention;
 					if (cc == ProcCC_ForeignBlockDefault) {
 						cc = ProcCC_CDecl;
-						if (c->context.default_foreign_cc > 0) {
-							cc = c->context.default_foreign_cc;
+						if (c->context.foreign_context.default_cc > 0) {
+							cc = c->context.foreign_context.default_cc;
 						}
 					}
-					e->Procedure.link_prefix = c->context.foreign_link_prefix;
+					e->Procedure.link_prefix = c->context.foreign_context.link_prefix;
 
 					GB_ASSERT(cc != ProcCC_Invalid);
 					pl->type->ProcType.calling_convention = cc;
 
-				} else if (c->context.in_foreign_export) {
+				} else if (c->context.foreign_context.in_export) {
 					e->Procedure.is_export = true;
 				}
 				d->proc_lit = init;
@@ -2157,7 +2159,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) {
 			e->identifier = name;
 
 			if (e->kind != Entity_Procedure) {
-				if (fl != nullptr || c->context.in_foreign_export) {
+				if (fl != nullptr || c->context.foreign_context.in_export) {
 					AstNodeKind kind = init->kind;
 					error(name, "Only procedures and variables are allowed to be in a foreign block, got %.*s", LIT(ast_node_strings[kind]));
 					if (kind == AstNode_ProcType) {
@@ -2182,15 +2184,14 @@ void check_add_foreign_block_decl(Checker *c, AstNode *decl) {
 
 	AstNode *foreign_library = fb->foreign_library;
 
-
 	CheckerContext prev_context = c->context;
 	if (foreign_library->kind == AstNode_Ident) {
-		c->context.curr_foreign_library = foreign_library;
+		c->context.foreign_context.curr_library = foreign_library;
 	} else if (foreign_library->kind == AstNode_Implicit && foreign_library->Implicit.kind == Token_export) {
-		c->context.in_foreign_export = true;
+		c->context.foreign_context.in_export = true;
 	} else {
 		error(foreign_library, "Foreign block name must be an identifier or `export`");
-		c->context.curr_foreign_library = nullptr;
+		c->context.foreign_context.curr_library = nullptr;
 	}
 
 	check_foreign_block_decl_attributes(c, fb);

+ 2 - 39
src/parser.cpp

@@ -115,10 +115,6 @@ enum ProcCallingConvention {
 	ProcCC_ForeignBlockDefault = -1,
 };
 
-enum VarDeclFlag {
-	VarDeclFlag_using = 1<<0,
-};
-
 enum StmtStateFlag {
 	StmtStateFlag_bounds_check    = 1<<0,
 	StmtStateFlag_no_bounds_check = 1<<1,
@@ -347,7 +343,7 @@ AST_NODE_KIND(_DeclBegin,      "", i32) \
 		Array<AstNode *> names;        \
 		AstNode *        type;         \
 		Array<AstNode *> values;       \
-		u64              flags;        \
+		bool             is_using;     \
 		bool             is_mutable;   \
 		bool             been_handled; \
 		Array<AstNode *> attributes;   \
@@ -3517,39 +3513,6 @@ AstNode *parse_struct_field_list(AstFile *f, isize *name_count_) {
 	AstNode *params = parse_field_list(f, &total_name_count, FieldFlag_Struct, Token_CloseBrace, true, false);
 	if (name_count_) *name_count_ = total_name_count;
 	return params;
-
-#if 0
-	while (f->curr_token.kind != Token_CloseBrace &&
-	       f->curr_token.kind != Token_EOF) {
-		AstNode *decl = parse_stmt(f);
-		switch (decl->kind) {
-		case AstNode_EmptyStmt:
-		case AstNode_BadStmt:
-		case AstNode_BadDecl:
-			break;
-
-		case_ast_node(vd, ValueDecl, decl);
-			if (vd->flags&VarDeclFlag_thread_local) {
-				vd->flags &= ~VarDeclFlag_thread_local;
-				syntax_error(decl, "Field values cannot be #thread_local");
-			}
-			array_add(&decls, decl);
-			total_name_count += vd->names.count;
-		case_end;
-
-		case AstNode_WhenStmt:
-			array_add(&decls, decl);
-			break;
-
-		default:
-			syntax_error(decl, "Expected a value declaration, got %.*s", LIT(ast_node_strings[decl->kind]));
-			break;
-		}
-	}
-
-	if (name_count_) *name_count_ = total_name_count;
-	return ast_field_list(f, start_token, decls);
-#endif
 }
 
 AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKind follow, bool allow_default_parameters, bool allow_type_token) {
@@ -4549,7 +4512,7 @@ AstNode *parse_stmt(AstFile *f) {
 				syntax_error(token, "`using` may only be applied to variable declarations");
 				return decl;
 			}
-			decl->ValueDecl.flags |= VarDeclFlag_using;
+			decl->ValueDecl.is_using = true;
 			return decl;
 		}