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

View File

@ -101,7 +101,7 @@ struct ASTNode* ConstructASTNode(int Operation, int Type,
Node = (struct ASTNode*) malloc(sizeof(struct ASTNode));
if (!Node)
Die("Unable to allocate node!");
ErrorReport("Unable to allocate node: %s\n", errno);
Node->Operation = Operation;
@ -158,7 +158,7 @@ int ParseTokenToOperation(int Token) {
if (Token > LI_EOF && Token < LI_INT)
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);
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
printf("\t\tAssigning variable: %s\n", LeftNode->Symbol->Name);
@ -292,7 +292,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
*/
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
@ -304,7 +304,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
if (LeftTemp != NULL)
LeftNode = LeftTemp; //ConstructASTBranch(LeftType, RightNode->ExprType, LeftNode, 0);
LeftNode = LeftTemp;
/**
* Same here, but there is a higher chance
@ -313,7 +313,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
*/
if (RightTemp != NULL)
RightNode = RightTemp; // ConstructASTBranch(RightType, LeftNode->ExprType, RightNode, 0);
RightNode = RightTemp;
}
@ -352,7 +352,7 @@ struct ASTNode* CallFunction() {
//TODO: Test structural type!
if ((Function = FindSymbol(CurrentIdentifier)) == NULL || (Function->Structure != ST_FUNC))
DieMessage("Undeclared function", CurrentIdentifier);
ErrorReport("Undeclared function: %s\n", CurrentIdentifier);
VerifyToken(LI_LPARE, "(");
@ -386,6 +386,7 @@ struct ASTNode* ParseExpressionList(int terminate) {
Safe();
while (CurrentFile->CurrentSymbol.type != terminate) {
// TODO: for(int x = 0;
Child = ParsePrecedenceASTNode(0);
Count++;
Safe();

View File

@ -37,7 +37,7 @@
int PointerTo(int Type) {
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));
return (Type + 1);
}
@ -53,7 +53,7 @@ int PointerTo(int Type) {
int ValueAt(int Type) {
printf("\t\tDereferencing a %s\n", TypeNames(Type));
if ((Type & 0xf) == 0x0)
DieDecimal("Unrecognized type in defererencing", Type);
ErrorReport("Unrecognized type in defererencing: %d (%s)\n", Type, TypeNames(Type));
return (Type - 1);
}
@ -74,7 +74,7 @@ struct ASTNode* AccessArray() {
printf("\tAccessing array %s as requested\r\n", CurrentIdentifier);
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);
Tokenise();
@ -84,7 +84,7 @@ struct ASTNode* AccessArray() {
VerifyToken(LI_RBRAS, "]");
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),
TypeNames(LeftNode->ExprType));
@ -114,11 +114,13 @@ struct ASTNode* AccessMember(bool Deref) {
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)))
DieMessage("Undeclared struct", CurrentIdentifier);
ErrorReport("Undeclared struct: %s\n", CurrentIdentifier);
if (!Deref && (CompositeVar->Type != DAT_STRUCT && CompositeVar->Type != DAT_UNION))
DieMessage("Undeclared struct", CurrentIdentifier);
ErrorReport("Undeclared struct: %s\n", CurrentIdentifier);
Safe();
if (Deref)
LeftNode = ConstructASTLeaf(REF_IDENT, PointerTo(CompositeVar->Type), CompositeVar, 0);
@ -140,8 +142,9 @@ struct ASTNode* AccessMember(bool Deref) {
}
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);
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 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.
* 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) {
struct SymbolTableEntry* Symbol = NULL;
int Elems = -1, MaxElems, *InitialList, i, j;
int Elems = -1, MaxElems, *InitialList, i = 0, j = 0;
Tokenise();
Safe();
@ -197,9 +222,17 @@ static struct SymbolTableEntry* ParseArrayDeclaration(char* name, int Type, stru
Tokenise();
}
VerifyToken(LI_RBRAC, "]");
VerifyToken(LI_RBRAS, "]");
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 (Storage != SC_GLOBAL)
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 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
* @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;
struct SymbolTableEntry* symbol;
@ -319,7 +352,7 @@ int ParseDeclarationList(struct SymbolTableEntry** CompositeType, int ClassType,
}
// Terminate at either symbol
if (CurrentFile->CurrentSymbol.type == StatementEndSymbool || CurrentFile->CurrentSymbol.type == TerminateSymbol)
if (CurrentFile->CurrentSymbol.type == StatementEndSymbol || CurrentFile->CurrentSymbol.type == TerminateSymbol)
return type;
// 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");
}
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.
* 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) {
struct SymbolTableEntry* symbol = NULL;
char* variableName = strdup(CurrentIdentifier);
malloc(2);
char* variableName = copyString(CurrentIdentifier);
int structureType = ST_VAR;
Safe();
@ -567,36 +609,17 @@ static struct SymbolTableEntry* ParseDeclarationSymbol(int Type, struct SymbolTa
}
// 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);
structureType = ST_ARR;
} else {
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;
}
/*
* Handles the declaration of a new composite type.
* 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) {
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) {
(*Tail)->NextSymbol = Node;

View File

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

View File

@ -169,7 +169,7 @@ static int AsAlignMemory(int Type, int Offset, int Direction) {
case RET_LONG:
break;
default:
DieDecimal("Unable to align type", Type);
ErrorReport("Unable to align type %s\n", TypeNames(Type));
}
int Alignment = 4;
@ -713,7 +713,7 @@ static int AsStrDeref(int Register1, int Register2, int Type) {
}
static void AsDataSegment() {
fprintf(stdout, ".data:\n");
fprintf(OutputFile, ".data:\n");
}
// 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->Structure == ST_FUNC) return;
if (Entry->Structure = ST_ARR) {
if (Entry->Structure == ST_ARR) {
type = ValueAt(Entry->Type);
size = TypeSize(type, Entry->CompositeType);
} else {
@ -737,15 +737,15 @@ static void AsGlobalSymbol(struct SymbolTableEntry* Entry) {
for (i = 0; i < Entry->Length; i++) {
init = 0;
if (Entry->InitialValues)
if (Entry->InitialValues != NULL)
init = Entry->InitialValues[i];
switch (size) {
case 1:
fprintf(OutputFile, "\t.byte\t0\r\n");
fprintf(OutputFile, "\t.byte\t%d\r\n", init);
break;
case 4:
fprintf(OutputFile, "\t.long\t0\r\n");
fprintf(OutputFile, "\t.long\t%d\r\n", init);
break;
case 8:
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:
default:
DieDecimal("Can't ASSIGN in AssembleTree: ", Node->Operation);
ErrorReport("Can't ASSIGN in AssembleTree: %s", OperationNames[Node->Operation]);
}; return 0;
case OP_WIDEN:

View File

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