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:
marcobaye 2020-04-28 16:02:09 +00:00
parent 0a4c13bb2e
commit 669f95c238
14 changed files with 265 additions and 266 deletions

234
src/alu.c
View File

@ -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();
}

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)
};

View File

@ -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;

View File

@ -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;
}

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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