mirror of
https://github.com/uffejakobsen/acme.git
synced 2025-01-26 17:35:19 +00:00
renamed a bunch of stuff, no change in functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@128 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
parent
0a4c13bb2e
commit
669f95c238
234
src/alu.c
234
src/alu.c
@ -155,7 +155,7 @@ static struct dynabuf *undefsym_dyna_buf; // dynamic buffer for name of undefine
|
||||
static struct operator **operator_stack = NULL;
|
||||
static int operator_stk_size = HALF_INITIAL_STACK_SIZE;
|
||||
static int operator_sp; // operator stack pointer
|
||||
static struct result *operand_stack = NULL; // flags and value
|
||||
static struct number *operand_stack = NULL; // flags and value
|
||||
static int operand_stk_size = HALF_INITIAL_STACK_SIZE;
|
||||
static int operand_sp; // value stack pointer
|
||||
enum alu_state {
|
||||
@ -214,11 +214,11 @@ do { \
|
||||
operand_stack[operand_sp].val.intval = (i); \
|
||||
operand_stack[operand_sp++].addr_refs = (r); \
|
||||
} while (0)
|
||||
#define PUSH_FPOPERAND(fp, f) \
|
||||
do { \
|
||||
operand_stack[operand_sp].flags = (f) | MVALUE_IS_FP; \
|
||||
operand_stack[operand_sp].val.fpval = (fp); \
|
||||
operand_stack[operand_sp++].addr_refs = 0; \
|
||||
#define PUSH_FPOPERAND(fp, f) \
|
||||
do { \
|
||||
operand_stack[operand_sp].flags = (f) | NUMBER_IS_FLOAT; \
|
||||
operand_stack[operand_sp].val.fpval = (fp); \
|
||||
operand_stack[operand_sp++].addr_refs = 0; \
|
||||
} while (0)
|
||||
|
||||
|
||||
@ -320,7 +320,7 @@ static intval_t my_asr(intval_t left, intval_t right)
|
||||
// if undefined, remember name for error output
|
||||
static void check_for_def(int flags, char optional_prefix_char, char *name, size_t length)
|
||||
{
|
||||
if ((flags & MVALUE_DEFINED) == 0) {
|
||||
if ((flags & NUMBER_IS_DEFINED) == 0) {
|
||||
DYNABUF_CLEAR(undefsym_dyna_buf);
|
||||
if (optional_prefix_char) {
|
||||
DynaBuf_append(undefsym_dyna_buf, optional_prefix_char);
|
||||
@ -347,7 +347,7 @@ static void get_symbol_value(scope_t scope, char optional_prefix_char, size_t na
|
||||
struct symbol *symbol;
|
||||
|
||||
// if the symbol gets created now, mark it as unsure
|
||||
symbol = symbol_find(scope, MVALUE_UNSURE);
|
||||
symbol = symbol_find(scope, NUMBER_EVER_UNDEFINED);
|
||||
// if needed, remember name for "undefined" error output
|
||||
check_for_def(symbol->result.flags, optional_prefix_char, GLOBALDYNABUF_CURRENT, name_length);
|
||||
// in first pass, count usage
|
||||
@ -387,7 +387,7 @@ static void parse_quoted_character(char closing_quote)
|
||||
alu_state = STATE_ERROR;
|
||||
}
|
||||
}
|
||||
PUSH_INTOPERAND(value, MVALUE_DEFINED | MVALUE_ISBYTE, 0);
|
||||
PUSH_INTOPERAND(value, NUMBER_IS_DEFINED | NUMBER_FITS_BYTE, 0);
|
||||
// Now GotByte = char following closing quote (or CHAR_EOS on error)
|
||||
}
|
||||
|
||||
@ -398,7 +398,7 @@ static void parse_quoted_character(char closing_quote)
|
||||
static void parse_binary_value(void) // Now GotByte = "%" or "b"
|
||||
{
|
||||
intval_t value = 0;
|
||||
int flags = MVALUE_DEFINED,
|
||||
int flags = NUMBER_IS_DEFINED,
|
||||
digits = -1; // digit counter
|
||||
|
||||
for (;;) {
|
||||
@ -420,10 +420,10 @@ static void parse_binary_value(void) // Now GotByte = "%" or "b"
|
||||
if (digits > 8) {
|
||||
if (digits > 16) {
|
||||
if (value < 65536)
|
||||
flags |= MVALUE_FORCE24;
|
||||
flags |= NUMBER_FORCES_24;
|
||||
} else {
|
||||
if (value < 256)
|
||||
flags |= MVALUE_FORCE16;
|
||||
flags |= NUMBER_FORCES_16;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -439,7 +439,7 @@ static void parse_hexadecimal_value(void) // Now GotByte = "$" or "x"
|
||||
{
|
||||
char byte;
|
||||
int digits = -1, // digit counter
|
||||
flags = MVALUE_DEFINED;
|
||||
flags = NUMBER_IS_DEFINED;
|
||||
intval_t value = 0;
|
||||
|
||||
for (;;) {
|
||||
@ -465,10 +465,10 @@ static void parse_hexadecimal_value(void) // Now GotByte = "$" or "x"
|
||||
if (digits > 2) {
|
||||
if (digits > 4) {
|
||||
if (value < 65536)
|
||||
flags |= MVALUE_FORCE24;
|
||||
flags |= NUMBER_FORCES_24;
|
||||
} else {
|
||||
if (value < 256)
|
||||
flags |= MVALUE_FORCE16;
|
||||
flags |= NUMBER_FORCES_16;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -490,7 +490,7 @@ static void parse_frac_part(int integer_part) // Now GotByte = first digit after
|
||||
GetByte();
|
||||
}
|
||||
// FIXME - add possibility to read 'e' and exponent!
|
||||
PUSH_FPOPERAND(fpval / denominator, MVALUE_DEFINED);
|
||||
PUSH_FPOPERAND(fpval / denominator, NUMBER_IS_DEFINED);
|
||||
}
|
||||
|
||||
|
||||
@ -535,7 +535,7 @@ static void parse_decimal_value(void) // Now GotByte = first digit
|
||||
GetByte();
|
||||
parse_frac_part(intval);
|
||||
} else {
|
||||
PUSH_INTOPERAND(intval, MVALUE_DEFINED, 0);
|
||||
PUSH_INTOPERAND(intval, NUMBER_IS_DEFINED, 0);
|
||||
}
|
||||
// Now GotByte = non-decimal char
|
||||
}
|
||||
@ -546,7 +546,7 @@ static void parse_decimal_value(void) // Now GotByte = first digit
|
||||
static void parse_octal_value(void) // Now GotByte = "&"
|
||||
{
|
||||
intval_t value = 0;
|
||||
int flags = MVALUE_DEFINED,
|
||||
int flags = NUMBER_IS_DEFINED,
|
||||
digits = 0; // digit counter
|
||||
|
||||
GetByte();
|
||||
@ -560,10 +560,10 @@ static void parse_octal_value(void) // Now GotByte = "&"
|
||||
if (digits > 3) {
|
||||
if (digits > 6) {
|
||||
if (value < 65536)
|
||||
flags |= MVALUE_FORCE24;
|
||||
flags |= NUMBER_FORCES_24;
|
||||
} else {
|
||||
if (value < 256)
|
||||
flags |= MVALUE_FORCE16;
|
||||
flags |= NUMBER_FORCES_16;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -575,7 +575,7 @@ static void parse_octal_value(void) // Now GotByte = "&"
|
||||
// Parse program counter ('*')
|
||||
static void parse_program_counter(void) // Now GotByte = "*"
|
||||
{
|
||||
struct result pc;
|
||||
struct number pc;
|
||||
|
||||
GetByte();
|
||||
vcpu_read_pc(&pc);
|
||||
@ -947,9 +947,9 @@ push_dyadic:
|
||||
// call C's sin/cos/tan function
|
||||
static void perform_fp(double (*fn)(double))
|
||||
{
|
||||
if ((RIGHT_FLAGS & MVALUE_IS_FP) == 0) {
|
||||
if ((RIGHT_FLAGS & NUMBER_IS_FLOAT) == 0) {
|
||||
RIGHT_FPVAL = RIGHT_INTVAL;
|
||||
RIGHT_FLAGS |= MVALUE_IS_FP;
|
||||
RIGHT_FLAGS |= NUMBER_IS_FLOAT;
|
||||
}
|
||||
RIGHT_FPVAL = fn(RIGHT_FPVAL);
|
||||
RIGHT_ADDRREFS = 0; // result now is a non-address
|
||||
@ -959,14 +959,14 @@ static void perform_fp(double (*fn)(double))
|
||||
// make sure arg is in [-1, 1] range before calling function
|
||||
static void perform_ranged_fp(double (*fn)(double))
|
||||
{
|
||||
if ((RIGHT_FLAGS & MVALUE_IS_FP) == 0) {
|
||||
if ((RIGHT_FLAGS & NUMBER_IS_FLOAT) == 0) {
|
||||
RIGHT_FPVAL = RIGHT_INTVAL;
|
||||
RIGHT_FLAGS |= MVALUE_IS_FP;
|
||||
RIGHT_FLAGS |= NUMBER_IS_FLOAT;
|
||||
}
|
||||
if ((RIGHT_FPVAL >= -1) && (RIGHT_FPVAL <= 1)) {
|
||||
RIGHT_FPVAL = fn(RIGHT_FPVAL);
|
||||
} else {
|
||||
if (RIGHT_FLAGS & MVALUE_DEFINED)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_DEFINED)
|
||||
Throw_error("Argument out of range.");
|
||||
RIGHT_FPVAL = 0;
|
||||
}
|
||||
@ -978,7 +978,7 @@ static void perform_ranged_fp(double (*fn)(double))
|
||||
static void right_fp_to_int(void)
|
||||
{
|
||||
RIGHT_INTVAL = RIGHT_FPVAL;
|
||||
RIGHT_FLAGS &= ~MVALUE_IS_FP;
|
||||
RIGHT_FLAGS &= ~NUMBER_IS_FLOAT;
|
||||
}
|
||||
|
||||
|
||||
@ -986,13 +986,13 @@ static void right_fp_to_int(void)
|
||||
// in first pass, throw warning
|
||||
static void both_ensure_int(int warn)
|
||||
{
|
||||
if (LEFT_FLAGS & MVALUE_IS_FP) {
|
||||
if (LEFT_FLAGS & NUMBER_IS_FLOAT) {
|
||||
LEFT_INTVAL = LEFT_FPVAL;
|
||||
LEFT_FLAGS &= ~MVALUE_IS_FP;
|
||||
LEFT_FLAGS &= ~NUMBER_IS_FLOAT;
|
||||
}
|
||||
if (RIGHT_FLAGS & MVALUE_IS_FP) {
|
||||
if (RIGHT_FLAGS & NUMBER_IS_FLOAT) {
|
||||
RIGHT_INTVAL = RIGHT_FPVAL;
|
||||
RIGHT_FLAGS &= ~MVALUE_IS_FP;
|
||||
RIGHT_FLAGS &= ~NUMBER_IS_FLOAT;
|
||||
}
|
||||
// FIXME - warning is never seen if both operands are undefined in first pass!
|
||||
Throw_first_pass_warning("Converted to integer for binary logic operator.");
|
||||
@ -1002,13 +1002,13 @@ static void both_ensure_int(int warn)
|
||||
// check both left-hand and right-hand values. if int, convert to float.
|
||||
static void both_ensure_fp(void)
|
||||
{
|
||||
if ((LEFT_FLAGS & MVALUE_IS_FP) == 0) {
|
||||
if ((LEFT_FLAGS & NUMBER_IS_FLOAT) == 0) {
|
||||
LEFT_FPVAL = LEFT_INTVAL;
|
||||
LEFT_FLAGS |= MVALUE_IS_FP;
|
||||
LEFT_FLAGS |= NUMBER_IS_FLOAT;
|
||||
}
|
||||
if ((RIGHT_FLAGS & MVALUE_IS_FP) == 0) {
|
||||
if ((RIGHT_FLAGS & NUMBER_IS_FLOAT) == 0) {
|
||||
RIGHT_FPVAL = RIGHT_INTVAL;
|
||||
RIGHT_FLAGS |= MVALUE_IS_FP;
|
||||
RIGHT_FLAGS |= NUMBER_IS_FLOAT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1017,7 +1017,7 @@ static void both_ensure_fp(void)
|
||||
static void ensure_int_from_fp(void)
|
||||
{
|
||||
both_ensure_fp();
|
||||
LEFT_FLAGS &= ~MVALUE_IS_FP;
|
||||
LEFT_FLAGS &= ~NUMBER_IS_FLOAT;
|
||||
}
|
||||
|
||||
|
||||
@ -1080,16 +1080,16 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto remove_next_to_last_operator;
|
||||
|
||||
case OPHANDLE_INT:
|
||||
if (RIGHT_FLAGS & MVALUE_IS_FP)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_FLOAT)
|
||||
right_fp_to_int();
|
||||
RIGHT_ADDRREFS = 0; // result now is a non-address
|
||||
goto remove_next_to_last_operator;
|
||||
|
||||
case OPHANDLE_FLOAT:
|
||||
// convert right-hand value from int to fp
|
||||
if ((RIGHT_FLAGS & MVALUE_IS_FP) == 0) {
|
||||
if ((RIGHT_FLAGS & NUMBER_IS_FLOAT) == 0) {
|
||||
RIGHT_FPVAL = RIGHT_INTVAL;
|
||||
RIGHT_FLAGS |= MVALUE_IS_FP;
|
||||
RIGHT_FLAGS |= NUMBER_IS_FLOAT;
|
||||
}
|
||||
RIGHT_ADDRREFS = 0; // result now is a non-address
|
||||
goto remove_next_to_last_operator;
|
||||
@ -1121,55 +1121,55 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
// monadic operators
|
||||
case OPHANDLE_NOT:
|
||||
// fp becomes int
|
||||
if (RIGHT_FLAGS & MVALUE_IS_FP)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_FLOAT)
|
||||
right_fp_to_int();
|
||||
RIGHT_INTVAL = ~(RIGHT_INTVAL);
|
||||
RIGHT_FLAGS &= ~MVALUE_ISBYTE;
|
||||
RIGHT_FLAGS &= ~NUMBER_FITS_BYTE;
|
||||
goto remove_next_to_last_operator;
|
||||
|
||||
case OPHANDLE_NEGATE:
|
||||
// different operations for fp and int
|
||||
if (RIGHT_FLAGS & MVALUE_IS_FP)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_FLOAT)
|
||||
RIGHT_FPVAL = -(RIGHT_FPVAL);
|
||||
else
|
||||
RIGHT_INTVAL = -(RIGHT_INTVAL);
|
||||
RIGHT_FLAGS &= ~MVALUE_ISBYTE;
|
||||
RIGHT_FLAGS &= ~NUMBER_FITS_BYTE;
|
||||
RIGHT_ADDRREFS = -RIGHT_ADDRREFS; // negate address ref count as well
|
||||
goto remove_next_to_last_operator;
|
||||
|
||||
case OPHANDLE_LOWBYTEOF:
|
||||
// fp becomes int
|
||||
if (RIGHT_FLAGS & MVALUE_IS_FP)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_FLOAT)
|
||||
right_fp_to_int();
|
||||
RIGHT_INTVAL = (RIGHT_INTVAL) & 255;
|
||||
RIGHT_FLAGS |= MVALUE_ISBYTE;
|
||||
RIGHT_FLAGS &= ~MVALUE_FORCEBITS;
|
||||
RIGHT_FLAGS |= NUMBER_FITS_BYTE;
|
||||
RIGHT_FLAGS &= ~NUMBER_FORCEBITS;
|
||||
RIGHT_ADDRREFS = 0; // result now is a non-address
|
||||
goto remove_next_to_last_operator;
|
||||
|
||||
case OPHANDLE_HIGHBYTEOF:
|
||||
// fp becomes int
|
||||
if (RIGHT_FLAGS & MVALUE_IS_FP)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_FLOAT)
|
||||
right_fp_to_int();
|
||||
RIGHT_INTVAL = ((RIGHT_INTVAL) >> 8) & 255;
|
||||
RIGHT_FLAGS |= MVALUE_ISBYTE;
|
||||
RIGHT_FLAGS &= ~MVALUE_FORCEBITS;
|
||||
RIGHT_FLAGS |= NUMBER_FITS_BYTE;
|
||||
RIGHT_FLAGS &= ~NUMBER_FORCEBITS;
|
||||
RIGHT_ADDRREFS = 0; // result now is a non-address
|
||||
goto remove_next_to_last_operator;
|
||||
|
||||
case OPHANDLE_BANKBYTEOF:
|
||||
// fp becomes int
|
||||
if (RIGHT_FLAGS & MVALUE_IS_FP)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_FLOAT)
|
||||
right_fp_to_int();
|
||||
RIGHT_INTVAL = ((RIGHT_INTVAL) >> 16) & 255;
|
||||
RIGHT_FLAGS |= MVALUE_ISBYTE;
|
||||
RIGHT_FLAGS &= ~MVALUE_FORCEBITS;
|
||||
RIGHT_FLAGS |= NUMBER_FITS_BYTE;
|
||||
RIGHT_FLAGS &= ~NUMBER_FORCEBITS;
|
||||
RIGHT_ADDRREFS = 0; // result now is a non-address
|
||||
goto remove_next_to_last_operator;
|
||||
|
||||
// dyadic operators
|
||||
case OPHANDLE_POWEROF:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) {
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT) {
|
||||
both_ensure_fp();
|
||||
LEFT_FPVAL = pow(LEFT_FPVAL, RIGHT_FPVAL);
|
||||
LEFT_ADDRREFS = 0; // result now is a non-address
|
||||
@ -1179,7 +1179,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
if (RIGHT_INTVAL >= 0) {
|
||||
LEFT_INTVAL = my_pow(LEFT_INTVAL, RIGHT_INTVAL);
|
||||
} else {
|
||||
if (RIGHT_FLAGS & MVALUE_DEFINED)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_DEFINED)
|
||||
Throw_error("Exponent is negative.");
|
||||
LEFT_INTVAL = 0;
|
||||
}
|
||||
@ -1187,7 +1187,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_MULTIPLY:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) {
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT) {
|
||||
both_ensure_fp();
|
||||
LEFT_FPVAL *= RIGHT_FPVAL;
|
||||
} else {
|
||||
@ -1197,12 +1197,12 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_DIVIDE:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) {
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT) {
|
||||
both_ensure_fp();
|
||||
if (RIGHT_FPVAL) {
|
||||
LEFT_FPVAL /= RIGHT_FPVAL;
|
||||
} else {
|
||||
if (RIGHT_FLAGS & MVALUE_DEFINED)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_DEFINED)
|
||||
Throw_error(exception_div_by_zero);
|
||||
LEFT_FPVAL = 0;
|
||||
}
|
||||
@ -1210,7 +1210,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
if (RIGHT_INTVAL) {
|
||||
LEFT_INTVAL /= RIGHT_INTVAL;
|
||||
} else {
|
||||
if (RIGHT_FLAGS & MVALUE_DEFINED)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_DEFINED)
|
||||
Throw_error(exception_div_by_zero);
|
||||
LEFT_INTVAL = 0;
|
||||
}
|
||||
@ -1219,21 +1219,21 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_INTDIV:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) {
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT) {
|
||||
both_ensure_fp();
|
||||
if (RIGHT_FPVAL) {
|
||||
LEFT_INTVAL = LEFT_FPVAL / RIGHT_FPVAL;
|
||||
} else {
|
||||
if (RIGHT_FLAGS & MVALUE_DEFINED)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_DEFINED)
|
||||
Throw_error(exception_div_by_zero);
|
||||
LEFT_INTVAL = 0;
|
||||
}
|
||||
LEFT_FLAGS &= ~MVALUE_IS_FP;
|
||||
LEFT_FLAGS &= ~NUMBER_IS_FLOAT;
|
||||
} else {
|
||||
if (RIGHT_INTVAL) {
|
||||
LEFT_INTVAL /= RIGHT_INTVAL;
|
||||
} else {
|
||||
if (RIGHT_FLAGS & MVALUE_DEFINED)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_DEFINED)
|
||||
Throw_error(exception_div_by_zero);
|
||||
LEFT_INTVAL = 0;
|
||||
}
|
||||
@ -1242,12 +1242,12 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_MODULO:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP)
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT)
|
||||
both_ensure_int(FALSE);
|
||||
if (RIGHT_INTVAL) {
|
||||
LEFT_INTVAL %= RIGHT_INTVAL;
|
||||
} else {
|
||||
if (RIGHT_FLAGS & MVALUE_DEFINED)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_DEFINED)
|
||||
Throw_error(exception_div_by_zero);
|
||||
LEFT_INTVAL = 0;
|
||||
}
|
||||
@ -1255,7 +1255,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_ADD:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) {
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT) {
|
||||
both_ensure_fp();
|
||||
LEFT_FPVAL += RIGHT_FPVAL;
|
||||
} else {
|
||||
@ -1265,7 +1265,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_SUBTRACT:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) {
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT) {
|
||||
both_ensure_fp();
|
||||
LEFT_FPVAL -= RIGHT_FPVAL;
|
||||
} else {
|
||||
@ -1275,9 +1275,9 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_SL:
|
||||
if (RIGHT_FLAGS & MVALUE_IS_FP)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_FLOAT)
|
||||
right_fp_to_int();
|
||||
if (LEFT_FLAGS & MVALUE_IS_FP)
|
||||
if (LEFT_FLAGS & NUMBER_IS_FLOAT)
|
||||
LEFT_FPVAL *= pow(2.0, RIGHT_INTVAL);
|
||||
else
|
||||
LEFT_INTVAL <<= RIGHT_INTVAL;
|
||||
@ -1285,9 +1285,9 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_ASR:
|
||||
if (RIGHT_FLAGS & MVALUE_IS_FP)
|
||||
if (RIGHT_FLAGS & NUMBER_IS_FLOAT)
|
||||
right_fp_to_int();
|
||||
if (LEFT_FLAGS & MVALUE_IS_FP)
|
||||
if (LEFT_FLAGS & NUMBER_IS_FLOAT)
|
||||
LEFT_FPVAL /= (1 << RIGHT_INTVAL);
|
||||
else
|
||||
LEFT_INTVAL = my_asr(LEFT_INTVAL, RIGHT_INTVAL);
|
||||
@ -1296,14 +1296,14 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
|
||||
case OPHANDLE_LSR:
|
||||
// fp become int
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP)
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT)
|
||||
both_ensure_int(TRUE);
|
||||
LEFT_INTVAL = ((uintval_t) LEFT_INTVAL) >> RIGHT_INTVAL;
|
||||
LEFT_ADDRREFS = 0; // result now is a non-address
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_LE:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) {
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT) {
|
||||
ensure_int_from_fp();
|
||||
LEFT_INTVAL = (LEFT_FPVAL <= RIGHT_FPVAL);
|
||||
} else {
|
||||
@ -1313,7 +1313,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_LESSTHAN:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) {
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT) {
|
||||
ensure_int_from_fp();
|
||||
LEFT_INTVAL = (LEFT_FPVAL < RIGHT_FPVAL);
|
||||
} else {
|
||||
@ -1323,7 +1323,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_GE:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) {
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT) {
|
||||
ensure_int_from_fp();
|
||||
LEFT_INTVAL = (LEFT_FPVAL >= RIGHT_FPVAL);
|
||||
} else {
|
||||
@ -1333,7 +1333,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_GREATERTHAN:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) {
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT) {
|
||||
ensure_int_from_fp();
|
||||
LEFT_INTVAL = (LEFT_FPVAL > RIGHT_FPVAL);
|
||||
} else {
|
||||
@ -1343,7 +1343,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_NOTEQUAL:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) {
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT) {
|
||||
ensure_int_from_fp();
|
||||
LEFT_INTVAL = (LEFT_FPVAL != RIGHT_FPVAL);
|
||||
} else {
|
||||
@ -1353,7 +1353,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
goto handle_flags_and_dec_stacks;
|
||||
|
||||
case OPHANDLE_EQUALS:
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) {
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT) {
|
||||
ensure_int_from_fp();
|
||||
LEFT_INTVAL = (LEFT_FPVAL == RIGHT_FPVAL);
|
||||
} else {
|
||||
@ -1364,7 +1364,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
|
||||
case OPHANDLE_AND:
|
||||
// fp become int
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP)
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT)
|
||||
both_ensure_int(TRUE);
|
||||
LEFT_INTVAL &= RIGHT_INTVAL;
|
||||
LEFT_ADDRREFS += RIGHT_ADDRREFS; // add address references
|
||||
@ -1375,7 +1375,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
/*FALLTHROUGH*/
|
||||
case OPHANDLE_XOR:
|
||||
// fp become int
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP)
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT)
|
||||
both_ensure_int(TRUE);
|
||||
LEFT_INTVAL ^= RIGHT_INTVAL;
|
||||
LEFT_ADDRREFS += RIGHT_ADDRREFS; // add address references
|
||||
@ -1383,7 +1383,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
|
||||
case OPHANDLE_OR:
|
||||
// fp become int
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP)
|
||||
if ((RIGHT_FLAGS | LEFT_FLAGS) & NUMBER_IS_FLOAT)
|
||||
both_ensure_int(TRUE);
|
||||
LEFT_INTVAL |= RIGHT_INTVAL;
|
||||
LEFT_ADDRREFS += RIGHT_ADDRREFS; // add address references
|
||||
@ -1399,11 +1399,11 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
// entry point for dyadic operators
|
||||
handle_flags_and_dec_stacks:
|
||||
// Handle flags and decrement value stack pointer
|
||||
// "OR" UNSURE and FORCEBIT flags
|
||||
LEFT_FLAGS |= RIGHT_FLAGS & (MVALUE_UNSURE | MVALUE_FORCEBITS);
|
||||
// "OR" EVER_UNDEFINED and FORCEBIT flags
|
||||
LEFT_FLAGS |= RIGHT_FLAGS & (NUMBER_EVER_UNDEFINED | NUMBER_FORCEBITS);
|
||||
// "AND" DEFINED flag
|
||||
LEFT_FLAGS &= (RIGHT_FLAGS | ~MVALUE_DEFINED);
|
||||
LEFT_FLAGS &= ~MVALUE_ISBYTE; // clear ISBYTE flag
|
||||
LEFT_FLAGS &= (RIGHT_FLAGS | ~NUMBER_IS_DEFINED);
|
||||
LEFT_FLAGS &= ~NUMBER_FITS_BYTE; // clear FITS BYTE flag
|
||||
--operand_sp;
|
||||
// entry point for monadic operators
|
||||
remove_next_to_last_operator:
|
||||
@ -1421,7 +1421,7 @@ RNTLObutDontTouchIndirectFlag:
|
||||
// FIXME - make state machine using function pointers? or too slow?
|
||||
static void parse_expression(struct expression *expression)
|
||||
{
|
||||
struct result *result = &expression->number;
|
||||
struct number *result = &expression->number;
|
||||
|
||||
// init
|
||||
expression->is_empty = TRUE; // becomes FALSE when first valid char gets parsed
|
||||
@ -1468,33 +1468,33 @@ static void parse_expression(struct expression *expression)
|
||||
// copy result
|
||||
*result = operand_stack[0];
|
||||
// only allow *one* force bit
|
||||
if (result->flags & MVALUE_FORCE24)
|
||||
result->flags &= ~(MVALUE_FORCE16 | MVALUE_FORCE08);
|
||||
else if (result->flags & MVALUE_FORCE16)
|
||||
result->flags &= ~MVALUE_FORCE08;
|
||||
if (result->flags & NUMBER_FORCES_24)
|
||||
result->flags &= ~(NUMBER_FORCES_16 | NUMBER_FORCES_8);
|
||||
else if (result->flags & NUMBER_FORCES_16)
|
||||
result->flags &= ~NUMBER_FORCES_8;
|
||||
// if there was nothing to parse, mark as undefined
|
||||
// (so ALU_defined_int() can react)
|
||||
if (expression->is_empty)
|
||||
result->flags &= ~MVALUE_DEFINED;
|
||||
result->flags &= ~NUMBER_IS_DEFINED;
|
||||
// do some checks depending on int/float
|
||||
if (result->flags & MVALUE_IS_FP) {
|
||||
if (result->flags & NUMBER_IS_FLOAT) {
|
||||
/*float*/ // if undefined, return zero
|
||||
if ((result->flags & MVALUE_DEFINED) == 0)
|
||||
if ((result->flags & NUMBER_IS_DEFINED) == 0)
|
||||
result->val.fpval = 0;
|
||||
// if value is sure, check to set ISBYTE
|
||||
else if (((result->flags & MVALUE_UNSURE) == 0)
|
||||
// if value is sure, check to set FITS BYTE
|
||||
else if (((result->flags & NUMBER_EVER_UNDEFINED) == 0)
|
||||
&& (result->val.fpval <= 255.0)
|
||||
&& (result->val.fpval >= -128.0))
|
||||
result->flags |= MVALUE_ISBYTE;
|
||||
result->flags |= NUMBER_FITS_BYTE;
|
||||
} else {
|
||||
/*int*/ // if undefined, return zero
|
||||
if ((result->flags & MVALUE_DEFINED) == 0)
|
||||
if ((result->flags & NUMBER_IS_DEFINED) == 0)
|
||||
result->val.intval = 0;
|
||||
// if value is sure, check to set ISBYTE
|
||||
else if (((result->flags & MVALUE_UNSURE) == 0)
|
||||
// if value is sure, check to set FITS BYTE
|
||||
else if (((result->flags & NUMBER_EVER_UNDEFINED) == 0)
|
||||
&& (result->val.intval <= 255)
|
||||
&& (result->val.intval >= -128))
|
||||
result->flags |= MVALUE_ISBYTE;
|
||||
result->flags |= NUMBER_FITS_BYTE;
|
||||
}
|
||||
} else {
|
||||
// State is STATE_ERROR. Errors have already been reported,
|
||||
@ -1528,13 +1528,13 @@ int ALU_optional_defined_int(intval_t *target) // ACCEPT_EMPTY
|
||||
if (expression.open_parentheses)
|
||||
Throw_error(exception_paren_open);
|
||||
if ((expression.is_empty == FALSE)
|
||||
&& ((expression.number.flags & MVALUE_DEFINED) == 0))
|
||||
&& ((expression.number.flags & NUMBER_IS_DEFINED) == 0))
|
||||
Throw_serious_error(value_not_defined());
|
||||
if (expression.is_empty)
|
||||
return 0;
|
||||
|
||||
// something was given, so store
|
||||
if (expression.number.flags & MVALUE_IS_FP)
|
||||
if (expression.number.flags & NUMBER_IS_FLOAT)
|
||||
*target = expression.number.val.fpval;
|
||||
else
|
||||
*target = expression.number.val.intval;
|
||||
@ -1550,7 +1550,7 @@ int ALU_optional_defined_int(intval_t *target) // ACCEPT_EMPTY
|
||||
// EMPTY: complain
|
||||
// UNDEFINED: allow
|
||||
// FLOAT: convert to int
|
||||
void ALU_int_result(struct result *intresult) // ACCEPT_UNDEFINED
|
||||
void ALU_int_result(struct number *intresult) // ACCEPT_UNDEFINED
|
||||
{
|
||||
struct expression expression;
|
||||
|
||||
@ -1559,13 +1559,13 @@ void ALU_int_result(struct result *intresult) // ACCEPT_UNDEFINED
|
||||
if (expression.open_parentheses)
|
||||
Throw_error(exception_paren_open);
|
||||
// make sure result is not float
|
||||
if (intresult->flags & MVALUE_IS_FP) {
|
||||
if (intresult->flags & NUMBER_IS_FLOAT) {
|
||||
intresult->val.intval = intresult->val.fpval;
|
||||
intresult->flags &= ~MVALUE_IS_FP;
|
||||
intresult->flags &= ~NUMBER_IS_FLOAT;
|
||||
}
|
||||
if (expression.is_empty)
|
||||
Throw_error(exception_no_value);
|
||||
else if ((intresult->flags & MVALUE_DEFINED) == 0)
|
||||
else if ((intresult->flags & NUMBER_IS_DEFINED) == 0)
|
||||
result_is_undefined();
|
||||
}
|
||||
|
||||
@ -1588,9 +1588,9 @@ intval_t ALU_any_int(void) // ACCEPT_UNDEFINED
|
||||
Throw_error(exception_paren_open);
|
||||
if (expression.is_empty)
|
||||
Throw_error(exception_no_value);
|
||||
else if ((expression.number.flags & MVALUE_DEFINED) == 0)
|
||||
else if ((expression.number.flags & NUMBER_IS_DEFINED) == 0)
|
||||
result_is_undefined();
|
||||
if (expression.number.flags & MVALUE_IS_FP)
|
||||
if (expression.number.flags & NUMBER_IS_FLOAT)
|
||||
return expression.number.val.fpval;
|
||||
else
|
||||
return expression.number.val.intval;
|
||||
@ -1603,7 +1603,7 @@ intval_t ALU_any_int(void) // ACCEPT_UNDEFINED
|
||||
// EMPTY: treat as UNDEFINED <= this is a problem - maybe use a wrapper fn for this use case?
|
||||
// UNDEFINED: complain _seriously_
|
||||
// FLOAT: convert to int
|
||||
void ALU_defined_int(struct result *intresult) // no ACCEPT constants?
|
||||
void ALU_defined_int(struct number *intresult) // no ACCEPT constants?
|
||||
{
|
||||
struct expression expression;
|
||||
|
||||
@ -1611,11 +1611,11 @@ void ALU_defined_int(struct result *intresult) // no ACCEPT constants?
|
||||
*intresult = expression.number;
|
||||
if (expression.open_parentheses)
|
||||
Throw_error(exception_paren_open);
|
||||
if ((intresult->flags & MVALUE_DEFINED) == 0)
|
||||
if ((intresult->flags & NUMBER_IS_DEFINED) == 0)
|
||||
Throw_serious_error(value_not_defined());
|
||||
if (intresult->flags & MVALUE_IS_FP) {
|
||||
if (intresult->flags & NUMBER_IS_FLOAT) {
|
||||
intresult->val.intval = intresult->val.fpval;
|
||||
intresult->flags &= ~MVALUE_IS_FP;
|
||||
intresult->flags &= ~NUMBER_IS_FLOAT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1631,13 +1631,13 @@ void ALU_defined_int(struct result *intresult) // no ACCEPT constants?
|
||||
// FLOAT: convert to int
|
||||
void ALU_liberal_int(struct expression *expression) // ACCEPT_UNDEFINED | ACCEPT_OPENPARENTHESIS
|
||||
{
|
||||
struct result *intresult = &expression->number;
|
||||
struct number *intresult = &expression->number;
|
||||
|
||||
parse_expression(expression);
|
||||
// make sure result is not float
|
||||
if (intresult->flags & MVALUE_IS_FP) {
|
||||
if (intresult->flags & NUMBER_IS_FLOAT) {
|
||||
intresult->val.intval = intresult->val.fpval;
|
||||
intresult->flags &= ~MVALUE_IS_FP;
|
||||
intresult->flags &= ~NUMBER_IS_FLOAT;
|
||||
}
|
||||
if (expression->open_parentheses > 1) {
|
||||
expression->open_parentheses = 0;
|
||||
@ -1646,7 +1646,7 @@ void ALU_liberal_int(struct expression *expression) // ACCEPT_UNDEFINED | ACCEPT
|
||||
if (expression->is_empty)
|
||||
Throw_error(exception_no_value);
|
||||
if ((expression->is_empty == FALSE)
|
||||
&& ((intresult->flags & MVALUE_DEFINED) == 0))
|
||||
&& ((intresult->flags & NUMBER_IS_DEFINED) == 0))
|
||||
result_is_undefined();
|
||||
}
|
||||
|
||||
@ -1659,7 +1659,7 @@ void ALU_liberal_int(struct expression *expression) // ACCEPT_UNDEFINED | ACCEPT
|
||||
// EMPTY: complain
|
||||
// UNDEFINED: allow
|
||||
// FLOAT: keep
|
||||
void ALU_any_result(struct result *result) // ACCEPT_UNDEFINED | ACCEPT_FLOAT
|
||||
void ALU_any_result(struct number *result) // ACCEPT_UNDEFINED | ACCEPT_FLOAT
|
||||
{
|
||||
struct expression expression;
|
||||
|
||||
@ -1669,6 +1669,6 @@ void ALU_any_result(struct result *result) // ACCEPT_UNDEFINED | ACCEPT_FLOAT
|
||||
Throw_error(exception_paren_open);
|
||||
if (expression.is_empty)
|
||||
Throw_error(exception_no_value);
|
||||
else if ((result->flags & MVALUE_DEFINED) == 0)
|
||||
else if ((result->flags & NUMBER_IS_DEFINED) == 0)
|
||||
result_is_undefined();
|
||||
}
|
||||
|
26
src/alu.h
26
src/alu.h
@ -22,7 +22,7 @@ enum expression_type {
|
||||
*/
|
||||
struct expression {
|
||||
//enum expression_type type;
|
||||
struct result number;
|
||||
struct number number;
|
||||
int is_empty; // actually bool: nothing parsed (first character was a delimiter) FIXME - make into its own result type!
|
||||
int open_parentheses; // number of parentheses still open
|
||||
int is_parenthesized; // actually bool: whole expression was in parentheses (indicating indirect addressing)
|
||||
@ -31,18 +31,18 @@ struct expression {
|
||||
|
||||
// constants
|
||||
|
||||
// meaning of bits in "flags" of struct result:
|
||||
#define MVALUE_IS_FP (1u << 6) // floating point value
|
||||
#define MVALUE_UNSURE (1u << 5) // value once was related to undefined
|
||||
// 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 MVALUE_DEFINED (1u << 4) // 0: undefined expression (value will be zero). 1: known result
|
||||
#define MVALUE_ISBYTE (1u << 3) // value is guaranteed to fit in one byte
|
||||
#define MVALUE_FORCE24 (1u << 2) // value usage forces 24-bit usage
|
||||
#define MVALUE_FORCE16 (1u << 1) // value usage forces 16-bit usage
|
||||
#define MVALUE_FORCE08 (1u << 0) // value usage forces 8-bit usage
|
||||
#define MVALUE_FORCEBITS (MVALUE_FORCE08 | MVALUE_FORCE16 | MVALUE_FORCE24)
|
||||
#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_FORCEBITS (NUMBER_FORCES_8 | NUMBER_FORCES_16 | NUMBER_FORCES_24)
|
||||
|
||||
|
||||
// create dynamic buffer, operator/function trees and operator/operand stacks
|
||||
@ -70,14 +70,14 @@ extern int 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)
|
||||
extern void ALU_int_result(struct result *intresult);
|
||||
extern void ALU_int_result(struct number *intresult);
|
||||
// stores int value and flags (floats are transformed to int)
|
||||
// if result was undefined, serious error is thrown
|
||||
extern void ALU_defined_int(struct result *intresult);
|
||||
extern void ALU_defined_int(struct number *intresult);
|
||||
// stores int value and flags, allowing for one '(' too many (x-indirect addr).
|
||||
extern void ALU_liberal_int(struct expression *expression);
|
||||
// stores value and flags (result may be either int or float)
|
||||
extern void ALU_any_result(struct result *result);
|
||||
extern void ALU_any_result(struct number *result);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -12,7 +12,7 @@ typedef unsigned int scope_t;
|
||||
typedef signed long intval_t; // at least 32 bits
|
||||
typedef unsigned long uintval_t; // just for logical shift right
|
||||
// result structure type definition with support for floating point
|
||||
struct result { // either int or float (TODO - rename to "number"?)
|
||||
struct number { // either int or float
|
||||
int flags; // result flags (see alu.h, one if these tells ints and floats apart)
|
||||
union {
|
||||
intval_t intval; // integer value
|
||||
|
@ -43,7 +43,7 @@ void flow_forloop(struct for_loop *loop)
|
||||
{
|
||||
struct input loop_input,
|
||||
*outer_input;
|
||||
struct result loop_counter;
|
||||
struct number loop_counter;
|
||||
|
||||
// switching input makes us lose GotByte. But we know it's '}' anyway!
|
||||
// set up new input
|
||||
@ -55,7 +55,7 @@ void flow_forloop(struct for_loop *loop)
|
||||
// (not yet useable; pointer and line number are still missing)
|
||||
Input_now = &loop_input;
|
||||
// init counter
|
||||
loop_counter.flags = MVALUE_DEFINED;
|
||||
loop_counter.flags = NUMBER_IS_DEFINED;
|
||||
loop_counter.val.intval = loop->counter.first;
|
||||
loop_counter.addr_refs = loop->counter.addr_refs;
|
||||
symbol_set_value(loop->symbol, &loop_counter, TRUE);
|
||||
@ -120,7 +120,7 @@ void flow_store_doloop_condition(struct loop_condition *condition, char terminat
|
||||
// check a condition expression
|
||||
static int check_condition(struct loop_condition *condition)
|
||||
{
|
||||
struct result intresult;
|
||||
struct number intresult;
|
||||
|
||||
// first, check whether there actually *is* a condition
|
||||
if (condition->body == NULL)
|
||||
|
@ -575,11 +575,11 @@ int Input_get_force_bit(void)
|
||||
if (GotByte == '+') {
|
||||
byte = GetByte();
|
||||
if (byte == '1')
|
||||
force_bit = MVALUE_FORCE08;
|
||||
force_bit = NUMBER_FORCES_8;
|
||||
else if (byte == '2')
|
||||
force_bit = MVALUE_FORCE16;
|
||||
force_bit = NUMBER_FORCES_16;
|
||||
else if (byte == '3')
|
||||
force_bit = MVALUE_FORCE24;
|
||||
force_bit = NUMBER_FORCES_24;
|
||||
if (force_bit)
|
||||
GetByte();
|
||||
else
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
|
||||
// Copyright (C) 1998-2017 Marco Baye
|
||||
// Copyright (C) 1998-2020 Marco Baye
|
||||
// Have a look at "acme.c" for further info
|
||||
//
|
||||
// Macro stuff
|
||||
@ -42,7 +42,7 @@ struct macro {
|
||||
// gives us the possibility to find out which args are call-by-value and
|
||||
// which ones are call-by-reference.
|
||||
union macro_arg_t {
|
||||
struct result result; // value and flags (call by value)
|
||||
struct number result; // value and flags (call by value)
|
||||
struct symbol *symbol; // pointer to symbol struct (call by reference)
|
||||
};
|
||||
|
||||
|
113
src/mnemo.c
113
src/mnemo.c
@ -54,16 +54,11 @@
|
||||
#define LONG_INDIRECT_Y_INDEXED_ADDRESSING (AMB_LONGINDIRECT | AMB_INDEX(INDEX_Y))
|
||||
|
||||
// Constant values, used to mark the possible parameter lengths of commands.
|
||||
// Not all of the eight values are actually used, however (because of the
|
||||
// supported CPUs).
|
||||
#define MAYBE______ (0)
|
||||
#define MAYBE_1____ (MVALUE_FORCE08)
|
||||
#define MAYBE___2__ (MVALUE_FORCE16)
|
||||
#define MAYBE_1_2__ (MVALUE_FORCE08 | MVALUE_FORCE16)
|
||||
#define MAYBE_____3 (MVALUE_FORCE24)
|
||||
#define MAYBE_1___3 (MVALUE_FORCE08 | MVALUE_FORCE24)
|
||||
#define MAYBE___2_3 (MVALUE_FORCE16 | MVALUE_FORCE24)
|
||||
#define MAYBE_1_2_3 (MVALUE_FORCE08 | MVALUE_FORCE16 | MVALUE_FORCE24)
|
||||
// Not all of the eight possible combinations are actually used, however (because of the supported CPUs).
|
||||
#define MAYBE______ 0
|
||||
#define MAYBE_1____ NUMBER_FORCES_8
|
||||
#define MAYBE___2__ NUMBER_FORCES_16
|
||||
#define MAYBE_____3 NUMBER_FORCES_24
|
||||
|
||||
// The mnemonics are split up into groups, each group has its own function to be dealt with:
|
||||
enum mnemogroup {
|
||||
@ -521,7 +516,7 @@ static int get_index(int next)
|
||||
|
||||
// This function stores the command's argument in the given result
|
||||
// structure (using the valueparser). The addressing mode is returned.
|
||||
static int get_argument(struct result *result)
|
||||
static int get_argument(struct number *result)
|
||||
{
|
||||
struct expression expression;
|
||||
int address_mode_bits = 0;
|
||||
@ -574,15 +569,15 @@ static int get_argument(struct result *result)
|
||||
}
|
||||
|
||||
// Helper function for calc_arg_size()
|
||||
// Only call with "size_bit = MVALUE_FORCE16" or "size_bit = MVALUE_FORCE24"
|
||||
static int check_oversize(int size_bit, struct result *argument)
|
||||
// Only call with "size_bit = NUMBER_FORCES_16" or "size_bit = NUMBER_FORCES_24"
|
||||
static int check_oversize(int size_bit, struct number *argument)
|
||||
{
|
||||
// only check if value is *defined*
|
||||
if ((argument->flags & MVALUE_DEFINED) == 0)
|
||||
if ((argument->flags & NUMBER_IS_DEFINED) == 0)
|
||||
return size_bit; // pass on result
|
||||
|
||||
// value is defined, so check
|
||||
if (size_bit == MVALUE_FORCE16) {
|
||||
if (size_bit == NUMBER_FORCES_16) {
|
||||
// check 16-bit argument for high byte zero
|
||||
if ((argument->val.intval <= 255) && (argument->val.intval >= -128))
|
||||
Throw_warning(exception_oversized_addrmode);
|
||||
@ -602,7 +597,7 @@ static int check_oversize(int size_bit, struct result *argument)
|
||||
// argument value and flags of parameter
|
||||
// addressing_modes adressing modes (8b, 16b, 24b or any combination)
|
||||
// Return value = force bit for number of parameter bytes to send (0 = error)
|
||||
static int calc_arg_size(int force_bit, struct result *argument, int addressing_modes)
|
||||
static int calc_arg_size(int force_bit, struct number *argument, int addressing_modes)
|
||||
{
|
||||
// if there are no possible addressing modes, complain
|
||||
if (addressing_modes == MAYBE______) {
|
||||
@ -622,16 +617,16 @@ static int calc_arg_size(int force_bit, struct result *argument, int addressing_
|
||||
|
||||
// Command has no force bit. Check whether value has one
|
||||
// if value has force bit, act upon it
|
||||
if (argument->flags & MVALUE_FORCEBITS) {
|
||||
if (argument->flags & NUMBER_FORCEBITS) {
|
||||
// Value has force bit set, so return this or bigger size
|
||||
if (MVALUE_FORCE08 & addressing_modes & argument->flags)
|
||||
return MVALUE_FORCE08;
|
||||
if (NUMBER_FORCES_8 & addressing_modes & argument->flags)
|
||||
return NUMBER_FORCES_8;
|
||||
|
||||
if (MVALUE_FORCE16 & addressing_modes & argument->flags)
|
||||
return MVALUE_FORCE16;
|
||||
if (NUMBER_FORCES_16 & addressing_modes & argument->flags)
|
||||
return NUMBER_FORCES_16;
|
||||
|
||||
if (MVALUE_FORCE24 & addressing_modes)
|
||||
return MVALUE_FORCE24;
|
||||
if (NUMBER_FORCES_24 & addressing_modes)
|
||||
return NUMBER_FORCES_24;
|
||||
|
||||
Throw_error(exception_number_out_of_range); // else error
|
||||
return 0;
|
||||
@ -639,32 +634,32 @@ static int calc_arg_size(int force_bit, struct result *argument, int addressing_
|
||||
|
||||
// Value has no force bit. Check whether there's only one addr mode
|
||||
// if only one addressing mode, use that
|
||||
if ((addressing_modes == MVALUE_FORCE08)
|
||||
|| (addressing_modes == MVALUE_FORCE16)
|
||||
|| (addressing_modes == MVALUE_FORCE24))
|
||||
if ((addressing_modes == NUMBER_FORCES_8)
|
||||
|| (addressing_modes == NUMBER_FORCES_16)
|
||||
|| (addressing_modes == NUMBER_FORCES_24))
|
||||
return addressing_modes; // There's only one, so use it
|
||||
|
||||
// There's more than one addressing mode. Check whether value is sure
|
||||
// if value is unsure, use default size
|
||||
if (argument->flags & MVALUE_UNSURE) {
|
||||
if (argument->flags & NUMBER_EVER_UNDEFINED) {
|
||||
// if there is an 8-bit addressing mode *and* the value
|
||||
// is sure to fit into 8 bits, use the 8-bit mode
|
||||
if ((addressing_modes & MVALUE_FORCE08) && (argument->flags & MVALUE_ISBYTE))
|
||||
return MVALUE_FORCE08;
|
||||
if ((addressing_modes & NUMBER_FORCES_8) && (argument->flags & NUMBER_FITS_BYTE))
|
||||
return NUMBER_FORCES_8;
|
||||
|
||||
// if there is a 16-bit addressing, use that
|
||||
// call helper function for "oversized addr mode" warning
|
||||
if (MVALUE_FORCE16 & addressing_modes)
|
||||
return check_oversize(MVALUE_FORCE16, argument);
|
||||
if (NUMBER_FORCES_16 & addressing_modes)
|
||||
return check_oversize(NUMBER_FORCES_16, argument);
|
||||
|
||||
// if there is a 24-bit addressing, use that
|
||||
// call helper function for "oversized addr mode" warning
|
||||
if (MVALUE_FORCE24 & addressing_modes)
|
||||
return check_oversize(MVALUE_FORCE24, argument);
|
||||
if (NUMBER_FORCES_24 & addressing_modes)
|
||||
return check_oversize(NUMBER_FORCES_24, argument);
|
||||
|
||||
// otherwise, use 8-bit-addressing, which will raise an
|
||||
// error later on if the value won't fit
|
||||
return MVALUE_FORCE08;
|
||||
return NUMBER_FORCES_8;
|
||||
}
|
||||
|
||||
// Value is sure, so use its own size
|
||||
@ -676,17 +671,17 @@ static int calc_arg_size(int force_bit, struct result *argument, int addressing_
|
||||
|
||||
// Value is positive or zero. Check size ranges
|
||||
// if there is an 8-bit addressing mode and value fits, use 8 bits
|
||||
if ((addressing_modes & MVALUE_FORCE08) && (argument->val.intval < 256))
|
||||
return MVALUE_FORCE08;
|
||||
if ((addressing_modes & NUMBER_FORCES_8) && (argument->val.intval < 256))
|
||||
return NUMBER_FORCES_8;
|
||||
|
||||
// if there is a 16-bit addressing mode and value fits, use 16 bits
|
||||
if ((addressing_modes & MVALUE_FORCE16) && (argument->val.intval < 65536))
|
||||
return MVALUE_FORCE16;
|
||||
if ((addressing_modes & NUMBER_FORCES_16) && (argument->val.intval < 65536))
|
||||
return NUMBER_FORCES_16;
|
||||
|
||||
// if there is a 24-bit addressing mode, use that. In case the
|
||||
// value doesn't fit, the output function will do the complaining.
|
||||
if (addressing_modes & MVALUE_FORCE24)
|
||||
return MVALUE_FORCE24;
|
||||
if (addressing_modes & NUMBER_FORCES_24)
|
||||
return NUMBER_FORCES_24;
|
||||
|
||||
// Value is too big for all possible addressing modes
|
||||
Throw_error(exception_number_out_of_range);
|
||||
@ -715,13 +710,13 @@ static void not_in_bank(intval_t target)
|
||||
// helper function for branches with 8-bit offset (including bbr0..7/bbs0..7)
|
||||
static void near_branch(int preoffset)
|
||||
{
|
||||
struct result target;
|
||||
struct number target;
|
||||
intval_t offset = 0; // dummy value, to not throw more errors than necessary
|
||||
|
||||
ALU_int_result(&target); // FIXME - check for outermost parentheses and raise error!
|
||||
typesystem_want_addr(&target);
|
||||
// FIXME - read pc via function call instead!
|
||||
if (CPU_state.pc.flags & target.flags & MVALUE_DEFINED) {
|
||||
if (CPU_state.pc.flags & target.flags & NUMBER_IS_DEFINED) {
|
||||
if ((target.val.intval | 0xffff) != 0xffff) {
|
||||
not_in_bank(target.val.intval);
|
||||
} else {
|
||||
@ -749,13 +744,13 @@ static void near_branch(int preoffset)
|
||||
// helper function for relative addressing with 16-bit offset
|
||||
static void far_branch(int preoffset)
|
||||
{
|
||||
struct result target;
|
||||
struct number target;
|
||||
intval_t offset = 0; // dummy value, to not throw more errors than necessary
|
||||
|
||||
ALU_int_result(&target); // FIXME - check for outermost parentheses and raise error!
|
||||
typesystem_want_addr(&target);
|
||||
// FIXME - read pc via function call instead!
|
||||
if (CPU_state.pc.flags & target.flags & MVALUE_DEFINED) {
|
||||
if (CPU_state.pc.flags & target.flags & NUMBER_IS_DEFINED) {
|
||||
if ((target.val.intval | 0xffff) != 0xffff) {
|
||||
not_in_bank(target.val.intval);
|
||||
} else {
|
||||
@ -769,7 +764,7 @@ static void far_branch(int preoffset)
|
||||
|
||||
// set addressing mode bits depending on which opcodes exist, then calculate
|
||||
// argument size and output both opcode and argument
|
||||
static void make_command(int force_bit, struct result *result, unsigned long opcodes)
|
||||
static void make_command(int force_bit, struct number *result, unsigned long opcodes)
|
||||
{
|
||||
int addressing_modes = MAYBE______;
|
||||
|
||||
@ -780,15 +775,15 @@ static void make_command(int force_bit, struct result *result, unsigned long opc
|
||||
if (opcodes & 0xff0000)
|
||||
addressing_modes |= MAYBE_____3;
|
||||
switch (calc_arg_size(force_bit, result, addressing_modes)) {
|
||||
case MVALUE_FORCE08:
|
||||
case NUMBER_FORCES_8:
|
||||
Output_byte(opcodes & 255);
|
||||
output_8(result->val.intval);
|
||||
break;
|
||||
case MVALUE_FORCE16:
|
||||
case NUMBER_FORCES_16:
|
||||
Output_byte((opcodes >> 8) & 255);
|
||||
output_le16(result->val.intval);
|
||||
break;
|
||||
case MVALUE_FORCE24:
|
||||
case NUMBER_FORCES_24:
|
||||
Output_byte((opcodes >> 16) & 255);
|
||||
output_le24(result->val.intval);
|
||||
}
|
||||
@ -823,16 +818,16 @@ static unsigned int imm_ops(int *force_bit, unsigned char opcode, int immediate_
|
||||
|
||||
// check force bits - if no force bits given, use cpu state and convert to force bit
|
||||
if (*force_bit == 0)
|
||||
*force_bit = long_register ? MVALUE_FORCE16 : MVALUE_FORCE08;
|
||||
*force_bit = long_register ? NUMBER_FORCES_16 : NUMBER_FORCES_8;
|
||||
// return identical opcodes for single-byte and two-byte arguments:
|
||||
return (((unsigned int) opcode) << 8) | opcode;
|
||||
}
|
||||
|
||||
// helper function to warn if zp pointer wraps around
|
||||
static void check_zp_wraparound(struct result *result)
|
||||
static void check_zp_wraparound(struct number *result)
|
||||
{
|
||||
if ((result->val.intval == 0xff)
|
||||
&& (result->flags & MVALUE_DEFINED))
|
||||
&& (result->flags & NUMBER_IS_DEFINED))
|
||||
Throw_warning("Zeropage pointer wraps around from $ff to $00");
|
||||
}
|
||||
|
||||
@ -841,7 +836,7 @@ static void check_zp_wraparound(struct result *result)
|
||||
static void group_main(int index, int immediate_mode)
|
||||
{
|
||||
unsigned long immediate_opcodes;
|
||||
struct result result;
|
||||
struct number result;
|
||||
int force_bit = Input_get_force_bit(); // skips spaces after
|
||||
|
||||
switch (get_argument(&result)) {
|
||||
@ -896,7 +891,7 @@ static void group_main(int index, int immediate_mode)
|
||||
static void group_misc(int index, int immediate_mode)
|
||||
{
|
||||
unsigned long immediate_opcodes;
|
||||
struct result result;
|
||||
struct number result;
|
||||
int force_bit = Input_get_force_bit(); // skips spaces after
|
||||
|
||||
switch (get_argument(&result)) {
|
||||
@ -914,7 +909,7 @@ static void group_misc(int index, int immediate_mode)
|
||||
// check whether to warn about 6510's unstable ANE/LXA
|
||||
if ((CPU_state.type->flags & CPUFLAG_8B_AND_AB_NEED_0_ARG)
|
||||
&& ((result.val.intval & 0xff) != 0x00)
|
||||
&& (result.flags & MVALUE_DEFINED)) {
|
||||
&& (result.flags & NUMBER_IS_DEFINED)) {
|
||||
if (immediate_opcodes == 0x8b)
|
||||
Throw_warning("Assembling unstable ANE #NONZERO instruction");
|
||||
else if (immediate_opcodes == 0xab)
|
||||
@ -945,7 +940,7 @@ static void group_std_branches(int opcode)
|
||||
// "bbr0..7" and "bbs0..7"
|
||||
static void group_bbr_bbs(int opcode)
|
||||
{
|
||||
struct result zpmem;
|
||||
struct number zpmem;
|
||||
|
||||
ALU_int_result(&zpmem); // FIXME - check for outermost parentheses and raise error!
|
||||
typesystem_want_addr(&zpmem);
|
||||
@ -968,7 +963,7 @@ static void group_relative16(int opcode, int preoffset)
|
||||
// "mvn" and "mvp"
|
||||
static void group_mvn_mvp(int opcode)
|
||||
{
|
||||
struct result source,
|
||||
struct number source,
|
||||
target;
|
||||
|
||||
// assembler syntax: "mnemonic source, target"
|
||||
@ -990,7 +985,7 @@ static void group_mvn_mvp(int opcode)
|
||||
// "rmb0..7" and "smb0..7"
|
||||
static void group_only_zp(int opcode)
|
||||
{
|
||||
struct result target;
|
||||
struct number target;
|
||||
|
||||
ALU_int_result(&target); // FIXME - check for outermost parentheses and raise error!
|
||||
typesystem_want_addr(&target);
|
||||
@ -1002,7 +997,7 @@ static void group_only_zp(int opcode)
|
||||
// The jump instructions.
|
||||
static void group_jump(int index)
|
||||
{
|
||||
struct result result;
|
||||
struct number result;
|
||||
int force_bit = Input_get_force_bit(); // skips spaces after
|
||||
|
||||
switch (get_argument(&result)) {
|
||||
@ -1013,7 +1008,7 @@ static void group_jump(int index)
|
||||
make_command(force_bit, &result, jump_ind[index]);
|
||||
// check whether to warn about 6502's JMP() bug
|
||||
if (((result.val.intval & 0xff) == 0xff)
|
||||
&& (result.flags & MVALUE_DEFINED)
|
||||
&& (result.flags & NUMBER_IS_DEFINED)
|
||||
&& (CPU_state.type->flags & CPUFLAG_INDIRECTJMPBUGGY))
|
||||
Throw_warning("Assembling buggy JMP($xxff) instruction");
|
||||
break;
|
||||
|
@ -573,7 +573,7 @@ void vcpu_set_pc(intval_t new_pc, int segment_flags)
|
||||
|
||||
new_offset = (new_pc - CPU_state.pc.val.intval) & 0xffff;
|
||||
CPU_state.pc.val.intval = new_pc;
|
||||
CPU_state.pc.flags |= MVALUE_DEFINED; // FIXME - remove when allowing undefined!
|
||||
CPU_state.pc.flags |= NUMBER_IS_DEFINED; // FIXME - remove when allowing undefined!
|
||||
CPU_state.pc.addr_refs = 1; // yes, PC counts as address
|
||||
// now tell output buffer to start a new segment
|
||||
Output_start_segment(new_offset, segment_flags);
|
||||
@ -609,7 +609,7 @@ Maybe like this:
|
||||
|
||||
|
||||
// get program counter
|
||||
void vcpu_read_pc(struct result *target)
|
||||
void vcpu_read_pc(struct number *target)
|
||||
{
|
||||
*target = CPU_state.pc;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
|
||||
// Copyright (C) 1998-2016 Marco Baye
|
||||
// Copyright (C) 1998-2020 Marco Baye
|
||||
// Have a look at "acme.c" for further info
|
||||
//
|
||||
// Output stuff (FIXME - split into outbuf, outfile/format and vcpu parts)
|
||||
@ -19,10 +19,10 @@
|
||||
|
||||
|
||||
// current CPU state
|
||||
// FIXME - move vcpu struct definition to .c file and change other .c files' accesses to fn calls
|
||||
// FIXME - move vcpu struct definition to .c file and change other .c files' accesses to fn calls. then replace "struct number" with minimized version.
|
||||
struct vcpu {
|
||||
const struct cpu_type *type; // current CPU type (default 6502) (FIXME - move out of struct again?)
|
||||
struct result pc; // current program counter (pseudo value)
|
||||
struct number pc; // current program counter (pseudo value)
|
||||
int add_to_pc; // add to PC after statement
|
||||
int a_is_long;
|
||||
int xy_are_long;
|
||||
@ -93,7 +93,7 @@ extern void output_set_xor(char xor);
|
||||
// set program counter to defined value (TODO - allow undefined!)
|
||||
extern void vcpu_set_pc(intval_t new_pc, int flags);
|
||||
// get program counter
|
||||
extern void vcpu_read_pc(struct result *target);
|
||||
extern void vcpu_read_pc(struct number *target);
|
||||
// get size of current statement (until now) - needed for "!bin" verbose output
|
||||
extern int vcpu_get_statement_size(void);
|
||||
// adjust program counter (called at end of each statement)
|
||||
|
@ -48,7 +48,7 @@ static struct ronode *pseudo_opcode_tree = NULL; // tree to hold pseudo opcodes
|
||||
void notreallypo_setpc(void)
|
||||
{
|
||||
int segment_flags = 0;
|
||||
struct result intresult;
|
||||
struct number intresult;
|
||||
|
||||
ALU_defined_int(&intresult); // read new address
|
||||
// check for modifiers
|
||||
@ -79,7 +79,7 @@ void notreallypo_setpc(void)
|
||||
// define default value for empty memory ("!initmem" pseudo opcode)
|
||||
static enum eos po_initmem(void)
|
||||
{
|
||||
struct result intresult;
|
||||
struct number intresult;
|
||||
|
||||
// ignore in all passes but in first
|
||||
if (pass_count)
|
||||
@ -479,7 +479,7 @@ static enum eos po_binary(void)
|
||||
// reserve space by sending bytes of given value ("!fi" / "!fill" pseudo opcode)
|
||||
static enum eos po_fill(void)
|
||||
{
|
||||
struct result sizeresult;
|
||||
struct number sizeresult;
|
||||
intval_t fill = FILLVALUE_FILL;
|
||||
|
||||
ALU_defined_int(&sizeresult); // FIXME - forbid addresses!
|
||||
@ -496,7 +496,7 @@ static enum eos po_fill(void)
|
||||
// (...and it will be needed in future for assemble-to-end-address)
|
||||
static enum eos po_skip(void) // now GotByte = illegal char
|
||||
{
|
||||
struct result amount;
|
||||
struct number amount;
|
||||
|
||||
ALU_defined_int(&amount); // FIXME - forbid addresses!
|
||||
if (amount.val.intval < 0)
|
||||
@ -511,15 +511,15 @@ static enum eos po_skip(void) // now GotByte = illegal char
|
||||
static enum eos po_align(void)
|
||||
{
|
||||
// FIXME - read cpu state via function call!
|
||||
struct result andresult,
|
||||
struct number andresult,
|
||||
equalresult;
|
||||
intval_t fill,
|
||||
test = CPU_state.pc.val.intval;
|
||||
|
||||
// make sure PC is defined.
|
||||
if ((CPU_state.pc.flags & MVALUE_DEFINED) == 0) {
|
||||
if ((CPU_state.pc.flags & NUMBER_IS_DEFINED) == 0) {
|
||||
Throw_error(exception_pc_undefined);
|
||||
CPU_state.pc.flags |= MVALUE_DEFINED; // do not complain again
|
||||
CPU_state.pc.flags |= NUMBER_IS_DEFINED; // do not complain again
|
||||
return SKIP_REMAINDER;
|
||||
}
|
||||
|
||||
@ -549,7 +549,7 @@ static const char Error_old_offset_assembly[] =
|
||||
static enum eos po_pseudopc(void)
|
||||
{
|
||||
// FIXME - read pc using a function call!
|
||||
struct result new_pc_result;
|
||||
struct number new_pc_result;
|
||||
intval_t new_offset;
|
||||
int outer_flags = CPU_state.pc.flags;
|
||||
|
||||
@ -557,7 +557,7 @@ static enum eos po_pseudopc(void)
|
||||
ALU_defined_int(&new_pc_result); // FIXME - allow for undefined! (complaining about non-addresses would be logical, but annoying)
|
||||
new_offset = (new_pc_result.val.intval - CPU_state.pc.val.intval) & 0xffff;
|
||||
CPU_state.pc.val.intval = new_pc_result.val.intval;
|
||||
CPU_state.pc.flags |= MVALUE_DEFINED; // FIXME - remove when allowing undefined!
|
||||
CPU_state.pc.flags |= NUMBER_IS_DEFINED; // FIXME - remove when allowing undefined!
|
||||
// TODO - accept ", name=SECTIONNAME"
|
||||
// if there's a block, parse that and then restore old value!
|
||||
if (Parse_optional_block()) {
|
||||
@ -663,7 +663,7 @@ Throw_serious_error("Not yet"); // FIXME
|
||||
// (re)set symbol
|
||||
static enum eos po_set(void) // now GotByte = illegal char
|
||||
{
|
||||
struct result result;
|
||||
struct number result;
|
||||
int force_bit;
|
||||
struct symbol *symbol;
|
||||
scope_t scope;
|
||||
@ -683,10 +683,10 @@ static enum eos po_set(void) // now GotByte = illegal char
|
||||
GetByte(); // proceed with next char
|
||||
ALU_any_result(&result);
|
||||
// clear symbol's force bits and set new ones
|
||||
symbol->result.flags &= ~(MVALUE_FORCEBITS | MVALUE_ISBYTE);
|
||||
symbol->result.flags &= ~(NUMBER_FORCEBITS | NUMBER_FITS_BYTE);
|
||||
if (force_bit) {
|
||||
symbol->result.flags |= force_bit;
|
||||
result.flags &= ~(MVALUE_FORCEBITS | MVALUE_ISBYTE);
|
||||
result.flags &= ~(NUMBER_FORCEBITS | NUMBER_FITS_BYTE);
|
||||
}
|
||||
symbol_set_value(symbol, &result, TRUE);
|
||||
return ENSURE_EOS;
|
||||
@ -813,7 +813,7 @@ static enum eos po_source(void) // now GotByte = illegal char
|
||||
// conditional assembly ("!if"). has to be re-entrant.
|
||||
static enum eos po_if(void) // now GotByte = illegal char
|
||||
{
|
||||
struct result cond_result;
|
||||
struct number cond_result;
|
||||
|
||||
ALU_defined_int(&cond_result);
|
||||
if (GotByte != CHAR_SOB)
|
||||
@ -840,7 +840,7 @@ static enum eos ifdef_ifndef(int is_ifndef) // now GotByte = illegal char
|
||||
// in first pass, count usage
|
||||
if (pass_count == 0)
|
||||
symbol->usage++;
|
||||
if (symbol->result.flags & MVALUE_DEFINED)
|
||||
if (symbol->result.flags & NUMBER_IS_DEFINED)
|
||||
defined = TRUE;
|
||||
}
|
||||
SKIPSPACE();
|
||||
@ -876,7 +876,7 @@ static enum eos po_for(void) // now GotByte = illegal char
|
||||
{
|
||||
scope_t scope;
|
||||
int force_bit;
|
||||
struct result intresult;
|
||||
struct number intresult;
|
||||
struct for_loop loop;
|
||||
|
||||
if (Input_read_scope_and_keyword(&scope) == 0) // skips spaces before
|
||||
@ -1003,7 +1003,7 @@ static struct dynabuf *user_message; // dynamic buffer (!warn/error/serious)
|
||||
// helper function to show user-defined messages
|
||||
static enum eos throw_string(const char prefix[], void (*fn)(const char *))
|
||||
{
|
||||
struct result result;
|
||||
struct number result;
|
||||
|
||||
DYNABUF_CLEAR(user_message);
|
||||
DynaBuf_add_string(user_message, prefix);
|
||||
@ -1023,9 +1023,9 @@ static enum eos throw_string(const char prefix[], void (*fn)(const char *))
|
||||
} else {
|
||||
// parse value
|
||||
ALU_any_result(&result);
|
||||
if (result.flags & MVALUE_IS_FP) {
|
||||
if (result.flags & NUMBER_IS_FLOAT) {
|
||||
// floating point
|
||||
if (result.flags & MVALUE_DEFINED) {
|
||||
if (result.flags & NUMBER_IS_DEFINED) {
|
||||
char buffer[40];
|
||||
|
||||
// write up to 30 significant characters.
|
||||
@ -1038,7 +1038,7 @@ static enum eos throw_string(const char prefix[], void (*fn)(const char *))
|
||||
}
|
||||
} else {
|
||||
// integer
|
||||
if (result.flags & MVALUE_DEFINED) {
|
||||
if (result.flags & NUMBER_IS_DEFINED) {
|
||||
char buffer[32]; // 11 for dec, 8 for hex
|
||||
|
||||
sprintf(buffer, "%ld (0x%lx)", (long) result.val.intval, (long) result.val.intval);
|
||||
|
64
src/symbol.c
64
src/symbol.c
@ -35,27 +35,27 @@ static void dump_one_symbol(struct rwnode *node, FILE *fd)
|
||||
&& symbol->result.addr_refs == 1)
|
||||
fprintf(fd, "!addr");
|
||||
fprintf(fd, "\t%s", node->id_string);
|
||||
switch (symbol->result.flags & MVALUE_FORCEBITS) {
|
||||
case MVALUE_FORCE16:
|
||||
switch (symbol->result.flags & NUMBER_FORCEBITS) {
|
||||
case NUMBER_FORCES_16:
|
||||
fprintf(fd, "+2\t= ");
|
||||
break;
|
||||
case MVALUE_FORCE16 | MVALUE_FORCE24:
|
||||
case NUMBER_FORCES_16 | NUMBER_FORCES_24:
|
||||
/*FALLTHROUGH*/
|
||||
case MVALUE_FORCE24:
|
||||
case NUMBER_FORCES_24:
|
||||
fprintf(fd, "+3\t= ");
|
||||
break;
|
||||
default:
|
||||
fprintf(fd, "\t= ");
|
||||
}
|
||||
if (symbol->result.flags & MVALUE_DEFINED) {
|
||||
if (symbol->result.flags & MVALUE_IS_FP)
|
||||
if (symbol->result.flags & NUMBER_IS_DEFINED) {
|
||||
if (symbol->result.flags & NUMBER_IS_FLOAT)
|
||||
fprintf(fd, "%.30f", symbol->result.val.fpval); //FIXME %g
|
||||
else
|
||||
fprintf(fd, "$%x", (unsigned) symbol->result.val.intval);
|
||||
} else {
|
||||
fprintf(fd, " ?"); // TODO - maybe write "UNDEFINED" instead? then the file could at least be parsed without errors
|
||||
}
|
||||
if (symbol->result.flags & MVALUE_UNSURE)
|
||||
if (symbol->result.flags & NUMBER_EVER_UNDEFINED)
|
||||
fprintf(fd, "\t; ?"); // TODO - write "forward" instead?
|
||||
if (symbol->usage == 0)
|
||||
fprintf(fd, "\t; unused");
|
||||
@ -69,8 +69,8 @@ static void dump_vice_address(struct rwnode *node, FILE *fd)
|
||||
struct symbol *symbol = node->body;
|
||||
|
||||
// dump address symbols even if they are not used
|
||||
if ((symbol->result.flags & MVALUE_DEFINED)
|
||||
&& !(symbol->result.flags & MVALUE_IS_FP)
|
||||
if ((symbol->result.flags & NUMBER_IS_DEFINED)
|
||||
&& !(symbol->result.flags & NUMBER_IS_FLOAT)
|
||||
&& (symbol->result.addr_refs == 1))
|
||||
fprintf(fd, "al C:%04x .%s\n", (unsigned) symbol->result.val.intval, node->id_string);
|
||||
}
|
||||
@ -80,8 +80,8 @@ static void dump_vice_usednonaddress(struct rwnode *node, FILE *fd)
|
||||
|
||||
// dump non-addresses that are used
|
||||
if (symbol->usage
|
||||
&& (symbol->result.flags & MVALUE_DEFINED)
|
||||
&& !(symbol->result.flags & MVALUE_IS_FP)
|
||||
&& (symbol->result.flags & NUMBER_IS_DEFINED)
|
||||
&& !(symbol->result.flags & NUMBER_IS_FLOAT)
|
||||
&& (symbol->result.addr_refs != 1))
|
||||
fprintf(fd, "al C:%04x .%s\n", (unsigned) symbol->result.val.intval, node->id_string);
|
||||
}
|
||||
@ -91,8 +91,8 @@ static void dump_vice_unusednonaddress(struct rwnode *node, FILE *fd)
|
||||
|
||||
// dump non-addresses that are unused
|
||||
if (!symbol->usage
|
||||
&& (symbol->result.flags & MVALUE_DEFINED)
|
||||
&& !(symbol->result.flags & MVALUE_IS_FP)
|
||||
&& (symbol->result.flags & NUMBER_IS_DEFINED)
|
||||
&& !(symbol->result.flags & NUMBER_IS_FLOAT)
|
||||
&& (symbol->result.addr_refs != 1))
|
||||
fprintf(fd, "al C:%04x .%s\n", (unsigned) symbol->result.val.intval, node->id_string);
|
||||
}
|
||||
@ -105,7 +105,7 @@ struct symbol *symbol_find(scope_t scope, int flags)
|
||||
struct rwnode *node;
|
||||
struct symbol *symbol;
|
||||
int node_created,
|
||||
force_bits = flags & MVALUE_FORCEBITS;
|
||||
force_bits = flags & NUMBER_FORCEBITS;
|
||||
|
||||
node_created = Tree_hard_scan(&node, symbols_forest, scope, TRUE);
|
||||
// if node has just been created, create symbol as well
|
||||
@ -115,7 +115,7 @@ struct symbol *symbol_find(scope_t scope, int flags)
|
||||
// finish empty symbol item
|
||||
symbol->result.flags = flags;
|
||||
symbol->result.addr_refs = 0;
|
||||
if (flags & MVALUE_IS_FP)
|
||||
if (flags & NUMBER_IS_FLOAT)
|
||||
symbol->result.val.fpval = 0;
|
||||
else
|
||||
symbol->result.val.intval = 0;
|
||||
@ -127,7 +127,7 @@ struct symbol *symbol_find(scope_t scope, int flags)
|
||||
}
|
||||
// make sure the force bits don't clash
|
||||
if ((node_created == FALSE) && force_bits)
|
||||
if ((symbol->result.flags & MVALUE_FORCEBITS) != force_bits)
|
||||
if ((symbol->result.flags & NUMBER_FORCEBITS) != force_bits)
|
||||
Throw_error("Too late for postfix.");
|
||||
return symbol;
|
||||
}
|
||||
@ -135,16 +135,16 @@ struct symbol *symbol_find(scope_t scope, int flags)
|
||||
|
||||
// assign value to symbol. the function acts upon the symbol's flag bits and
|
||||
// produces an error if needed.
|
||||
void symbol_set_value(struct symbol *symbol, struct result *new_value, int change_allowed)
|
||||
void symbol_set_value(struct symbol *symbol, struct number *new_value, int change_allowed)
|
||||
{
|
||||
int oldflags = symbol->result.flags;
|
||||
|
||||
// value stuff
|
||||
if ((oldflags & MVALUE_DEFINED) && (change_allowed == FALSE)) {
|
||||
if ((oldflags & NUMBER_IS_DEFINED) && (change_allowed == FALSE)) {
|
||||
// symbol is already defined, so compare new and old values
|
||||
// if different type OR same type but different value, complain
|
||||
if (((oldflags ^ new_value->flags) & MVALUE_IS_FP)
|
||||
|| ((oldflags & MVALUE_IS_FP) ? (symbol->result.val.fpval != new_value->val.fpval) : (symbol->result.val.intval != new_value->val.intval)))
|
||||
if (((oldflags ^ new_value->flags) & NUMBER_IS_FLOAT)
|
||||
|| ((oldflags & NUMBER_IS_FLOAT) ? (symbol->result.val.fpval != new_value->val.fpval) : (symbol->result.val.intval != new_value->val.intval)))
|
||||
Throw_error("Symbol already defined.");
|
||||
} else {
|
||||
// symbol is not defined yet OR redefinitions are allowed
|
||||
@ -152,15 +152,15 @@ void symbol_set_value(struct symbol *symbol, struct result *new_value, int chang
|
||||
}
|
||||
// flags stuff
|
||||
// Ensure that "unsure" symbols without "isByte" state don't get that
|
||||
if ((oldflags & (MVALUE_UNSURE | MVALUE_ISBYTE)) == MVALUE_UNSURE)
|
||||
new_value->flags &= ~MVALUE_ISBYTE;
|
||||
if ((oldflags & (NUMBER_EVER_UNDEFINED | NUMBER_FITS_BYTE)) == NUMBER_EVER_UNDEFINED)
|
||||
new_value->flags &= ~NUMBER_FITS_BYTE;
|
||||
if (change_allowed) {
|
||||
oldflags = (oldflags & MVALUE_UNSURE) | new_value->flags;
|
||||
oldflags = (oldflags & NUMBER_EVER_UNDEFINED) | new_value->flags;
|
||||
} else {
|
||||
if ((oldflags & MVALUE_FORCEBITS) == 0)
|
||||
if ((oldflags & (MVALUE_UNSURE | MVALUE_DEFINED)) == 0)
|
||||
oldflags |= new_value->flags & MVALUE_FORCEBITS;
|
||||
oldflags |= new_value->flags & ~MVALUE_FORCEBITS;
|
||||
if ((oldflags & NUMBER_FORCEBITS) == 0)
|
||||
if ((oldflags & (NUMBER_EVER_UNDEFINED | NUMBER_IS_DEFINED)) == 0)
|
||||
oldflags |= new_value->flags & NUMBER_FORCEBITS;
|
||||
oldflags |= new_value->flags & ~NUMBER_FORCEBITS;
|
||||
}
|
||||
symbol->result.flags = oldflags;
|
||||
}
|
||||
@ -170,7 +170,7 @@ void symbol_set_value(struct symbol *symbol, struct result *new_value, int chang
|
||||
// name must be held in GlobalDynaBuf.
|
||||
void symbol_set_label(scope_t scope, int stat_flags, int force_bit, int change_allowed)
|
||||
{
|
||||
struct result pc,
|
||||
struct number pc,
|
||||
result;
|
||||
struct symbol *symbol;
|
||||
|
||||
@ -179,7 +179,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)
|
||||
Throw_first_pass_warning("Label name not in leftmost column.");
|
||||
vcpu_read_pc(&pc);
|
||||
result.flags = pc.flags & MVALUE_DEFINED;
|
||||
result.flags = pc.flags & NUMBER_IS_DEFINED;
|
||||
result.val.intval = pc.val.intval;
|
||||
result.addr_refs = pc.addr_refs;
|
||||
symbol_set_value(symbol, &result, change_allowed);
|
||||
@ -193,7 +193,7 @@ void symbol_set_label(scope_t scope, int stat_flags, int force_bit, int change_a
|
||||
// name must be held in GlobalDynaBuf.
|
||||
void symbol_parse_definition(scope_t scope, int stat_flags)
|
||||
{
|
||||
struct result result;
|
||||
struct number result;
|
||||
struct symbol *symbol;
|
||||
int force_bit = Input_get_force_bit(); // skips spaces after
|
||||
// FIXME - force bit is allowed for label definitions?!
|
||||
@ -219,10 +219,10 @@ void symbol_parse_definition(scope_t scope, int stat_flags)
|
||||
// Name must be held in GlobalDynaBuf.
|
||||
void symbol_define(intval_t value)
|
||||
{
|
||||
struct result result;
|
||||
struct number result;
|
||||
struct symbol *symbol;
|
||||
|
||||
result.flags = MVALUE_DEFINED;
|
||||
result.flags = NUMBER_IS_DEFINED;
|
||||
result.val.intval = value;
|
||||
symbol = symbol_find(SCOPE_GLOBAL, 0);
|
||||
symbol_set_value(symbol, &result, TRUE);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
|
||||
// Copyright (C) 1998-2017 Marco Baye
|
||||
// Copyright (C) 1998-2020 Marco Baye
|
||||
// Have a look at "acme.c" for further info
|
||||
//
|
||||
// symbol stuff
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
struct symbol {
|
||||
struct result result; // expression flags and value
|
||||
struct number result; // flags, value, address refs
|
||||
int usage; // usage count
|
||||
int pass; // pass of creation (for anon counters)
|
||||
// add flag to indicate "has already been reported as undefined"
|
||||
@ -29,7 +29,7 @@ extern struct rwnode *symbols_forest[]; // trees (because of 8-bit hash)
|
||||
|
||||
|
||||
// function acts upon the symbol's flag bits and produces an error if needed.
|
||||
extern void symbol_set_value(struct symbol *symbol, struct result *new_value, int change_allowed);
|
||||
extern void symbol_set_value(struct symbol *symbol, struct number *new_value, int change_allowed);
|
||||
// parse label definition (can be either global or local).
|
||||
// name must be held in GlobalDynaBuf.
|
||||
extern void symbol_set_label(scope_t scope, int stat_flags, int force_bit, int change_allowed);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
|
||||
// Copyright (C) 1998-2017 Marco Baye
|
||||
// Copyright (C) 1998-2020 Marco Baye
|
||||
// Have a look at "acme.c" for further info
|
||||
//
|
||||
// type system stuff
|
||||
@ -33,23 +33,27 @@ void typesystem_force_address_statement(int value)
|
||||
in_address_statement = value;
|
||||
}
|
||||
|
||||
void typesystem_want_imm(struct result *result)
|
||||
void typesystem_want_imm(struct number *result)
|
||||
{
|
||||
if (!config.warn_on_type_mismatch)
|
||||
return;
|
||||
if (!(result->flags & MVALUE_DEFINED))
|
||||
|
||||
if (!(result->flags & NUMBER_IS_DEFINED))
|
||||
return;
|
||||
|
||||
if (result->addr_refs != 0) {
|
||||
Throw_warning("Wrong type - expected integer.");
|
||||
//printf("refcount should be 0, but is %d\n", result->addr_refs);
|
||||
}
|
||||
}
|
||||
void typesystem_want_addr(struct result *result)
|
||||
void typesystem_want_addr(struct number *result)
|
||||
{
|
||||
if (!config.warn_on_type_mismatch)
|
||||
return;
|
||||
if (!(result->flags & MVALUE_DEFINED))
|
||||
|
||||
if (!(result->flags & NUMBER_IS_DEFINED))
|
||||
return;
|
||||
|
||||
if (result->addr_refs != 1) {
|
||||
Throw_warning("Wrong type - expected address.");
|
||||
//printf("refcount should be 1, but is %d\n", result->addr_refs);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
|
||||
// Copyright (C) 1998-2016 Marco Baye
|
||||
// Copyright (C) 1998-2020 Marco Baye
|
||||
// Have a look at "acme.c" for further info
|
||||
//
|
||||
// Type system stuff
|
||||
@ -17,9 +17,9 @@ extern void typesystem_force_address_block(void);
|
||||
// force address mode on or off for the next statement
|
||||
extern void typesystem_force_address_statement(int value);
|
||||
// warn if result is not integer
|
||||
extern void typesystem_want_imm(struct result *result);
|
||||
extern void typesystem_want_imm(struct number *result);
|
||||
// warn if result is not address
|
||||
extern void typesystem_want_addr(struct result *result);
|
||||
extern void typesystem_want_addr(struct number *result);
|
||||
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user