aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-11-30 20:07:23 +0000
committerGinger Bill <bill@gingerbill.org>2016-11-30 20:07:23 +0000
commitab2ca7cf5975b78c254b87fa5590be147853b79a (patch)
treeb301bcfe2dcdc5d03856970a598b789f5945fc4e /src
parentb76c8abe7379f1d1a88fddf9387fe6338ad920e3 (diff)
Fix illegal type declaration error
Diffstat (limited to 'src')
-rw-r--r--src/checker/checker.c39
-rw-r--r--src/checker/decl.c2
-rw-r--r--src/checker/expr.c12
-rw-r--r--src/checker/types.c3
-rw-r--r--src/parser.c13
-rw-r--r--src/tokenizer.c10
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,