aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-05-09 10:01:10 +0100
committerGinger Bill <bill@gingerbill.org>2017-05-09 10:01:10 +0100
commit64b5afd82096f3e9dfde125a8846d606db7c85fb (patch)
tree3771f57ca8afc6420ce11a219f0cb31108b0eb81 /src
parent7692061eef48765ac51b8a8f3024491381fdf182 (diff)
Fix issue #63 for block comments not terminating at an EOF
Diffstat (limited to 'src')
-rw-r--r--src/check_decl.c7
-rw-r--r--src/check_expr.c10
-rw-r--r--src/check_stmt.c9
-rw-r--r--src/checker.c19
-rw-r--r--src/entity.c9
-rw-r--r--src/tokenizer.c4
6 files changed, 42 insertions, 16 deletions
diff --git a/src/check_decl.c b/src/check_decl.c
index 587877be7..3778197c6 100644
--- a/src/check_decl.c
+++ b/src/check_decl.c
@@ -44,6 +44,8 @@ Type *check_init_variable(Checker *c, Entity *e, Operand *operand, String contex
e->type = t;
}
+ e->parent_proc_decl = c->context.curr_proc_decl;
+
check_assignment(c, operand, e->type, context_name);
if (operand->mode == Addressing_Invalid) {
return NULL;
@@ -122,6 +124,8 @@ void check_init_constant(Checker *c, Entity *e, Operand *operand) {
return;
}
+ e->parent_proc_decl = c->context.curr_proc_decl;
+
e->Constant.value = operand->value;
}
@@ -497,6 +501,8 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
c->context.scope = d->scope;
c->context.decl = d;
+ e->parent_proc_decl = c->context.curr_proc_decl;
+
switch (e->kind) {
case Entity_Variable:
check_var_decl(c, e, d->entities, d->entity_count, d->type_expr, d->init_expr);
@@ -535,6 +541,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
c->context.scope = decl->scope;
c->context.decl = decl;
c->context.proc_name = proc_name;
+ c->context.curr_proc_decl = decl;
GB_ASSERT(type->kind == Type_Proc);
if (type->Proc.param_count > 0) {
diff --git a/src/check_expr.c b/src/check_expr.c
index 414b15f06..089f706e4 100644
--- a/src/check_expr.c
+++ b/src/check_expr.c
@@ -1208,6 +1208,16 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
}
return NULL;
}
+ if (e->parent_proc_decl != NULL &&
+ e->parent_proc_decl != c->context.curr_proc_decl) {
+ if (e->kind == Entity_Variable) {
+ error(n->Ident, "Nested procedures do not capture its parent's variables: %.*s", LIT(name));
+ return NULL;
+ } else if (e->kind == Entity_Label) {
+ error(n->Ident, "Nested procedures do not capture its parent's labels: %.*s", LIT(name));
+ return NULL;
+ }
+ }
bool is_overloaded = false;
isize overload_count = 0;
diff --git a/src/check_stmt.c b/src/check_stmt.c
index 99e972727..2d25e88a9 100644
--- a/src/check_stmt.c
+++ b/src/check_stmt.c
@@ -425,6 +425,7 @@ void check_label(Checker *c, AstNode *label) {
Entity *e = make_entity_label(c->allocator, c->context.scope, l->name->Ident, t_invalid, label);
add_entity(c, c->context.scope, l->name, e);
+ e->parent_proc_decl = c->context.curr_proc_decl;
if (ok) {
BlockLabel bl = {name, label};
@@ -1448,7 +1449,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
}
AstNode *ident = bs->label;
String name = ident->Ident.string;
- Entity *e = scope_lookup_entity(c->context.scope, name);
+ Operand o = {0};
+ Entity *e = check_ident(c, &o, ident, NULL, NULL, false);
if (e == NULL) {
error_node(ident, "Undeclared label name: %.*s", LIT(name));
return;
@@ -1473,8 +1475,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
bool is_selector = false;
if (expr->kind == AstNode_Ident) {
- String name = expr->Ident.string;
- e = scope_lookup_entity(c->context.scope, name);
+ Operand o = {0};
+ e = check_ident(c, &o, expr, NULL, NULL, true);
} else if (expr->kind == AstNode_SelectorExpr) {
Operand o = {0};
e = check_selector(c, &o, expr, NULL);
@@ -1548,6 +1550,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
if (entity == NULL) {
entity = make_entity_dummy_variable(c->allocator, c->global_scope, ast_node_token(name));
}
+ entity->parent_proc_decl = c->context.curr_proc_decl;
entities[entity_count++] = entity;
}
diff --git a/src/checker.c b/src/checker.c
index c2d5a3bf6..fae2eef2d 100644
--- a/src/checker.c
+++ b/src/checker.c
@@ -299,6 +299,7 @@ typedef struct CheckerContext {
bool in_defer; // TODO(bill): Actually handle correctly
String proc_name;
Type * type_hint;
+ DeclInfo * curr_proc_decl;
} CheckerContext;
// CheckerInfo stores all the symbol information for a type-checked program
@@ -489,14 +490,14 @@ void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entit
if (found) {
Entity *e = *found;
if (gone_thru_proc) {
- if (e->kind == Entity_Label) {
- continue;
- }
- if (e->kind == Entity_Variable &&
- !e->scope->is_file &&
- !e->scope->is_global) {
- continue;
- }
+ // if (e->kind == Entity_Label) {
+ // continue;
+ // }
+ // if (e->kind == Entity_Variable &&
+ // !e->scope->is_file &&
+ // !e->scope->is_global) {
+ // continue;
+ // }
}
if (entity_) *entity_ = e;
@@ -1079,7 +1080,7 @@ void pop_procedure(Checker *c) {
array_pop(&c->proc_stack);
}
-Type *const curr_procedure(Checker *c) {
+Type *const curr_procedure_type(Checker *c) {
isize count = c->proc_stack.count;
if (count > 0) {
return c->proc_stack.e[count-1];
diff --git a/src/entity.c b/src/entity.c
index 18b318a1f..465d75640 100644
--- a/src/entity.c
+++ b/src/entity.c
@@ -1,6 +1,7 @@
-typedef struct Scope Scope;
-typedef struct Checker Checker;
-typedef struct Type Type;
+typedef struct Scope Scope;
+typedef struct Checker Checker;
+typedef struct Type Type;
+typedef struct DeclInfo DeclInfo;
// typedef enum BuiltinProcId BuiltinProcId;
@@ -67,6 +68,7 @@ struct Entity {
Scope * scope;
Type * type;
AstNode * identifier; // Can be NULL
+ DeclInfo * parent_proc_decl; // NULL if in file/global scope
// TODO(bill): Cleanup how `using` works for entities
Entity * using_parent;
@@ -169,6 +171,7 @@ Entity *make_entity_using_variable(gbAllocator a, Entity *parent, Token token, T
token.pos = parent->token.pos;
Entity *entity = alloc_entity(a, Entity_Variable, parent->scope, token, type);
entity->using_parent = parent;
+ entity->parent_proc_decl = parent->parent_proc_decl;
entity->flags |= EntityFlag_Using;
return entity;
}
diff --git a/src/tokenizer.c b/src/tokenizer.c
index 9dcade195..bc979a784 100644
--- a/src/tokenizer.c
+++ b/src/tokenizer.c
@@ -909,7 +909,9 @@ Token tokenizer_get_token(Tokenizer *t) {
isize comment_scope = 1;
advance_to_next_rune(t);
while (comment_scope > 0) {
- if (t->curr_rune == '/') {
+ if (t->curr_rune == GB_RUNE_EOF) {
+ break;
+ } else if (t->curr_rune == '/') {
advance_to_next_rune(t);
if (t->curr_rune == '*') {
advance_to_next_rune(t);