From 47f09e98040c4cf7760cefa63485a66020f13fb2 Mon Sep 17 00:00:00 2001 From: marcobaye Date: Sat, 21 Oct 2017 19:59:56 +0000 Subject: [PATCH] a bit of internal cleanup of names and comments, no change in functionality git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@92 4df02467-bbd4-4a76-a152-e7ce94205b78 --- src/alu.c | 28 ++++++++---- src/global.c | 1 + src/global.h | 1 + src/mnemo.c | 6 +-- src/output.c | 13 ++++-- src/output.h | 13 ++++-- src/pseudoopcodes.c | 108 ++++++++++++++++++++++++++++++++++++++++---- src/symbol.c | 4 +- src/version.h | 2 +- 9 files changed, 140 insertions(+), 36 deletions(-) diff --git a/src/alu.c b/src/alu.c index b259d40..4ead9b2 100644 --- a/src/alu.c +++ b/src/alu.c @@ -47,8 +47,8 @@ static const char s_arctan[] = "arctan"; // operator handles (FIXME - use function pointers instead? or too slow?) enum operator_handle { // special values (pseudo operators) - OPHANDLE_END, // "reached end of expression" - OPHANDLE_RETURN, // "return value to caller" + OPHANDLE_EXPRSTART, // "start of expression" + OPHANDLE_EXPREND, // "end of expression" // functions OPHANDLE_ADDR, // addr(v) OPHANDLE_INT, // int(v) @@ -96,8 +96,8 @@ struct operator { #define IS_RIGHT_ASSOCIATIVE(p) ((p) & 1) // lsb of priority value signals right-associtivity // operator structs (only hold handle and priority/associativity value) -static struct operator ops_end = {OPHANDLE_END, 0}; // special -static struct operator ops_return = {OPHANDLE_RETURN, 2}; // special +static struct operator ops_exprend = {OPHANDLE_EXPREND, 0}; // special +static struct operator ops_exprstart = {OPHANDLE_EXPRSTART, 2}; // special static struct operator ops_closing = {OPHANDLE_CLOSING, 4}; // dyadic static struct operator ops_opening = {OPHANDLE_OPENING, 6}; // monadic static struct operator ops_or = {OPHANDLE_OR, 8}; // dyadic @@ -749,10 +749,12 @@ static void expect_operand_or_monadic_operator(void) } } else { // illegal character read - so don't go on + // we found end-of-expression instead of an operand, + // that's either an empty expression or an erroneous one! PUSH_INTOPERAND(0, 0, 0); // push dummy operand so stack is ok // push pseudo value, EXISTS flag is clear - if (operator_stack[operator_sp - 1] == &ops_return) { - PUSH_OPERATOR(&ops_end); + if (operator_stack[operator_sp - 1] == &ops_exprstart) { + PUSH_OPERATOR(&ops_exprend); alu_state = STATE_TRY_TO_REDUCE_STACKS; } else { Throw_error(exception_syntax); @@ -905,7 +907,8 @@ static void expect_dyadic_operator(void) Throw_error("Unknown operator."); alu_state = STATE_ERROR; } else { - operator = &ops_end; + // we found end-of-expression when expecting an operator, that's ok. + operator = &ops_exprend; goto push_dyadic; } @@ -999,6 +1002,7 @@ static void ensure_int_from_fp(void) // Try to reduce stacks by performing high-priority operations +// (if the previous operator has a higher priority than the current one, do it) static void try_to_reduce_stacks(int *open_parentheses) { if (operator_sp < 2) { @@ -1019,9 +1023,13 @@ static void try_to_reduce_stacks(int *open_parentheses) return; } + // process previous operator switch (operator_stack[operator_sp - 2]->handle) { // special (pseudo) operators - case OPHANDLE_RETURN: + case OPHANDLE_EXPRSTART: + // the only operator with a lower priority than this + // "start-of-expression" operator is "end-of-expression", + // therefore we know we are done. // don't touch indirect_flag; needed for INDIRECT flag --operator_sp; // decrement operator stack pointer alu_state = STATE_END; @@ -1033,7 +1041,7 @@ static void try_to_reduce_stacks(int *open_parentheses) operator_sp -= 2; // remove both of them alu_state = STATE_EXPECT_DYADIC_OPERATOR; break; - case OPHANDLE_END: // unmatched parenthesis + case OPHANDLE_EXPREND: // unmatched parenthesis ++(*open_parentheses); // count goto RNTLObutDontTouchIndirectFlag; @@ -1399,7 +1407,7 @@ static int parse_expression(struct result *result) // begin by reading value (or monadic operator) alu_state = STATE_EXPECT_OPERAND_OR_MONADIC_OPERATOR; indirect_flag = 0; // Contains either 0 or MVALUE_INDIRECT - PUSH_OPERATOR(&ops_return); + PUSH_OPERATOR(&ops_exprstart); do { // check stack sizes. enlarge if needed if (operator_sp >= operator_stk_size) diff --git a/src/global.c b/src/global.c index af79f95..63aca02 100644 --- a/src/global.c +++ b/src/global.c @@ -47,6 +47,7 @@ const char s_scr[] = "scr"; // Exception messages during assembly const char exception_cannot_open_input_file[] = "Cannot open input file."; const char exception_missing_string[] = "No string given."; +const char exception_negative_size[] = "Negative size argument."; const char exception_no_left_brace[] = "Missing '{'."; const char exception_no_memory_left[] = "Out of memory."; const char exception_no_right_brace[] = "Found end-of-file instead of '}'."; diff --git a/src/global.h b/src/global.h index 7ec7f2d..d0fd384 100644 --- a/src/global.h +++ b/src/global.h @@ -41,6 +41,7 @@ extern const char s_scr[]; // error messages during assembly extern const char exception_cannot_open_input_file[]; extern const char exception_missing_string[]; +extern const char exception_negative_size[]; extern const char exception_no_left_brace[]; extern const char exception_no_memory_left[]; extern const char exception_no_right_brace[]; diff --git a/src/mnemo.c b/src/mnemo.c index 3f272b1..2106570 100644 --- a/src/mnemo.c +++ b/src/mnemo.c @@ -139,7 +139,7 @@ SCS jump_lind[] = { 0, 0, 0xdc00, 0, 0, 0, 0xdc0 // error message strings static const char exception_illegal_combination[] = "Illegal combination of command and addressing mode."; -static const char exception_highbyte_zero[] = "Using oversized addressing mode."; +static const char exception_oversized_addrmode[] = "Using oversized addressing mode."; // Variables @@ -584,11 +584,11 @@ static int check_oversize(int size_bit, struct result *argument) if (size_bit == MVALUE_FORCE16) { // check 16-bit argument for high byte zero if ((argument->val.intval <= 255) && (argument->val.intval >= -128)) - Throw_warning(exception_highbyte_zero); + Throw_warning(exception_oversized_addrmode); } else { // check 24-bit argument for bank byte zero if ((argument->val.intval <= 65535) && (argument->val.intval >= -32768)) - Throw_warning(exception_highbyte_zero); + Throw_warning(exception_oversized_addrmode); } return size_bit; // pass on result } diff --git a/src/output.c b/src/output.c index 67c372e..eaef19a 100644 --- a/src/output.c +++ b/src/output.c @@ -157,13 +157,16 @@ static void no_output(intval_t byte) } -// call this if really calling Output_byte would be a waste of time -// FIXME - check all users of this, because future changes -// ("several-projects-at-once") may be incompatible with this! -void Output_fake(int size) +// skip over some bytes in output buffer without starting a new segment +// (used by "!skip", and also called by "!binary" if really calling +// Output_byte would be a waste of time) +void output_skip(int size) { - if (size < 1) + if (size < 1) { + // FIXME - ok for zero, but why is there no error message + // output for negative values? return; + } // check whether ptr undefined if (Output_byte == no_output) { diff --git a/src/output.h b/src/output.h index 965319b..6f019b2 100644 --- a/src/output.h +++ b/src/output.h @@ -39,10 +39,16 @@ extern struct vcpu CPU_state; // current CPU state FIXME - restrict visibility t extern void Output_init(signed long fill_value); // clear segment list and disable output extern void Output_passinit(void); -// call this if really calling Output_byte would be a waste of time -extern void Output_fake(int size); +// skip over some bytes in output buffer without starting a new segment +// (used by "!skip", and also called by "!binary" if really calling +// Output_byte would be a waste of time) +extern void output_skip(int size); // Send low byte of arg to output buffer and advance pointer +// FIXME - replace by output_sequence(char *src, size_t size) extern void (*Output_byte)(intval_t); +// define default value for empty memory ("!initmem" pseudo opcode) +// returns zero if ok, nonzero if already set +extern int output_initmem(char content); // Output 8-bit value with range check extern void output_8(intval_t); // Output 16-bit value with range check big-endian @@ -57,9 +63,6 @@ extern void output_le24(intval_t); extern void output_be32(intval_t); // Output 32-bit value (without range check) little-endian extern void output_le32(intval_t); -// define default value for empty memory ("!initmem" pseudo opcode) -// returns zero if ok, nonzero if already set -extern int output_initmem(char content); // try to set output format held in DynaBuf. Returns zero on success. extern int outputfile_set_format(void); extern const char outputfile_formats[]; // string to show if outputfile_set_format() returns nonzero diff --git a/src/pseudoopcodes.c b/src/pseudoopcodes.c index 002fc91..9c06d67 100644 --- a/src/pseudoopcodes.c +++ b/src/pseudoopcodes.c @@ -201,6 +201,59 @@ static enum eos po_le32(void) } +#if 0 +// Insert bytes given as pairs of hex digits (helper for source code generators) +static enum eos po_hex(void) // now GotByte = illegal char +{ + int digits = 0; + unsigned char byte = 0; + + for (;;) { + if (digits == 2) { + Output_byte(byte); + digits = 0; + byte = 0; + } + if (GotByte >= '0' && GotByte <= '9') { + byte = (byte << 4) | (GotByte - '0'); + ++digits; + GetByte(); + continue; + } + if (GotByte >= 'a' && GotByte <= 'f') { + byte = (byte << 4) | (GotByte - 'a' + 10); + ++digits; + GetByte(); + continue; + } + if (GotByte >= 'A' && GotByte <= 'F') { + byte = (byte << 4) | (GotByte - 'A' + 10); + ++digits; + GetByte(); + continue; + } + // if we're here, the current character is not a hex digit, + // which ist only allowed outside of pairs: + if (digits == 1) { + Throw_error("Hex digits are not given in pairs"); + return SKIP_REMAINDER; // error exit + } + switch (GotByte) { + case ' ': + case '\t': + GetByte(); // spaces and tabs are ignored (maybe add commas, too?) + continue; + case CHAR_EOS: + return AT_EOS_ANYWAY; // normal exit + default: + Throw_error(exception_syntax); // all other characters are errors + return SKIP_REMAINDER; // error exit + } + } +} +#endif + + // "!cbm" pseudo opcode (now obsolete) static enum eos obsolete_po_cbm(void) { @@ -349,13 +402,15 @@ static enum eos po_binary(void) if (Input_accept_comma()) { if (ALU_optional_defined_int(&size) && (size < 0)) - Throw_serious_error("Negative size argument."); + Throw_serious_error(exception_negative_size); if (Input_accept_comma()) ALU_optional_defined_int(&skip); // read skip } // check whether including is a waste of time + // FIXME - future changes ("several-projects-at-once") + // may be incompatible with this! if ((size >= 0) && (pass_undefined_count || pass_real_errors)) { - Output_fake(size); // really including is useless anyway + output_skip(size); // really including is useless anyway } else { // really insert file fseek(fd, skip, SEEK_SET); // set read pointer @@ -403,6 +458,24 @@ static enum eos po_fill(void) } +#if 0 +// skip over some bytes in output without starting a new segment ("!skip" pseudo opcode) +// in contrast to "*=*+AMOUNT", "!skip AMOUNT" does not start a new segment. +// (...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; + + ALU_defined_int(&amount); // FIXME - forbid addresses! + if (amount.val.intval < 0) + Throw_serious_error(exception_negative_size); + else + output_skip(amount.val.intval); + return ENSURE_EOS; +} +#endif + + // insert byte until PC fits condition static enum eos po_align(void) { @@ -538,6 +611,19 @@ static enum eos po_address(void) // now GotByte = illegal char } +#if 0 +// enumerate constants +static enum eos po_enum(void) // now GotByte = illegal char +{ + intval_t step = 1; + + ALU_optional_defined_int(&step); +Throw_serious_error("Not yet"); // FIXME + return ENSURE_EOS; +} +#endif + + // (re)set symbol static enum eos po_set(void) // now GotByte = illegal char { @@ -600,13 +686,6 @@ static enum eos po_symbollist(void) return ENSURE_EOS; } -/* -// TODO - add "!skip AMOUNT" pseudo opcode as alternative to "* = * + AMOUNT" (needed for assemble-to-end-address) -// the new pseudo opcode would skip the given amount of bytes without starting a new segment -static enum eos po_skip(void) // now GotByte = illegal char -{ -} -*/ // switch to new zone ("!zone" or "!zn"). has to be re-entrant. static enum eos po_zone(void) @@ -847,6 +926,16 @@ static enum eos po_do(void) // now GotByte = illegal char } +#if 0 +// looping assembly (alternative for people used to c-style loops) +static enum eos po_while(void) // now GotByte = illegal char +{ +Throw_serious_error("Not yet"); // FIXME + return ENSURE_EOS; +} +#endif + + // macro definition ("!macro"). static enum eos po_macro(void) // now GotByte = illegal char { @@ -1014,7 +1103,6 @@ static struct ronode pseudo_opcode_list[] = { PREDEFNODE("set", po_set), PREDEFNODE(s_sl, po_symbollist), PREDEFNODE("symbollist", po_symbollist), -// PREDEFNODE("skip", po_skip), PREDEFNODE("zn", po_zone), PREDEFNODE(s_zone, po_zone), PREDEFNODE("sz", obsolete_po_subzone), diff --git a/src/symbol.c b/src/symbol.c index f85d69a..c3b443f 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -53,10 +53,10 @@ static void dump_one_symbol(struct rwnode *node, FILE *fd) else fprintf(fd, "$%x", (unsigned) symbol->result.val.intval); } else { - fprintf(fd, " ?"); + fprintf(fd, " ?"); // TODO - maybe write "UNDEFINED" instead? then the file could at least be parsed without errors } if (symbol->result.flags & MVALUE_UNSURE) - fprintf(fd, "\t; ?"); + fprintf(fd, "\t; ?"); // TODO - write "forward" instead? if (symbol->usage == 0) fprintf(fd, "\t; unused"); fprintf(fd, "\n"); diff --git a/src/version.h b/src/version.h index a644ad4..4c55cfb 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ #define RELEASE "0.96.2" // update before release (FIXME) #define CODENAME "Fenchurch" // update before release -#define CHANGE_DATE "10 Mar" // update before release +#define CHANGE_DATE "21 Oct" // update before release #define CHANGE_YEAR "2017" // update before release //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" // FIXME #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME