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
|
||||
#include <stdio.h>
|
||||
#include <Defs.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#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];
|
||||
|
||||
|
|
|
@ -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 * * * * * * * * *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
|
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[]) {
|
||||
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);
|
||||
}
|
|
@ -11,7 +11,7 @@ int :: main() {
|
|||
|
||||
textbuffer = " ";
|
||||
|
||||
sourcefile = open("tests/cat", 0);
|
||||
sourcefile = open("tests/cat.er", 0);
|
||||
if(sourcefile =? -1) {
|
||||
return (1);
|
||||
}
|
Loading…
Reference in New Issue
Block a user