mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-06-27 02:29:27 +00:00
refactored symbol assignment (unfinished)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@214 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
parent
72fc28e84c
commit
00d0462f74
|
@ -351,7 +351,14 @@ static void get_symbol_value(scope_t scope, char optional_prefix_char, size_t na
|
||||||
struct object *arg;
|
struct object *arg;
|
||||||
|
|
||||||
// if the symbol gets created now, mark it as unsure
|
// if the symbol gets created now, mark it as unsure
|
||||||
symbol = symbol_find(scope, NUMBER_EVER_UNDEFINED); // TODO - split into "find" and "if NULL object, make into undefined int"
|
symbol = symbol_find(scope);
|
||||||
|
if (symbol->object.type == NULL) {
|
||||||
|
// finish symbol item by making it an undefined int
|
||||||
|
symbol->object.type = &type_int;
|
||||||
|
symbol->object.u.number.flags = NUMBER_EVER_UNDEFINED;
|
||||||
|
symbol->object.u.number.addr_refs = 0;
|
||||||
|
symbol->object.u.number.val.intval = 0;
|
||||||
|
}
|
||||||
// first push on arg stack, so we have a local copy we can "unpseudopc"
|
// first push on arg stack, so we have a local copy we can "unpseudopc"
|
||||||
arg = &arg_stack[arg_sp++];
|
arg = &arg_stack[arg_sp++];
|
||||||
*arg = symbol->object;
|
*arg = symbol->object;
|
||||||
|
|
66
src/global.c
66
src/global.c
|
@ -168,16 +168,17 @@ static void set_label(scope_t scope, int stat_flags, int force_bit, boolean chan
|
||||||
struct object result;
|
struct object result;
|
||||||
struct symbol *symbol;
|
struct symbol *symbol;
|
||||||
|
|
||||||
symbol = symbol_find(scope, force_bit); // TODO - split into "find", "forcebit handling", "if NULL object, make int" and "if not int, complain"
|
|
||||||
// label definition
|
|
||||||
if ((stat_flags & SF_FOUND_BLANK) && config.warn_on_indented_labels)
|
if ((stat_flags & SF_FOUND_BLANK) && config.warn_on_indented_labels)
|
||||||
Throw_first_pass_warning("Label name not in leftmost column.");
|
Throw_first_pass_warning("Label name not in leftmost column.");
|
||||||
|
symbol = symbol_find(scope);
|
||||||
|
// label definition
|
||||||
vcpu_read_pc(&pc);
|
vcpu_read_pc(&pc);
|
||||||
// FIXME - if undefined, check pass.complain_about_undefined and maybe throw "value not defined"!
|
// FIXME - if undefined, check pass.complain_about_undefined and maybe throw "value not defined"!
|
||||||
result.type = &type_int;
|
result.type = &type_int;
|
||||||
result.u.number.flags = pc.flags & NUMBER_IS_DEFINED;
|
result.u.number.flags = pc.flags & NUMBER_IS_DEFINED;
|
||||||
result.u.number.val.intval = pc.val.intval;
|
result.u.number.val.intval = pc.val.intval;
|
||||||
result.u.number.addr_refs = pc.addr_refs;
|
result.u.number.addr_refs = pc.addr_refs;
|
||||||
|
symbol_forcebit(symbol, force_bit); // TODO - "if NULL object, make int" and "if not int, complain"
|
||||||
symbol_set_object(symbol, &result, change_allowed); // FIXME - "backward anon allows number redef" is different from "!set allows object redef"!
|
symbol_set_object(symbol, &result, change_allowed); // FIXME - "backward anon allows number redef" is different from "!set allows object redef"!
|
||||||
symbol->pseudopc = pseudopc_get_context();
|
symbol->pseudopc = pseudopc_get_context();
|
||||||
// global labels must open new scope for cheap locals
|
// global labels must open new scope for cheap locals
|
||||||
|
@ -186,29 +187,55 @@ static void set_label(scope_t scope, int stat_flags, int force_bit, boolean chan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// call with symbol name in GlobalDynaBuf and GotByte == '='
|
||||||
|
// "po_set" is for "!set" pseudo opcode, so changes are allowed
|
||||||
|
void parse_assignment(scope_t scope, int force_bit, boolean po_set)
|
||||||
|
{
|
||||||
|
struct symbol *symbol;
|
||||||
|
struct object result;
|
||||||
|
|
||||||
|
GetByte(); // eat '='
|
||||||
|
symbol = symbol_find(scope);
|
||||||
|
ALU_any_result(&result);
|
||||||
|
// if wanted, mark as address reference
|
||||||
|
if (typesystem_says_address()) {
|
||||||
|
// FIXME - checking types explicitly is ugly...
|
||||||
|
if ((result.type == &type_int)
|
||||||
|
|| (result.type == &type_float))
|
||||||
|
result.u.number.addr_refs = 1;
|
||||||
|
}
|
||||||
|
// FIXME - force bit can only be used if result is number! check!
|
||||||
|
symbol_forcebit(symbol, force_bit);
|
||||||
|
// if this was called by !set, new force bit replaces old one:
|
||||||
|
if (po_set) {
|
||||||
|
// clear symbol's force bits and set new ones
|
||||||
|
// (but only do this for numbers!)
|
||||||
|
if (((symbol->object.type == &type_int) || (symbol->object.type == &type_float))
|
||||||
|
&& ((result.type == &type_int) || (result.type == &type_float))) {
|
||||||
|
symbol->object.u.number.flags &= ~(NUMBER_FORCEBITS | NUMBER_FITS_BYTE);
|
||||||
|
if (force_bit) {
|
||||||
|
symbol->object.u.number.flags |= force_bit;
|
||||||
|
result.u.number.flags &= ~(NUMBER_FORCEBITS | NUMBER_FITS_BYTE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// FIXME - take a good look at the flags handling above and in the fn called below and clean this up!
|
||||||
|
}
|
||||||
|
symbol_set_object(symbol, &result, po_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// parse symbol definition (can be either global or local, may turn out to be a label).
|
// parse symbol definition (can be either global or local, may turn out to be a label).
|
||||||
// name must be held in GlobalDynaBuf.
|
// name must be held in GlobalDynaBuf.
|
||||||
static void parse_symbol_definition(scope_t scope, int stat_flags)
|
static void parse_symbol_definition(scope_t scope, int stat_flags)
|
||||||
{
|
{
|
||||||
struct object result;
|
struct object result;
|
||||||
struct symbol *symbol;
|
struct symbol *symbol;
|
||||||
int force_bit = Input_get_force_bit(); // skips spaces after
|
int force_bit;
|
||||||
// FIXME - force bit is allowed for label definitions?!
|
|
||||||
|
|
||||||
|
force_bit = Input_get_force_bit(); // skips spaces after (yes, force bit is allowed for label definitions)
|
||||||
if (GotByte == '=') {
|
if (GotByte == '=') {
|
||||||
// explicit symbol definition (symbol = <something>)
|
// explicit symbol definition (symbol = <something>)
|
||||||
symbol = symbol_find(scope, force_bit); // FIXME - split into "find", "forcebit handling", "if not NULL object, types must be equal"...
|
parse_assignment(scope, force_bit, FALSE);
|
||||||
// symbol = parsed value
|
|
||||||
GetByte(); // skip '='
|
|
||||||
ALU_any_result(&result);
|
|
||||||
// if wanted, mark as address reference
|
|
||||||
if (typesystem_says_address()) {
|
|
||||||
// FIXME - checking types explicitly is ugly...
|
|
||||||
if ((result.type == &type_int)
|
|
||||||
|| (result.type == &type_float))
|
|
||||||
result.u.number.addr_refs = 1;
|
|
||||||
}
|
|
||||||
symbol_set_object(symbol, &result, FALSE);
|
|
||||||
Input_ensure_EOS();
|
Input_ensure_EOS();
|
||||||
} else {
|
} else {
|
||||||
// implicit symbol definition (label)
|
// implicit symbol definition (label)
|
||||||
|
@ -220,8 +247,11 @@ static void parse_symbol_definition(scope_t scope, int stat_flags)
|
||||||
// Parse global symbol definition or assembler mnemonic
|
// Parse global symbol definition or assembler mnemonic
|
||||||
static void parse_mnemo_or_global_symbol_def(int *statement_flags)
|
static void parse_mnemo_or_global_symbol_def(int *statement_flags)
|
||||||
{
|
{
|
||||||
|
boolean is_mnemonic;
|
||||||
|
|
||||||
|
is_mnemonic = CPU_state.type->keyword_is_mnemonic(Input_read_keyword());
|
||||||
// It is only a label if it isn't a mnemonic
|
// It is only a label if it isn't a mnemonic
|
||||||
if ((CPU_state.type->keyword_is_mnemonic(Input_read_keyword()) == FALSE)
|
if ((!is_mnemonic)
|
||||||
&& first_label_of_statement(statement_flags)) {
|
&& first_label_of_statement(statement_flags)) {
|
||||||
// Now GotByte = illegal char
|
// Now GotByte = illegal char
|
||||||
// 04 Jun 2005: this fix should help to explain "strange" error messages.
|
// 04 Jun 2005: this fix should help to explain "strange" error messages.
|
||||||
|
@ -297,7 +327,7 @@ void Parse_until_eob_or_eof(void)
|
||||||
statement_flags = 0; // no "label = pc" definition yet
|
statement_flags = 0; // no "label = pc" definition yet
|
||||||
typesystem_force_address_statement(FALSE);
|
typesystem_force_address_statement(FALSE);
|
||||||
// Parse until end of statement. Only loops if statement
|
// Parse until end of statement. Only loops if statement
|
||||||
// contains "label = pc" definition and something else; or
|
// contains implicit label definition (=pc) and something else; or
|
||||||
// if "!ifdef/ifndef" is true/false, or if "!addr" is used without block.
|
// if "!ifdef/ifndef" is true/false, or if "!addr" is used without block.
|
||||||
do {
|
do {
|
||||||
// check for pseudo opcodes was moved out of switch,
|
// check for pseudo opcodes was moved out of switch,
|
||||||
|
|
|
@ -134,6 +134,9 @@ do { \
|
||||||
extern void config_default(struct config *conf);
|
extern void config_default(struct config *conf);
|
||||||
// allocate memory and die if not available
|
// allocate memory and die if not available
|
||||||
extern void *safe_malloc(size_t amount);
|
extern void *safe_malloc(size_t amount);
|
||||||
|
// call with symbol name in GlobalDynaBuf and GotByte == '='
|
||||||
|
// "po_set" is for "!set" pseudo opcode, so changes are allowed
|
||||||
|
extern void parse_assignment(scope_t scope, int force_bit, boolean po_set);
|
||||||
// Parse block, beginning with next byte.
|
// Parse block, beginning with next byte.
|
||||||
// End reason (either CHAR_EOB or CHAR_EOF) can be found in GotByte afterwards
|
// End reason (either CHAR_EOB or CHAR_EOF) can be found in GotByte afterwards
|
||||||
// Has to be re-entrant.
|
// Has to be re-entrant.
|
||||||
|
|
21
src/macro.c
21
src/macro.c
|
@ -250,8 +250,8 @@ void Macro_parse_call(void) // Now GotByte = dot or first char of macro name
|
||||||
// internal_name = MacroTitle ARG_SEPARATOR (grows to signature)
|
// internal_name = MacroTitle ARG_SEPARATOR (grows to signature)
|
||||||
// Accept n>=0 comma-separated arguments before CHAR_EOS.
|
// Accept n>=0 comma-separated arguments before CHAR_EOS.
|
||||||
// Valid argument formats are:
|
// Valid argument formats are:
|
||||||
// EXPRESSION (everything that does NOT start with '~'
|
// ~SYMBOL call by ref
|
||||||
// ~SYMBOL
|
// EXPRESSION call by value (everything that does NOT start with '~')
|
||||||
// now GotByte = non-space
|
// now GotByte = non-space
|
||||||
if (GotByte != CHAR_EOS) { // any at all?
|
if (GotByte != CHAR_EOS) { // any at all?
|
||||||
do {
|
do {
|
||||||
|
@ -263,10 +263,10 @@ void Macro_parse_call(void) // Now GotByte = dot or first char of macro name
|
||||||
if (GotByte == REFERENCE_CHAR) {
|
if (GotByte == REFERENCE_CHAR) {
|
||||||
// read call-by-reference arg
|
// read call-by-reference arg
|
||||||
DynaBuf_append(internal_name, ARGTYPE_REF);
|
DynaBuf_append(internal_name, ARGTYPE_REF);
|
||||||
GetByte(); // skip '~' character
|
GetByte(); // eat '~'
|
||||||
Input_read_scope_and_keyword(&symbol_scope);
|
Input_read_scope_and_keyword(&symbol_scope);
|
||||||
// GotByte = illegal char
|
// GotByte = illegal char
|
||||||
arg_table[arg_count].symbol = symbol_find(symbol_scope, 0); // FIXME - do not default to undefined int!
|
arg_table[arg_count].symbol = symbol_find(symbol_scope); // CAUTION, object type may be NULL!
|
||||||
} else {
|
} else {
|
||||||
// read call-by-value arg
|
// read call-by-value arg
|
||||||
DynaBuf_append(internal_name, ARGTYPE_VALUE);
|
DynaBuf_append(internal_name, ARGTYPE_VALUE);
|
||||||
|
@ -317,22 +317,21 @@ void Macro_parse_call(void) // Now GotByte = dot or first char of macro name
|
||||||
// In both cases, GlobalDynaBuf may be used.
|
// In both cases, GlobalDynaBuf may be used.
|
||||||
if (GotByte == REFERENCE_CHAR) {
|
if (GotByte == REFERENCE_CHAR) {
|
||||||
// assign call-by-reference arg
|
// assign call-by-reference arg
|
||||||
GetByte(); // skip '~' character
|
GetByte(); // eat '~'
|
||||||
Input_read_scope_and_keyword(&symbol_scope);
|
Input_read_scope_and_keyword(&symbol_scope);
|
||||||
// create new tree node and link existing symbol struct from arg list to it
|
// create new tree node and link existing symbol struct from arg list to it
|
||||||
if ((Tree_hard_scan(&symbol_node, symbols_forest, symbol_scope, TRUE) == FALSE)
|
if ((Tree_hard_scan(&symbol_node, symbols_forest, symbol_scope, TRUE) == FALSE)
|
||||||
&& (FIRST_PASS))
|
&& (FIRST_PASS))
|
||||||
Throw_error("Macro parameter twice.");
|
Throw_error("Macro parameter twice.");
|
||||||
symbol_node->body = arg_table[arg_count].symbol;
|
symbol_node->body = arg_table[arg_count].symbol; // CAUTION, object type may be NULL
|
||||||
} else {
|
} else {
|
||||||
// assign call-by-value arg
|
// assign call-by-value arg
|
||||||
Input_read_scope_and_keyword(&symbol_scope);
|
Input_read_scope_and_keyword(&symbol_scope);
|
||||||
symbol = symbol_find(symbol_scope, 0); // FIXME - split into "find", "ensure freshly created"
|
symbol = symbol_find(symbol_scope);
|
||||||
// FIXME - add a possibility to symbol_find to make it possible to find out
|
// FIXME - find out if symbol was just created.
|
||||||
// whether symbol was just created. Then check for the same error message here
|
// Then check for the same error message here as above ("Macro parameter twice.").
|
||||||
// as above ("Macro parameter twice.").
|
|
||||||
// TODO - on the other hand, this would rule out globals as args (stupid anyway, but not illegal yet!)
|
// TODO - on the other hand, this would rule out globals as args (stupid anyway, but not illegal yet!)
|
||||||
symbol->object = arg_table[arg_count].result; // FIXME - this assignment redefines globals without throwing errors!
|
symbol->object = arg_table[arg_count].result; // FIXME - this assignment redefines globals/whatever without throwing errors!
|
||||||
}
|
}
|
||||||
++arg_count;
|
++arg_count;
|
||||||
} while (Input_accept_comma());
|
} while (Input_accept_comma());
|
||||||
|
|
|
@ -739,37 +739,19 @@ Throw_serious_error("Not yet"); // FIXME
|
||||||
// (re)set symbol
|
// (re)set symbol
|
||||||
static enum eos po_set(void) // now GotByte = illegal char
|
static enum eos po_set(void) // now GotByte = illegal char
|
||||||
{
|
{
|
||||||
struct object result;
|
scope_t scope;
|
||||||
int force_bit;
|
int force_bit;
|
||||||
struct symbol *symbol;
|
|
||||||
scope_t scope;
|
|
||||||
|
|
||||||
if (Input_read_scope_and_keyword(&scope) == 0) // skips spaces before
|
if (Input_read_scope_and_keyword(&scope) == 0) // skips spaces before
|
||||||
// now GotByte = illegal char
|
return SKIP_REMAINDER; // zero length
|
||||||
return SKIP_REMAINDER;
|
|
||||||
|
|
||||||
force_bit = Input_get_force_bit(); // skips spaces after
|
force_bit = Input_get_force_bit(); // skips spaces after
|
||||||
symbol = symbol_find(scope, force_bit); // FIXME - split into "find" and "handle forcebits", remove the "default to undefined int" part!
|
|
||||||
if (GotByte != '=') {
|
if (GotByte != '=') {
|
||||||
Throw_error(exception_syntax);
|
Throw_error(exception_syntax);
|
||||||
return SKIP_REMAINDER;
|
return SKIP_REMAINDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// symbol = parsed value
|
parse_assignment(scope, force_bit, TRUE);
|
||||||
GetByte(); // proceed with next char
|
|
||||||
ALU_any_result(&result);
|
|
||||||
// clear symbol's force bits and set new ones
|
|
||||||
// (but only do this for numbers!)
|
|
||||||
if (((symbol->object.type == &type_int) || (symbol->object.type == &type_float))
|
|
||||||
&& ((result.type == &type_int) || (result.type == &type_float))) {
|
|
||||||
symbol->object.u.number.flags &= ~(NUMBER_FORCEBITS | NUMBER_FITS_BYTE);
|
|
||||||
if (force_bit) {
|
|
||||||
symbol->object.u.number.flags |= force_bit;
|
|
||||||
result.u.number.flags &= ~(NUMBER_FORCEBITS | NUMBER_FITS_BYTE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// FIXME - take a good look at the flags handling above and in the fn called below and clean this up!
|
|
||||||
symbol_set_object(symbol, &result, TRUE);
|
|
||||||
return ENSURE_EOS;
|
return ENSURE_EOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1053,11 +1035,12 @@ static enum eos po_for(void) // now GotByte = illegal char
|
||||||
struct for_loop loop;
|
struct for_loop loop;
|
||||||
|
|
||||||
if (Input_read_scope_and_keyword(&scope) == 0) // skips spaces before
|
if (Input_read_scope_and_keyword(&scope) == 0) // skips spaces before
|
||||||
return SKIP_REMAINDER;
|
return SKIP_REMAINDER; // zero length
|
||||||
|
|
||||||
// now GotByte = illegal char
|
// now GotByte = illegal char
|
||||||
force_bit = Input_get_force_bit(); // skips spaces after
|
force_bit = Input_get_force_bit(); // skips spaces after
|
||||||
loop.symbol = symbol_find(scope, force_bit); // FIXME - split into "find" and "handle force bit". if type is not NULL, complain if not number!
|
loop.symbol = symbol_find(scope); // FIXME - if type is not NULL, complain if not number!
|
||||||
|
symbol_forcebit(loop.symbol, force_bit);
|
||||||
if (!Input_accept_comma()) {
|
if (!Input_accept_comma()) {
|
||||||
Throw_error(exception_syntax);
|
Throw_error(exception_syntax);
|
||||||
return SKIP_REMAINDER;
|
return SKIP_REMAINDER;
|
||||||
|
@ -1066,7 +1049,8 @@ static enum eos po_for(void) // now GotByte = illegal char
|
||||||
ALU_defined_int(&intresult); // read first argument
|
ALU_defined_int(&intresult); // read first argument
|
||||||
loop.counter.addr_refs = intresult.addr_refs;
|
loop.counter.addr_refs = intresult.addr_refs;
|
||||||
if (Input_accept_comma()) {
|
if (Input_accept_comma()) {
|
||||||
loop.use_old_algo = FALSE; // new format - yay!
|
// new format - yay!
|
||||||
|
loop.use_old_algo = FALSE;
|
||||||
if (config.wanted_version < VER_NEWFORSYNTAX)
|
if (config.wanted_version < VER_NEWFORSYNTAX)
|
||||||
Throw_first_pass_warning("Found new \"!for\" syntax.");
|
Throw_first_pass_warning("Found new \"!for\" syntax.");
|
||||||
loop.counter.first = intresult.val.intval; // use first argument
|
loop.counter.first = intresult.val.intval; // use first argument
|
||||||
|
@ -1079,7 +1063,8 @@ static enum eos po_for(void) // now GotByte = illegal char
|
||||||
}
|
}
|
||||||
loop.counter.increment = (loop.counter.last < loop.counter.first) ? -1 : 1;
|
loop.counter.increment = (loop.counter.last < loop.counter.first) ? -1 : 1;
|
||||||
} else {
|
} else {
|
||||||
loop.use_old_algo = TRUE; // old format - booo!
|
// old format - booo!
|
||||||
|
loop.use_old_algo = TRUE;
|
||||||
if (config.wanted_version >= VER_NEWFORSYNTAX)
|
if (config.wanted_version >= VER_NEWFORSYNTAX)
|
||||||
Throw_first_pass_warning("Found old \"!for\" syntax.");
|
Throw_first_pass_warning("Found old \"!for\" syntax.");
|
||||||
if (intresult.val.intval < 0)
|
if (intresult.val.intval < 0)
|
||||||
|
|
66
src/symbol.c
66
src/symbol.c
|
@ -107,8 +107,9 @@ static void dump_vice_unusednonaddress(struct rwnode *node, FILE *fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// temporary helper function to properly refactor this mess
|
// search for symbol. if it does not exist, create with NULL object (CAUTION!).
|
||||||
static struct symbol *temp_find(scope_t scope)
|
// the symbol name must be held in GlobalDynaBuf.
|
||||||
|
struct symbol *symbol_find(scope_t scope)
|
||||||
{
|
{
|
||||||
struct rwnode *node;
|
struct rwnode *node;
|
||||||
struct symbol *symbol;
|
struct symbol *symbol;
|
||||||
|
@ -132,51 +133,27 @@ static struct symbol *temp_find(scope_t scope)
|
||||||
return symbol; // now symbol->object.type can be tested to see if this was freshly created.
|
return symbol; // now symbol->object.type can be tested to see if this was freshly created.
|
||||||
// CAUTION: this only works if caller always sets a type pointer after checking! if NULL is kept, the struct still looks new later on...
|
// CAUTION: this only works if caller always sets a type pointer after checking! if NULL is kept, the struct still looks new later on...
|
||||||
}
|
}
|
||||||
// search for symbol. create if nonexistant. if created, give it flags "flags".
|
|
||||||
// the symbol name must be held in GlobalDynaBuf.
|
|
||||||
/*
|
|
||||||
FIXME - to get lists/strings to work, this can no longer create an int by default!
|
|
||||||
maybe get rid of "int flags" and use some "struct object *default" instead?
|
|
||||||
called by;
|
|
||||||
alu.c
|
|
||||||
get_symbol_value (here it's okay to create an undefined int)
|
|
||||||
global.c
|
|
||||||
set_label implicit symbol definition (gets assigned pc, so int is ok)
|
|
||||||
parse_symbol_definition explicit symbol definition
|
|
||||||
macro.c
|
|
||||||
Macro_parse_call early to build array of outer refs in case of call-by-ref
|
|
||||||
Macro_parse_call later to lookup inner symbols in case of call-by-value
|
|
||||||
symbol.c
|
|
||||||
symbol_define
|
|
||||||
symbol_fix_forward_anon_name
|
|
||||||
*/
|
|
||||||
struct symbol *symbol_find(scope_t scope, int flags) // FIXME - "flags" is either 0 or UNDEFINED or a forcebit, right? move UNDEFINED and forcebit stuff elsewhere!
|
|
||||||
{
|
|
||||||
struct symbol *symbol;
|
|
||||||
int new_force_bits;
|
|
||||||
|
|
||||||
symbol = temp_find(scope);
|
|
||||||
|
// FIXME - merge with function below!
|
||||||
|
void symbol_forcebit(struct symbol *symbol, int force_bit)
|
||||||
|
{
|
||||||
// if symbol has no object assigned to it, make it an int
|
// if symbol has no object assigned to it, make it an int
|
||||||
if (symbol->object.type == NULL) {
|
if (symbol->object.type == NULL) {
|
||||||
// finish empty symbol item
|
// finish empty symbol item
|
||||||
symbol->object.type = &type_int;
|
symbol->object.type = &type_int;
|
||||||
symbol->object.u.number.flags = flags;
|
symbol->object.u.number.flags = force_bit;
|
||||||
symbol->object.u.number.addr_refs = 0;
|
symbol->object.u.number.addr_refs = 0;
|
||||||
symbol->object.u.number.val.intval = 0;
|
symbol->object.u.number.val.intval = 0;
|
||||||
} else {
|
} else {
|
||||||
// make sure the force bits don't clash
|
// make sure the force bits don't clash
|
||||||
if ((symbol->object.type == &type_int)
|
if ((symbol->object.type == &type_int)
|
||||||
|| (symbol->object.type == &type_float)) {
|
|| (symbol->object.type == &type_float)) {
|
||||||
new_force_bits = flags & NUMBER_FORCEBITS;
|
if ((symbol->object.u.number.flags & NUMBER_FORCEBITS) != force_bit)
|
||||||
if (new_force_bits)
|
Throw_error("Too late for postfix.");
|
||||||
if ((symbol->object.u.number.flags & NUMBER_FORCEBITS) != new_force_bits)
|
|
||||||
Throw_error("Too late for postfix.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return symbol;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// assign value to symbol. the function acts upon the symbol's flag bits and
|
// assign value to symbol. the function acts upon the symbol's flag bits and
|
||||||
// produces an error if needed.
|
// produces an error if needed.
|
||||||
// TODO - split checks into two parts: first deal with object type. in case of number, then check value/flags/whatever
|
// TODO - split checks into two parts: first deal with object type. in case of number, then check value/flags/whatever
|
||||||
|
@ -237,8 +214,8 @@ void symbol_define(intval_t value)
|
||||||
result.type = &type_int;
|
result.type = &type_int;
|
||||||
result.u.number.flags = NUMBER_IS_DEFINED;
|
result.u.number.flags = NUMBER_IS_DEFINED;
|
||||||
result.u.number.val.intval = value;
|
result.u.number.val.intval = value;
|
||||||
symbol = symbol_find(SCOPE_GLOBAL, 0);
|
symbol = symbol_find(SCOPE_GLOBAL);
|
||||||
symbol_set_object(symbol, &result, TRUE);
|
symbol->object = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -268,6 +245,12 @@ void symbols_vicelabels(FILE *fd)
|
||||||
// references the *next* anonymous forward label definition. The tricky bit is,
|
// references the *next* anonymous forward label definition. The tricky bit is,
|
||||||
// each name length would need its own counter. But hey, ACME's real quick in
|
// each name length would need its own counter. But hey, ACME's real quick in
|
||||||
// finding symbols, so I'll just abuse the symbol system to store those counters.
|
// finding symbols, so I'll just abuse the symbol system to store those counters.
|
||||||
|
// example:
|
||||||
|
// forward anon name is "+++"
|
||||||
|
// we look up that symbol's value in the current local scope -> $12
|
||||||
|
// we attach hex digits to name -> "+++21"
|
||||||
|
// that's the name of the symbol that _actually_ contains the address
|
||||||
|
// caller sets "increment" to TRUE for writing, FALSE for reading
|
||||||
void symbol_fix_forward_anon_name(boolean increment)
|
void symbol_fix_forward_anon_name(boolean increment)
|
||||||
{
|
{
|
||||||
struct symbol *counter_symbol;
|
struct symbol *counter_symbol;
|
||||||
|
@ -275,10 +258,17 @@ void symbol_fix_forward_anon_name(boolean increment)
|
||||||
|
|
||||||
// terminate name, find "counter" symbol and read value
|
// terminate name, find "counter" symbol and read value
|
||||||
DynaBuf_append(GlobalDynaBuf, '\0');
|
DynaBuf_append(GlobalDynaBuf, '\0');
|
||||||
counter_symbol = symbol_find(section_now->local_scope, 0);
|
counter_symbol = symbol_find(section_now->local_scope);
|
||||||
// sanity check: it must be an int!
|
if (counter_symbol->object.type == NULL) {
|
||||||
if (counter_symbol->object.type != &type_int)
|
// finish freshly created symbol item
|
||||||
|
counter_symbol->object.type = &type_int;
|
||||||
|
counter_symbol->object.u.number.flags = NUMBER_IS_DEFINED;
|
||||||
|
counter_symbol->object.u.number.addr_refs = 0;
|
||||||
|
counter_symbol->object.u.number.val.intval = 0;
|
||||||
|
} else if (counter_symbol->object.type != &type_int) {
|
||||||
|
// sanity check: it must be an int!
|
||||||
Bug_found("ForwardAnonCounterNotInt", 0);
|
Bug_found("ForwardAnonCounterNotInt", 0);
|
||||||
|
}
|
||||||
// make sure it gets reset to zero in each new pass
|
// make sure it gets reset to zero in each new pass
|
||||||
if (counter_symbol->pass != pass.number) {
|
if (counter_symbol->pass != pass.number) {
|
||||||
counter_symbol->pass = pass.number;
|
counter_symbol->pass = pass.number;
|
||||||
|
|
|
@ -31,9 +31,11 @@ extern struct rwnode *symbols_forest[]; // trees (because of 8-bit hash)
|
||||||
|
|
||||||
// function acts upon the symbol's flag bits and produces an error if needed.
|
// function acts upon the symbol's flag bits and produces an error if needed.
|
||||||
extern void symbol_set_object(struct symbol *symbol, struct object *new_obj, boolean change_allowed);
|
extern void symbol_set_object(struct symbol *symbol, struct object *new_obj, boolean change_allowed);
|
||||||
// search for symbol. create if nonexistant. if created, assign flags.
|
// search for symbol. if it does not exist, create with NULL object (CAUTION!).
|
||||||
// name must be held in GlobalDynaBuf.
|
// the symbol name must be held in GlobalDynaBuf.
|
||||||
extern struct symbol *symbol_find(scope_t, int flags);
|
extern struct symbol *symbol_find(scope_t scope);
|
||||||
|
// FIXME
|
||||||
|
extern void symbol_forcebit(struct symbol *symbol, int force_bit);
|
||||||
// set global symbol to value, no questions asked (for "-D" switch)
|
// set global symbol to value, no questions asked (for "-D" switch)
|
||||||
// name must be held in GlobalDynaBuf.
|
// name must be held in GlobalDynaBuf.
|
||||||
extern void symbol_define(intval_t value);
|
extern void symbol_define(intval_t value);
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#define RELEASE "0.96.5" // update before release FIXME
|
#define RELEASE "0.96.5" // update before release FIXME
|
||||||
#define CODENAME "Fenchurch" // update before release
|
#define CODENAME "Fenchurch" // update before release
|
||||||
#define CHANGE_DATE "3 June" // update before release FIXME
|
#define CHANGE_DATE "5 June" // update before release FIXME
|
||||||
#define CHANGE_YEAR "2020" // update before release
|
#define CHANGE_YEAR "2020" // update before release
|
||||||
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
|
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
|
||||||
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME
|
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME
|
||||||
|
|
Loading…
Reference in New Issue
Block a user