Wire in enhanced error handling to all crash situations

This commit is contained in:
Curle 2023-04-25 00:06:35 +01:00
parent 0f77480d5b
commit bc787c3adb
9 changed files with 87 additions and 64 deletions

View File

@ -98,6 +98,7 @@ void VerifyToken(int Type, char* TokenExpected) {
if (CurrentFile->CurrentSymbol.type == Type) if (CurrentFile->CurrentSymbol.type == Type)
Tokenise(); Tokenise();
else { else {
Tokenise();
ErrorReport("Expected %s, but got %s instead.\n", TokenExpected, TokenNames[CurrentFile->CurrentSymbol.type]); ErrorReport("Expected %s, but got %s instead.\n", TokenExpected, TokenNames[CurrentFile->CurrentSymbol.type]);
exit(1); exit(1);
} }
@ -570,7 +571,7 @@ void Tokenise() {
Token->type = LI_INT; Token->type = LI_INT;
if (NextChar() != '\'') if (NextChar() != '\'')
Die("Expected '\\'' at the end of a character."); ErrorReport("Expected '\\'' at the end of a character.\n");
break; break;
case '"': case '"':
@ -596,13 +597,9 @@ void Tokenise() {
Token->type = TY_IDENTIFIER; Token->type = TY_IDENTIFIER;
break; break;
//printf.er("Line %d: Unrecognized symbol %s\n", CurrentIdentifier, Line);
//exit(1);
} }
ErrorReport("Unrecognized character: %c\n", Char);
DieChar("Unrecognized character", Char);
} }
} }

View File

@ -101,7 +101,7 @@ struct ASTNode* ConstructASTNode(int Operation, int Type,
Node = (struct ASTNode*) malloc(sizeof(struct ASTNode)); Node = (struct ASTNode*) malloc(sizeof(struct ASTNode));
if (!Node) if (!Node)
Die("Unable to allocate node!"); ErrorReport("Unable to allocate node: %s\n", errno);
Node->Operation = Operation; Node->Operation = Operation;
@ -158,7 +158,7 @@ int ParseTokenToOperation(int Token) {
if (Token > LI_EOF && Token < LI_INT) if (Token > LI_EOF && Token < LI_INT)
return Token; return Token;
DieDecimal("ParseToken: Unknown token", Token); ErrorReport("ParseToken: Unknown token %s\n", TokenNames[Token]);
} }
/* /*
@ -267,7 +267,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
RightNode = MutateType(RightNode, LeftNode->ExprType, 0); RightNode = MutateType(RightNode, LeftNode->ExprType, 0);
if (RightNode == NULL) if (RightNode == NULL)
Die("Incompatible Expression encountered in assignment"); ErrorReport("Incompatible types encountered in assignment: %s, %s\n", TypeNames(RightNode->ExprType), TypeNames(LeftNode->ExprType));
// LeftNode holds the target, the target variable in this case // LeftNode holds the target, the target variable in this case
printf("\t\tAssigning variable: %s\n", LeftNode->Symbol->Name); printf("\t\tAssigning variable: %s\n", LeftNode->Symbol->Name);
@ -292,7 +292,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
*/ */
if (LeftTemp == NULL && RightTemp == NULL) if (LeftTemp == NULL && RightTemp == NULL)
Die("Incompatible types in parsing nodes"); ErrorReport("Incompatible types in parsing nodes: %s, %s\n", TypeNames(LeftNode->ExprType), TypeNames(RightNode->ExprType));
/** /**
* If the left was valid, or valid for * If the left was valid, or valid for
@ -304,7 +304,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
if (LeftTemp != NULL) if (LeftTemp != NULL)
LeftNode = LeftTemp; //ConstructASTBranch(LeftType, RightNode->ExprType, LeftNode, 0); LeftNode = LeftTemp;
/** /**
* Same here, but there is a higher chance * Same here, but there is a higher chance
@ -313,7 +313,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
*/ */
if (RightTemp != NULL) if (RightTemp != NULL)
RightNode = RightTemp; // ConstructASTBranch(RightType, LeftNode->ExprType, RightNode, 0); RightNode = RightTemp;
} }
@ -352,7 +352,7 @@ struct ASTNode* CallFunction() {
//TODO: Test structural type! //TODO: Test structural type!
if ((Function = FindSymbol(CurrentIdentifier)) == NULL || (Function->Structure != ST_FUNC)) if ((Function = FindSymbol(CurrentIdentifier)) == NULL || (Function->Structure != ST_FUNC))
DieMessage("Undeclared function", CurrentIdentifier); ErrorReport("Undeclared function: %s\n", CurrentIdentifier);
VerifyToken(LI_LPARE, "("); VerifyToken(LI_LPARE, "(");
@ -386,6 +386,7 @@ struct ASTNode* ParseExpressionList(int terminate) {
Safe(); Safe();
while (CurrentFile->CurrentSymbol.type != terminate) { while (CurrentFile->CurrentSymbol.type != terminate) {
// TODO: for(int x = 0;
Child = ParsePrecedenceASTNode(0); Child = ParsePrecedenceASTNode(0);
Count++; Count++;
Safe(); Safe();

View File

@ -37,7 +37,7 @@
int PointerTo(int Type) { int PointerTo(int Type) {
if ((Type & 0xf) == 0xf) if ((Type & 0xf) == 0xf)
DieDecimal("Unrecognized type in pointerisation", Type); ErrorReport("Unrecognized type in pointerisation: %d\n", Type);
printf("\t\tPointerising a %s\n", TypeNames(Type)); printf("\t\tPointerising a %s\n", TypeNames(Type));
return (Type + 1); return (Type + 1);
} }
@ -53,7 +53,7 @@ int PointerTo(int Type) {
int ValueAt(int Type) { int ValueAt(int Type) {
printf("\t\tDereferencing a %s\n", TypeNames(Type)); printf("\t\tDereferencing a %s\n", TypeNames(Type));
if ((Type & 0xf) == 0x0) if ((Type & 0xf) == 0x0)
DieDecimal("Unrecognized type in defererencing", Type); ErrorReport("Unrecognized type in defererencing: %d (%s)\n", Type, TypeNames(Type));
return (Type - 1); return (Type - 1);
} }
@ -74,7 +74,7 @@ struct ASTNode* AccessArray() {
printf("\tAccessing array %s as requested\r\n", CurrentIdentifier); printf("\tAccessing array %s as requested\r\n", CurrentIdentifier);
if ((Entry = FindSymbol(CurrentIdentifier)) == NULL || Entry->Structure != ST_ARR) if ((Entry = FindSymbol(CurrentIdentifier)) == NULL || Entry->Structure != ST_ARR)
DieMessage("Accessing undeclared array", CurrentIdentifier); ErrorReport("Accessing undeclared array: %s\n", CurrentIdentifier);
LeftNode = ConstructASTLeaf(OP_ADDRESS, Entry->Type, Entry, 0); LeftNode = ConstructASTLeaf(OP_ADDRESS, Entry->Type, Entry, 0);
Tokenise(); Tokenise();
@ -84,7 +84,7 @@ struct ASTNode* AccessArray() {
VerifyToken(LI_RBRAS, "]"); VerifyToken(LI_RBRAS, "]");
if (!TypeIsInt(RightNode->ExprType)) if (!TypeIsInt(RightNode->ExprType))
Die("Array index is not integer"); ErrorReport("Array index is not integer");
printf("\t\tPreparing types - RightNode of type %s must be mutated to LeftNode type %s\r\n", TypeNames(RightNode->ExprType), printf("\t\tPreparing types - RightNode of type %s must be mutated to LeftNode type %s\r\n", TypeNames(RightNode->ExprType),
TypeNames(LeftNode->ExprType)); TypeNames(LeftNode->ExprType));
@ -114,11 +114,13 @@ struct ASTNode* AccessMember(bool Deref) {
if ((CompositeVar = FindSymbol(CurrentIdentifier)) == NULL) if ((CompositeVar = FindSymbol(CurrentIdentifier)) == NULL)
DieMessage("Undeclared variable", CurrentIdentifier); ErrorReport("Undeclared variable: %s\n", CurrentIdentifier);
if (Deref && (CompositeVar->Type != PointerTo(DAT_STRUCT) && CompositeVar->Type != PointerTo(DAT_UNION))) if (Deref && (CompositeVar->Type != PointerTo(DAT_STRUCT) && CompositeVar->Type != PointerTo(DAT_UNION)))
DieMessage("Undeclared struct", CurrentIdentifier); ErrorReport("Undeclared struct: %s\n", CurrentIdentifier);
if (!Deref && (CompositeVar->Type != DAT_STRUCT && CompositeVar->Type != DAT_UNION)) if (!Deref && (CompositeVar->Type != DAT_STRUCT && CompositeVar->Type != DAT_UNION))
DieMessage("Undeclared struct", CurrentIdentifier); ErrorReport("Undeclared struct: %s\n", CurrentIdentifier);
Safe();
if (Deref) if (Deref)
LeftNode = ConstructASTLeaf(REF_IDENT, PointerTo(CompositeVar->Type), CompositeVar, 0); LeftNode = ConstructASTLeaf(REF_IDENT, PointerTo(CompositeVar->Type), CompositeVar, 0);
@ -140,8 +142,9 @@ struct ASTNode* AccessMember(bool Deref) {
} }
if (Member == NULL) if (Member == NULL)
DieMessage("Invalid composite member", CurrentIdentifier); ErrorReport("Invalid composite member: %s\n", CurrentIdentifier);
Safe();
RightNode = ConstructASTLeaf(TERM_INTLITERAL, RET_INT, NULL, Member->SinkOffset); RightNode = ConstructASTLeaf(TERM_INTLITERAL, RET_INT, NULL, Member->SinkOffset);
LeftNode = ConstructASTNode(OP_ADD, PointerTo(Member->Type), LeftNode, NULL, RightNode, NULL, 0); LeftNode = ConstructASTNode(OP_ADD, PointerTo(Member->Type), LeftNode, NULL, RightNode, NULL, 0);

View File

@ -12,6 +12,31 @@ static void ParseEnumDeclaration();
static struct SymbolTableEntry* ParseDeclarationSymbol(int Type, struct SymbolTableEntry* CompositeType, int Storage); static struct SymbolTableEntry* ParseDeclarationSymbol(int Type, struct SymbolTableEntry* CompositeType, int Storage);
static int ParseAliasDeclaration(struct SymbolTableEntry** CompositeType); static int ParseAliasDeclaration(struct SymbolTableEntry** CompositeType);
/**
*
// Determine whether we're initializing immediately
if (CurrentFile->CurrentSymbol.type == LI_EQUAL) {
// TODO: Default parameters
if (Storage == SC_PARAM)
ErrorReport("Initialization of parameter not permitted.\n");
// TODO: Enum initialization
if (Storage == SC_MEMBER)
ErrorReport("Initialization of a member not permitted.\n");
Tokenise();
if (structureType == ST_ARR) {
ParseArrayInitialization(symbol, Type, CompositeType, Storage);
} else {
// TODO: Inline initialization
ErrorReport("Initialization of a scalar not permitted.\n");
}
}
*
*/
/* /*
* Handles parsing multiple statements or expressions in a row. * Handles parsing multiple statements or expressions in a row.
* These are typically grouped together with the Compound tokens "{ }" * These are typically grouped together with the Compound tokens "{ }"
@ -185,7 +210,7 @@ static int ParsePointerType(int Type) {
*/ */
static struct SymbolTableEntry* ParseArrayDeclaration(char* name, int Type, struct SymbolTableEntry* CompositeType, int Storage) { static struct SymbolTableEntry* ParseArrayDeclaration(char* name, int Type, struct SymbolTableEntry* CompositeType, int Storage) {
struct SymbolTableEntry* Symbol = NULL; struct SymbolTableEntry* Symbol = NULL;
int Elems = -1, MaxElems, *InitialList, i, j; int Elems = -1, MaxElems, *InitialList, i = 0, j = 0;
Tokenise(); Tokenise();
Safe(); Safe();
@ -197,9 +222,17 @@ static struct SymbolTableEntry* ParseArrayDeclaration(char* name, int Type, stru
Tokenise(); Tokenise();
} }
VerifyToken(LI_RBRAC, "]"); VerifyToken(LI_RBRAS, "]");
Safe(); Safe();
switch (Storage) {
case SC_GLOBAL:
Symbol = AddSymbol(name, PointerTo(Type), ST_ARR, SC_GLOBAL, 0, 0, CompositeType);
break;
default:
ErrorReport("Local array declaration not supported\n");
}
if (CurrentFile->CurrentSymbol.type == LI_EQUAL) { if (CurrentFile->CurrentSymbol.type == LI_EQUAL) {
if (Storage != SC_GLOBAL) if (Storage != SC_GLOBAL)
ErrorReport("Non-global array cannot be initialized.\n"); ErrorReport("Non-global array cannot be initialized.\n");
@ -292,12 +325,12 @@ static struct SymbolTableEntry* ParseScalarDeclaration(char* name, int Type, str
* *
* @param CompositeType out: the type of the declaration list. * @param CompositeType out: the type of the declaration list.
* @param ClassType the type of the class * @param ClassType the type of the class
* @param StatementEndSymbool the symbol that marks the end of the declaration list * @param StatementEndSymbol the symbol that marks the end of the declaration list
* @param TerminateSymbol the symbol that marks the end of parsing * @param TerminateSymbol the symbol that marks the end of parsing
* @return the type of the declaration * @return the type of the declaration
* *
*/ */
int ParseDeclarationList(struct SymbolTableEntry** CompositeType, int ClassType, int StatementEndSymbool, int TerminateSymbol) { int ParseDeclarationList(struct SymbolTableEntry** CompositeType, int ClassType, int StatementEndSymbol, int TerminateSymbol) {
int initType, type; int initType, type;
struct SymbolTableEntry* symbol; struct SymbolTableEntry* symbol;
@ -319,7 +352,7 @@ int ParseDeclarationList(struct SymbolTableEntry** CompositeType, int ClassType,
} }
// Terminate at either symbol // Terminate at either symbol
if (CurrentFile->CurrentSymbol.type == StatementEndSymbool || CurrentFile->CurrentSymbol.type == TerminateSymbol) if (CurrentFile->CurrentSymbol.type == StatementEndSymbol || CurrentFile->CurrentSymbol.type == TerminateSymbol)
return type; return type;
// We must be continuing the list, so parse a comma // We must be continuing the list, so parse a comma
@ -529,6 +562,14 @@ static void ParseArrayInitialization(struct SymbolTableEntry* Symbol, int Type,
ErrorReport("Array initialization not permitted.\n"); ErrorReport("Array initialization not permitted.\n");
} }
static char* copyString(char* str) {
size_t len = strlen(str);
char *dst = malloc(len + 1); // Space for length plus nul
if (dst == NULL) return NULL; // No memory
strcpy(dst, str); // Copy the characters
return dst; // Return the new string
}
/* /*
* Parse a name symbol for a declaration. * Parse a name symbol for a declaration.
* Calls out to parse functions, arrays and scalars alike. * Calls out to parse functions, arrays and scalars alike.
@ -541,7 +582,8 @@ static void ParseArrayInitialization(struct SymbolTableEntry* Symbol, int Type,
*/ */
static struct SymbolTableEntry* ParseDeclarationSymbol(int Type, struct SymbolTableEntry* CompositeType, int Storage) { static struct SymbolTableEntry* ParseDeclarationSymbol(int Type, struct SymbolTableEntry* CompositeType, int Storage) {
struct SymbolTableEntry* symbol = NULL; struct SymbolTableEntry* symbol = NULL;
char* variableName = strdup(CurrentIdentifier); malloc(2);
char* variableName = copyString(CurrentIdentifier);
int structureType = ST_VAR; int structureType = ST_VAR;
Safe(); Safe();
@ -567,36 +609,17 @@ static struct SymbolTableEntry* ParseDeclarationSymbol(int Type, struct SymbolTa
} }
// Determine whether this is an array or scalar. // Determine whether this is an array or scalar.
if (CurrentFile->CurrentSymbol.type == LI_LBRAC) { if (CurrentFile->CurrentSymbol.type == LI_LBRAS) {
symbol = ParseArrayDeclaration(variableName, Type, CompositeType, Storage); symbol = ParseArrayDeclaration(variableName, Type, CompositeType, Storage);
structureType = ST_ARR; structureType = ST_ARR;
} else { } else {
symbol = ParseScalarDeclaration(variableName, Type, CompositeType, Storage); symbol = ParseScalarDeclaration(variableName, Type, CompositeType, Storage);
} }
// Determine whether we're initializing immediately
if (CurrentFile->CurrentSymbol.type == LI_EQUAL) {
// TODO: Default parameters
if (Storage == SC_PARAM)
ErrorReport("Initialization of parameter not permitted.\n");
// TODO: Enum initialization
if (Storage == SC_MEMBER)
ErrorReport("Initialization of a member not permitted.\n");
Tokenise();
if (structureType == ST_ARR) {
ParseArrayInitialization(symbol, Type, CompositeType, Storage);
} else {
// TODO: Inline initialization
ErrorReport("Initialization of a scalar not permitted.\n");
}
}
return symbol; return symbol;
} }
/* /*
* Handles the declaration of a new composite type. * Handles the declaration of a new composite type.
* For example, a struct is a composite of multiple different named positions: * For example, a struct is a composite of multiple different named positions:

View File

@ -190,7 +190,7 @@ struct SymbolTableEntry* FindMember(char* Symbol) {
*/ */
void AppendSymbol(struct SymbolTableEntry** Head, struct SymbolTableEntry** Tail, struct SymbolTableEntry* Node) { void AppendSymbol(struct SymbolTableEntry** Head, struct SymbolTableEntry** Tail, struct SymbolTableEntry* Node) {
if (Head == NULL || Tail == NULL || Node == NULL) if (Head == NULL || Tail == NULL || Node == NULL)
Die("Not enough data to append a symbol to the tables"); ErrorReport("Not enough data to append a symbol to the tables. Missing: %s\n", Head == NULL ? "Head" : Tail == NULL ? "Tail" : "Node");
if (*Tail) { if (*Tail) {
(*Tail)->NextSymbol = Node; (*Tail)->NextSymbol = Node;

View File

@ -42,7 +42,6 @@ int TypeIsPtr(int Type) {
*/ */
int PrimitiveSize(int Type) { int PrimitiveSize(int Type) {
if (TypeIsPtr(Type)) return 8; if (TypeIsPtr(Type)) return 8;
switch (Type) { switch (Type) {
case RET_CHAR: case RET_CHAR:
@ -52,7 +51,7 @@ int PrimitiveSize(int Type) {
case RET_LONG: case RET_LONG:
return 8; return 8;
default: default:
DieDecimal("Bad type in PrimitiveSize", Type); ErrorReport("Bad type in PrimitiveSize: %s\n", TypeNames(Type));
} }
return 0; return 0;
} }

View File

@ -169,7 +169,7 @@ static int AsAlignMemory(int Type, int Offset, int Direction) {
case RET_LONG: case RET_LONG:
break; break;
default: default:
DieDecimal("Unable to align type", Type); ErrorReport("Unable to align type %s\n", TypeNames(Type));
} }
int Alignment = 4; int Alignment = 4;
@ -713,7 +713,7 @@ static int AsStrDeref(int Register1, int Register2, int Type) {
} }
static void AsDataSegment() { static void AsDataSegment() {
fprintf(stdout, ".data:\n"); fprintf(OutputFile, ".data:\n");
} }
// Assemble a global symbol (variable, struct, enum, function, string) // Assemble a global symbol (variable, struct, enum, function, string)
@ -723,7 +723,7 @@ static void AsGlobalSymbol(struct SymbolTableEntry* Entry) {
if (Entry == NULL) return; if (Entry == NULL) return;
if (Entry->Structure == ST_FUNC) return; if (Entry->Structure == ST_FUNC) return;
if (Entry->Structure = ST_ARR) { if (Entry->Structure == ST_ARR) {
type = ValueAt(Entry->Type); type = ValueAt(Entry->Type);
size = TypeSize(type, Entry->CompositeType); size = TypeSize(type, Entry->CompositeType);
} else { } else {
@ -737,15 +737,15 @@ static void AsGlobalSymbol(struct SymbolTableEntry* Entry) {
for (i = 0; i < Entry->Length; i++) { for (i = 0; i < Entry->Length; i++) {
init = 0; init = 0;
if (Entry->InitialValues) if (Entry->InitialValues != NULL)
init = Entry->InitialValues[i]; init = Entry->InitialValues[i];
switch (size) { switch (size) {
case 1: case 1:
fprintf(OutputFile, "\t.byte\t0\r\n"); fprintf(OutputFile, "\t.byte\t%d\r\n", init);
break; break;
case 4: case 4:
fprintf(OutputFile, "\t.long\t0\r\n"); fprintf(OutputFile, "\t.long\t%d\r\n", init);
break; break;
case 8: case 8:
if (Entry->InitialValues && type == PointerTo(RET_CHAR)) if (Entry->InitialValues && type == PointerTo(RET_CHAR))

View File

@ -97,7 +97,7 @@ static int AssembleTree(struct ASTNode* Node, int Register, int LoopBeginLabel,
case OP_DEREF: case OP_DEREF:
default: default:
DieDecimal("Can't ASSIGN in AssembleTree: ", Node->Operation); ErrorReport("Can't ASSIGN in AssembleTree: %s", OperationNames[Node->Operation]);
}; return 0; }; return 0;
case OP_WIDEN: case OP_WIDEN:

View File

@ -1,21 +1,21 @@
import "tests/print.em" import "tests/print.em"
int stuff[] = { 5, 7, 9 };
int :: main() { int :: main() {
int x; int x;
int y; int y;
y = 0;
for (x = 0; x < 5; x++) { for (x = 0; x < 5; x++) {
y = 0;
switch(x) { switch(x) {
case 1: { case 1: {
y = 5; y = stuff[0];
break; } break; }
case 2: case 2:
y = 7; y = stuff[1];
break; break;
case 3: case 3:
y = 9; y = stuff[2];
default: default:
y = 100; y = 100;
} }