Browse Source

Make `require_results` an attribute rather than a suffix tag for procedures

gingerBill 6 years ago
parent
commit
b311540b16
6 changed files with 15 additions and 8 deletions
  1. 0 1
      core/odin/ast/ast.odin
  2. 0 2
      core/odin/parser/parser.odin
  3. 3 4
      src/check_decl.cpp
  4. 6 0
      src/checker.cpp
  5. 1 0
      src/checker.hpp
  6. 5 1
      src/parser.cpp

+ 0 - 1
core/odin/ast/ast.odin

@@ -5,7 +5,6 @@ import "core:odin/token"
 Proc_Tag :: enum {
 	Bounds_Check,
 	No_Bounds_Check,
-	Require_Results,
 }
 Proc_Tags :: distinct bit_set[Proc_Tag; u32];
 

+ 0 - 2
core/odin/parser/parser.odin

@@ -1745,8 +1745,6 @@ parse_proc_tags :: proc(p: ^Parser) -> (tags: ast.Proc_Tags) {
 		ident := expect_token(p, token.Ident);
 
 		switch ident.text {
-		case "require_results":
-			tags |= {.Require_Results};
 		case "bounds_check":
 			tags |= {.Bounds_Check};
 		case "no_bounds_check":

+ 3 - 4
src/check_decl.cpp

@@ -654,7 +654,6 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
 
 	bool is_foreign         = e->Procedure.is_foreign;
 	bool is_export          = e->Procedure.is_export;
-	bool is_require_results = (pl->tags & ProcTag_require_results) != 0;
 
 	if (e->pkg != nullptr && e->token.string == "main") {
 		if (pt->param_count != 0 ||
@@ -714,10 +713,10 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
 		}
 	}
 
-	if (pt->result_count == 0 && is_require_results) {
-		error(pl->type, "'#require_results' is not needed on a procedure with no results");
+	if (pt->result_count == 0 && ac.require_results) {
+		error(pl->type, "'require_results' is not needed on a procedure with no results");
 	} else {
-		pt->require_results = is_require_results;
+		pt->require_results = ac.require_results;
 	}
 
 	if (ac.link_name.len > 0) {

+ 6 - 0
src/checker.cpp

@@ -2187,6 +2187,12 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
 			error(elem, "Expected a string value for '%.*s'", LIT(name));
 		}
 		return true;
+	} else if (name == "require_results") {
+		if (value != nullptr) {
+			error(elem, "Expected no value for '%.*s'", LIT(name));
+		}
+		ac->require_results = true;
+		return true;
 	}
 	return false;
 }

+ 1 - 0
src/checker.hpp

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

+ 5 - 1
src/parser.cpp

@@ -1855,7 +1855,7 @@ Ast *parse_operand(AstFile *f, bool lhs) {
 		}
 
 		if (tags != 0) {
-			syntax_error(token, "A procedure type cannot have tags");
+			syntax_error(token, "A procedure type cannot have suffix tags");
 		}
 
 		return type;
@@ -2828,6 +2828,10 @@ Ast *parse_proc_type(AstFile *f, Token proc_token) {
 
 	u64 tags = 0;
 	parse_proc_tags(f, &tags);
+	if ((tags & ProcTag_require_results) != 0) {
+		syntax_error(f->curr_token, "#require_results has now been replaced as an attribute @(require_results) on the declaration");
+		tags &= ~ProcTag_require_results;
+	}
 
 	bool is_generic = false;