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.
// if no condition given, NULL is written to structure.
// 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
condition->line = Input_now->line_number;
// set defaults
condition->is_until = FALSE;
condition->invert = FALSE;
condition->body = NULL;
// check for empty condition
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
if (Input_read_and_lower_keyword()) {
if (strcmp(GlobalDynaBuf->buffer, "while") == 0) {
//condition.is_until = FALSE;
//condition.invert = FALSE;
} else if (strcmp(GlobalDynaBuf->buffer, "until") == 0) {
condition->is_until = TRUE;
condition->invert = TRUE;
} else {
Throw_error(exception_syntax);
return;
}
// write given condition into buffer
SKIPSPACE();
DYNABUF_CLEAR(GlobalDynaBuf);
Input_until_terminator(terminator);
DynaBuf_append(GlobalDynaBuf, CHAR_EOS); // ensure terminator
condition->body = DynaBuf_get_copy(GlobalDynaBuf);
copy_condition(condition, terminator);
}
}
// 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
static int check_condition(struct loop_condition *condition)
static int check_condition(struct condition *condition)
{
struct number intresult;
@ -133,12 +150,12 @@ static int check_condition(struct loop_condition *condition)
ALU_defined_int(&intresult);
if (GotByte)
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
void flow_doloop(struct do_loop *loop)
// back end function for "!do" and "!while" pseudo opcodes
void flow_do_while(struct do_while *loop)
{
struct input loop_input;
struct input *outer_input;

View File

@ -29,32 +29,37 @@ struct for_loop {
struct block block;
};
// structs to pass "!do" loop stuff from pseudoopcodes.c to flow.c
struct loop_condition {
// structs to pass "!do"/"!while" stuff from pseudoopcodes.c to flow.c
struct condition {
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
};
struct do_loop {
struct loop_condition head_cond;
struct do_while {
struct condition head_cond;
struct block block;
struct loop_condition tail_cond;
struct condition tail_cond;
};
// back end function for "!for" pseudo opcode
extern void flow_forloop(struct for_loop *loop);
// try to read a condition into DynaBuf and store copy pointer in
// given loop_condition structure.
// try to read a condition into DynaBuf and store pointer to copy in
// given condition structure.
// if no condition given, NULL is written to structure.
// 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
extern void flow_doloop(struct do_loop *loop);
extern void flow_do_while(struct do_while *loop);
// parse a whole source code file
extern void flow_parse_and_close_file(FILE *fd, const char *filename);
// parse {block} [else {block}]
extern void flow_parse_block_else_block(int parse_first);
// TODO - add an "else if" possibility
#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.
static enum eos po_do(void) // now GotByte = illegal char
{
struct do_loop loop;
struct do_while loop;
// read head condition to buffer
SKIPSPACE();
@ -954,7 +954,7 @@ static enum eos po_do(void) // now GotByte = illegal char
// read tail condition to buffer
flow_store_doloop_condition(&loop.tail_cond, CHAR_EOS); // must be freed!
// now GotByte = CHAR_EOS
flow_doloop(&loop);
flow_do_while(&loop);
// free memory
free(loop.head_cond.body);
free(loop.block.body);
@ -963,14 +963,31 @@ static enum eos po_do(void) // now GotByte = illegal char
}
#if 0
// looping assembly (alternative for people used to c-style loops)
// looping assembly ("!while", alternative for people used to c-style loops). has to be re-entrant.
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;
}
#endif
// 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)
Throw_first_pass_warning("Label name not in leftmost column.");
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.val.intval = pc.val.intval;
result.addr_refs = pc.addr_refs;

View File

@ -9,7 +9,7 @@
#define RELEASE "0.96.5" // update before release FIXME
#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 HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME