got rid of input_now pointer

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@390 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2024-08-06 11:02:55 +00:00
parent 1fd0bee24c
commit b9dd2d650d
3 changed files with 80 additions and 85 deletions

View File

@ -18,7 +18,7 @@
// type definitions // type definitions
// values for input_now->state // values for current_input.state
enum inputstate { enum inputstate {
INPUTSTATE_SOF, // start of file (check for hashbang) INPUTSTATE_SOF, // start of file (check for hashbang)
INPUTSTATE_NORMAL, // everything's fine INPUTSTATE_NORMAL, // everything's fine
@ -33,7 +33,8 @@ enum inputstate {
}; };
// Constants // constants
const char FILE_READBINARY[] = "rb"; const char FILE_READBINARY[] = "rb";
#define CHAR_LF (10) // line feed (in file) #define CHAR_LF (10) // line feed (in file)
// (10) // start of line (in high-level format) // (10) // start of line (in high-level format)
@ -41,8 +42,8 @@ const char FILE_READBINARY[] = "rb";
// (13) // end of file (in high-level format) // (13) // end of file (in high-level format)
// if the characters above are changed, don't forget to adjust byte_flags[]! // if the characters above are changed, don't forget to adjust byte_flags[]!
// fake input structure (for error msgs before any real input is established) // current input structure (init values are for error msgs before any real input is established)
static struct input outermost = { static struct input current_input = {
{ {
"<none>", // file name where code initially came from (differs during macro execution) "<none>", // file name where code initially came from (differs during macro execution)
0, // line number 0, // line number
@ -56,8 +57,8 @@ static struct input outermost = {
// variables // variables
struct input *input_now = &outermost; // current input structure
char GotByte; // last byte read (processed) TODO: move into input struct! char GotByte; // last byte read (processed)
// name of source file used for resolving relative paths // name of source file used for resolving relative paths
// (i.e. not changed during macro execution): // (i.e. not changed during macro execution):
const char *input_plat_pathref_filename = ""; // file name in platform format const char *input_plat_pathref_filename = ""; // file name in platform format
@ -123,7 +124,7 @@ static void report_printline(int line_number)
static void report_flush(void) static void report_flush(void)
{ {
if (report->fd) { if (report->fd) {
report_printline(input_now->location.line_number); report_printline(current_input.location.line_number);
} }
} }
@ -148,7 +149,7 @@ static void report_srcchar(int new_char)
prev_char = '\0'; prev_char = '\0';
} }
if (prev_char == '\n') { if (prev_char == '\n') {
report_printline(input_now->location.line_number - 1); report_printline(current_input.location.line_number - 1);
} }
if (new_char != '\n' && new_char != '\r') { // detect line break if (new_char != '\n' && new_char != '\r') { // detect line break
if (report->asc_used < REPORT_ASCBUFSIZE) if (report->asc_used < REPORT_ASCBUFSIZE)
@ -164,23 +165,23 @@ static char get_processed_from_file(void)
static int from_file = 0; static int from_file = 0;
for (;;) { for (;;) {
switch (input_now->state) { switch (current_input.state) {
case INPUTSTATE_SOF: case INPUTSTATE_SOF:
// fetch first byte from the current source file // fetch first byte from the current source file
from_file = getc(input_now->src.fd); from_file = getc(current_input.u.fd);
IF_WANTED_REPORT_SRCCHAR(from_file); IF_WANTED_REPORT_SRCCHAR(from_file);
//TODO - check for bogus/malformed BOM (0xef 0xbb 0xbf as UTF-8-encoded 0xfeff) and ignore? //TODO - check for bogus/malformed BOM (0xef 0xbb 0xbf as UTF-8-encoded 0xfeff) and ignore?
// check for hashbang line and ignore // check for hashbang line and ignore
if (from_file == '#') { if (from_file == '#') {
// remember to skip remainder of line // remember to skip remainder of line
input_now->state = INPUTSTATE_COMMENT; current_input.state = INPUTSTATE_COMMENT;
return CHAR_EOS; // end of statement return CHAR_EOS; // end of statement
} }
input_now->state = INPUTSTATE_AGAIN; current_input.state = INPUTSTATE_AGAIN;
break; break;
case INPUTSTATE_NORMAL: case INPUTSTATE_NORMAL:
// fetch a fresh byte from the current source file // fetch a fresh byte from the current source file
from_file = getc(input_now->src.fd); from_file = getc(current_input.u.fd);
IF_WANTED_REPORT_SRCCHAR(from_file); IF_WANTED_REPORT_SRCCHAR(from_file);
// now process it // now process it
/*FALLTHROUGH*/ /*FALLTHROUGH*/
@ -191,12 +192,12 @@ static char get_processed_from_file(void)
// If the source is changed so there is a possibility // If the source is changed so there is a possibility
// to enter INPUTSTATE_AGAIN mode without first having // to enter INPUTSTATE_AGAIN mode without first having
// defined "from_file", trouble may arise... // defined "from_file", trouble may arise...
input_now->state = INPUTSTATE_NORMAL; current_input.state = INPUTSTATE_NORMAL;
// EOF must be checked first because it cannot be used // EOF must be checked first because it cannot be used
// as an index into global_byte_flags[] // as an index into global_byte_flags[]
if (from_file == EOF) { if (from_file == EOF) {
// remember to send an end-of-file // remember to send an end-of-file
input_now->state = INPUTSTATE_EOF; current_input.state = INPUTSTATE_EOF;
return CHAR_EOS; // end of statement return CHAR_EOS; // end of statement
} }
@ -210,38 +211,38 @@ static char get_processed_from_file(void)
case '\t': case '\t':
case ' ': case ' ':
// remember to skip all following blanks // remember to skip all following blanks
input_now->state = INPUTSTATE_SKIPBLANKS; current_input.state = INPUTSTATE_SKIPBLANKS;
return ' '; return ' ';
case CHAR_LF: // LF character case CHAR_LF: // LF character
// remember to send a start-of-line // remember to send a start-of-line
input_now->state = INPUTSTATE_LF; current_input.state = INPUTSTATE_LF;
return CHAR_EOS; // end of statement return CHAR_EOS; // end of statement
case CHAR_CR: // CR character case CHAR_CR: // CR character
// remember to check CRLF + send start-of-line // remember to check CRLF + send start-of-line
input_now->state = INPUTSTATE_CR; current_input.state = INPUTSTATE_CR;
return CHAR_EOS; // end of statement return CHAR_EOS; // end of statement
case CHAR_EOB: case CHAR_EOB:
// remember to send an end-of-block // remember to send an end-of-block
input_now->state = INPUTSTATE_EOB; current_input.state = INPUTSTATE_EOB;
return CHAR_EOS; // end of statement return CHAR_EOS; // end of statement
case '/': case '/':
// to check for "//", get another byte: // to check for "//", get another byte:
from_file = getc(input_now->src.fd); from_file = getc(current_input.u.fd);
IF_WANTED_REPORT_SRCCHAR(from_file); IF_WANTED_REPORT_SRCCHAR(from_file);
if (from_file != '/') { if (from_file != '/') {
// not "//", so: // not "//", so:
input_now->state = INPUTSTATE_AGAIN; // second byte must be parsed normally later on current_input.state = INPUTSTATE_AGAIN; // second byte must be parsed normally later on
return '/'; // first byte is returned normally right now return '/'; // first byte is returned normally right now
} }
// it's really "//", so act as if ';' // it's really "//", so act as if ';'
/*FALLTHROUGH*/ /*FALLTHROUGH*/
case ';': case ';':
// remember to skip remainder of line // remember to skip remainder of line
input_now->state = INPUTSTATE_COMMENT; current_input.state = INPUTSTATE_COMMENT;
return CHAR_EOS; // end of statement return CHAR_EOS; // end of statement
case ':': // statement delimiter case ':': // statement delimiter
@ -256,53 +257,53 @@ static char get_processed_from_file(void)
case INPUTSTATE_SKIPBLANKS: case INPUTSTATE_SKIPBLANKS:
// read until non-blank, then deliver that // read until non-blank, then deliver that
do { do {
from_file = getc(input_now->src.fd); from_file = getc(current_input.u.fd);
IF_WANTED_REPORT_SRCCHAR(from_file); IF_WANTED_REPORT_SRCCHAR(from_file);
} while ((from_file == '\t') || (from_file == ' ')); } while ((from_file == '\t') || (from_file == ' '));
// re-process last byte // re-process last byte
input_now->state = INPUTSTATE_AGAIN; current_input.state = INPUTSTATE_AGAIN;
break; break;
case INPUTSTATE_LF: case INPUTSTATE_LF:
// return start-of-line, then continue in normal mode // return start-of-line, then continue in normal mode
input_now->state = INPUTSTATE_NORMAL; current_input.state = INPUTSTATE_NORMAL;
return CHAR_SOL; // new line return CHAR_SOL; // new line
case INPUTSTATE_CR: case INPUTSTATE_CR:
// return start-of-line, remember to check for LF // return start-of-line, remember to check for LF
input_now->state = INPUTSTATE_SKIPLF; current_input.state = INPUTSTATE_SKIPLF;
return CHAR_SOL; // new line return CHAR_SOL; // new line
case INPUTSTATE_SKIPLF: case INPUTSTATE_SKIPLF:
from_file = getc(input_now->src.fd); from_file = getc(current_input.u.fd);
IF_WANTED_REPORT_SRCCHAR(from_file); IF_WANTED_REPORT_SRCCHAR(from_file);
// if LF, ignore it and fetch another byte // if LF, ignore it and fetch another byte
// otherwise, process current byte // otherwise, process current byte
if (from_file == CHAR_LF) if (from_file == CHAR_LF)
input_now->state = INPUTSTATE_NORMAL; current_input.state = INPUTSTATE_NORMAL;
else else
input_now->state = INPUTSTATE_AGAIN; current_input.state = INPUTSTATE_AGAIN;
break; break;
case INPUTSTATE_COMMENT: case INPUTSTATE_COMMENT:
// read until end-of-line or end-of-file // read until end-of-line or end-of-file
do { do {
from_file = getc(input_now->src.fd); from_file = getc(current_input.u.fd);
IF_WANTED_REPORT_SRCCHAR(from_file); IF_WANTED_REPORT_SRCCHAR(from_file);
} while ((from_file != EOF) && (from_file != CHAR_CR) && (from_file != CHAR_LF)); } while ((from_file != EOF) && (from_file != CHAR_CR) && (from_file != CHAR_LF));
// re-process last byte // re-process last byte
input_now->state = INPUTSTATE_AGAIN; current_input.state = INPUTSTATE_AGAIN;
break; break;
case INPUTSTATE_EOB: case INPUTSTATE_EOB:
// deliver EOB // deliver EOB
input_now->state = INPUTSTATE_NORMAL; current_input.state = INPUTSTATE_NORMAL;
return CHAR_EOB; // end of block return CHAR_EOB; // end of block
case INPUTSTATE_EOF: case INPUTSTATE_EOF:
// deliver EOF // deliver EOF
input_now->state = INPUTSTATE_NORMAL; current_input.state = INPUTSTATE_NORMAL;
return CHAR_EOF; // end of file return CHAR_EOF; // end of file
default: default:
BUG("StrangeInputMode", input_now->state); BUG("StrangeInputMode", current_input.state);
} }
} }
} }
@ -318,25 +319,25 @@ char GetByte(void)
// high-level format // high-level format
// Otherwise, the source is a file. This means we will call // Otherwise, the source is a file. This means we will call
// get_processed_from_file() which will do a shit load of conversions. // get_processed_from_file() which will do a shit load of conversions.
switch (input_now->source) { switch (current_input.srctype) {
case INPUTSRC_RAM: case INPUTSRC_RAM:
GotByte = *(input_now->src.ram_ptr++); GotByte = *(current_input.u.ram_ptr++);
if (input_now->state== INPUTSTATE_NORMAL) if (current_input.state== INPUTSTATE_NORMAL)
IF_WANTED_REPORT_SRCCHAR(GotByte); IF_WANTED_REPORT_SRCCHAR(GotByte);
break; break;
case INPUTSRC_FILE: case INPUTSRC_FILE:
GotByte = get_processed_from_file(); GotByte = get_processed_from_file();
break; break;
default: default:
BUG("IllegalInputSrc", input_now->source); BUG("IllegalInputSrc", current_input.srctype);
} }
// // if start-of-line was read, increment line counter and repeat // // if start-of-line was read, increment line counter and repeat
// if (GotByte != CHAR_SOL) // if (GotByte != CHAR_SOL)
// return GotByte; // return GotByte;
// input_now->location.line_number++; // current_input.location.line_number++;
// } // }
if (GotByte == CHAR_SOL) if (GotByte == CHAR_SOL)
input_now->location.line_number++; current_input.location.line_number++;
return GotByte; return GotByte;
} }
@ -348,31 +349,31 @@ static char GetQuotedByte(void)
{ {
int from_file; // must be an int to catch EOF int from_file; // must be an int to catch EOF
switch (input_now->source) { switch (current_input.srctype) {
case INPUTSRC_RAM: case INPUTSRC_RAM:
// if byte source is RAM, then no conversion is necessary, // if byte source is RAM, then no conversion is necessary,
// because in RAM the source already has high-level format // because in RAM the source already has high-level format
GotByte = *(input_now->src.ram_ptr++); GotByte = *(current_input.u.ram_ptr++);
IF_WANTED_REPORT_SRCCHAR(GotByte); IF_WANTED_REPORT_SRCCHAR(GotByte);
break; break;
case INPUTSRC_FILE: case INPUTSRC_FILE:
// fetch a fresh byte from the current source file // fetch a fresh byte from the current source file
from_file = getc(input_now->src.fd); from_file = getc(current_input.u.fd);
IF_WANTED_REPORT_SRCCHAR(from_file); IF_WANTED_REPORT_SRCCHAR(from_file);
switch (from_file) { switch (from_file) {
case EOF: case EOF:
// remember to send an end-of-file // remember to send an end-of-file
input_now->state = INPUTSTATE_EOF; current_input.state = INPUTSTATE_EOF;
GotByte = CHAR_EOS; // end of statement GotByte = CHAR_EOS; // end of statement
break; break;
case CHAR_LF: // LF character case CHAR_LF: // LF character
// remember to send a start-of-line // remember to send a start-of-line
input_now->state = INPUTSTATE_LF; current_input.state = INPUTSTATE_LF;
GotByte = CHAR_EOS; // end of statement GotByte = CHAR_EOS; // end of statement
break; break;
case CHAR_CR: // CR character case CHAR_CR: // CR character
// remember to check for CRLF + send a start-of-line // remember to check for CRLF + send a start-of-line
input_now->state = INPUTSTATE_CR; current_input.state = INPUTSTATE_CR;
GotByte = CHAR_EOS; // end of statement GotByte = CHAR_EOS; // end of statement
break; break;
default: default:
@ -380,7 +381,7 @@ static char GetQuotedByte(void)
} }
break; break;
default: default:
BUG("IllegalInputSrc", input_now->source); BUG("IllegalInputSrc", current_input.srctype);
} }
// now check for end of statement // now check for end of statement
if (GotByte == CHAR_EOS) if (GotByte == CHAR_EOS)
@ -557,7 +558,7 @@ void input_block_skip(void)
void input_block_getcopy(struct block *block) void input_block_getcopy(struct block *block)
{ {
// first store line number... // first store line number...
block->line_number = input_now->location.line_number; block->line_number = current_input.location.line_number;
// ...then get block // ...then get block
block_to_dynabuf(); block_to_dynabuf();
// add EOF, just to make sure block is never read too far // add EOF, just to make sure block is never read too far
@ -777,7 +778,7 @@ int input_expect(int chr)
// (back end function for "!eof" pseudo opcode) // (back end function for "!eof" pseudo opcode)
void input_force_eof(void) void input_force_eof(void)
{ {
input_now->state = INPUTSTATE_EOF; current_input.state = INPUTSTATE_EOF;
} }
@ -881,7 +882,7 @@ int input_read_output_filename(void)
// write current "location" (file name and line number) to given target // write current "location" (file name and line number) to given target
void input_get_location(struct location *target) void input_get_location(struct location *target)
{ {
*target = input_now->location; *target = current_input.location;
} }
@ -892,19 +893,15 @@ void inputchange_new_file(struct inputchange_buf *icb, FILE *fd, const char *ete
{ {
report_flush(); report_flush();
// TODO: in future, really buffer old data here! (instead of storing new data and changing pointer) // remember old state in buffer struct
// setup new input icb->input = current_input;
icb->new_input = *input_now; // copy current input structure into new
icb->new_input.location.plat_filename = eternal_plat_filename;
icb->new_input.location.line_number = 1;
icb->new_input.source = INPUTSRC_FILE;
icb->new_input.state = INPUTSTATE_SOF;
icb->new_input.src.fd = fd;
// remember where outer input struct is
icb->outer_input = input_now;
icb->gb = GotByte; icb->gb = GotByte;
// activate new input // set new state
input_now = &icb->new_input; current_input.location.plat_filename = eternal_plat_filename;
current_input.location.line_number = 1;
current_input.srctype = INPUTSRC_FILE;
current_input.state = INPUTSTATE_SOF;
current_input.u.fd = fd;
report_inputchange("Source: ", eternal_plat_filename); report_inputchange("Source: ", eternal_plat_filename);
} }
@ -913,47 +910,46 @@ void inputchange_new_ram(struct inputchange_buf *icb)
{ {
report_flush(); report_flush();
icb->new_input = *input_now; // copy current input structure into new // remember old state in buffer struct
icb->new_input.source = INPUTSRC_RAM; // set new byte source icb->input = current_input;
icb->new_input.src.ram_ptr = NULL; // force crash if used before setup is finished
// remember where outer input struct is
icb->outer_input = input_now;
icb->gb = GotByte; icb->gb = GotByte;
// activate new input (not useable yet, as pointer and line number are not yet set up) // set new state (not useable yet, as pointer and line number are not yet set up)
input_now = &icb->new_input; current_input.srctype = INPUTSRC_RAM; // set new byte source
current_input.u.ram_ptr = NULL; // force crash if used before setup is finished
} }
// FIXME - merge these three functions into a single one (by always using a "location"): // FIXME - merge these three functions into a single one (by always using a "location"):
// setup for reading from RAM (for parsing loop conditions etc.) // setup for reading from RAM (for parsing loop conditions etc.)
void inputchange_set_ram(int line_num, const char *body) void inputchange_set_ram(int line_num, const char *body)
{ {
input_now->location.line_number = line_num; current_input.location.line_number = line_num;
input_now->src.ram_ptr = body; current_input.u.ram_ptr = body;
} }
// switch input to macro parameters // switch input to macro parameters
void inputchange_macro1_params(const struct location *def, const char *params) void inputchange_macro1_params(const struct location *def, const char *params)
{ {
input_now->location = *def; current_input.location = *def;
input_now->src.ram_ptr = params; current_input.u.ram_ptr = params;
input_now->state = INPUTSTATE_NORMAL; // FIXME - fix others! current_input.state = INPUTSTATE_NORMAL; // FIXME - fix others!
report_inputchange("macro from ", def->plat_filename); report_inputchange("macro from ", def->plat_filename);
} }
// switch from macro parameters to macro body // switch from macro parameters to macro body
void inputchange_macro2_body(const char *macro_body) void inputchange_macro2_body(const char *macro_body)
{ {
input_now->src.ram_ptr = macro_body; current_input.u.ram_ptr = macro_body;
input_now->state = INPUTSTATE_NORMAL; // FIXME - fix others! current_input.state = INPUTSTATE_NORMAL; // FIXME - fix others!
} }
// restore input struct from buffer // restore input struct from buffer
void inputchange_back(const struct inputchange_buf *icb) void inputchange_back(const struct inputchange_buf *icb)
{ {
report_flush(); report_flush();
input_now = icb->outer_input; // restore old state from buffer struct
current_input = icb->input;
GotByte = icb->gb; GotByte = icb->gb;
if (input_now->source == INPUTSRC_FILE) if (current_input.srctype == INPUTSRC_FILE)
report_inputchange("Source: ", input_now->location.plat_filename); report_inputchange("Source: ", current_input.location.plat_filename);
else else
report_inputchange("back", ""); report_inputchange("back", "");
} }

View File

@ -21,12 +21,12 @@ struct input {
// the filename below (in "location") refers to the source file where // the filename below (in "location") refers to the source file where
// the current code initially came from, i.e. it may change during macro execution. // the current code initially came from, i.e. it may change during macro execution.
struct location location; // file + line (during RAM reads as well) struct location location; // file + line (during RAM reads as well)
enum inputsrc source; enum inputsrc srctype;
int state; // state of input (type is really "enum inputstate") int state; // state of input (type is really "enum inputstate")
union { union {
FILE *fd; // file descriptor FILE *fd; // file descriptor
const char *ram_ptr; // RAM read ptr (loop or macro block) const char *ram_ptr; // RAM read ptr (loop or macro block)
} src; } u;
}; };
struct filespecflags { struct filespecflags {
boolean uses_lib; // file name was given in <...> instead of "..." boolean uses_lib; // file name was given in <...> instead of "..."
@ -152,8 +152,7 @@ extern void input_get_location(struct location *target);
// treat this struct as opaque, its components should only be referenced by inputchange_* functions! // treat this struct as opaque, its components should only be referenced by inputchange_* functions!
struct inputchange_buf { struct inputchange_buf {
struct input new_input, struct input input;
*outer_input;
char gb; // buffer for GotByte char gb; // buffer for GotByte
}; };
// save current input struct in buffer, then switch input to new source code file // save current input struct in buffer, then switch input to new source code file

View File

@ -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 "26 Jul" // update before release FIXME #define CHANGE_DATE "27 Jul" // update before release FIXME
#define CHANGE_YEAR "2024" // update before release #define CHANGE_YEAR "2024" // 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