diff --git a/src/alu.c b/src/alu.c index 50b0b73..292404f 100644 --- a/src/alu.c +++ b/src/alu.c @@ -1545,31 +1545,6 @@ boolean ALU_optional_defined_int(intval_t *target) // ACCEPT_EMPTY } -// Store int value and flags (floats are transformed to int) -// For empty expressions, an error is thrown. -// OPEN_PARENTHESIS: complain -// EMPTY: complain -// UNDEFINED: allow -// FLOAT: convert to int -void ALU_int_result(struct number *intresult) // ACCEPT_UNDEFINED -{ - struct expression expression; - - parse_expression(&expression); - *intresult = expression.number; - if (expression.open_parentheses) - Throw_error(exception_paren_open); - // make sure result is not float - if (intresult->flags & NUMBER_IS_FLOAT) { - intresult->val.intval = intresult->val.fpval; - intresult->flags &= ~NUMBER_IS_FLOAT; - } - if (expression.is_empty) - Throw_error(exception_no_value); - // FIXME - add warning for unneeded "()" -} - - // return int value (if undefined, return zero) // For empty expressions, an error is thrown. // OPEN_PARENTHESIS: complain @@ -1578,7 +1553,6 @@ void ALU_int_result(struct number *intresult) // ACCEPT_UNDEFINED // FLOAT: convert to int intval_t ALU_any_int(void) // ACCEPT_UNDEFINED { - // FIXME - replace this fn with a call to ALU_int_result() above! struct expression expression; parse_expression(&expression); @@ -1631,13 +1605,11 @@ void ALU_defined_int(struct number *intresult) // no ACCEPT constants? // FLOAT: convert to int void ALU_addrmode_int(struct expression *expression, int paren) // ACCEPT_UNDEFINED | ACCEPT_OPENPARENTHESIS { - struct number *intresult = &expression->number; - parse_expression(expression); - // make sure result is not float - if (intresult->flags & NUMBER_IS_FLOAT) { - intresult->val.intval = intresult->val.fpval; - intresult->flags &= ~NUMBER_IS_FLOAT; + // convert float to int + if (expression->number.flags & NUMBER_IS_FLOAT) { + expression->number.val.intval = expression->number.val.fpval; + expression->number.flags &= ~NUMBER_IS_FLOAT; } if (expression->open_parentheses > paren) { expression->open_parentheses = 0; @@ -1669,21 +1641,10 @@ void ALU_any_result(struct number *result) // ACCEPT_UNDEFINED | ACCEPT_FLOAT /* TODO -// stores int value and flags, allowing for one '(' too many (x-indirect addr). +// stores int value and flags, allowing for "paren" '(' too many (x-indirect addr). void ALU_addrmode_int(struct expression *expression, int paren) mnemo.c - when parsing addressing mode (except after '#' and '[') needvalue! - -// stores int value and flags (floats are transformed to int) -void ALU_int_result(struct number *intresult) - mnemo.c - when parsing address arg after '#' indirect? needvalue! - when parsing address arg after '[' indirect? needvalue! - when parsing address after near branch indirect? needvalue! - when parsing address after far branch indirect? needvalue! - when parsing address after bbrX/bbsX indirect? needvalue! - when parsing address after rmbX/smbX indirect? needvalue! - twice when parsing MVN/MVP indirect? needvalue! + when parsing addressing modes needvalue! // stores value and flags (result may be either int or float) void ALU_any_result(struct number *result) diff --git a/src/alu.h b/src/alu.h index b2c30dd..62d8105 100644 --- a/src/alu.h +++ b/src/alu.h @@ -66,8 +66,6 @@ extern boolean ALU_optional_defined_int(intval_t *target); // returns int value (0 if result was undefined) extern intval_t ALU_any_int(void); // stores int value and flags (floats are transformed to int) -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 number *intresult); // stores int value and flags, allowing for "paren" '(' too many (x-indirect addr). diff --git a/src/mnemo.c b/src/mnemo.c index 6bc1cc3..00e98bc 100644 --- a/src/mnemo.c +++ b/src/mnemo.c @@ -514,9 +514,24 @@ static int get_index(int next) return INDEX_NONE; } -// 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 number *result) + +// wrapper function to read integer argument +static void get_int_arg(struct number *result, boolean complain_about_indirect) +{ + struct expression expression; + + ALU_addrmode_int(&expression, 0); // accept 0 parentheses still open (-> complain!) + if (expression.is_parenthesized && complain_about_indirect) { + // FIXME - add warning for "there are useless (), you know this mnemonic does not have indirect addressing, right?" + // or rather raise error and be done with it? + } + *result = expression.number; +} + + +// wrapper function to detect addressing mode, and, if not IMPLIED, read arg. +// argument is stored in given result structure, addressing mode is returned. +static int get_addr_mode(struct number *result) { struct expression expression; int address_mode_bits = 0; @@ -529,12 +544,12 @@ static int get_argument(struct number *result) case '#': GetByte(); // proceed with next char address_mode_bits = AMB_IMMEDIATE; - ALU_int_result(result); - typesystem_want_imm(result); // FIXME - this is wrong for 65ce02's PHW# + get_int_arg(result, FALSE); + typesystem_want_nonaddr(result); // FIXME - this is wrong for 65ce02's PHW# break; case '[': GetByte(); // proceed with next char - ALU_int_result(result); + get_int_arg(result, FALSE); typesystem_want_addr(result); if (GotByte == ']') address_mode_bits = AMB_LONGINDIRECT | AMB_INDEX(get_index(TRUE)); @@ -542,8 +557,7 @@ static int get_argument(struct number *result) Throw_error(exception_syntax); break; default: - // liberal, to allow for "(...," - ALU_addrmode_int(&expression, 1); + ALU_addrmode_int(&expression, 1); // direct call instead of wrapper, to allow for "(...," *result = expression.number; typesystem_want_addr(result); // check for indirect addressing @@ -713,7 +727,7 @@ static void near_branch(int preoffset) 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! + get_int_arg(&target, TRUE); typesystem_want_addr(&target); // FIXME - read pc via function call instead! if (CPU_state.pc.flags & target.flags & NUMBER_IS_DEFINED) { @@ -747,7 +761,7 @@ static void far_branch(int preoffset) 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! + get_int_arg(&target, TRUE); typesystem_want_addr(&target); // FIXME - read pc via function call instead! if (CPU_state.pc.flags & target.flags & NUMBER_IS_DEFINED) { @@ -839,7 +853,7 @@ static void group_main(int index, int immediate_mode) struct number result; int force_bit = Input_get_force_bit(); // skips spaces after - switch (get_argument(&result)) { + switch (get_addr_mode(&result)) { case IMMEDIATE_ADDRESSING: // #$ff or #$ffff (depending on accu length) immediate_opcodes = imm_ops(&force_bit, accu_imm[index], immediate_mode); // CAUTION - do not incorporate the line above into the line @@ -894,7 +908,7 @@ static void group_misc(int index, int immediate_mode) struct number result; int force_bit = Input_get_force_bit(); // skips spaces after - switch (get_argument(&result)) { + switch (get_addr_mode(&result)) { case IMPLIED_ADDRESSING: // implied addressing if (misc_impl[index]) Output_byte(misc_impl[index]); @@ -942,7 +956,7 @@ static void group_bbr_bbs(int opcode) { struct number zpmem; - ALU_int_result(&zpmem); // FIXME - check for outermost parentheses and raise error! + get_int_arg(&zpmem, TRUE); typesystem_want_addr(&zpmem); if (Input_accept_comma()) { Output_byte(opcode); @@ -961,17 +975,18 @@ static void group_relative16(int opcode, int preoffset) } // "mvn" and "mvp" +// TODO - allow alternative syntax with '#' and 24-bit addresses (select via CLI switch) static void group_mvn_mvp(int opcode) { struct number source, target; // assembler syntax: "mnemonic source, target" - ALU_int_result(&source); // FIXME - check for outermost parentheses and raise error! - typesystem_want_imm(&source); + get_int_arg(&source, TRUE); + typesystem_want_nonaddr(&source); if (Input_accept_comma()) { - ALU_int_result(&target); // FIXME - check for outermost parentheses and raise error! - typesystem_want_imm(&target); + get_int_arg(&target, TRUE); + typesystem_want_nonaddr(&target); // machine language order: "opcode target source" Output_byte(opcode); output_8(target.val.intval); @@ -987,7 +1002,7 @@ static void group_only_zp(int opcode) { struct number target; - ALU_int_result(&target); // FIXME - check for outermost parentheses and raise error! + get_int_arg(&target, TRUE); typesystem_want_addr(&target); Output_byte(opcode); output_8(target.val.intval); @@ -1000,7 +1015,7 @@ static void group_jump(int index) struct number result; int force_bit = Input_get_force_bit(); // skips spaces after - switch (get_argument(&result)) { + switch (get_addr_mode(&result)) { case ABSOLUTE_ADDRESSING: // absolute16 or absolute24 make_command(force_bit, &result, jump_abs[index]); break; diff --git a/src/typesystem.c b/src/typesystem.c index e0c4b6e..f56c7d3 100644 --- a/src/typesystem.c +++ b/src/typesystem.c @@ -37,7 +37,7 @@ void typesystem_force_address_statement(boolean value) } // warn if result is not integer -void typesystem_want_imm(struct number *result) +void typesystem_want_nonaddr(struct number *result) { if (!config.warn_on_type_mismatch) return; diff --git a/src/typesystem.h b/src/typesystem.h index 72b53ee..66a850e 100644 --- a/src/typesystem.h +++ b/src/typesystem.h @@ -17,7 +17,7 @@ extern void typesystem_force_address_block(void); // force address mode on or off for the next statement extern void typesystem_force_address_statement(boolean value); // warn if result is not integer -extern void typesystem_want_imm(struct number *result); +extern void typesystem_want_nonaddr(struct number *result); // warn if result is not address extern void typesystem_want_addr(struct number *result);