mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-11-22 18:32:09 +00:00
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:
parent
4565070849
commit
5c459cad56
45
src/flow.c
45
src/flow.c
@ -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;
|
||||
|
25
src/flow.h
25
src/flow.h
@ -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
|
||||
|
@ -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").
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user