refactored !bin, !fill and !align a bit

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@422 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2024-09-05 22:18:29 +00:00
parent df8e52b544
commit 4d260b2826
5 changed files with 117 additions and 76 deletions

View File

@ -617,7 +617,7 @@ void throw_finalpass_warning(const char msg[])
throw_warning(msg);
}
// throw "macro twice" error (FIXME - also use for "symbol twice"!)
// throw "macro twice"/"symbol twice" error
// first output error as "error", then location of initial definition as "info"
void throw_redef_error(const char error_msg[], struct location *old_def, const char info_msg[])
{

View File

@ -238,7 +238,7 @@ extern void throw_pass1_warning(const char msg[]);
// final pass because values might be undefined earlier!)
extern void throw_finalpass_warning(const char msg[]);
// throw "macro twice" error (FIXME - also use for "symbol twice"!)
// throw "macro twice"/"symbol twice" error
// first output error as "error", then location of initial definition as "info"
extern void throw_redef_error(const char error_msg[], struct location *old_def, const char info_msg[]);

View File

@ -923,11 +923,10 @@ int input_read_input_filename(struct filespecflags *flags)
return 1; // unterminated or escaping error
GetByte(); // eat terminator
// new algo:
// new algo: (FIXME)
// it should be possible to construct the name of input file from symbols, so
// build environments can define a name at one place and use it at another.
// FIXME - use expression parser to read filename string!
// see lines 416 and 1317 in pseudoopcodes.c for two more possible callers!
}
// check length, remember abs/rel, unescape, terminate, do platform conversion

View File

@ -24,6 +24,15 @@
// TODO - make new, keyword-based argument parser for !bin, !fill and !align
// helper function to support switching from positional arguments to keyword arguments
static boolean line_uses_keyword_arguments(void)
{
// to be on the safe side, return FALSE if dialect < 0.98!
// read line to buffer, check if it begins with '[a-zA-Z]+='
// change input to RAM, return result
// ...and the caller needs to pass us some struct so it can change input back later on!
return FALSE;
}
// different ways to handle end-of-statement:
@ -525,19 +534,54 @@ static enum eos po_scrxor(void)
return SKIP_REMAINDER;
}
// "backend" function for "!binary"
static void include_file(FILE *stream, intval_t size, intval_t offset)
{
int byte,
amount;
// check whether including is a waste of time
// FIXME - future changes ("several-projects-at-once")
// may be incompatible with this!
if ((size >= 0) && (!pass.flags.generate_output)) {
output_skip(size); // really including is useless anyway
return;
}
// really insert file
fseek(stream, offset, SEEK_SET); // set read pointer
// read "size" bytes. if size is "NO_VALUE_GIVEN" (which is -1),
// decrementing it won't give zero, so we'll read until EOF,
// which is exactly what we want if no size was given:
while (size != 0) {
byte = getc(stream);
if (byte == EOF)
break;
output_byte(byte);
--size;
}
// if more should have been read, warn and add padding
if (size > 0) {
throw_warning("Padding with zeroes.");
do {
output_byte(0);
} while (--size);
}
// if verbose, produce some output
if (config.process_verbosity >= 2) {
amount = output_get_statement_size();
printf("Loaded %d (0x%04x) bytes from file offset %d (0x%04x).\n",
amount, amount, offset, offset);
}
}
// include binary file ("!binary" pseudo opcode)
// FIXME - split this into "parser" and "worker" fn and move worker fn somewhere else.
static enum eos po_binary(void)
{
struct filespecflags flags;
FILE *stream;
int byte;
struct number size,
skip;
int amount;
size.val.intval = -1; // means "not given" => "until EOF"
skip.val.intval = 0;
struct number arg;
intval_t size = NO_VALUE_GIVEN, // means "until EOF"
skip = 0;
// read file name and convert from UNIX style to platform style
if (input_read_input_filename(&flags))
@ -548,55 +592,36 @@ static enum eos po_binary(void)
if (stream == NULL)
return SKIP_REMAINDER;
// read optional arguments
// any more arguments?
if (parser_accept_comma()) {
// any size given?
if ((GotByte != ',') && (GotByte != CHAR_EOS)) {
// then parse it
ALU_defined_int(&size);
if (size.val.intval < 0)
throw_serious_error(exception_negative_size);
}
// more?
if (parser_accept_comma()) {
// any skip given?
if (GotByte != CHAR_EOS) {
// then parse it
ALU_defined_int(&skip);
if (line_uses_keyword_arguments()) {
// read keyword arguments
// TODO!
BUG("KeywordArgsNotYet", 0);
} else {
// read old-style, positional arguments:
if ((GotByte != ',') && (GotByte != CHAR_EOS)) {
// first arg is "size"
ALU_defined_int(&arg);
size = arg.val.intval;
// CAUTION: do not move this check elsewhere,
// because the default value -1 is ok!
if (size < 0)
throw_serious_error(exception_negative_size);
}
// more?
if (parser_accept_comma()) {
// second arg is "skip"
if (GotByte != CHAR_EOS) {
// then parse it
ALU_defined_int(&arg);
skip = arg.val.intval;
}
}
}
}
// check whether including is a waste of time
// FIXME - future changes ("several-projects-at-once")
// may be incompatible with this!
if ((size.val.intval >= 0) && (!pass.flags.generate_output)) {
output_skip(size.val.intval); // really including is useless anyway
} else {
// really insert file
fseek(stream, skip.val.intval, SEEK_SET); // set read pointer
// if "size" non-negative, read "size" bytes.
// otherwise, read until EOF.
while (size.val.intval != 0) {
byte = getc(stream);
if (byte == EOF)
break;
output_byte(byte);
--size.val.intval;
}
// if more should have been read, warn and add padding
if (size.val.intval > 0) {
throw_warning("Padding with zeroes.");
do {
output_byte(0);
} while (--size.val.intval);
}
// if verbose, produce some output
if (config.process_verbosity >= 2) {
amount = output_get_statement_size();
printf("Loaded %d (0x%04x) bytes from file offset %d (0x%04x).\n",
amount, amount, skip.val.intval, skip.val.intval);
}
}
// FIXME - add check for "skip" and complain if negative!
include_file(stream, size, skip);
fclose(stream);
return ENSURE_EOS;
}
@ -608,9 +633,17 @@ static enum eos po_fill(void)
struct number sizeresult;
intval_t fill = FILLVALUE_FILL;
ALU_defined_int(&sizeresult); // FIXME - forbid addresses!
if (parser_accept_comma())
ALU_any_int(&fill); // FIXME - forbid addresses!
if (line_uses_keyword_arguments()) {
// read keyword arguments
// TODO!
BUG("KeywordArgsNotYet", 1);
} else {
// read old-style, positional arguments:
ALU_defined_int(&sizeresult); // FIXME - forbid addresses!
if (parser_accept_comma())
ALU_any_int(&fill); // FIXME - forbid addresses!
}
while (sizeresult.val.intval--)
output_8(fill);
return ENSURE_EOS;
@ -633,25 +666,34 @@ static enum eos po_skip(void) // now GotByte = illegal char
// insert byte until PC fits condition
// TODO:
// now: "!align ANDVALUE, EQUALVALUE [,FILLVALUE]"
// in future: use keyword arguments so "!align fillvalue=17, blocksize=64" is
// possible (where blocksize must be a power of two)
static enum eos po_align(void)
{
struct number andresult,
equalresult;
intval_t fill;
struct number arg;
intval_t andresult,
equalresult,
fill = cpu_current_type->default_align_value;
struct number pc;
// TODO:
// now: "!align ANDVALUE, EQUALVALUE [,FILLVALUE]"
// in future: "!align BLOCKSIZE" where block size must be a power of two
ALU_defined_int(&andresult); // FIXME - forbid addresses!
if (parser_expect(',')) {
// fn already does everything for us
if (line_uses_keyword_arguments()) {
// read keyword arguments
// TODO!
BUG("KeywordArgsNotYet", 2);
} else {
// read old-style, positional arguments:
ALU_defined_int(&arg); // FIXME - forbid addresses!
andresult = arg.val.intval;
if (parser_expect(',')) {
// fn already does everything for us
}
ALU_defined_int(&arg); // ...allow addresses (unlikely, but possible)
equalresult = arg.val.intval;
if (parser_accept_comma())
ALU_any_int(&fill);
}
ALU_defined_int(&equalresult); // ...allow addresses (unlikely, but possible)
if (parser_accept_comma())
ALU_any_int(&fill);
else
fill = cpu_current_type->default_align_value;
// make sure PC is defined
programcounter_read_pc(&pc);
@ -660,7 +702,7 @@ static enum eos po_align(void)
return SKIP_REMAINDER;
}
while ((pc.val.intval++ & andresult.val.intval) != equalresult.val.intval)
while ((pc.val.intval++ & andresult) != equalresult)
output_8(fill);
return ENSURE_EOS;
}

View File

@ -9,7 +9,7 @@
#define RELEASE "0.97" // update before release FIXME
#define CODENAME "Zem" // update before release
#define CHANGE_DATE "24 Aug" // update before release FIXME
#define CHANGE_DATE "25 Aug" // update before release FIXME
#define CHANGE_YEAR "2024" // update before release
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME