More error handling - locations of refs to undefined symbols.

This commit is contained in:
Stephen Dolan committed 2012-09-11 12:24:54 +01:00
1 parent 4c7bede5a4
commit 062a6aa6d7
5 files changed
+90 -43

No files matched your search

+32 -8
View File
@@ -3,7 +3,7 @@
#include <stdlib.h>
#include "opcode.h"
#include "compile.h"
#include "locfile.h"
struct inst {
struct inst* next;
@@ -18,6 +18,8 @@ struct inst {
struct cfunction* cfunc;
} imm;
location source;
// Binding
// An instruction requiring binding (for parameters/variables)
// is in one of three states:
@@ -45,6 +47,7 @@ static inst* inst_new(opcode op) {
i->bound_by = 0;
i->symbol = 0;
i->subfn = gen_noop();
i->source = UNKNOWN_LOCATION;
return i;
}
@@ -82,6 +85,16 @@ static inst* block_take(block* b) {
return i;
}
block gen_location(location loc, block b) {
for (inst* i = b.first; i; i = i->next) {
if (i->source.start == UNKNOWN_LOCATION.start &&
i->source.end == UNKNOWN_LOCATION.end) {
i->source = loc;
}
}
return b;
}
block gen_noop() {
block b = {0,0};
return b;
@@ -429,7 +442,8 @@ static int count_cfunctions(block b) {
return n;
}
static void compile(struct bytecode* bc, block b) {
static int compile(struct locfile* locations, struct bytecode* bc, block b) {
int errors = 0;
int pos = 0;
int var_frame_idx = 0;
bc->nsubfunctions = 0;
@@ -442,7 +456,10 @@ static void compile(struct bytecode* bc, block b) {
int opflags = opcode_describe(curr->op)->flags;
if (opflags & OP_HAS_BINDING) {
assert(curr->bound_by && "unbound term");
if (!curr->bound_by) {
locfile_locate(locations, curr->source, "error: %s is not defined", curr->symbol);
errors++;
}
}
if ((opflags & OP_HAS_VARIABLE) &&
curr->bound_by == curr) {
@@ -472,7 +489,7 @@ static void compile(struct bytecode* bc, block b) {
bc->subfunctions[curr->imm.intval] = subfn;
subfn->globals = bc->globals;
subfn->parent = bc;
compile(subfn, curr->subfn);
errors += compile(locations, subfn, curr->subfn);
}
} else {
bc->subfunctions = 0;
@@ -483,7 +500,7 @@ static void compile(struct bytecode* bc, block b) {
pos = 0;
jv constant_pool = jv_array();
int maxvar = -1;
for (inst* curr = b.first; curr; curr = curr->next) {
if (!errors) for (inst* curr = b.first; curr; curr = curr->next) {
const struct opcode_description* op = opcode_describe(curr->op);
if (op->length == 0)
continue;
@@ -551,18 +568,25 @@ static void compile(struct bytecode* bc, block b) {
}
bc->constants = constant_pool;
bc->nlocals = maxvar + 2; // FIXME: frames of size zero?
return errors;
}
struct bytecode* block_compile(block b) {
int block_compile(block b, struct locfile* locations, struct bytecode** out) {
struct bytecode* bc = malloc(sizeof(struct bytecode));
bc->parent = 0;
bc->globals = malloc(sizeof(struct symbol_table));
int ncfunc = count_cfunctions(b);
bc->globals->ncfunctions = 0;
bc->globals->cfunctions = malloc(sizeof(struct cfunction) * ncfunc);
compile(bc, b);
int nerrors = compile(locations, bc, b);
assert(bc->globals->ncfunctions == ncfunc);
return bc;
if (nerrors > 0) {
bytecode_free(bc);
*out = 0;
} else {
*out = bc;
}
return nerrors;
}
void block_free(block b) {