diff --git a/docs/Errors.txt b/docs/Errors.txt index 3f7a52f..5854cea 100644 --- a/docs/Errors.txt +++ b/docs/Errors.txt @@ -50,6 +50,12 @@ Assembling unstable LXA #NONZERO instruction Therefore ACME issues these warnings if it is about to generate these instructions with a non-zero argument. +Binary literal without any digits. +Hex literal without any digits. +Octal literal without any digits. + A special literal was started, but then no digits followed. Expect + this to become an error in future! + Bug in ACME, code follows A situation has been encountered implying there is a bug in ACME. See the last section in this file. @@ -108,19 +114,21 @@ Output file already chosen. Segment reached another one, overwriting it. The program counter has just reached the start of another segment. Because some people might want to assemble "onto" a binary file - that was loaded before, this warning can be switched off using - modifier keywords when changing the program counter via "* =". - Future versions of ACME might throw an error instead of a warning - in this case. + that was loaded before, this warning can be inhibited using + modifier keywords when changing the program counter via "*=". + For extra safety you can also turn this warning into an error + using the "--strict-segments" CLI switch. In future versions of + ACME this might become the default. Segment starts inside another one, overwriting it. - The given value in a "* =" command is located inside another + The given value in a "*=" command is located inside another segment. Because some people might want to assemble "onto" a - binary file that was loaded before, this warning can be switched - off using modifier keywords when changing the program counter via - "* =". - Future versions of ACME might throw an error instead of a warning - in this case. + binary file that was loaded before, this warning can be inhibited + using modifier keywords when changing the program counter via + "*=". + For extra safety you can also turn this warning into an error + using the "--strict-segments" CLI switch. In future versions of + ACME this might become the default. Symbol list file name already chosen. The "!sl" command was given more than once (or in addition to the @@ -193,6 +201,9 @@ Section: Errors during assembly This is given when the pseudo opcode "!error" is executed. The actual message varies according to the pseudo opcode's arguments. +Argument out of range. + You called arcsin/arccos with something not in the [-1, 1] range. + Cannot open input file. ACME had problems opening an input file ("!bin", "!convtab" or "!src"). Maybe you mistyped its name. @@ -208,6 +219,10 @@ Exponent is negative. Using negative exponents only give sensible results when using floating point maths. +Expression did not return a number. + An expression returned a string or a list but a number (integer or + float) was expected. + File name quotes not found ("" or <>). File names have to be given in quotes. Either "" quoting for files located in the current directory or <> quoting for library files. @@ -216,8 +231,9 @@ Found '}' instead of end-of-file. ACME encountered a '}' character when it expected the file to end instead (because no blocks were open). -Garbage data at end of statement. - There are still arguments when there should not be any more. +Garbage data at end of statement (unexpected 'CHAR'). + There are still arguments when there should not be any more. The + given character is the one where end-of-line was expected. Hex digits are not given in pairs. The two digits of a hex byte are separated by another character, @@ -234,6 +250,12 @@ Illegal combination of command and postfix. Illegal postfix. You used a postfix other than "+1", "+2" or "+3". +Index is undefined. + You attempted an indexing operation with some undefined symbol. + +Index out of range. + The value for an indexing operation wasn't in the allowed range. + Macro already defined. Macros can only be defined once. If you define a macro twice, ACME will help you find the definitions by giving a warning for the @@ -265,6 +287,13 @@ No string given. Number out of range. A value is too high or too low. + This can also mean the desired addressing mode is not available, + as in "ldy $e000, x". + +Operation not supported: Cannot apply "OP" to "TYPE". +Operation not supported: Cannot apply "OP" to "TYPE" and "TYPE". + You tried to use an operator on the wrong type(s) of argument(s), + like indexing a float or negating a string. Program counter is unset. You didn't set the program counter, so ACME didn't know where to @@ -305,12 +334,12 @@ Too late for postfix. Too many '('. A formula ends before all parentheses were closed. -Too many ')'. - There are more closing than opening parentheses in a formula. - Unknown encoding. You used the "!convtab" command with a keyword ACME does not know. +Unknown function. + You used a mathematical function ACME does not know. + Unknown operator. You used an arithmetic/logical operator ACME does not know. @@ -326,6 +355,12 @@ Unknown pseudo opcode. Unknown "* =" segment modifier. You used a modifier keyword ACME does not know. +Unterminated index spec. + An index was started with '[' but did not end with ']'. + +Unterminated list. + A list was started with '[' but did not end with ']'. + Value not defined (SYMBOL NAME). A value could not be worked out. Maybe you mistyped a symbol name. Whether this is given as a "normal" or as a serious error depends @@ -374,12 +409,15 @@ Syntax error. Too deeply nested. Recursive macro calls? The only reason for ACME to have a limit on macro call nesting - at all is to find infinite recursions. Current limit is 64. + at all is to find infinite recursions. + The default limit is 64, this can be changed using the + "--maxdepth" CLI switch. Too deeply nested. Recursive "!source"? The only reason for ACME to still have a limit on "!source" - nesting at all is to find infinite recursions. Current limit is - 64. + nesting at all is to find infinite recursions. + The default limit is 64, this can be changed using the + "--maxdepth" CLI switch. Value not yet defined. A value could not be worked out. Maybe you mistyped a symbol name. @@ -420,29 +458,49 @@ Section: Bugs in ACME The hint messages are of no real interest to the end user, but here they are for completeness' sake. +ArgStackEmpty + There was no data for a monadic operator to work on. + +ArgStackNotEmpty + The expression parser has finished though there are still + arguments left to process. + IllegalGroupIndex The mnemonic tree contains a group that I didn't add. IllegalBlockTerminator A RAM block (macro or loop) was terminated incorrectly. -IllegalOperatorHandle +IllegalOperatorId +IllegalOperatorGroup The expression parser found an operator that does not exist. IllegalImmediateMode The mnemonic tree contains invalid info about the size of immediate arguments. -OperandStackNotEmpty - The expression parser has finished though there are still operands - left to parse. +IllegalSymbolNameLength + A sanity check on string lengths failed. + +NotEnoughArgs + There was not enough data for a dyadic operator to work on. + +OperatorIsNotDyadic +OperatorIsNotMonadic + A function was passed the wrong type of operator. OperatorStackNotEmpty The expression parser has finished though there are still - operators left to parse. + operators left to process. + +SecondArgIsNotAnInt + A sanity check failed: An argument should have been converted to + integer but wasn't. StrangeInputMode The input state machine has reached a state that does not exist. +StrangeIndexBracket +StrangeListBracket StrangeParenthesis The expression parser found a non-existing operator. diff --git a/src/alu.c b/src/alu.c index e895c38..2f39459 100644 --- a/src/alu.c +++ b/src/alu.c @@ -41,6 +41,7 @@ static const char exception_div_by_zero[] = "Division by zero."; static const char exception_no_value[] = "No value given."; static const char exception_paren_open[] = "Too many '('."; +static const char exception_not_number[] = "Expression did not return a number."; #define s_or (s_eor + 1) // Yes, I know I'm sick #define s_xor (s_scrxor + 3) // Yes, I know I'm sick static const char s_arcsin[] = "arcsin"; @@ -336,7 +337,7 @@ static void is_not_defined(struct symbol *optional_symbol, char optional_prefix_ } DynaBuf_add_string(errormsg_dyna_buf, name); if (errormsg_dyna_buf->size < length) { - Bug_found("Illegal symbol name length", errormsg_dyna_buf->size - length); + Bug_found("IllegalSymbolNameLength", errormsg_dyna_buf->size - length); } else { errormsg_dyna_buf->size = length; } @@ -465,7 +466,7 @@ static void parse_binary_literal(void) // Now GotByte = "%" or "b" break; // found illegal character } if (!digits) - Throw_warning("Binary literal without any digits"); // FIXME - make into error! + Throw_warning("Binary literal without any digits."); // FIXME - make into error! // set force bits if (config.honor_leading_zeroes) { if (digits > 8) { @@ -512,7 +513,7 @@ static void parse_hex_literal(void) // Now GotByte = "$" or "x" break; // found illegal character } if (!digits) - Throw_warning("Hex literal without any digits"); // FIXME - make into error! + Throw_warning("Hex literal without any digits."); // FIXME - make into error! // set force bits if (config.honor_leading_zeroes) { if (digits > 2) { @@ -609,7 +610,7 @@ static void parse_octal_literal(void) // Now GotByte = "&" GetByte(); } if (!digits) - Throw_warning("Octal literal without any digits"); // FIXME - make into error! + Throw_warning("Octal literal without any digits."); // FIXME - make into error! // set force bits if (config.honor_leading_zeroes) { if (digits > 3) { @@ -1027,13 +1028,13 @@ static void unsupported_operation(struct object *optional, struct op *op, struct { if (optional) { if (op->group != OPGROUP_DYADIC) - Bug_found("OperatorIsNotDyadic", op->id); // FIXME - add to docs + Bug_found("OperatorIsNotDyadic", op->id); } else { if (op->group != OPGROUP_MONADIC) - Bug_found("OperatorIsNotMonadic", op->id); // FIXME - add to docs + Bug_found("OperatorIsNotMonadic", op->id); } DYNABUF_CLEAR(errormsg_dyna_buf); - DynaBuf_add_string(errormsg_dyna_buf, "Operation not supported: Cannot apply \""); // FIXME - add to docs + DynaBuf_add_string(errormsg_dyna_buf, "Operation not supported: Cannot apply \""); DynaBuf_add_string(errormsg_dyna_buf, op->text_version); DynaBuf_add_string(errormsg_dyna_buf, "\" to \""); if (optional) { @@ -1328,7 +1329,7 @@ static void int_handle_dyadic_operator(struct object *self, struct op *op, struc // maybe put this into an extra "int_dyadic_int" function? // sanity check, now "other" must be an int if (other->type != &type_int) - Bug_found("SecondArgIsNotAnInt", op->id); // FIXME - rename? then add to docs! + Bug_found("SecondArgIsNotAnInt", op->id); // part 2: now we got rid of non-ints, perform actual operation: switch (op->id) { @@ -1582,7 +1583,7 @@ static int get_valid_index(int *target, int length, struct object *self, struct return 1; } if (!(other->u.number.flags & NUMBER_IS_DEFINED)) { - Throw_error("Index is undefined."); // FIXME - add to docs + Throw_error("Index is undefined."); return 1; } index = other->u.number.val.intval; @@ -1821,11 +1822,10 @@ static boolean handle_special_operator(struct expression *expression, enum op_id // unmatched parenthesis, as in "lda ($80,x)" ++(expression->open_parentheses); // count return TRUE; // caller can remove "OPID_LEFT_PARENTHESIS" operator from stack -// Throw_error("Too many ')'."); // FIXME - remove from docs! case OPID_START_LIST: if (current != OPID_END_EXPRESSION) - Bug_found("StrangeListBracket", current); // FIXME - add to docs! + Bug_found("StrangeListBracket", current); if (GotByte == ',') { GetByte(); // eat ',' op_stack[op_sp - 1] = &ops_list_append; // change "end of expression" to "append" @@ -1838,25 +1838,25 @@ static boolean handle_special_operator(struct expression *expression, enum op_id alu_state = STATE_EXPECT_DYADIC_OP; return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it } - Throw_error("Unterminated list"); // FIXME - add to docs! + Throw_error("Unterminated list."); alu_state = STATE_ERROR; return TRUE; // caller can remove LISTBUILDER operator from stack case OPID_START_INDEX: if (current != OPID_END_EXPRESSION) - Bug_found("StrangeIndexBracket", current); // FIXME - add to docs! + Bug_found("StrangeIndexBracket", current); if (GotByte == ']') { GetByte(); // eat ']' op_sp -= 2; // remove both OPENINDEX and END_EXPRESSION alu_state = STATE_EXPECT_DYADIC_OP; return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it } - Throw_error("Unterminated index spec"); // FIXME - add to docs! + Throw_error("Unterminated index spec."); alu_state = STATE_ERROR; return TRUE; // caller can remove START_INDEX operator from stack default: - Bug_found("IllegalOperatorIdS", previous); + Bug_found("IllegalOperatorId", previous); } // this is unreachable return FALSE; // stack is done, so caller shouldn't touch it @@ -1903,14 +1903,14 @@ static void try_to_reduce_stacks(struct expression *expression) switch (previous_op->group) { case OPGROUP_MONADIC: // monadic operators if (arg_sp < 1) - Bug_found("ArgStackEmpty", arg_sp); // FIXME - add to docs! + Bug_found("ArgStackEmpty", arg_sp); ARG_NOW.type->handle_monadic_operator(&ARG_NOW, previous_op); // operation was something other than parentheses expression->is_parenthesized = FALSE; break; case OPGROUP_DYADIC: // dyadic operators if (arg_sp < 2) - Bug_found("NotEnoughArgs", arg_sp); // FIXME - add to docs! + Bug_found("NotEnoughArgs", arg_sp); ARG_PREV.type->handle_dyadic_operator(&ARG_PREV, previous_op, &ARG_NOW); // decrement argument stack pointer because dyadic operator merged two arguments into one --arg_sp; @@ -1924,7 +1924,7 @@ static void try_to_reduce_stacks(struct expression *expression) // both monadics and dyadics clear "is_parenthesized", but here we don't touch it! break; default: - Bug_found("IllegalOperatorGroup", previous_op->group); // FIXME - add to docs! + Bug_found("IllegalOperatorGroup", previous_op->group); } // shared endings for "we did the operation indicated by previous operator": // fix stack: @@ -1978,7 +1978,7 @@ static int parse_expression(struct expression *expression) if (alu_state == STATE_END) { // check for bugs if (arg_sp != 1) - Bug_found("OperandStackNotEmpty", arg_sp); + Bug_found("ArgStackNotEmpty", arg_sp); if (op_sp != 1) Bug_found("OperatorStackNotEmpty", op_sp); // copy result @@ -2039,7 +2039,7 @@ void ALU_any_int(intval_t *target) // ACCEPT_UNDEFINED *target = expression.result.u.number.val.fpval; else { *target = 0; - Throw_error("Expression did not return a number."); // TODO - add to docs! + Throw_error(exception_not_number); } } @@ -2069,7 +2069,7 @@ void ALU_defined_int(struct number *intresult) // no ACCEPT constants? } else if (expression.result.type == &type_float) { float_to_int(&expression.result); } else { - Throw_serious_error("Expression did not return a number."); + Throw_serious_error(exception_not_number); } if (!(expression.result.u.number.flags & NUMBER_IS_DEFINED)) Throw_serious_error(exception_value_not_defined); @@ -2092,7 +2092,7 @@ void ALU_addrmode_int(struct expression *expression, int paren) // ACCEPT_UNDEFI if (expression->result.type == &type_float) float_to_int(&(expression->result)); if (expression->result.type != &type_int) - Throw_error("Expression did not return a number."); + Throw_error(exception_not_number); if (expression->open_parentheses > paren) { expression->open_parentheses = 0; Throw_error(exception_paren_open);