diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-11-30 10:52:09 +0000 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-11-30 10:52:09 +0000 |
| commit | b76c8abe7379f1d1a88fddf9387fe6338ad920e3 (patch) | |
| tree | 0ff8fde6f770e522d6e1f24b59f947ce4376f481 /src/parser.c | |
| parent | d9c686b53d63023c432293fa906d96224cc36a23 (diff) | |
error_node
Diffstat (limited to 'src/parser.c')
| -rw-r--r-- | src/parser.c | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/src/parser.c b/src/parser.c index f46bae4da..1923b51d3 100644 --- a/src/parser.c +++ b/src/parser.c @@ -355,8 +355,6 @@ typedef struct AstNode { #define case_end } break; - - gb_inline bool is_ast_node_expr(AstNode *node) { return gb_is_between(node->kind, AstNode__ExprBegin+1, AstNode__ExprEnd-1); } @@ -500,6 +498,38 @@ Token ast_node_token(AstNode *node) { return empty_token; } + +void error_node(AstNode *node, char *fmt, ...) { + va_list va; + va_start(va, fmt); + error_va(ast_node_token(node), fmt, va); + va_end(va); +} + +void warning_node(AstNode *node, char *fmt, ...) { + va_list va; + va_start(va, fmt); + warning_va(ast_node_token(node), fmt, va); + va_end(va); +} + +void syntax_error_node(AstNode *node, char *fmt, ...) { + va_list va; + va_start(va, fmt); + syntax_error_va(ast_node_token(node), fmt, va); + va_end(va); +} + + +bool ast_node_expect(AstNode *node, AstNodeKind kind) { + if (node->kind != kind) { + error_node(node, "Expected %.*s, got %.*s", LIT(ast_node_strings[node->kind])); + return false; + } + return true; +} + + // NOTE(bill): And this below is why is I/we need a new language! Discriminated unions are a pain in C/C++ AstNode *make_node(AstFile *f, AstNodeKind kind) { gbArena *arena = &f->arena; @@ -1232,7 +1262,7 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags); void check_proc_add_tag(AstFile *f, AstNode *tag_expr, u64 *tags, ProcTag tag, String tag_name) { if (*tags & tag) { - syntax_error(ast_node_token(tag_expr), "Procedure tag already used: %.*s", LIT(tag_name)); + syntax_error_node(tag_expr, "Procedure tag already used: %.*s", LIT(tag_name)); } *tags |= tag; } @@ -1306,7 +1336,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n *foreign_name = f->curr_token.string; // TODO(bill): Check if valid string if (!is_foreign_name_valid(*foreign_name)) { - syntax_error(ast_node_token(tag_expr), "Invalid alternative foreign procedure name: `%.*s`", LIT(*foreign_name)); + syntax_error_node(tag_expr, "Invalid alternative foreign procedure name: `%.*s`", LIT(*foreign_name)); } next_token(f); @@ -1317,7 +1347,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n *link_name = f->curr_token.string; // TODO(bill): Check if valid string if (!is_foreign_name_valid(*link_name)) { - syntax_error(ast_node_token(tag_expr), "Invalid alternative link procedure name `%.*s`", LIT(*link_name)); + syntax_error_node(tag_expr, "Invalid alternative link procedure name `%.*s`", LIT(*link_name)); } next_token(f); @@ -1335,7 +1365,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n ELSE_IF_ADD_TAG(fastcall) // ELSE_IF_ADD_TAG(cdecl) else { - syntax_error(ast_node_token(tag_expr), "Unknown procedure tag"); + syntax_error_node(tag_expr, "Unknown procedure tag"); } #undef ELSE_IF_ADD_TAG @@ -1437,7 +1467,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) { AstNode *expr = parse_expr(f, false); operand = make_run_expr(f, token, name, expr); if (unparen_expr(expr)->kind != AstNode_CallExpr) { - error(ast_node_token(expr), "#run can only be applied to procedure calls"); + error_node(expr, "#run can only be applied to procedure calls"); operand = make_bad_expr(f, token, f->curr_token); } warning(token, "#run is not yet implemented"); @@ -1999,7 +2029,7 @@ AstNodeArray parse_record_params(AstFile *f, isize *decl_count_, bool using_allo } array_add(&decls, vd); } else { - syntax_error(ast_node_token(decl), "Illegal %.*s field", LIT(context)); + syntax_error_node(decl, "Illegal %.*s field", LIT(context)); } } break; @@ -2021,7 +2051,7 @@ AstNodeArray parse_record_params(AstFile *f, isize *decl_count_, bool using_allo break; } } else { - syntax_error(ast_node_token(decl), "Illegal record field: %.*s", LIT(ast_node_strings[decl->kind])); + syntax_error_node(decl, "Illegal record field: %.*s", LIT(ast_node_strings[decl->kind])); } } @@ -2293,7 +2323,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) { String n = name->Ident.string; // NOTE(bill): Check for reserved identifiers if (str_eq(n, str_lit("context"))) { - syntax_error(ast_node_token(name), "`context` is a reserved identifier"); + syntax_error_node(name, "`context` is a reserved identifier"); break; } } @@ -2326,7 +2356,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) { next_token(f); } if (names.count != 1) { - syntax_error(ast_node_token(names.e[0]), "You can only declare one type at a time"); + syntax_error_node(names.e[0], "You can only declare one type at a time"); return make_bad_decl(f, names.e[0]->Ident, token); } @@ -3164,7 +3194,7 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, AstNodeArray node->kind != AstNode_BadStmt && node->kind != AstNode_EmptyStmt) { // NOTE(bill): Sanity check - syntax_error(ast_node_token(node), "Only declarations are allowed at file scope"); + syntax_error_node(node, "Only declarations are allowed at file scope"); } else if (node->kind == AstNode_WhenStmt) { parse_setup_file_when_stmt(p, f, base_dir, &node->WhenStmt); } else if (node->kind == AstNode_ImportDecl) { @@ -3173,9 +3203,9 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, AstNodeArray if (!is_import_path_valid(file_str)) { if (id->is_load) { - syntax_error(ast_node_token(node), "Invalid #load path: `%.*s`", LIT(file_str)); + syntax_error_node(node, "Invalid #load path: `%.*s`", LIT(file_str)); } else { - syntax_error(ast_node_token(node), "Invalid #import path: `%.*s`", LIT(file_str)); + syntax_error_node(node, "Invalid #import path: `%.*s`", LIT(file_str)); } // NOTE(bill): It's a naughty name decls.e[i] = make_bad_decl(f, id->token, id->token); @@ -3202,9 +3232,9 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, AstNodeArray if (!is_import_path_valid(file_str)) { if (fl->is_system) { - syntax_error(ast_node_token(node), "Invalid `foreign_system_library` path"); + syntax_error_node(node, "Invalid `foreign_system_library` path"); } else { - syntax_error(ast_node_token(node), "Invalid `foreign_library` path"); + syntax_error_node(node, "Invalid `foreign_library` path"); } // NOTE(bill): It's a naughty name f->decls.e[i] = make_bad_decl(f, fl->token, fl->token); |