macross/errorStuff.c

361 lines
11 KiB
C

/*
errorStuff.c -- Error handling for the Macross assembler
Chip Morningstar -- Lucasfilm Ltd.
5-November-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
bool nullStatementFlag;
/* puntOnError handles syntax errors and the like encountered during parsing
or lexical analysis: it issues the relevent error message and scans the
input up to the end of the line, in a (probably futile) effort to recover
from the booboo. */
void
puntOnError(theError, arg1, arg2, arg3)
errorType theError;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
char c;
void error();
while ((c = getc(input))!='\n' && c!=EOF)
;
ungetc(c, input);
error(theError, arg1, arg2, arg3);
}
/* printErrorMessage is the general error message handler */
void
printErrorMessage(theError, arg1, arg2, arg3)
errorType theError;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
/* This table MUST be maintained congruently with the definition of the
enumerated type 'errorType'. */
void fatalError();
static bool dying = FALSE;
static char *errorMessageStrings[] = {
"assignment in 'define' statement is not '='",
"digit '%c' is not valid in base %d",
"closing \"'\" missing in character constant",
"closing '\"' missing in string constant",
"octal value '0%o' too large to fit in a character",
"character '%c' not allowed here",
"comment not closed at end of file",
"line comment not closed at end of file",
"fatal: unable to open temporary scratch file '%s'",
"%s cannot be a valid address for an 'org'",
"negative block size in 'block' statement",
"'%s' is %s and hence unassignable",
"left and right hand sides of assignment are incompatible for '%s' operator",
"operands of '%s' are incompatible with each other",
"postincrement operand is %s and hence un-postincrementable",
"postdecrement operand is %s and hence un-postdecrementable",
"preincrement operand is %s and hence un-preincrementable",
"predecrement operand is %s and hence un-predecrementable",
"operand of '%s' is incompatible with operator",
"value is not an address",
"value is not an integer",
"can't 'align' to zero or negative value",
"left hand operand of '%s' has no value",
"too many operands for '%s' instruction (should have %d)",
"illegal address mode for '%s' instruction",
"value %d is too large to fit in a byte",
"value %d is too large to fit in a word",
"illegal address mode for '%s' instruction",
"divide by zero",
"symbol '%s' undefined",
"relative branch offset too large",
"label '%s' previously defined",
"fatal: can't open object file '%s'",
"%s can't be made external",
"warning: more than one output file name given on command line",
"warning: '-%c' is not a recognized command line flag",
"fatal: no output file name given on command line after '-o'",
"fatal: unable to open input file '%s'",
"fatal: unable to open include file '%s'",
"%s cannot be a valid boolean value",
"symbol '%s' was previously defined",
"assignment to undeclared variable '%s'",
"redefinition of variable '%s'",
"'%s' is not a struct",
"struct is too large for all components to be addressed",
"struct field '%s' previously defined",
"struct definition inside a struct definition",
"'%s' is not a struct field",
"macro '%s' previously defined",
"macro definition inside a macro or function",
"too many arguments given to macro '%s' (expects no more than %d)",
"function definition inside a macro or function",
"function '%s' previously defined",
"too many arguments given to function '%s' (expects no more than %d)",
"'%s' is not a function",
"function '%s' did not return a value",
"operand already has an address mode",
"multiple address modes in expression",
"include file name given is not a string",
"start address previously given",
"attempt to use function name '%s' as a value",
"statement with side-effects not allowed inside a function",
"symbolName can't find symbol",
"error inside macro '%s'",
"error inside function '%s'",
"fatal: no listing file name given on command line after '-l'",
"fatal: no symbol dump file name given on command line after '-%c'",
"warning: more than one listing file name given on command line",
"warning: more than one symbol dump file name given on command line",
"fatal: can't open listing file '%s'",
"fatal: can't open symbol dump file '%s'",
"fatal: source file '%s' does not have a Macross source file name",
"fatal: output file '%s' has a Macross source file name",
"fatal: list file '%s' has a Macross source file name",
"fatal: symbol dump file '%s' has a Macross source file name",
"constraint value is not an integer",
"constrained block crosses 0x%x boundary",
"symbol '%s' has no value",
"bad start address",
"align inside constraint block -- alignment ignored",
"constrain inside constraint block -- constraint ignored",
"can't emit %s as a word",
"can't emit %s as a byte",
"too few operands for '%s' instruction (should have %d)",
"bad color argument to 'atasciiColor'",
"'printf' format argument is not a string",
"'%s' argument #%d is not a string",
"no arguments given to '%s'",
"'%s' argument is not a string",
"too few arguments to '%s'",
"'%s' argument #%d is not an absolute value",
"bad substring indices",
"invalid 'assert' condition",
"invalid 'assert' message",
"'assert' failed: %s",
"'assert' failed",
"can't use %s as a switch value",
"can't use %s as a case value",
"can't forward reference a block",
"warning: turning macro expansion listing off because listing in general is off",
"inappropriate address modes",
"can't do byte address op",
"quick data out of range",
"ccr op is byte op",
"sr op is word op",
"shift op is word op",
"cmp address is not byte op",
"usp move is long op",
"ccr move is word op",
"sr move is word op",
"cr move is long op",
"address move not byte op",
"trap data too large",
"relative offset value too large",
"can't do op from A register",
"forward reference not allowed here",
"fatal: address 0x%x is outside the available address space",
"argument '%s' to 'apply' is not a macro name",
"can't 'target' in relocatable mode",
"%s cannot be a valid address for a 'target'",
"macro '%s' is undefined",
"bad position argument to 'nthChar'",
"value argument to 'symbolDefine' is not an expression operand",
"attempt to use %s as an array",
"attempt to index an array with %s",
"array index of %d exceeds maximum of %d",
"too many initialization values for variable",
"negative array index",
"can't emit %s as a long",
"can't use ++ or -- on an element of a string",
"can't assign a non-character value into a string element",
"negative array size given to 'makeArray'",
"too many initialization values given to 'makeArray'",
"array element has no value",
"can't use prefix '%s' in an expression containing a forward reference",
"can't use postfix '%s' in an expression containing a forward reference",
"can't use assignment in an expression containing a forward reference",
"fatal: too many errors (choke, gasp, wheeze, die...)",
"expression too large for object file encoding",
"operator assignment not allowed in object file expression",
"temporary symbol '%s' in object file expression",
"block operand in object file expression",
"register operand in object file expression",
"selection operand in object file expression (not yet)",
"%s not allowed in object file expression",
"array term not allowed in object file expression",
"%s not allowed in object file function",
"array mvariable declaration in object file function",
"built-in function '%s' is not available in the linker",
"fatal: no name definition given on command line after '-D'",
"bad name definition: '%s'",
"warning: perform statement has no side effects",
};
static int errorCount = 0;
if (!terseErrorMessages || currentFileName != lastErrorFile ||
currentLineNumber != lastErrorLine) {
lastErrorFile = currentFileName;
lastErrorLine = currentLineNumber;
printf("\"%s\", line %d: ", currentFileName, currentLineNumber
-1);
printf(errorMessageStrings[(int)theError], arg1, arg2, arg3);
printf("\n");
fflush(stdout);
}
if (++errorCount > ERROR_LIMIT && !dying) {
dying = TRUE;
fatalError(TOO_MANY_ERRORS_ERROR);
}
}
void
error(theError, arg1, arg2, arg3)
errorType theError;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
printErrorMessage(theError, arg1, arg2, arg3);
errorFlag = TRUE;
}
void
warning(theError, arg1, arg2, arg3)
errorType theError;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
printErrorMessage(theError, arg1, arg2, arg3);
}
void
fatalError(theError, arg1, arg2, arg3)
errorType theError;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
printErrorMessage(theError, arg1, arg2, arg3);
chokePukeAndDie();
}
void
fatalSystemError(theError, arg1, arg2, arg3)
errorType theError;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
printErrorMessage(theError, arg1, arg2, arg3);
perror("Unix says");
chokePukeAndDie();
}
/* yyerror is what yacc expects to call when it hits an error. Yacc passes
the error message as a string (this is almost always 'syntax error'). */
void
yyerror(s)
char *s;
{
printf("\"%s\", line %d: %s\n", currentFileName, currentLineNumber,s);
fflush(stdout);
errorFlag = TRUE;
}
/* usageString is used in reporting errors having to do with symbol usage.
It provides a translation between the internal representation and
something printable (with the printable something designed to be embedded
in a sentence). */
char *
usageString(usageKind)
symbolUsageKindType usageKind;
{
/* This table MUST be maintained congruently with the definition of the
enumerated type 'symbolUsageKindType'. */
static char *usageStrings[NUM_OF_SYM_USAGES] = {
"a struct name",
"a struct field name",
"a macro name",
"an argument variable name",
"a label",
"an external symbol",
"a variable",
"a macro variable",
"a symbol of unknown type",
"a dead symbol",
"a function name",
"a built-in-function name",
"a nested symbol of unknown type",
"a define symbol",
"a macro define symbol",
"an unknown function",
"an unknown macro",
};
return(usageStrings[(int)usageKind]);
}
/* valueKindString similarly deals with the different kinds of values. */
char *
valueKindString(valueKind)
valueKindType valueKind;
{
/* This table MUST be maintained congruently with the definition of the
enumerated type 'valueKindType'. */
static char *valueKindStrings[] = {
"an absolute value",
"a data value",
"a relocatable value",
"a bss value",
"a struct name",
"a field name",
"a macro name",
"an operand value",
"a string value",
"a condition code",
"an undefined value",
"a function name",
"a block of statements",
"a built in function",
"an array",
"a failed expression"
};
return (valueKindStrings[(int)valueKind]);
}
/* assignmentString similarly handles assignments */
char *
assignmentString(assignment)
assignmentKindType assignment;
{
/* This table MUST be maintained congruently with the definition of the
enumerated type 'assignmentKindType'. */
static char *assignmentStringTable[] = {
"=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=",
"<<=", ">>=", "macross botch! no assigment"
};
return(assignmentStringTable[(int)assignment]);
}