Wire in enhanced error handling to all crash situations
This commit is contained in:
parent
0f77480d5b
commit
bc787c3adb
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
15
src/Parser.c
15
src/Parser.c
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user