"symbol twice" error now outputs location of previous definition,

just as "macro twice" does.


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@406 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2024-08-29 18:27:50 +00:00
parent 45ce8164e9
commit 158379ce9a
10 changed files with 48 additions and 28 deletions

View File

@ -399,9 +399,9 @@ static void perform_pass(bits passflags)
}
// now increment pass number
// this must be done _after_ the pass because assignments done via
// "-DSYMBOL=VALUE" cli args must be handled as if they were done at the
// start of pass 1, so we cannot change that variable at the start of
// the pass.
// "-D SYMBOL=VALUE" cli args must be handled as if they were done at
// the start of pass 1, so we cannot change that variable at the start
// of the pass.
++pass.number;
}
@ -788,7 +788,7 @@ int main(int argc, const char *argv[])
if (argc == 1)
show_help_and_exit();
cliargs_init(argc, argv);
// init pass number because any assignments done via "-DSYMBOL=VALUE"
// init pass number because any assignments done via "-D SYMBOL=VALUE"
// cli args must be handled as if they happened at the start of pass 1:
pass.number = 1;
// init platform-specific stuff.

View File

@ -1405,7 +1405,7 @@ static boolean string_differs(const struct object *self, const struct object *ot
// int/float:
// assign new value
static void number_assign(struct object *self, const struct object *new_value, boolean accept_change)
static boolean number_assign(struct object *self, const struct object *new_value, boolean accept_change)
{
bits own_flags = self->u.number.flags,
other_flags = new_value->u.number.flags;
@ -1427,10 +1427,9 @@ static void number_assign(struct object *self, const struct object *new_value, b
} else {
// symbol is already defined, so compare new and old values
// if values differ, complain and return
if (number_differs(self, new_value)) {
throw_error(exception_symbol_defined);
return;
}
if (number_differs(self, new_value))
return TRUE; // -> throw "symbol already defined" error
// values are the same, so only fiddle with flags
}
@ -1448,29 +1447,30 @@ static void number_assign(struct object *self, const struct object *new_value, b
own_flags |= other_flags & (NUMBER_FITS_BYTE | NUMBER_EVER_UNDEFINED);
self->u.number.flags = own_flags;
return FALSE;
}
// list:
// assign new value
static void list_assign(struct object *self, const struct object *new_value, boolean accept_change)
static boolean list_assign(struct object *self, const struct object *new_value, boolean accept_change)
{
if ((!accept_change) && list_differs(self, new_value)) {
throw_error(exception_symbol_defined);
return;
}
if ((!accept_change) && list_differs(self, new_value))
return TRUE; // -> throw "symbol already defined" error
*self = *new_value;
return FALSE;
}
// string:
// assign new value
static void string_assign(struct object *self, const struct object *new_value, boolean accept_change)
static boolean string_assign(struct object *self, const struct object *new_value, boolean accept_change)
{
if ((!accept_change) && string_differs(self, new_value)) {
throw_error(exception_symbol_defined);
return;
}
if ((!accept_change) && string_differs(self, new_value))
return TRUE; // -> throw "symbol already defined" error
*self = *new_value;
return FALSE;
}

View File

@ -16,7 +16,7 @@ struct type {
const char *name;
boolean (*is_defined)(const struct object *self);
boolean (*differs)(const struct object *self, const struct object *other);
void (*assign)(struct object *self, const struct object *new_value, boolean accept_change);
boolean (*assign)(struct object *self, const struct object *new_value, boolean accept_change);
void (*monadic_op)(struct object *self, const struct op *op);
void (*dyadic_op)(struct object *self, const struct op *op, struct object *other);
void (*fix_result)(struct object *self);

View File

@ -22,7 +22,7 @@ typedef signed int intval_t; // at least 32 bits
typedef unsigned int uintval_t; // at least 32 bits (only used for logical shift right)
#define OUTBUF_MAXSIZE 0x1000000 // 16 MiB ought to be enough for anybody
// struct to remember where macros were defined (FIXME - use for symbols as well!)
// struct to remember where macros/symbols were defined
struct location {
const char *plat_filename; // filename in platform style
int line_number;

View File

@ -627,12 +627,19 @@ void throw_redef_error(const char error_msg[], struct location *old_def, const c
// show error with current location
throw_error(error_msg);
// symbol structs do not necessarily have valid location data:
if (old_def->plat_filename == NULL)
return;
// CAUTION, ugly kluge: fiddle with section_now data to generate
// "earlier definition" section.
// buffer old section
buffered_section_type = section_now->type;
buffered_section_title = section_now->title;
// set new (fake) section
// FIXME - maybe store section in definition, just as location is stored?
// then we could use real data here instead of faking it, but it would
// take a bit more memory...
section_now->type = "earlier";
section_now->title = "section";
// show info message with location of earlier definition

View File

@ -123,6 +123,10 @@ struct symbol *symbol_find(scope_t scope)
symbol->has_been_read = FALSE;
symbol->has_been_reported = FALSE;
symbol->pseudopc = NULL;
// we must set "definition" fields to dummy data, because the object
// has been created, but not necessarily set to a defined value:
symbol->definition.plat_filename = NULL;
symbol->definition.line_number = 0;
} else {
symbol = node->body;
}
@ -142,6 +146,8 @@ struct symbol *symbol_find(scope_t scope)
// CAUTION: actual incrementing of counter is then done directly without calls here!
void symbol_set_object(struct symbol *symbol, struct object *new_value, bits powers)
{
boolean complain;
if (symbol->object.type == NULL) {
// symbol has no object assigned to it yet
symbol->object = *new_value; // copy whole struct including type
@ -154,22 +160,27 @@ void symbol_set_object(struct symbol *symbol, struct object *new_value, bits pow
// if too different, needs power (or complains)
if (symbol->object.type != new_value->type) {
if (!(powers & POWER_CHANGE_OBJTYPE))
throw_error(exception_symbol_defined);
// CAUTION: if above line throws error, we still go ahead and change type!
complain = TRUE;
// CAUTION: if line above triggers, we still go ahead and change type!
// this is to keep "!for" working, where the counter var is accessed.
symbol->object = *new_value; // copy whole struct including type
// clear flag so caller can adjust force bits:
symbol->has_been_read = FALSE; // it's basically a new symbol now
} else {
// symbol and new value have compatible types, so call handler:
symbol->object.type->assign(&symbol->object, new_value, !!(powers & POWER_CHANGE_VALUE));
complain = symbol->object.type->assign(&symbol->object, new_value, !!(powers & POWER_CHANGE_VALUE));
}
// if needed, throw "already defined" error with location of previous definition
if (complain)
throw_redef_error(exception_symbol_defined, &symbol->definition, "Previous definition.");
}
// if symbol is an address, give it a pseudopc context:
if ((symbol->object.type == &type_number)
&& (symbol->object.u.number.addr_refs == 1)) {
symbol->pseudopc = pseudopc_get_context();
}
// remember current location for "symbol twice" errors in future:
input_get_location(&symbol->definition);
}
@ -212,6 +223,8 @@ void symbol_define(intval_t value)
result.u.number.val.intval = value;
symbol = symbol_find(SCOPE_GLOBAL);
symbol->object = result;
symbol->definition.plat_filename = "\"-D SYMBOL=VALUE\"";
symbol->definition.line_number = 1;
}

View File

@ -17,7 +17,7 @@ struct symbol {
boolean has_been_read; // to find out if actually used
boolean has_been_reported; // indicates "has been reported as undefined"
struct pseudopc *pseudopc; // for "unpseudopc"-Operator '&', may be NULL
//TODO struct location definition; // for "label twice" error
struct location definition; // for "label twice" error
};

View File

@ -9,7 +9,7 @@
#define RELEASE "0.97" // update before release FIXME
#define CODENAME "Zem" // update before release
#define CHANGE_DATE "8 Aug" // update before release FIXME
#define CHANGE_DATE "9 Aug" // update before release FIXME
#define CHANGE_YEAR "2024" // update before release
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME

View File

@ -1,4 +1,4 @@
ACMEFLAGS = -v0
ACMEFLAGS = -v0 --color
FILES := $(wildcard *.a)
TESTS = $(subst .a,.test,$(FILES))

View File

@ -1,4 +1,4 @@
ACMEFLAGS = -v0
ACMEFLAGS = -v0 --color
FILES := $(wildcard *.a)
FAILTESTS = $(subst .a,.fail,$(FILES))
SUCCTESTS = $(subst .a,.succ,$(FILES))