diff --git a/src/Lexer.c b/src/Lexer.c index 7ad19ae..97d2ac2 100644 --- a/src/Lexer.c +++ b/src/Lexer.c @@ -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); } } diff --git a/src/Parser.c b/src/Parser.c index 7b04734..802d770 100644 --- a/src/Parser.c +++ b/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(); diff --git a/src/Pointers.c b/src/Pointers.c index 0dce068..9a88c35 100644 --- a/src/Pointers.c +++ b/src/Pointers.c @@ -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); diff --git a/src/Statements.c b/src/Statements.c index 235c270..04cc32d 100644 --- a/src/Statements.c +++ b/src/Statements.c @@ -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: diff --git a/src/Symbols.c b/src/Symbols.c index 58120d7..51ea0fd 100644 --- a/src/Symbols.c +++ b/src/Symbols.c @@ -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; diff --git a/src/Types.c b/src/Types.c index 634cdfb..c2ba01e 100644 --- a/src/Types.c +++ b/src/Types.c @@ -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; } diff --git a/src/assemble/ASMAssembler.c b/src/assemble/ASMAssembler.c index b2d8f78..6e02a1f 100644 --- a/src/assemble/ASMAssembler.c +++ b/src/assemble/ASMAssembler.c @@ -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)) diff --git a/src/assemble/JVMAssembler.c b/src/assemble/JVMAssembler.c index 36081bf..c789c9e 100644 --- a/src/assemble/JVMAssembler.c +++ b/src/assemble/JVMAssembler.c @@ -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: diff --git a/tests/switch.er b/tests/switch.er index b25ef74..7e32969 100644 --- a/tests/switch.er +++ b/tests/switch.er @@ -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; }