step 3 to fix ALU_* calls

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@144 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2020-05-08 13:22:15 +00:00
parent 4b81e40c63
commit c1f62fdef5
3 changed files with 56 additions and 75 deletions

View File

@ -1512,39 +1512,6 @@ static void parse_expression(struct expression *expression)
}
// Store int value if given. Returns whether stored. Throws error if undefined.
// This function needs either a defined value or no expression at all. So
// empty expressions are accepted, but undefined ones are not.
// If the result is non-empty but undefined, a serious error is thrown, stopping assembly.
// OPEN_PARENTHESIS: complain
// EMPTY: allow
// UNDEFINED: complain _seriously_
// FLOAT: convert to int
boolean ALU_optional_defined_int(intval_t *target) // ACCEPT_EMPTY
{
struct expression expression;
boolean buf = pass.complain_about_undefined;
pass.complain_about_undefined = TRUE;
parse_expression(&expression);
pass.complain_about_undefined = buf;
if (expression.open_parentheses)
Throw_error(exception_paren_open);
if ((!expression.is_empty)
&& (!(expression.number.flags & NUMBER_IS_DEFINED)))
Throw_serious_error(exception_value_not_defined);
if (expression.is_empty)
return FALSE;
// something was given, so store
if (expression.number.flags & NUMBER_IS_FLOAT)
*target = expression.number.val.fpval;
else
*target = expression.number.val.intval;
return TRUE;
}
// return int value (if undefined, return zero)
// For empty expressions, an error is thrown.
// OPEN_PARENTHESIS: complain
@ -1641,6 +1608,13 @@ void ALU_any_result(struct number *result) // ACCEPT_UNDEFINED | ACCEPT_FLOAT
/* TODO
change parse_expression() to return error/ok.
after that, move
if (expression.is_empty)
Throw_error(exception_no_value);
to end of parse_expression()
// stores int value and flags, allowing for "paren" '(' too many (x-indirect addr).
void ALU_addrmode_int(struct expression *expression, int paren)
mnemo.c
@ -1670,10 +1644,6 @@ void ALU_defined_int(struct number *intresult)
!pseudopc (FIXME, allow undefined) needvalue!
!if make bool serious
twice in !for serious
// stores int value if given. Returns whether stored. Throws error if undefined.
int ALU_optional_defined_int(intval_t *target)
pseudoopcodes.c
twice for !binary (maybe allow undefined?) needvalue!
//!enum

View File

@ -13,7 +13,6 @@
// types
/*
enum expression_type {
EXTY_EMPTY, // next char after space was comma or end-of-statement
EXTY_NUMBER, // int or float (what is returned by the current functions)
EXTY_STRING, // TODO
EXTY_REGISTER, // reserved cpu constant (register names), TODO
@ -23,7 +22,7 @@ enum expression_type {
struct expression {
//enum expression_type type;
struct number number;
boolean is_empty; // nothing parsed (first character was a delimiter) FIXME - make into its own result type!
boolean is_empty; // nothing parsed (first character was a delimiter)
int open_parentheses; // number of parentheses still open
boolean is_parenthesized; // whole expression was in parentheses (indicating indirect addressing)
};
@ -32,37 +31,35 @@ struct expression {
// constants
// flag bits in number struct:
#define NUMBER_IS_FLOAT (1u << 6) // floating point value
#define NUMBER_EVER_UNDEFINED (1u << 5) // value once was related to undefined
// expression. Needed for producing the same addresses in all passes; because in
// the first pass there will almost for sure be labels that are undefined, you
// can't simply get the addressing mode from looking at the parameter's value.
#define NUMBER_IS_DEFINED (1u << 4) // 0: undefined expression (value will be zero). 1: known result
#define NUMBER_FITS_BYTE (1u << 3) // value is guaranteed to fit in one byte
#define NUMBER_FORCES_24 (1u << 2) // value usage forces 24-bit usage
#define NUMBER_FORCES_16 (1u << 1) // value usage forces 16-bit usage
#define NUMBER_FORCES_8 (1u << 0) // value usage forces 8-bit usage
#define NUMBER_FORCES_16 (1u << 1) // value usage forces 16-bit usage
#define NUMBER_FORCES_24 (1u << 2) // value usage forces 24-bit usage
#define NUMBER_FORCEBITS (NUMBER_FORCES_8 | NUMBER_FORCES_16 | NUMBER_FORCES_24)
#define NUMBER_FITS_BYTE (1u << 3) // value is guaranteed to fit in one byte
#define NUMBER_IS_DEFINED (1u << 4) // 0: undefined expression (value will be zero). 1: known result
#define NUMBER_EVER_UNDEFINED (1u << 5) // value once was related to
// undefined expression. Needed for producing the same addresses in all
// passes; because in the first pass there will almost for sure be
// labels that are undefined, we can't simply get the addressing mode
// from looking at the parameter's value.
#define NUMBER_IS_FLOAT (1u << 6) // floating point value
// create dynamic buffer, operator/function trees and operator/operand stacks
extern void ALU_init(void);
/*
// FIXME - replace all the functions below with a single one using a "flags" arg!
/* its return value would then be "error"/"ok".
// its return value would then be "error"/"ok".
// input flags:
#define ACCEPT_EMPTY (1u << 0) // if not given, throws error
#define ACCEPT_UNDEFINED (1u << 1) // if not given, undefined throws serious error
//#define ACCEPT_INT (1u << ) needed when strings come along!
#define ACCEPT_UNDEFINED (1u << 0) // if not given, undefined throws serious error
#define ACCEPT_INT (1u << 1) needed when strings come along!
#define ACCEPT_FLOAT (1u << 2) // if not given, floats are converted to integer
#define ACCEPT_OPENPARENTHESIS (1u << 3) // if not given, throws syntax error
//#define ACCEPT_STRING
// do I need ACCEPT_INT and/or ACCEPT_ADDRESS?
// do I need ACCEPT_NONADDR and/or ACCEPT_ADDRESS?
*/
// stores int value if given. Returns whether stored. Throws error if undefined.
extern boolean ALU_optional_defined_int(intval_t *target);
// returns int value (0 if result was undefined)
extern intval_t ALU_any_int(void);
// stores int value and flags (floats are transformed to int)

View File

@ -433,8 +433,11 @@ static enum eos po_binary(void)
boolean uses_lib;
FILE *stream;
int byte;
intval_t size = -1, // means "not given" => "until EOF"
skip = 0;
struct number size,
skip;
size.val.intval = -1; // means "not given" => "until EOF"
skip.val.intval = 0;
// if file name is missing, don't bother continuing
if (Input_read_filename(TRUE, &uses_lib))
@ -447,36 +450,46 @@ static enum eos po_binary(void)
// read optional arguments
if (Input_accept_comma()) {
if (ALU_optional_defined_int(&size)
&& (size < 0))
Throw_serious_error(exception_negative_size);
if (Input_accept_comma())
ALU_optional_defined_int(&skip); // read skip
// 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 (Input_accept_comma()) {
// any skip given?
if (GotByte != CHAR_EOS) {
// then parse it
ALU_defined_int(&skip);
}
}
}
// check whether including is a waste of time
// FIXME - future changes ("several-projects-at-once")
// may be incompatible with this!
if ((size >= 0) && (pass.undefined_count || pass.error_count)) {
//if ((size >= 0) && (pass.needvalue_count || pass.error_count)) { FIXME - use!
output_skip(size); // really including is useless anyway
if ((size.val.intval >= 0) && (pass.undefined_count || pass.error_count)) {
//if ((size.val.intval >= 0) && (pass.needvalue_count || pass.error_count)) { FIXME - use!
output_skip(size.val.intval); // really including is useless anyway
} else {
// really insert file
fseek(stream, skip, SEEK_SET); // set read pointer
fseek(stream, skip.val.intval, SEEK_SET); // set read pointer
// if "size" non-negative, read "size" bytes.
// otherwise, read until EOF.
while (size != 0) {
while (size.val.intval != 0) {
byte = getc(stream);
if (byte == EOF)
break;
Output_byte(byte);
--size;
--size.val.intval;
}
// if more should have been read, warn and add padding
if (size > 0) {
if (size.val.intval > 0) {
Throw_warning("Padding with zeroes.");
do
Output_byte(0);
while (--size);
while (--size.val.intval);
}
}
fclose(stream);
@ -485,7 +498,7 @@ static enum eos po_binary(void)
int amount = vcpu_get_statement_size();
printf("Loaded %d (0x%04x) bytes from file offset %ld (0x%04lx).\n",
amount, amount, skip, skip);
amount, amount, skip.val.intval, skip.val.intval);
}
return ENSURE_EOS;
}
@ -663,12 +676,13 @@ static enum eos po_address(void) // now GotByte = illegal char
#if 0
// enumerate constants
// enumerate constants ("!enum")
static enum eos po_enum(void) // now GotByte = illegal char
{
intval_t step = 1;
struct number step;
ALU_optional_defined_int(&step);
step.val.intval = 1;
ALU_defined_int(&step);
Throw_serious_error("Not yet"); // FIXME
return ENSURE_EOS;
}