mirror of
https://github.com/uffejakobsen/acme.git
synced 2025-02-16 19:32:16 +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.
|
// 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;
|
||||||
|
25
src/flow.h
25
src/flow.h
@ -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
|
||||||
|
@ -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").
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user