diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-11-30 20:07:23 +0000 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-11-30 20:07:23 +0000 |
| commit | ab2ca7cf5975b78c254b87fa5590be147853b79a (patch) | |
| tree | b301bcfe2dcdc5d03856970a598b789f5945fc4e /src | |
| parent | b76c8abe7379f1d1a88fddf9387fe6338ad920e3 (diff) | |
Fix illegal type declaration error
Diffstat (limited to 'src')
| -rw-r--r-- | src/checker/checker.c | 39 | ||||
| -rw-r--r-- | src/checker/decl.c | 2 | ||||
| -rw-r--r-- | src/checker/expr.c | 12 | ||||
| -rw-r--r-- | src/checker/types.c | 3 | ||||
| -rw-r--r-- | src/parser.c | 13 | ||||
| -rw-r--r-- | src/tokenizer.c | 10 |
6 files changed, 46 insertions, 33 deletions
diff --git a/src/checker/checker.c b/src/checker/checker.c index 9461a9f41..122906e35 100644 --- a/src/checker/checker.c +++ b/src/checker/checker.c @@ -724,7 +724,7 @@ bool add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) { return false; } else { TokenPos pos = insert_entity->token.pos; - if (token_pos_are_equal(pos, entity->token.pos)) { + if (token_pos_eq(pos, entity->token.pos)) { // NOTE(bill): Error should have been handled already return false; } @@ -1048,27 +1048,29 @@ void check_global_entities_by_kind(Checker *c, EntityKind kind) { for_array(i, c->info.entities.entries) { MapDeclInfoEntry *entry = &c->info.entities.entries.e[i]; Entity *e = cast(Entity *)cast(uintptr)entry->key.key; - if (e->kind == kind) { - DeclInfo *d = entry->value; - if (d->scope != e->scope) { - continue; - } + DeclInfo *d = entry->value; - add_curr_ast_file(c, d->scope->file); - if (kind != Entity_Procedure && str_eq(e->token.string, str_lit("main"))) { - if (e->scope->is_init) { - error(e->token, "`main` is reserved as the entry point procedure in the initial scope"); - continue; - } - } else if (e->scope->is_global && str_eq(e->token.string, str_lit("main"))) { + if (e->kind != kind) { + continue; + } + if (d->scope != e->scope) { + continue; + } + + add_curr_ast_file(c, d->scope->file); + if (e->kind != Entity_Procedure && str_eq(e->token.string, str_lit("main"))) { + if (e->scope->is_init) { error(e->token, "`main` is reserved as the entry point procedure in the initial scope"); continue; } - - Scope *prev_scope = c->context.scope; - c->context.scope = d->scope; - check_entity_decl(c, e, d, NULL, NULL); + } else if (e->scope->is_global && str_eq(e->token.string, str_lit("main"))) { + error(e->token, "`main` is reserved as the entry point procedure in the initial scope"); + continue; } + + Scope *prev_scope = c->context.scope; + c->context.scope = d->scope; + check_entity_decl(c, e, d, NULL, NULL); } } @@ -1383,14 +1385,13 @@ void check_parsed_files(Checker *c) { } check_global_entities_by_kind(c, Entity_TypeName); - init_preload_types(c); add_implicit_value(c, ImplicitValue_context, str_lit("context"), str_lit("__context"), t_context); - check_global_entities_by_kind(c, Entity_Constant); check_global_entities_by_kind(c, Entity_Procedure); check_global_entities_by_kind(c, Entity_Variable); + for (isize i = 1; i < ImplicitValue_Count; i++) { // NOTE(bill): First is invalid Entity *e = c->info.implicit_values[i]; diff --git a/src/checker/decl.c b/src/checker/decl.c index 9a50687ba..57d116276 100644 --- a/src/checker/decl.c +++ b/src/checker/decl.c @@ -305,7 +305,7 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, Cycle named->Named.base = bt; named->Named.base = base_type(named->Named.base); if (named->Named.base == t_invalid) { - gb_printf("check_type_decl: %s\n", type_to_string(named)); + // gb_printf("check_type_decl: %s\n", type_to_string(named)); } cycle_checker_destroy(&local_cycle_checker); diff --git a/src/checker/expr.c b/src/checker/expr.c index a673150ae..f8f39c1b0 100644 --- a/src/checker/expr.c +++ b/src/checker/expr.c @@ -1329,14 +1329,19 @@ end: if (is_type_named(type)) { if (type->Named.base == NULL) { + error_node(e, "Invalid type definition"); type->Named.base = t_invalid; } } + if (is_type_typed(type)) { + add_type_and_value(&c->info, e, Addressing_Type, type, null_value); + } else { + error_node(e, "Invalid type definition"); + type = t_invalid; + } set_base_type(named_type, type); - GB_ASSERT(is_type_typed(type)); - add_type_and_value(&c->info, e, Addressing_Type, type, null_value); return type; @@ -3755,7 +3760,8 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) { } Type *proc_type = base_type(operand->type); - if (proc_type == NULL || proc_type->kind != Type_Proc) { + if (proc_type == NULL || proc_type->kind != Type_Proc || + !(operand->mode == Addressing_Value || operand->mode == Addressing_Variable)) { AstNode *e = operand->expr; gbString str = expr_to_string(e); error_node(e, "Cannot call a non-procedure: `%s`", str); diff --git a/src/checker/types.c b/src/checker/types.c index 72ce813ea..dc18984e5 100644 --- a/src/checker/types.c +++ b/src/checker/types.c @@ -490,6 +490,9 @@ bool is_type_string(Type *t) { } bool is_type_typed(Type *t) { t = base_type(t); + if (t == NULL) { + return false; + } if (t->kind == Type_Basic) { return (t->Basic.flags & BasicFlag_Untyped) == 0; } diff --git a/src/parser.c b/src/parser.c index 1923b51d3..6220a48a5 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1133,7 +1133,7 @@ void fix_advance_to_next_stmt(AstFile *f) { case Token_Hash: { - if (token_pos_are_equal(t.pos, f->fix_prev_pos) && + if (token_pos_eq(t.pos, f->fix_prev_pos) && f->fix_count < PARSER_MAX_FIX_COUNT) { f->fix_count++; return; @@ -2304,9 +2304,11 @@ AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) { if (f->curr_token.kind == Token_OpenBrace) { if ((tags & ProcTag_foreign) != 0) { - syntax_error(f->curr_token, "A procedure tagged as `#foreign` cannot have a body"); + syntax_error_node(name, "A procedure tagged as `#foreign` cannot have a body"); } body = parse_body(f); + } else if ((tags & ProcTag_foreign) == 0) { + syntax_error_node(name, "Only a procedure tagged as `#foreign` cannot have a body"); } f->curr_proc = curr_proc; @@ -2339,8 +2341,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) { bool is_mutable = true; - if (f->curr_token.kind == Token_Eq || - f->curr_token.kind == Token_Colon) { + if (f->curr_token.kind == Token_Eq || f->curr_token.kind == Token_Colon) { if (f->curr_token.kind == Token_Colon) { is_mutable = false; } @@ -2903,7 +2904,7 @@ AstNode *parse_stmt(AstFile *f) { } return make_import_decl(f, s->TagStmt.token, file_path, import_name, os, arch, false); - } else if (str_eq(tag, str_lit("load"))) { + } else if (str_eq(tag, str_lit("include"))) { String os = {0}; String arch = {0}; // TODO(bill): better error messages @@ -2914,7 +2915,7 @@ AstNode *parse_stmt(AstFile *f) { if (f->curr_proc == NULL) { return make_import_decl(f, s->TagStmt.token, file_path, import_name, os, arch, true); } - syntax_error(token, "You cannot use #load within a procedure. This must be done at the file scope"); + syntax_error(token, "You cannot use #include within a procedure. This must be done at the file scope"); return make_bad_decl(f, token, file_path); } else { diff --git a/src/tokenizer.c b/src/tokenizer.c index 7ff0b57fe..f0fd3b90b 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -83,6 +83,8 @@ TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \ \ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ TOKEN_KIND(Token_type, "type"), \ + /* TOKEN_KIND(Token_import, "import"), */ \ + /* TOKEN_KIND(Token_include, "include"), */ \ TOKEN_KIND(Token_proc, "proc"), \ TOKEN_KIND(Token_match, "match"), \ TOKEN_KIND(Token_break, "break"), \ @@ -143,7 +145,7 @@ i32 token_pos_cmp(TokenPos a, TokenPos b) { return (a.line < b.line) ? -1 : +1; } -bool token_pos_are_equal(TokenPos a, TokenPos b) { +bool token_pos_eq(TokenPos a, TokenPos b) { return token_pos_cmp(a, b) == 0; } @@ -182,7 +184,7 @@ void warning_va(Token token, char *fmt, va_list va) { global_error_collector.warning_count++; // NOTE(bill): Duplicate error, skip it - if (!token_pos_are_equal(global_error_collector.prev, token.pos)) { + if (!token_pos_eq(global_error_collector.prev, token.pos)) { global_error_collector.prev = token.pos; gb_printf_err("%.*s(%td:%td) Warning: %s\n", LIT(token.pos.file), token.pos.line, token.pos.column, @@ -197,7 +199,7 @@ void error_va(Token token, char *fmt, va_list va) { global_error_collector.count++; // NOTE(bill): Duplicate error, skip it - if (!token_pos_are_equal(global_error_collector.prev, token.pos)) { + if (!token_pos_eq(global_error_collector.prev, token.pos)) { global_error_collector.prev = token.pos; gb_printf_err("%.*s(%td:%td) %s\n", LIT(token.pos.file), token.pos.line, token.pos.column, @@ -212,7 +214,7 @@ void syntax_error_va(Token token, char *fmt, va_list va) { global_error_collector.count++; // NOTE(bill): Duplicate error, skip it - if (!token_pos_are_equal(global_error_collector.prev, token.pos)) { + if (!token_pos_eq(global_error_collector.prev, token.pos)) { global_error_collector.prev = token.pos; gb_printf_err("%.*s(%td:%td) Syntax Error: %s\n", LIT(token.pos.file), token.pos.line, token.pos.column, |