Browse Source

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

Ginger Bill 8 years ago
parent
commit
64b5afd820
8 changed files with 45 additions and 33 deletions
  1. 1 17
      code/demo.odin
  2. 2 0
      core/opengl.odin
  3. 7 0
      src/check_decl.c
  4. 10 0
      src/check_expr.c
  5. 6 3
      src/check_stmt.c
  6. 10 9
      src/checker.c
  7. 6 3
      src/entity.c
  8. 3 1
      src/tokenizer.c

+ 1 - 17
code/demo.odin

@@ -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);
+	/*
 }

+ 2 - 0
core/opengl.odin

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

+ 7 - 0
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) {

+ 10 - 0
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;

+ 6 - 3
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;
 			}
 

+ 10 - 9
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];

+ 6 - 3
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;
 }

+ 3 - 1
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);