diff --git a/include/Data.h b/include/Data.h index 7cdfcec..442e4d6 100644 --- a/include/Data.h +++ b/include/Data.h @@ -14,7 +14,6 @@ #endif #define TEXTLEN 512 -#define SYMBOLS 1024 // All currently open source files. extern_ struct FileData** Files; @@ -60,5 +59,3 @@ extern_ int Overread; extern_ char CurrentIdentifier[TEXTLEN + 1]; -extern_ int CurrentGlobal; -extern_ int CurrentLocal; diff --git a/include/Defs.h b/include/Defs.h index 5ab0d05..08797bf 100644 --- a/include/Defs.h +++ b/include/Defs.h @@ -352,7 +352,7 @@ void Compile(struct FileData* InputFile); void Assemble(struct FileData* InputFile); -void Link(char* Output, struct FileData* Objects[]); +void Link(char* Output, struct FileData* Objects[], int ObjectsLength); void DisplayUsage(char* ProgName); diff --git a/src/Assembler.c b/src/Assembler.c index b6dd080..6216b6c 100644 --- a/src/Assembler.c +++ b/src/Assembler.c @@ -79,9 +79,9 @@ int AssembleTree(struct ASTNode* Node, int Register, int LoopBeginLabel, int Loo return AsWhile(Node); case OP_COMP: - AssembleTree(Node->Left, -1, -1, -1, Node->Operation); + AssembleTree(Node->Left, -1, LoopBeginLabel, LoopEndLabel, Node->Operation); DeallocateAllRegisters(); - AssembleTree(Node->Right, -1, -1, -1, Node->Operation); + AssembleTree(Node->Right, -1, LoopBeginLabel, LoopEndLabel, Node->Operation); DeallocateAllRegisters(); return -1; @@ -90,17 +90,17 @@ int AssembleTree(struct ASTNode* Node, int Register, int LoopBeginLabel, int Loo case OP_FUNC: AsFunctionPreamble(Node->Symbol); - AssembleTree(Node->Left, -1, -1, -1, Node->Operation); + AssembleTree(Node->Left, -1, LoopBeginLabel, LoopEndLabel, Node->Operation); AsFunctionEpilogue(Node->Symbol); return -1; } if (Node->Left) - LeftVal = AssembleTree(Node->Left, -1, -1, -1, Node->Operation); + LeftVal = AssembleTree(Node->Left, -1, LoopBeginLabel, LoopEndLabel, Node->Operation); if (Node->Right) - RightVal = AssembleTree(Node->Right, LeftVal, -1, -1, Node->Operation); + RightVal = AssembleTree(Node->Right, LeftVal, LoopBeginLabel, LoopEndLabel, Node->Operation); switch (Node->Operation) { case OP_ADD: @@ -132,9 +132,11 @@ int AssembleTree(struct ASTNode* Node, int Register, int LoopBeginLabel, int Loo } case OP_BREAK: + printf("\t\tBreaking to the end of the loop; L%d\n", LoopEndLabel); AsJmp(LoopEndLabel); return -1; case OP_CONTINUE: + printf("\t\tContinuing to the start of the loop; L%d\n", LoopBeginLabel); AsJmp(LoopBeginLabel); return -1; @@ -368,9 +370,8 @@ int AsIf(struct ASTNode* Node, int LoopStartLabel, int LoopEndLabel) { if (Node->Right) EndLabel = NewLabel(); - // Left is the condition - AssembleTree(Node->Left, FalseLabel, -1, -1, Node->Operation); + AssembleTree(Node->Left, FalseLabel, LoopStartLabel, LoopEndLabel, Node->Operation); DeallocateAllRegisters(); // Middle is the true block @@ -913,9 +914,14 @@ int AsCall(struct SymbolTableEntry* Entry, int Args) { printf("\t\tCalling function %s with %d parameters\n", Entry->Name, Args); printf("\t\t\tFunction returns into %s\n", Registers[OutRegister]); + // Allocate shadow space + fprintf(OutputFile, "\taddq\t$-32, %rsp\n"); fprintf(OutputFile, "\tcall\t%s\n", Entry->Name); + // Deallocate arguments and stack space. if (Args > 4) - fprintf(OutputFile, "\taddq\t$%d, %%rsp\n", 8 * (Args - 4)); + fprintf(OutputFile, "\taddq\t$%d, %%rsp\n", (8 * (Args - 4)) + 32); + else + fprintf(OutputFile, "\taddq\t$32, %rsp\n"); fprintf(OutputFile, "\tmovq\t%%rax, %s\n", Registers[OutRegister]); diff --git a/src/Delegate.c b/src/Delegate.c index 8eab91f..868ac3f 100644 --- a/src/Delegate.c +++ b/src/Delegate.c @@ -128,6 +128,8 @@ void Assemble(struct FileData* InputFile) { exit(1); } + InputFile->ObjectName = OutputName; + snprintf(Command, TEXTLEN, "%s %s %s", "as -o ", OutputName, InputFile->AssemblyName); if (OptVerboseOutput) printf("%s\n", Command); @@ -152,8 +154,8 @@ void Assemble(struct FileData* InputFile) { * */ -void Link(char* Output, struct FileData* Objects[]) { - int Count, Size = TEXTLEN, Error; +void Link(char* Output, struct FileData** Objects, int ObjectsLength) { + int Count, Size = TEXTLEN, Error, ObjectIdx = 0; char Command[TEXTLEN], * CommandPtr; CommandPtr = Command; @@ -161,11 +163,11 @@ void Link(char* Output, struct FileData* Objects[]) { CommandPtr += Count; Size -= Count; - while (*Objects != NULL) { - Count = snprintf(CommandPtr, Size, "%s ", (*Objects)->ObjectName); + while (ObjectIdx < ObjectsLength - 1) { + Count = snprintf(CommandPtr, Size, "%s ", Objects[ObjectIdx]->ObjectName); CommandPtr += Count; Size -= Count; - Objects++; + ObjectIdx++; } if (OptVerboseOutput) diff --git a/src/Importer.c b/src/Importer.c index 99ca587..40b7c4f 100644 --- a/src/Importer.c +++ b/src/Importer.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -75,13 +74,22 @@ // Create a new file with the module name struct FileData* ModuleData = malloc(sizeof(struct FileData)); + memset(ModuleData, 0, sizeof(struct FileData)); ModuleData->AllowDefinitions = false; ModuleData->SourceName = ModulePath; printf("Swapping to module %s..\n\n", ModulePath); // Parse all relevant data from the module file... - Compile(ModuleData); + if ((ModuleData->Stream = fopen(ModuleData->SourceName, "r")) == NULL) { + fprintf(stderr, "Unable to open %s: %s\n", ModuleData->SourceName, strerror(errno)); + exit(1); + } + CurrentFile = ModuleData; + CurrentFile->CurrentLine = 1; + Tokenise(); + ParseGlobals(); + fclose(CurrentFile->Stream); printf("\n\nSwapping back to file %s..\n", SavedFile->SourceName); diff --git a/src/Main.c b/src/Main.c index 2042f84..e17c3e8 100644 --- a/src/Main.c +++ b/src/Main.c @@ -97,7 +97,7 @@ int main(int argc, char* argv[]) { // Option initialisers OptDumpTree = false; OptKeepAssembly = true; - OptAssembleFiles = false; + OptAssembleFiles = true; OptLinkFiles = true; OptVerboseOutput = false; @@ -147,16 +147,21 @@ int main(int argc, char* argv[]) { if (i >= argc) DisplayUsage(argv[0]); + int StartOfFiles = i; // Allocate enough files for the full specified source code - Files = malloc(sizeof(struct FileData) * i); + Files = malloc(sizeof(struct FileData*) * (argc - i) + 1); + memset(Files, 0, sizeof(struct FileData*) * (argc - i) + 1); + // For the rest of the files specified, we can iterate them right to left. while (i < argc) { // Prepare the source metadata before we start compiling struct FileData* Source = malloc(sizeof(struct FileData)); + memset(Source, 0, sizeof(struct FileData)); Source->SourceName = argv[i]; Source->AllowDefinitions = true; - Files[i] = Source; + printf("Compiling file %d (%s)\n", i - StartOfFiles, argv[i]); + Files[i - StartOfFiles] = Source; // Compile the file by invoking the Delegate Compile(Source); @@ -164,12 +169,6 @@ int main(int argc, char* argv[]) { // If we need to assemble (or link, which requires assembly) // then we invoke the Delegate again Assemble(Source); - // We can only keep track of 99 objects, so we should crash at 98 to ensure we have enough room for the output file too. - if (ObjectCount == 98) { - fprintf(stderr, "Too many inputs"); - return 1; // We use return because we're in main, rather than invoking Die. - } - } if (!OptKeepAssembly) @@ -181,10 +180,10 @@ int main(int argc, char* argv[]) { if (OptLinkFiles) { // If needed, invoke the Delegate one last time. - Link(OutputFileName, Files); + Link(OutputFileName, Files, (argc - StartOfFiles) + 1); if (!OptAssembleFiles) { // Even though we need to assemble to link, we can respect the user's options and delete the intermediary files. - for (i = 0; Files[i] != NULL; i++) { + for (i = 0; i < (argc - StartOfFiles) + 1; i++) { unlink(Files[i]->AssemblyName); unlink(Files[i]->ObjectName); } diff --git a/src/Statements.c b/src/Statements.c index 307706f..4808c23 100644 --- a/src/Statements.c +++ b/src/Statements.c @@ -256,7 +256,7 @@ struct ASTNode* ParseFunction(int Type) { struct ASTNode* Tree; struct ASTNode* FinalStatement; struct SymbolTableEntry* OldFunction, * NewFunction = NULL; - int SymbolSlot, BreakLabel, ParamCount, ID; + int BreakLabel = 0, ParamCount = 0; if ((OldFunction = FindSymbol(CurrentIdentifier)) != NULL) if (OldFunction->Storage != ST_FUNC) diff --git a/tests/breakcontinue.er b/tests/breakcontinue.er index ea3eab6..8e08caf 100644 --- a/tests/breakcontinue.er +++ b/tests/breakcontinue.er @@ -11,6 +11,7 @@ int :: main() { } if (x =? 10) { + x = x + 2; continue; }