mirror of
https://github.com/uffejakobsen/acme.git
synced 2025-04-08 20:37:20 +00:00
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:
parent
4b81e40c63
commit
c1f62fdef5
44
src/alu.c
44
src/alu.c
@ -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
|
||||
|
||||
|
35
src/alu.h
35
src/alu.h
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user