Rework compiler command line parsing, it can now assemble and link automatically
This commit is contained in:
parent
263e9d443a
commit
bcd313270f
|
@ -6,6 +6,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <Defs.h>
|
#include <Defs.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifndef extern_
|
#ifndef extern_
|
||||||
#define extern_ extern
|
#define extern_ extern
|
||||||
|
@ -16,6 +17,15 @@
|
||||||
|
|
||||||
extern_ struct SymbolTable Symbols[SYMBOLS];
|
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_ int TypeSizes[9];
|
||||||
extern_ char* TypeNames[9];
|
extern_ char* TypeNames[9];
|
||||||
|
|
||||||
|
|
|
@ -244,6 +244,18 @@ enum StructureType {
|
||||||
// This is a typedef
|
// 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 * * * * * * * * *
|
* * * * * * * * * L E X I N G * * * * * * * * *
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
122
src/Delegate.c
Normal file
122
src/Delegate.c
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
/*************/
|
||||||
|
/*GEMWIRE */
|
||||||
|
/* ERYTHRO*/
|
||||||
|
/*************/
|
||||||
|
|
||||||
|
#include <Defs.h>
|
||||||
|
#include <Data.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
95
src/Main.c
95
src/Main.c
|
@ -80,57 +80,108 @@ char* TypeNames[9] = { "none", "char", "int", "long", "void", "charptr", "intpt
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
Line = 1;
|
/* Line = 1;
|
||||||
Overread = '\n';
|
Overread = '\n';
|
||||||
CurrentGlobal = 0;
|
CurrentGlobal = 0;
|
||||||
CurrentLocal = SYMBOLS - 1;
|
|
||||||
struct ASTNode* Node;
|
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) {
|
for(int j = 1; (*argv[i] == '-') && argv[i][j]; j++) {
|
||||||
fprintf(stderr, "Unable to open %s: %s\n", argv[1], strerror(errno));
|
switch(argv[i][j]) {
|
||||||
exit(1);
|
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) {
|
if(i >= argc)
|
||||||
fprintf(stderr, "Unable to open %s: %s\n", argv[2], strerror(errno));
|
DisplayUsage(argv[0]);
|
||||||
exit(1);
|
|
||||||
|
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) {
|
void Die(char* Error) {
|
||||||
fprintf(stderr, "%s on line %d\n", Error, Line);
|
fprintf(stderr, "%s on line %d\n", Error, Line);
|
||||||
|
fclose(OutputFile);
|
||||||
|
unlink(OutputFileName);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DieMessage(char* Error, char* Reason) {
|
void DieMessage(char* Error, char* Reason) {
|
||||||
fprintf(stderr, "%s: %s on line %d\n", Error, Reason, Line);
|
fprintf(stderr, "%s: %s on line %d\n", Error, Reason, Line);
|
||||||
|
fclose(OutputFile);
|
||||||
|
unlink(OutputFileName);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DieDecimal(char* Error, int Number) {
|
void DieDecimal(char* Error, int Number) {
|
||||||
fprintf(stderr, "%s: %d on line %d\n", Error, Number, Line);
|
fprintf(stderr, "%s: %d on line %d\n", Error, Number, Line);
|
||||||
|
fclose(OutputFile);
|
||||||
|
unlink(OutputFileName);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DieChar(char* Error, int Char) {
|
void DieChar(char* Error, int Char) {
|
||||||
fprintf(stderr, "%s: %c on line %d\n", Error, Char, Line);
|
fprintf(stderr, "%s: %c on line %d\n", Error, Char, Line);
|
||||||
|
fclose(OutputFile);
|
||||||
|
unlink(OutputFileName);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
|
@ -11,7 +11,7 @@ int :: main() {
|
||||||
|
|
||||||
textbuffer = " ";
|
textbuffer = " ";
|
||||||
|
|
||||||
sourcefile = open("tests/cat", 0);
|
sourcefile = open("tests/cat.er", 0);
|
||||||
if(sourcefile =? -1) {
|
if(sourcefile =? -1) {
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user