Fix issue #63 for block comments not terminating at an EOF

This commit is contained in:
Ginger Bill
2017-05-09 10:01:10 +01:00
parent 7692061eef
commit 64b5afd820
8 changed files with 45 additions and 33 deletions

View File

@@ -1,19 +1,3 @@
#import "fmt.odin";
#import "os.odin";
main :: proc() {
immutable program := "+ + * - /";
accumulator := 0;
for token in program {
match token {
case '+': accumulator += 1;
case '-': accumulator -= 1;
case '*': accumulator *= 2;
case '/': accumulator /= 2;
default: // Ignore everything else
}
}
fmt.printf("The program \"%s\" calculates the value %d\n", program, accumulator);
/*
}

View File

@@ -54,6 +54,7 @@ GenSamplers: proc(count: i32, buffers: ^u32) #cc_c;
DeleteBuffers: proc(count: i32, buffers: ^u32) #cc_c;
BindBuffer: proc(target: i32, buffer: u32) #cc_c;
BindVertexArray: proc(buffer: u32) #cc_c;
DeleteVertexArrays: proc(count: i32, arrays: ^u32) #cc_c;
BindSampler: proc(position: i32, sampler: u32) #cc_c;
BufferData: proc(target: i32, size: int, data: rawptr, usage: i32) #cc_c;
BufferSubData: proc(target: i32, offset, size: int, data: rawptr) #cc_c;
@@ -120,6 +121,7 @@ init :: proc() {
set_proc_address(&BindBuffer, "glBindBuffer\x00");
set_proc_address(&BindSampler, "glBindSampler\x00");
set_proc_address(&BindVertexArray, "glBindVertexArray\x00");
set_proc_address(&DeleteVertexArrays, "glDeleteVertexArrays\x00");
set_proc_address(&BufferData, "glBufferData\x00");
set_proc_address(&BufferSubData, "glBufferSubData\x00");

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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];

View File

@@ -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;
}

View File

@@ -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);