fixed bug in anonymous backward labels

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@412 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2024-08-31 20:28:50 +00:00
parent 5eba16ed6c
commit f1a80756d1
6 changed files with 42 additions and 12 deletions

View File

@ -350,9 +350,14 @@ Operation not supported: Cannot apply "OP" to "TYPE" and "TYPE".
You tried to use an operator on the wrong type(s) of argument(s), You tried to use an operator on the wrong type(s) of argument(s),
like indexing a float or negating a string. like indexing a float or negating a string.
Program counter is unset. Program counter cannot be negative.
You didn't set the program counter, so ACME didn't know where to You used "--setpc VALUE", "* = VALUE" or "!pseudopc VALUE" with a
start. negative number.
Program counter undefined.
You tried to generate data before setting the program counter. Use
either "--setpc VALUE" on the command line or "* = VALUE" at the
start of your source code file.
Quotes still open at end of line. Quotes still open at end of line.
You forgot the closing quotes. You forgot the closing quotes.
@ -511,6 +516,14 @@ Too deeply nested. Recursive "!source"?
The default limit is 64, this can be changed using the The default limit is 64, this can be changed using the
"--maxdepth" CLI switch. "--maxdepth" CLI switch.
Tried to write to negative address.
This means that a new segment inside a !pseudopc block would be
placed before the start of the output buffer. Example:
* = $1000 ; ok (we begin at $1000)
!pseudopc $8000 { ; ok (we pretend to be at $8000)
* = $5000 ; error (we need to go back by $3000,
} ; which would mean going to -$2000!)
Unexpected char when evaluating loop condition. Unexpected char when evaluating loop condition.
There was a syntax error while evaluating the loop condition. There was a syntax error while evaluating the loop condition.

View File

@ -349,7 +349,7 @@ static void is_not_defined(struct symbol *optional_symbol, char *name, size_t le
// FIXME - just split this up into two different buffers, "user name" and "internal name", that way the scope can be changed to a prefix as well! // FIXME - just split this up into two different buffers, "user name" and "internal name", that way the scope can be changed to a prefix as well!
// This function is not allowed to change DynaBuf because that's where the // This function is not allowed to change DynaBuf because that's where the
// symbol name is stored! // symbol name is stored!
static void get_symbol_value(scope_t scope, size_t name_length, unsigned int unpseudo_count) static void get_symbol_value(scope_t scope, size_t name_length, unsigned int unpseudo_count, boolean check_pass_number)
{ {
struct symbol *symbol; struct symbol *symbol;
struct object *arg; struct object *arg;
@ -365,6 +365,14 @@ static void get_symbol_value(scope_t scope, size_t name_length, unsigned int unp
} else { } else {
// FIXME - add sanity check for UNDEFINED where EVER_UNDEFINED is false -> BUG()! // FIXME - add sanity check for UNDEFINED where EVER_UNDEFINED is false -> BUG()!
// (because the only way to have UNDEFINED is the block above, and EVER_UNDEFINED taints everything it touches) // (because the only way to have UNDEFINED is the block above, and EVER_UNDEFINED taints everything it touches)
// special kluge for anonymous backward labels:
// if they are referenced before they are defined, the last
// value of the previous pass would be used! so we check the
// pass number and if the value is from the previous pass, we
// delete it:
if (check_pass_number && (symbol->pass_number != pass.number))
symbol->object.u.number.ntype = NUMTYPE_UNDEFINED;
} }
// first push on arg stack, so we have a local copy we can "unpseudo" // first push on arg stack, so we have a local copy we can "unpseudo"
arg = &arg_stack[arg_sp++]; arg = &arg_stack[arg_sp++];
@ -732,7 +740,7 @@ static int parse_octal_or_unpseudo(void) // now GotByte = '&'
if (input_read_scope_and_symbol_name(&scope)) // now GotByte = illegal char if (input_read_scope_and_symbol_name(&scope)) // now GotByte = illegal char
return 1; // error (no string given) return 1; // error (no string given)
get_symbol_value(scope, GlobalDynaBuf->size - 1, unpseudo_count); // -1 to not count terminator get_symbol_value(scope, GlobalDynaBuf->size - 1, unpseudo_count, FALSE); // -1 to not count terminator, no pass number check
// } else if (...) { // } else if (...) {
// // anonymous symbol // // anonymous symbol
// "unpseudo"-ing anonymous symbols is not supported // "unpseudo"-ing anonymous symbols is not supported
@ -908,7 +916,7 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
} while (GetByte() == '+'); } while (GetByte() == '+');
ugly_length_kluge = GlobalDynaBuf->size; // FIXME - get rid of this! ugly_length_kluge = GlobalDynaBuf->size; // FIXME - get rid of this!
symbol_fix_forward_anon_name(FALSE); // FALSE: do not increment counter symbol_fix_forward_anon_name(FALSE); // FALSE: do not increment counter
get_symbol_value(section_now->local_scope, ugly_length_kluge, 0); // no prefix, no unpseudo get_symbol_value(section_now->local_scope, ugly_length_kluge, 0, FALSE); // no prefix, no unpseudo, no pass number check
goto now_expect_dyadic_op; goto now_expect_dyadic_op;
case '-': // NEGATION operator or anonymous backward label case '-': // NEGATION operator or anonymous backward label
@ -922,7 +930,7 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
SKIPSPACE(); SKIPSPACE();
if (BYTE_FOLLOWS_ANON(GotByte)) { if (BYTE_FOLLOWS_ANON(GotByte)) {
dynabuf_append(GlobalDynaBuf, '\0'); dynabuf_append(GlobalDynaBuf, '\0');
get_symbol_value(section_now->local_scope, GlobalDynaBuf->size - 1, 0); // no prefix, -1 to not count terminator, no unpseudo get_symbol_value(section_now->local_scope, GlobalDynaBuf->size - 1, 0, TRUE); // no prefix, -1 to not count terminator, no unpseudo, check pass number
goto now_expect_dyadic_op; goto now_expect_dyadic_op;
} }
@ -1008,7 +1016,7 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
// here we need to put '.' into GlobalDynaBuf even though we have already skipped it: // here we need to put '.' into GlobalDynaBuf even though we have already skipped it:
if (input_read_scope_and_symbol_name_KLUGED(&scope) == 0) { // now GotByte = illegal char if (input_read_scope_and_symbol_name_KLUGED(&scope) == 0) { // now GotByte = illegal char
get_symbol_value(scope, GlobalDynaBuf->size - 1, 0); // -1 to not count terminator, no unpseudo get_symbol_value(scope, GlobalDynaBuf->size - 1, 0, FALSE); // -1 to not count terminator, no unpseudo, no pass number check
goto now_expect_dyadic_op; // ok goto now_expect_dyadic_op; // ok
} }
@ -1018,7 +1026,7 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
case CHEAP_PREFIX: // cheap local symbol case CHEAP_PREFIX: // cheap local symbol
//printf("looking in cheap scope %d\n", section_now->cheap_scope); //printf("looking in cheap scope %d\n", section_now->cheap_scope);
if (input_read_scope_and_symbol_name(&scope) == 0) { // now GotByte = illegal char if (input_read_scope_and_symbol_name(&scope) == 0) { // now GotByte = illegal char
get_symbol_value(scope, GlobalDynaBuf->size - 1, 0); // -1 to not count terminator, no unpseudo get_symbol_value(scope, GlobalDynaBuf->size - 1, 0, FALSE); // -1 to not count terminator, no unpseudo, no pass number check
goto now_expect_dyadic_op; // ok goto now_expect_dyadic_op; // ok
} }
@ -1058,7 +1066,7 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
// however, apart from that check above, function calls have nothing to do with // however, apart from that check above, function calls have nothing to do with
// parentheses: "sin(x+y)" gets parsed just like "not(x+y)". // parentheses: "sin(x+y)" gets parsed just like "not(x+y)".
} else { } else {
get_symbol_value(SCOPE_GLOBAL, GlobalDynaBuf->size - 1, 0); // no prefix, -1 to not count terminator, no unpseudo get_symbol_value(SCOPE_GLOBAL, GlobalDynaBuf->size - 1, 0, FALSE); // no prefix, -1 to not count terminator, no unpseudo, no pass number check
goto now_expect_dyadic_op; goto now_expect_dyadic_op;
} }
} }

View File

@ -411,7 +411,7 @@ static void start_segment(intval_t address_change, bits segment_flags)
// calculate start of new segment // calculate start of new segment
out->write_idx = out->write_idx + address_change; out->write_idx = out->write_idx + address_change;
if (out->write_idx < 0) { if (out->write_idx < 0) {
throw_serious_error("Tried to write to negative addresses."); throw_serious_error("Tried to write to negative address.");
} else if (out->write_idx >= OUTBUF_MAXSIZE) { } else if (out->write_idx >= OUTBUF_MAXSIZE) {
throw_serious_error("Reached memory limit."); throw_serious_error("Reached memory limit.");
} }

View File

@ -9,7 +9,7 @@
#define RELEASE "0.97" // update before release FIXME #define RELEASE "0.97" // update before release FIXME
#define CODENAME "Zem" // update before release #define CODENAME "Zem" // update before release
#define CHANGE_DATE "14 Aug" // update before release FIXME #define CHANGE_DATE "15 Aug" // update before release FIXME
#define CHANGE_YEAR "2024" // update before release #define CHANGE_YEAR "2024" // update before release
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME

View File

@ -0,0 +1,5 @@
*=$1000
!pseudopc $8000 {
* = $6000 ; -> "Tried to write to negative address."
rts
}

View File

@ -0,0 +1,4 @@
*=$1000
jmp -- ; -> "Symbol not defined."
-- ; older versions had a bug where the last value set in a pass survived to the next pass
jmp --