diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-09-12 14:41:36 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-09-12 14:41:36 +0100 |
| commit | 9ff4a8b5ab1edaa333180b8206a734787cdfb9f1 (patch) | |
| tree | 3ae74f3ed02e4dc960d6f94eb1ed1f140516f74a /src/parser.cpp | |
| parent | 687e78d5ddf2d75022eedc060b3352643ebe2080 (diff) | |
Switchable array bounds checking
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 57 |
1 files changed, 45 insertions, 12 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index e923811f0..74a4fb71e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -59,10 +59,11 @@ enum DeclKind { }; enum ProcTag { - ProcTag_foreign = GB_BIT(0), - ProcTag_inline = GB_BIT(1), - ProcTag_no_inline = GB_BIT(2), - ProcTag_pure = GB_BIT(3), + ProcTag_abc = GB_BIT(0), + ProcTag_no_abc = GB_BIT(1), + ProcTag_foreign = GB_BIT(2), + ProcTag_inline = GB_BIT(3), + ProcTag_no_inline = GB_BIT(4), }; enum VarDeclTag { @@ -76,6 +77,12 @@ enum TypeFlag : u32 { TypeFlag_atomic = GB_BIT(1), }; +enum StmtStateFlag : u32 { + StmtStateFlag_abc = GB_BIT(0), + StmtStateFlag_no_abc = GB_BIT(1), +}; + + enum CallExprKind { CallExpr_Prefix, // call(...) CallExpr_Postfix, // a'call @@ -288,6 +295,7 @@ struct AstNode { AstNodeKind kind; // AstNode *prev, *next; // NOTE(bill): allow for Linked list u32 type_flags; + u32 stmt_state_flags; union { #define AST_NODE_KIND(_kind_name_, name, ...) __VA_ARGS__ _kind_name_; AST_NODE_KINDS @@ -1169,15 +1177,25 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name) { check_proc_add_tag(f, tag_expr, tags, ProcTag_inline, tag_name); } else if (are_strings_equal(tag_name, make_string("no_inline"))) { check_proc_add_tag(f, tag_expr, tags, ProcTag_no_inline, tag_name); - } else if (are_strings_equal(tag_name, make_string("pure"))) { - check_proc_add_tag(f, tag_expr, tags, ProcTag_pure, tag_name); + } else if (are_strings_equal(tag_name, make_string("abc"))) { + check_proc_add_tag(f, tag_expr, tags, ProcTag_abc, tag_name); + } else if (are_strings_equal(tag_name, make_string("no_abc"))) { + check_proc_add_tag(f, tag_expr, tags, ProcTag_no_abc, tag_name); } else { ast_file_err(f, ast_node_token(tag_expr), "Unknown procedure tag"); } } if ((*tags & ProcTag_inline) && (*tags & ProcTag_no_inline)) { - ast_file_err(f, f->cursor[0], "You cannot apply both `inline` and `no_inline` to a procedure"); + ast_file_err(f, f->cursor[0], "You cannot apply both #inline and #no_inline to a procedure"); + } + + if ((*tags & ProcTag_abc) && (*tags & ProcTag_no_abc)) { + ast_file_err(f, f->cursor[0], "You cannot apply both #abc and #no_abc to a procedure"); + } + + if (((*tags & ProcTag_abc) || (*tags & ProcTag_no_abc)) && (*tags & ProcTag_foreign)) { + ast_file_err(f, f->cursor[0], "You cannot apply both #abc or #no_abc to a procedure without a body"); } } @@ -2493,22 +2511,23 @@ AstNode *parse_stmt(AstFile *f) { case Token_Hash: { s = parse_tag_stmt(f, NULL); + String tag = s->TagStmt.name.string; - if (are_strings_equal(s->TagStmt.name.string, make_string("load"))) { + if (are_strings_equal(tag, make_string("load"))) { Token file_path = expect_token(f, Token_String); if (f->curr_proc == NULL) { return make_load_decl(f, s->TagStmt.token, file_path); } - ast_file_err(f, token, "You cannot `load` within a procedure. This must be done at the file scope."); + ast_file_err(f, token, "You cannot use #load within a procedure. This must be done at the file scope."); return make_bad_decl(f, token, file_path); - } else if (are_strings_equal(s->TagStmt.name.string, make_string("foreign_system_library"))) { + } else if (are_strings_equal(tag, make_string("foreign_system_library"))) { Token file_path = expect_token(f, Token_String); if (f->curr_proc == NULL) { return make_foreign_system_library(f, s->TagStmt.token, file_path); } - ast_file_err(f, token, "You cannot using `foreign_system_library` within a procedure. This must be done at the file scope."); + ast_file_err(f, token, "You cannot use #foreign_system_library within a procedure. This must be done at the file scope."); return make_bad_decl(f, token, file_path); - } else if (are_strings_equal(s->TagStmt.name.string, make_string("thread_local"))) { + } else if (are_strings_equal(tag, make_string("thread_local"))) { AstNode *var_decl = parse_simple_stmt(f); if (var_decl->kind != AstNode_VarDecl || var_decl->VarDecl.kind != Declaration_Mutable) { @@ -2521,6 +2540,20 @@ AstNode *parse_stmt(AstFile *f) { } var_decl->VarDecl.tags |= VarDeclTag_thread_local; return var_decl; + } else if (are_strings_equal(tag, make_string("abc"))) { + s = parse_stmt(f); + s->stmt_state_flags |= StmtStateFlag_abc; + if ((s->stmt_state_flags & StmtStateFlag_no_abc) != 0) { + ast_file_err(f, token, "#abc and #no_abc cannot be applied together"); + } + return s; + } else if (are_strings_equal(tag, make_string("no_abc"))) { + s = parse_stmt(f); + s->stmt_state_flags |= StmtStateFlag_no_abc; + if ((s->stmt_state_flags & StmtStateFlag_abc) != 0) { + ast_file_err(f, token, "#abc and #no_abc cannot be applied together"); + } + return s; } |