From bcd313270ff3d8d697588386be57fd75c44baa24 Mon Sep 17 00:00:00 2001 From: Curle Date: Mon, 18 Jan 2021 01:47:42 +0000 Subject: [PATCH] Rework compiler command line parsing, it can now assemble and link automatically --- include/Data.h | 10 ++++ include/Defs.h | 12 +++++ src/Delegate.c | 122 ++++++++++++++++++++++++++++++++++++++++++ src/Main.c | 95 ++++++++++++++++++++++++-------- tests/{cat => cat.er} | 2 +- 5 files changed, 218 insertions(+), 23 deletions(-) create mode 100644 src/Delegate.c rename tests/{cat => cat.er} (92%) diff --git a/include/Data.h b/include/Data.h index 654c869..162a2c1 100644 --- a/include/Data.h +++ b/include/Data.h @@ -6,6 +6,7 @@ #pragma once #include #include +#include #ifndef extern_ #define extern_ extern @@ -16,6 +17,15 @@ extern_ struct SymbolTable Symbols[SYMBOLS]; +extern_ bool OptDumpTree; +extern_ bool OptKeepAssembly; +extern_ bool OptAssembleFiles; +extern_ bool OptLinkFiles; +extern_ bool OptVerboseOutput; + +extern_ char* OutputFileName; +extern_ char* CurrentASMFile, *CurrentObjectFile; + extern_ int TypeSizes[9]; extern_ char* TypeNames[9]; diff --git a/include/Defs.h b/include/Defs.h index b4f8ecf..d833323 100644 --- a/include/Defs.h +++ b/include/Defs.h @@ -244,6 +244,18 @@ enum StructureType { // This is a typedef }; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * * * * * * A R G U M E N T S * * * * * * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +char* Suffixate(char* String, char Suffix); +char* Compile(char* InputFile); +char* Assemble(char* InputFile); +void Link(char* Output, char* Objects[]); +void DisplayUsage(char* ProgName); + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * L E X I N G * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ diff --git a/src/Delegate.c b/src/Delegate.c new file mode 100644 index 0000000..07e155e --- /dev/null +++ b/src/Delegate.c @@ -0,0 +1,122 @@ +/*************/ +/*GEMWIRE */ +/* ERYTHRO*/ +/*************/ + +#include +#include + +char* Suffixate(char* String, char Suffix) { + char* Pos, *NewStr; + + if((NewStr = strdup(String)) == NULL) + return NULL; + + if((Pos = strrchr(NewStr, '.')) == NULL) + return NULL; + + Pos++; + + if(*Pos == '\0') + return NULL; + + *Pos++ = Suffix; + *Pos = '\0'; + return NewStr; +} + +char* Compile(char* InputFile) { + char* OutputName; + OutputName = Suffixate(InputFile, 's'); + if(OutputName == NULL) { + fprintf(stderr, "%s must have a suffix.\r\n", InputFile); + exit(1); + } + + if((SourceFile = fopen(InputFile, "r")) == NULL) { + fprintf(stderr, "Unable to open %s: %s\n", InputFile, strerror(errno)); + exit(1); + } + + if((OutputFile = fopen(OutputName, "w")) == NULL) { + fprintf(stderr, "Unable to open %s: %s\n", OutputName, strerror(errno)); + exit(1); + } + + Line = 1; + Overread = '\n'; + CurrentGlobal = 0; + CurrentLocal = SYMBOLS - 1; + + if(OptVerboseOutput) + printf("Compiling %s\r\n", InputFile); + + Tokenise(&CurrentToken); + + AssemblerPreamble(); + + ParseGlobals(); + + fclose(OutputFile); + return OutputName; +} + +char* Assemble(char* InputFile) { + char Command[TEXTLEN]; + int Error; + char* OutputName; + OutputName = Suffixate(InputFile, 'o'); + if(OutputName == NULL) { + fprintf(stderr, "%s must have a suffix.\r\n", InputFile); + exit(1); + } + + snprintf(Command, TEXTLEN, "%s %s %s", "as -o ", OutputName, InputFile); + if(OptVerboseOutput) + printf("%s\n", Command); + + Error = system(Command); + + if(Error != 0) { + fprintf(stderr, "Assembling of %s failed with code %d\n", InputFile, Error); + exit(1); + } + return OutputName; +} + +void Link(char* Output, char* Objects[]) { + int Count, Size = TEXTLEN, Error; + char Command[TEXTLEN], *CommandPtr; + + CommandPtr = Command; + Count = snprintf(CommandPtr, Size, "%s %s ", "gcc -o ", OutputFileName); + CommandPtr += Count; + Size -= Count; + + while(*Objects != NULL) { + Count = snprintf(CommandPtr, Size, "%s ", *Objects); + CommandPtr += Count; + Size -= Count; + Objects++; + } + + if(OptVerboseOutput) + printf("%s\n", Command); + + Error = system(Command); + + if(Error != 0) { + fprintf(stderr, "Link failure\n"); + exit(1); + } +} + +void DisplayUsage(char* ProgName) { + fprintf(stderr, "Usage: %s -[vcST] {-o output} file [file ...]\n", ProgName); + fprintf(stderr, " -v: Verbose Output Level\n"); + fprintf(stderr, " -c: Compile without Linking\n"); + fprintf(stderr, " -S: Assemble without Linking\n"); + fprintf(stderr, " -T: Dump AST\n"); + fprintf(stderr, " -o: Name of the destination [executable/object/assembly] file.\n"); + exit(1); +} diff --git a/src/Main.c b/src/Main.c index 3dcc268..8aa2ad1 100644 --- a/src/Main.c +++ b/src/Main.c @@ -80,57 +80,108 @@ char* TypeNames[9] = { "none", "char", "int", "long", "void", "charptr", "intpt int main(int argc, char* argv[]) { - Line = 1; +/* Line = 1; Overread = '\n'; CurrentGlobal = 0; - CurrentLocal = SYMBOLS - 1; struct ASTNode* Node; + CurrentLocal = SYMBOLS - 1; */ + OptDumpTree = false; + OptKeepAssembly = false; + OptAssembleFiles = false; + OptLinkFiles = true; + OptVerboseOutput = false; + char* ObjectFiles[100]; + int ObjectCount = 0; + int i; + for(i = 1; i < argc; i++) { + if(*argv[i] != '-') // not a flag + break; - if((SourceFile = fopen(argv[1], "r")) == NULL) { - fprintf(stderr, "Unable to open %s: %s\n", argv[1], strerror(errno)); - exit(1); + for(int j = 1; (*argv[i] == '-') && argv[i][j]; j++) { + switch(argv[i][j]) { + case 'o': + OutputFileName = argv[++i]; + + break; + case 'T': + OptDumpTree = true; + break; + case 'c': + OptAssembleFiles = true; + OptKeepAssembly = false; + OptLinkFiles = false; + break; + case 'S': + OptAssembleFiles = false; + OptKeepAssembly = true; + OptLinkFiles = false; + break; + case 'v': + OptVerboseOutput = true; + break; + default: + DisplayUsage(argv[0]); + } + } } - if((OutputFile = fopen(argv[2], "w")) == NULL) { - fprintf(stderr, "Unable to open %s: %s\n", argv[2], strerror(errno)); - exit(1); + if(i >= argc) + DisplayUsage(argv[0]); + + while(i < argc) { + CurrentASMFile = Compile(argv[i]); + if(OptLinkFiles || OptAssembleFiles) { + CurrentObjectFile = Assemble(CurrentASMFile); + if(ObjectCount == 98) { + fprintf(stderr, "Too many inputs"); + return 1; + } + ObjectFiles[ObjectCount++] = CurrentObjectFile; + ObjectFiles[ObjectCount] = NULL; + } + + if(!OptKeepAssembly) + unlink(CurrentASMFile); + i++; } - Tokenise(&CurrentToken); + if(OptLinkFiles) { + Link(OutputFileName, ObjectFiles); + if(!OptAssembleFiles) { + for(i = 0; ObjectFiles[i] != NULL; i++) + unlink(ObjectFiles[i]); + } + } - AssemblerPreamble(); + return 0; - ParseGlobals(); - - //AsFunctionEpilogue(); - - //Node = ParsePrecedenceASTNode(); - //printf("%d\n", ParseAST(Node)); - - //AssembleNode(Node); - - fclose(OutputFile); - - exit(0); } void Die(char* Error) { fprintf(stderr, "%s on line %d\n", Error, Line); + fclose(OutputFile); + unlink(OutputFileName); exit(1); } void DieMessage(char* Error, char* Reason) { fprintf(stderr, "%s: %s on line %d\n", Error, Reason, Line); + fclose(OutputFile); + unlink(OutputFileName); exit(1); } void DieDecimal(char* Error, int Number) { fprintf(stderr, "%s: %d on line %d\n", Error, Number, Line); + fclose(OutputFile); + unlink(OutputFileName); exit(1); } void DieChar(char* Error, int Char) { fprintf(stderr, "%s: %c on line %d\n", Error, Char, Line); + fclose(OutputFile); + unlink(OutputFileName); exit(1); } \ No newline at end of file diff --git a/tests/cat b/tests/cat.er similarity index 92% rename from tests/cat rename to tests/cat.er index 402bf7d..65d6577 100644 --- a/tests/cat +++ b/tests/cat.er @@ -11,7 +11,7 @@ int :: main() { textbuffer = " "; - sourcefile = open("tests/cat", 0); + sourcefile = open("tests/cat.er", 0); if(sourcefile =? -1) { return (1); }