mirror of
https://github.com/uffejakobsen/acme.git
synced 2025-07-16 08:24:03 +00:00
fiddled with "!for" struct, no change in functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@303 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
28
src/flow.c
28
src/flow.c
@@ -85,8 +85,8 @@ void flow_forloop(struct for_loop *loop)
|
|||||||
loop_counter.type = &type_number;
|
loop_counter.type = &type_number;
|
||||||
loop_counter.u.number.ntype = NUMTYPE_INT;
|
loop_counter.u.number.ntype = NUMTYPE_INT;
|
||||||
loop_counter.u.number.flags = 0;
|
loop_counter.u.number.flags = 0;
|
||||||
loop_counter.u.number.val.intval = loop->counter.first;
|
loop_counter.u.number.val.intval = loop->u.counter.first;
|
||||||
loop_counter.u.number.addr_refs = loop->counter.addr_refs;
|
loop_counter.u.number.addr_refs = loop->u.counter.addr_refs;
|
||||||
// CAUTION: next line does not have power to change symbol type, but if
|
// CAUTION: next line does not have power to change symbol type, but if
|
||||||
// "symbol already defined" error is thrown, the type will still have
|
// "symbol already defined" error is thrown, the type will still have
|
||||||
// been changed. this was done so the code below has a counter var.
|
// been changed. this was done so the code below has a counter var.
|
||||||
@@ -102,23 +102,29 @@ void flow_forloop(struct for_loop *loop)
|
|||||||
symbol_set_force_bit(loop->symbol, loop->force_bit);
|
symbol_set_force_bit(loop->symbol, loop->force_bit);
|
||||||
loop_counter = loop->symbol->object; // update local copy with force bit
|
loop_counter = loop->symbol->object; // update local copy with force bit
|
||||||
loop->symbol->has_been_read = TRUE; // lock force bit
|
loop->symbol->has_been_read = TRUE; // lock force bit
|
||||||
if (loop->use_old_algo) {
|
switch (loop->algorithm) {
|
||||||
// old algo for old syntax:
|
case FORALGO_OLD: // old algo for old syntax:
|
||||||
// if count == 0, skip loop
|
// if count == 0, skip loop
|
||||||
if (loop->counter.last) {
|
if (loop->u.counter.last) {
|
||||||
do {
|
do {
|
||||||
loop_counter.u.number.val.intval += loop->counter.increment;
|
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
|
loop->symbol->object = loop_counter; // overwrite whole struct, in case some joker has re-assigned loop counter var
|
||||||
parse_ram_block(&loop->block);
|
parse_ram_block(&loop->block);
|
||||||
} while (loop_counter.u.number.val.intval < loop->counter.last);
|
} while (loop_counter.u.number.val.intval < loop->u.counter.last);
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
// new algo for new syntax:
|
case FORALGO_NEW: // new algo for new syntax:
|
||||||
do {
|
do {
|
||||||
parse_ram_block(&loop->block);
|
parse_ram_block(&loop->block);
|
||||||
loop_counter.u.number.val.intval += loop->counter.increment;
|
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
|
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->counter.last + loop->counter.increment));
|
} while (loop_counter.u.number.val.intval != (loop->u.counter.last + loop->u.counter.increment));
|
||||||
|
break;
|
||||||
|
// case FORALGO_ITER: // iterate over string/list contents:
|
||||||
|
// FIXME
|
||||||
|
// break;
|
||||||
|
default:
|
||||||
|
Bug_found("IllegalLoopAlgo", loop->algorithm);
|
||||||
}
|
}
|
||||||
// restore previous input:
|
// restore previous input:
|
||||||
Input_now = outer_input;
|
Input_now = outer_input;
|
||||||
|
18
src/flow.h
18
src/flow.h
@@ -17,16 +17,28 @@ struct block {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// struct to pass "!for" loop stuff from pseudoopcodes.c to flow.c
|
// struct to pass "!for" loop stuff from pseudoopcodes.c to flow.c
|
||||||
|
enum foralgo {
|
||||||
|
FORALGO_OLD, // block can be skipped by passing zero, counter keeps value after block
|
||||||
|
FORALGO_NEW, // first and last value are given, counter is out of range after block
|
||||||
|
//FORALGO_ITER, // iterate over string/list contents (old algo could be changed to use this!)
|
||||||
|
};
|
||||||
struct for_loop {
|
struct for_loop {
|
||||||
struct symbol *symbol;
|
struct symbol *symbol;
|
||||||
bits force_bit;
|
enum foralgo algorithm;
|
||||||
boolean use_old_algo;
|
bits force_bit; // TODO - move to counter struct? illegal for iter algo!
|
||||||
|
union {
|
||||||
struct {
|
struct {
|
||||||
intval_t first,
|
intval_t first,
|
||||||
last,
|
last,
|
||||||
increment;
|
increment; // 1 or -1
|
||||||
int addr_refs; // address reference count
|
int addr_refs; // address reference count
|
||||||
} counter;
|
} counter;
|
||||||
|
/* struct {
|
||||||
|
struct symbol *iterable;
|
||||||
|
int index;
|
||||||
|
add a "last" value here? or check len() in every iteration?
|
||||||
|
} iter;*/
|
||||||
|
} u;
|
||||||
struct block block;
|
struct block block;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1011,6 +1011,7 @@ static enum eos po_ifndef(void) // now GotByte = illegal char
|
|||||||
// looping assembly ("!for"). has to be re-entrant.
|
// looping assembly ("!for"). has to be re-entrant.
|
||||||
// old syntax: !for VAR, END { BLOCK } VAR counts from 1 to END
|
// old syntax: !for VAR, END { BLOCK } VAR counts from 1 to END
|
||||||
// new syntax: !for VAR, START, END { BLOCK } VAR counts from START to END
|
// new syntax: !for VAR, START, END { BLOCK } VAR counts from START to END
|
||||||
|
// maybe future alternative: !for VAR in ITERABLE { BLOCK } VAR iterates over string/list contents
|
||||||
static enum eos po_for(void) // now GotByte = illegal char
|
static enum eos po_for(void) // now GotByte = illegal char
|
||||||
{
|
{
|
||||||
scope_t scope;
|
scope_t scope;
|
||||||
@@ -1024,36 +1025,53 @@ static enum eos po_for(void) // now GotByte = illegal char
|
|||||||
loop.force_bit = Input_get_force_bit(); // skips spaces after
|
loop.force_bit = Input_get_force_bit(); // skips spaces after
|
||||||
loop.symbol = symbol_find(scope); // if not number, error will be reported on first assignment
|
loop.symbol = symbol_find(scope); // if not number, error will be reported on first assignment
|
||||||
if (!Input_accept_comma()) {
|
if (!Input_accept_comma()) {
|
||||||
|
#if 1
|
||||||
Throw_error(exception_syntax);
|
Throw_error(exception_syntax);
|
||||||
return SKIP_REMAINDER;
|
return SKIP_REMAINDER;
|
||||||
|
#else
|
||||||
|
// check for "in" keyword
|
||||||
|
if (Input_read_and_lower_keyword() == 0)
|
||||||
|
return SKIP_REMAINDER;
|
||||||
|
|
||||||
|
if (strcmp(GlobalDynaBuf->buffer, "in") != 0) {
|
||||||
|
Throw_error("Loop var must be followed by either \"in\" keyword or comma."); // TODO - add to docs!
|
||||||
|
return SKIP_REMAINDER;
|
||||||
|
}
|
||||||
|
if (loop.force_bit) {
|
||||||
|
Throw_error("Force bits can only be given to counters, not when iterating over string/list contents."); // TODO - add to docs!
|
||||||
|
return SKIP_REMAINDER;
|
||||||
|
}
|
||||||
|
loop.algorithm = FORALGO_ITER;
|
||||||
|
FIXME
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ALU_defined_int(&intresult); // read first argument
|
ALU_defined_int(&intresult); // read first argument
|
||||||
loop.counter.addr_refs = intresult.addr_refs;
|
loop.u.counter.addr_refs = intresult.addr_refs;
|
||||||
if (Input_accept_comma()) {
|
if (Input_accept_comma()) {
|
||||||
// new format - yay!
|
// new format - yay!
|
||||||
loop.use_old_algo = FALSE;
|
loop.algorithm = FORALGO_NEW;
|
||||||
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.u.counter.first = intresult.val.intval; // use first argument
|
||||||
ALU_defined_int(&intresult); // read second argument
|
ALU_defined_int(&intresult); // read second argument
|
||||||
loop.counter.last = intresult.val.intval; // use second argument
|
loop.u.counter.last = intresult.val.intval; // use second argument
|
||||||
// compare addr_ref counts and complain if not equal!
|
// compare addr_ref counts and complain if not equal!
|
||||||
if (config.warn_on_type_mismatch
|
if (config.warn_on_type_mismatch
|
||||||
&& (intresult.addr_refs != loop.counter.addr_refs)) {
|
&& (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.");
|
Throw_first_pass_warning("Wrong type for loop's END value - must match type of START value.");
|
||||||
}
|
}
|
||||||
loop.counter.increment = (loop.counter.last < loop.counter.first) ? -1 : 1;
|
loop.u.counter.increment = (loop.u.counter.last < loop.u.counter.first) ? -1 : 1;
|
||||||
} else {
|
} else {
|
||||||
// old format - booo!
|
// old format - booo!
|
||||||
loop.use_old_algo = TRUE;
|
loop.algorithm = FORALGO_OLD;
|
||||||
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)
|
||||||
Throw_serious_error("Loop count is negative.");
|
Throw_serious_error("Loop count is negative.");
|
||||||
loop.counter.first = 0; // CAUTION - old algo pre-increments and therefore starts with 1!
|
loop.u.counter.first = 0; // CAUTION - old algo pre-increments and therefore starts with 1!
|
||||||
loop.counter.last = intresult.val.intval; // use given argument
|
loop.u.counter.last = intresult.val.intval; // use given argument
|
||||||
loop.counter.increment = 1;
|
loop.u.counter.increment = 1;
|
||||||
}
|
}
|
||||||
if (GotByte != CHAR_SOB)
|
if (GotByte != CHAR_SOB)
|
||||||
Throw_serious_error(exception_no_left_brace);
|
Throw_serious_error(exception_no_left_brace);
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#define RELEASE "0.97" // update before release FIXME
|
#define RELEASE "0.97" // update before release FIXME
|
||||||
#define CODENAME "Zem" // update before release
|
#define CODENAME "Zem" // update before release
|
||||||
#define CHANGE_DATE "19 Oct" // update before release FIXME
|
#define CHANGE_DATE "21 Oct" // 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
|
||||||
|
Reference in New Issue
Block a user