another minor cleanup concerning "!for" loops, no change in functionality

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@304 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2020-10-22 17:33:44 +00:00
parent ecab6ba3d6
commit 1048e12fc7
4 changed files with 35 additions and 35 deletions

View File

@ -68,7 +68,7 @@ void flow_forloop(struct for_loop *loop)
{
struct input loop_input,
*outer_input;
struct object loop_counter;
struct object loop_var;
// switching input makes us lose GotByte. But we know it's '}' anyway!
// set up new input
@ -82,15 +82,15 @@ void flow_forloop(struct for_loop *loop)
// fix line number (not for block, but in case symbol handling throws errors)
Input_now->line_number = loop->block.start;
// init counter
loop_counter.type = &type_number;
loop_counter.u.number.ntype = NUMTYPE_INT;
loop_counter.u.number.flags = 0;
loop_counter.u.number.val.intval = loop->u.counter.first;
loop_counter.u.number.addr_refs = loop->u.counter.addr_refs;
loop_var.type = &type_number;
loop_var.u.number.ntype = NUMTYPE_INT;
loop_var.u.number.flags = 0;
loop_var.u.number.val.intval = 0; // SEE BELOW - default value if old algo skips loop entirely
loop_var.u.number.addr_refs = loop->u.counter.addr_refs;
// CAUTION: next line does not have power to change symbol type, but if
// "symbol already defined" error is thrown, the type will still have
// been changed. this was done so the code below has a counter var.
symbol_set_object(loop->symbol, &loop_counter, POWER_CHANGE_VALUE);
symbol_set_object(loop->symbol, &loop_var, POWER_CHANGE_VALUE);
// TODO: in versions before 0.97, force bit handling was broken
// in both "!set" and "!for":
// trying to change a force bit correctly raised an error, but
@ -100,32 +100,26 @@ void flow_forloop(struct for_loop *loop)
// maybe support this behaviour via --dialect?
if (loop->force_bit)
symbol_set_force_bit(loop->symbol, loop->force_bit);
loop_counter = loop->symbol->object; // update local copy with force bit
loop_var = loop->symbol->object; // update local copy with force bit
loop->symbol->has_been_read = TRUE; // lock force bit
switch (loop->algorithm) {
case FORALGO_OLD: // old algo for old syntax:
// if count == 0, skip loop
if (loop->u.counter.last) {
do {
loop_counter.u.number.val.intval += loop->u.counter.increment;
loop->symbol->object = loop_counter; // overwrite whole struct, in case some joker has re-assigned loop counter var
parse_ram_block(&loop->block);
} while (loop_counter.u.number.val.intval < loop->u.counter.last);
}
break;
case FORALGO_NEW: // new algo for new syntax:
do {
parse_ram_block(&loop->block);
loop_counter.u.number.val.intval += loop->u.counter.increment;
loop->symbol->object = loop_counter; // overwrite whole struct, in case some joker has re-assigned loop counter var
} while (loop_counter.u.number.val.intval != (loop->u.counter.last + loop->u.counter.increment));
break;
loop_var.u.number.val.intval = loop->u.counter.first; // SEE ABOVE - this may be nonzero, but has not yet been copied to user symbol!
while (loop->iterations_left) {
loop->symbol->object = loop_var; // overwrite whole struct, in case some joker has re-assigned loop counter var
parse_ram_block(&loop->block);
loop_var.u.number.val.intval += loop->u.counter.increment;
loop->iterations_left--;
}
// new algo wants illegal value in loop counter after block:
if (loop->algorithm == FORALGO_NEW)
loop->symbol->object = loop_var; // overwrite whole struct, in case some joker has re-assigned loop counter var
// case FORALGO_ITER: // iterate over string/list contents:
// FIXME
// break;
default:
Bug_found("IllegalLoopAlgo", loop->algorithm);
}
// default:
// Bug_found("IllegalLoopAlgo", loop->algorithm); // FIXME - add to docs!
// }
// restore previous input:
Input_now = outer_input;
}

View File

@ -26,10 +26,10 @@ struct for_loop {
struct symbol *symbol;
enum foralgo algorithm;
bits force_bit; // TODO - move to counter struct? illegal for iter algo!
intval_t iterations_left;
union {
struct {
intval_t first,
last,
increment; // 1 or -1
int addr_refs; // address reference count
} counter;

View File

@ -1055,13 +1055,19 @@ static enum eos po_for(void) // now GotByte = illegal char
Throw_first_pass_warning("Found new \"!for\" syntax.");
loop.u.counter.first = intresult.val.intval; // use first argument
ALU_defined_int(&intresult); // read second argument
loop.u.counter.last = intresult.val.intval; // use second argument
// compare addr_ref counts and complain if not equal!
if (config.warn_on_type_mismatch
&& (intresult.addr_refs != loop.u.counter.addr_refs)) {
Throw_first_pass_warning("Wrong type for loop's END value - must match type of START value.");
}
loop.u.counter.increment = (loop.u.counter.last < loop.u.counter.first) ? -1 : 1;
// setup direction and total
if (loop.u.counter.first <= intresult.val.intval) {
loop.iterations_left = 1 + intresult.val.intval - loop.u.counter.first;
loop.u.counter.increment = 1;
} else {
loop.iterations_left = 1 + loop.u.counter.first - intresult.val.intval;
loop.u.counter.increment = -1;
}
} else {
// old format - booo!
loop.algorithm = FORALGO_OLD;
@ -1069,8 +1075,8 @@ static enum eos po_for(void) // now GotByte = illegal char
Throw_first_pass_warning("Found old \"!for\" syntax.");
if (intresult.val.intval < 0)
Throw_serious_error("Loop count is negative.");
loop.u.counter.first = 0; // CAUTION - old algo pre-increments and therefore starts with 1!
loop.u.counter.last = intresult.val.intval; // use given argument
loop.u.counter.first = 1;
loop.iterations_left = intresult.val.intval; // use given argument
loop.u.counter.increment = 1;
}
if (GotByte != CHAR_SOB)

View File

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