added "!while" pseudo opcode (will be enabled in next release)

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@136 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2020-05-05 22:56:11 +00:00
parent 4565070849
commit 5c459cad56
5 changed files with 71 additions and 31 deletions

View File

@ -82,16 +82,26 @@ void flow_forloop(struct for_loop *loop)
} }
// try to read a condition into DynaBuf and store copy pointer in // read condition, make copy, link to struct
static void copy_condition(struct condition *condition, char terminator)
{
SKIPSPACE();
DYNABUF_CLEAR(GlobalDynaBuf);
Input_until_terminator(terminator);
DynaBuf_append(GlobalDynaBuf, CHAR_EOS); // ensure terminator
condition->body = DynaBuf_get_copy(GlobalDynaBuf);
}
// try to read a condition into DynaBuf and store pointer to copy in
// given loop_condition structure. // given loop_condition structure.
// if no condition given, NULL is written to structure. // if no condition given, NULL is written to structure.
// call with GotByte = first interesting character // call with GotByte = first interesting character
void flow_store_doloop_condition(struct loop_condition *condition, char terminator) void flow_store_doloop_condition(struct condition *condition, char terminator)
{ {
// write line number // write line number
condition->line = Input_now->line_number; condition->line = Input_now->line_number;
// set defaults // set defaults
condition->is_until = FALSE; condition->invert = FALSE;
condition->body = NULL; condition->body = NULL;
// check for empty condition // check for empty condition
if (GotByte == terminator) if (GotByte == terminator)
@ -100,25 +110,32 @@ void flow_store_doloop_condition(struct loop_condition *condition, char terminat
// seems as if there really *is* a condition, so check for until/while // seems as if there really *is* a condition, so check for until/while
if (Input_read_and_lower_keyword()) { if (Input_read_and_lower_keyword()) {
if (strcmp(GlobalDynaBuf->buffer, "while") == 0) { if (strcmp(GlobalDynaBuf->buffer, "while") == 0) {
//condition.is_until = FALSE; //condition.invert = FALSE;
} else if (strcmp(GlobalDynaBuf->buffer, "until") == 0) { } else if (strcmp(GlobalDynaBuf->buffer, "until") == 0) {
condition->is_until = TRUE; condition->invert = TRUE;
} else { } else {
Throw_error(exception_syntax); Throw_error(exception_syntax);
return; return;
} }
// write given condition into buffer // write given condition into buffer
SKIPSPACE(); copy_condition(condition, terminator);
DYNABUF_CLEAR(GlobalDynaBuf);
Input_until_terminator(terminator);
DynaBuf_append(GlobalDynaBuf, CHAR_EOS); // ensure terminator
condition->body = DynaBuf_get_copy(GlobalDynaBuf);
} }
} }
// read a condition into DynaBuf and store pointer to copy in
// given loop_condition structure.
// call with GotByte = first interesting character
void flow_store_while_condition(struct condition *condition)
{
condition->line = Input_now->line_number;
condition->invert = FALSE;
copy_condition(condition, CHAR_SOB);
}
// check a condition expression // check a condition expression
static int check_condition(struct loop_condition *condition) static int check_condition(struct condition *condition)
{ {
struct number intresult; struct number intresult;
@ -133,12 +150,12 @@ static int check_condition(struct loop_condition *condition)
ALU_defined_int(&intresult); ALU_defined_int(&intresult);
if (GotByte) if (GotByte)
Throw_serious_error(exception_syntax); Throw_serious_error(exception_syntax);
return condition->is_until ? !intresult.val.intval : !!intresult.val.intval; return condition->invert ? !intresult.val.intval : !!intresult.val.intval;
} }
// back end function for "!do" pseudo opcode // back end function for "!do" and "!while" pseudo opcodes
void flow_doloop(struct do_loop *loop) void flow_do_while(struct do_while *loop)
{ {
struct input loop_input; struct input loop_input;
struct input *outer_input; struct input *outer_input;

View File

@ -29,32 +29,37 @@ struct for_loop {
struct block block; struct block block;
}; };
// structs to pass "!do" loop stuff from pseudoopcodes.c to flow.c // structs to pass "!do"/"!while" stuff from pseudoopcodes.c to flow.c
struct loop_condition { struct condition {
int line; // original line number int line; // original line number
boolean is_until; // so FALSE means WHILE, TRUE means UNTIL) boolean invert; // only set for UNTIL conditions
char *body; // pointer to actual expression char *body; // pointer to actual expression
}; };
struct do_loop { struct do_while {
struct loop_condition head_cond; struct condition head_cond;
struct block block; struct block block;
struct loop_condition tail_cond; struct condition tail_cond;
}; };
// back end function for "!for" pseudo opcode // back end function for "!for" pseudo opcode
extern void flow_forloop(struct for_loop *loop); extern void flow_forloop(struct for_loop *loop);
// try to read a condition into DynaBuf and store copy pointer in // try to read a condition into DynaBuf and store pointer to copy in
// given loop_condition structure. // given condition structure.
// if no condition given, NULL is written to structure. // if no condition given, NULL is written to structure.
// call with GotByte = first interesting character // call with GotByte = first interesting character
extern void flow_store_doloop_condition(struct loop_condition *condition, char terminator); extern void flow_store_doloop_condition(struct condition *condition, char terminator);
// read a condition into DynaBuf and store pointer to copy in
// given condition structure.
// call with GotByte = first interesting character
extern void flow_store_while_condition(struct condition *condition);
// back end function for "!do" pseudo opcode // back end function for "!do" pseudo opcode
extern void flow_doloop(struct do_loop *loop); extern void flow_do_while(struct do_while *loop);
// parse a whole source code file // parse a whole source code file
extern void flow_parse_and_close_file(FILE *fd, const char *filename); extern void flow_parse_and_close_file(FILE *fd, const char *filename);
// parse {block} [else {block}] // parse {block} [else {block}]
extern void flow_parse_block_else_block(int parse_first); extern void flow_parse_block_else_block(int parse_first);
// TODO - add an "else if" possibility
#endif #endif

View File

@ -937,7 +937,7 @@ static enum eos po_for(void) // now GotByte = illegal char
// looping assembly ("!do"). has to be re-entrant. // looping assembly ("!do"). has to be re-entrant.
static enum eos po_do(void) // now GotByte = illegal char static enum eos po_do(void) // now GotByte = illegal char
{ {
struct do_loop loop; struct do_while loop;
// read head condition to buffer // read head condition to buffer
SKIPSPACE(); SKIPSPACE();
@ -954,7 +954,7 @@ static enum eos po_do(void) // now GotByte = illegal char
// read tail condition to buffer // read tail condition to buffer
flow_store_doloop_condition(&loop.tail_cond, CHAR_EOS); // must be freed! flow_store_doloop_condition(&loop.tail_cond, CHAR_EOS); // must be freed!
// now GotByte = CHAR_EOS // now GotByte = CHAR_EOS
flow_doloop(&loop); flow_do_while(&loop);
// free memory // free memory
free(loop.head_cond.body); free(loop.head_cond.body);
free(loop.block.body); free(loop.block.body);
@ -963,14 +963,31 @@ static enum eos po_do(void) // now GotByte = illegal char
} }
#if 0 // looping assembly ("!while", alternative for people used to c-style loops). has to be re-entrant.
// looping assembly (alternative for people used to c-style loops)
static enum eos po_while(void) // now GotByte = illegal char static enum eos po_while(void) // now GotByte = illegal char
{ {
Throw_serious_error("Not yet"); // FIXME struct do_while loop;
// read condition to buffer
SKIPSPACE();
flow_store_while_condition(&loop.head_cond); // must be freed!
if (GotByte != CHAR_SOB)
Throw_serious_error(exception_no_left_brace);
// remember line number of loop body,
// then read block and get copy
loop.block.start = Input_now->line_number;
// reading block changes line number!
loop.block.body = Input_skip_or_store_block(TRUE); // must be freed!
// clear tail condition
loop.tail_cond.body = NULL;
flow_do_while(&loop);
// free memory
free(loop.head_cond.body);
free(loop.block.body);
// GotByte of OuterInput would be '}' (if it would still exist)
GetByte(); // fetch next byte
return ENSURE_EOS; return ENSURE_EOS;
} }
#endif
// macro definition ("!macro"). // macro definition ("!macro").

View File

@ -180,6 +180,7 @@ void symbol_set_label(scope_t scope, int stat_flags, int force_bit, int change_a
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.");
vcpu_read_pc(&pc); vcpu_read_pc(&pc);
// FIXME - if undefined, check pass.complain_about_undefined and maybe throw "value not defined"!
result.flags = pc.flags & NUMBER_IS_DEFINED; result.flags = pc.flags & NUMBER_IS_DEFINED;
result.val.intval = pc.val.intval; result.val.intval = pc.val.intval;
result.addr_refs = pc.addr_refs; result.addr_refs = pc.addr_refs;

View File

@ -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 "2 May" // update before release FIXME #define CHANGE_DATE "6 May" // 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