fixed bugs and added enough runtime to execute first code after the compiler segfaults at shutdown
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,7 +5,9 @@ bison.output
|
||||
yab
|
||||
*.o
|
||||
*.so
|
||||
*.log
|
||||
.vscode/*
|
||||
yab2cpp
|
||||
tester
|
||||
output/*
|
||||
runtime/main
|
||||
|
||||
13
Makefile
13
Makefile
@@ -5,8 +5,9 @@ CFLAGS += -Os
|
||||
LFLAGS :=
|
||||
|
||||
ODIR := build
|
||||
RDIR := output
|
||||
|
||||
YABCODESTRUCTURES_SOURCE_DEPS := yabCodeStructures.cpp yab2cpp.h yab2cpp.cpp tester.cpp
|
||||
YABCODESTRUCTURES_SOURCE_DEPS := yabCodeStructures.cpp yab2cpp.h yab2cpp.cpp tester.cpp runtime/runtime.h
|
||||
YAB2CPP_SOURCE_DEPS := yab2cpp.cpp yab2cpp.h tester.cpp
|
||||
YABDATASTRUCTURES_SOURCE_DEPS := yabDataStructures.cpp yab2cpp.h yab2cpp.cpp tester.cpp
|
||||
YABFUNCTIONS_SOURCE_DEPS := yabFunctions.cpp yab2cpp.h yab2cpp.cpp tester.cpp
|
||||
@@ -17,15 +18,18 @@ all: binaries
|
||||
$(ODIR):
|
||||
@mkdir $(ODIR)
|
||||
|
||||
$(RDIR):
|
||||
@mkdir $(RDIR)
|
||||
|
||||
binaries: bin_yab2cpp bin_tester
|
||||
|
||||
YAB2CPP_OBJECT_DEPS := $(ODIR)/yabCodeStructures.o $(ODIR)/yabFunctions.o $(ODIR)/yabDataStructures.o $(ODIR)/yabIO.o $(ODIR)/yab2cpp.o
|
||||
TESTER_OBJECT_DEPS := $(ODIR)/yabCodeStructures.o $(ODIR)/yabFunctions.o $(ODIR)/yabDataStructures.o $(ODIR)/yabIO.o $(ODIR)/tester.o
|
||||
|
||||
bin_tester: $(ODIR) $(TESTER_OBJECT_DEPS)
|
||||
bin_tester: $(RDIR) $(ODIR) $(TESTER_OBJECT_DEPS)
|
||||
$(CC) -o tester $(TESTER_OBJECT_DEPS) $(LFLAGS)
|
||||
|
||||
bin_yab2cpp: $(ODIR) $(YAB2CPP_OBJECT_DEPS)
|
||||
bin_yab2cpp: $(RDIR) $(ODIR) $(YAB2CPP_OBJECT_DEPS)
|
||||
$(CC) -o yab2cpp $(YAB2CPP_OBJECT_DEPS) $(LFLAGS)
|
||||
|
||||
$(ODIR)/yabCodeStructures.o: $(ODIR) $(YABCODESTRUCTURES_SOURCE_DEPS)
|
||||
@@ -48,4 +52,5 @@ $(ODIR)/yabFunctions.o: $(ODIR) $(YABFUNCTIONS_SOURCE_DEPS)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf build/* yab2cpp tester
|
||||
rm -rf build/* output/* yab2cpp tester
|
||||
|
||||
28
runtime/Makefile
Normal file
28
runtime/Makefile
Normal file
@@ -0,0 +1,28 @@
|
||||
CC := g++
|
||||
CFLAGS := -Wall
|
||||
CFLAGS += -std=c++11
|
||||
CFLAGS += -Os
|
||||
LFLAGS :=
|
||||
|
||||
all: binaries
|
||||
|
||||
binaries: bin_main
|
||||
|
||||
SRC := ../output/
|
||||
|
||||
OUTPUT_DEPS := $(SRC)consts.h $(SRC)heap.h $(SRC)functions.h runtime.h $(SRC)output.cpp
|
||||
|
||||
MAIN_OBJ_DEPS := output.o main.o
|
||||
|
||||
bin_main: $(MAIN_OBJ_DEPS)
|
||||
$(CC) -o main $(MAIN_OBJ_DEPS)
|
||||
|
||||
main.o: $(OUTPUT_DEPS)
|
||||
$(CC) -o main.o -c main.cpp
|
||||
|
||||
output.o: $(OUTPUT_DEPS)
|
||||
$(CC) -I$(SRC) -o output.o -c $(SRC)output.cpp
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf *.o main
|
||||
16
runtime/main.cpp
Normal file
16
runtime/main.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
** Practice runtime for Yab2Cpp
|
||||
**
|
||||
** by Samuel D. Crow
|
||||
*/
|
||||
#include "runtime.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned int ret=run();
|
||||
if (ret!=EXIT)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
22
runtime/runtime.h
Normal file
22
runtime/runtime.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
** Practice runtime header for Yab2Cpp
|
||||
**
|
||||
** by Samuel D. Crow
|
||||
*/
|
||||
#ifndef YAB_RUNTIME
|
||||
#define YAB_RUTTIME
|
||||
|
||||
#include <cstdio>
|
||||
using namespace std;
|
||||
|
||||
enum STATES:unsigned int
|
||||
{
|
||||
EXIT,
|
||||
UNDEFINED_STATE_ERROR,
|
||||
START
|
||||
};
|
||||
|
||||
/* function prototype */
|
||||
unsigned int run();
|
||||
|
||||
#endif
|
||||
64
tester.cpp
64
tester.cpp
@@ -94,7 +94,6 @@ void shutDown();
|
||||
/* process command line parameters */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
atexit(shutDown);
|
||||
switch (argc)
|
||||
{
|
||||
case 1:
|
||||
@@ -152,6 +151,7 @@ int main(int argc, char *argv[])
|
||||
helpText(argv[0]);
|
||||
break;
|
||||
}
|
||||
cout << "vamanos!" <<endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -179,15 +179,26 @@ void setUp()
|
||||
funcs_h.open("output/functions.h");
|
||||
consts_h.open("output/consts.h");
|
||||
heap_h.open("output/heap.h");
|
||||
output_cpp << "#include <runtime.h>\n#include \"consts.h\"\n"
|
||||
output_cpp << "#include \"../runtime/runtime.h\"\n#include \"consts.h\"\n"
|
||||
<< "#include \"heap.h\"\n#include \"functions.h\"\n"
|
||||
<< "int main(int argc, char *argv[])\n{\n"
|
||||
<< "unsigned int state=start;\nint run(){\nwhile (state>=start){\n"
|
||||
<< "switch(state){\ncase start:" << endl;
|
||||
if (DUMP)
|
||||
{
|
||||
varNames.open("varnames.txt");
|
||||
}
|
||||
<< "unsigned int state=START;\nunsigned int run(){\n"
|
||||
<< "while (state>=START){\n"
|
||||
<< "switch(state){\ncase START:" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
output_cpp.open("/dev/null");
|
||||
funcs_h.open("/dev/null");
|
||||
consts_h.open("/dev/null");
|
||||
heap_h.open("/dev/null");
|
||||
}
|
||||
if (DUMP)
|
||||
{
|
||||
varNames.open("varnames.log");
|
||||
}
|
||||
else
|
||||
{
|
||||
varNames.open("/dev/null");
|
||||
}
|
||||
if (DEBUG)
|
||||
{
|
||||
@@ -195,10 +206,15 @@ void setUp()
|
||||
logfile.open("parse.log");
|
||||
logger("Setup complete.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logfile.open("/dev/null");
|
||||
}
|
||||
}
|
||||
|
||||
[[noreturn]] void error(enum COMPILE_ERRORS e)
|
||||
{
|
||||
cerr << COMPILE_ERROR_NAMES[e] << endl;
|
||||
errorLevel=e;
|
||||
exit(1);
|
||||
}
|
||||
@@ -220,7 +236,7 @@ void logger(string s)
|
||||
if (DEBUG)
|
||||
{
|
||||
indent();
|
||||
logfile << s << endl;
|
||||
logfile << s << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,19 +246,23 @@ void shutDown()
|
||||
if (errorLevel != E_OK) cerr << "\nERROR: "
|
||||
<< COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl;
|
||||
logger("Dumping stack.");
|
||||
if (DUMP && (logfile))
|
||||
if (DUMP && (logfile)) fn::dumpCallStack();
|
||||
if (DUMP)
|
||||
{
|
||||
fn::dumpCallStack();
|
||||
}
|
||||
varNames << "Global Variables\n";
|
||||
for(auto iter=globals.begin(); iter!=globals.end(); ++iter)
|
||||
{
|
||||
varNames << "variable " << iter->first
|
||||
<< " has ID " << iter->second << "\n";
|
||||
}
|
||||
varNames << endl;
|
||||
varNames << "Global Variables\n";
|
||||
for(auto iter=globals.begin(); iter!=globals.end(); ++iter)
|
||||
{
|
||||
varNames << "variable " << iter->first
|
||||
<< " has ID " << iter->second->getID() << "\n";
|
||||
}
|
||||
varNames << endl;
|
||||
label::dumpLabels();
|
||||
output_cpp << "}\n}return state;\n}"<< endl;
|
||||
}
|
||||
if (COMPILE)
|
||||
{
|
||||
output_cpp << "default:\nstate=UNDEFINED_STATE_ERROR;\n"
|
||||
<< "break;\n}\n}\nreturn state;\n}"<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
void testInt()
|
||||
@@ -255,6 +275,7 @@ void testInt()
|
||||
shared_ptr<printSegment>print=shared_ptr<printSegment>(
|
||||
new printSegment(shared_ptr<expression>(new expression(v))));
|
||||
print->generate();
|
||||
label::generateEnd();
|
||||
}
|
||||
|
||||
/* open files and compile */
|
||||
@@ -266,4 +287,3 @@ void compile()
|
||||
|
||||
shutDown();
|
||||
}
|
||||
|
||||
|
||||
18
yab2cpp.h
18
yab2cpp.h
@@ -160,19 +160,6 @@ enum OPERATORS
|
||||
void indent();
|
||||
void logger(string s);
|
||||
|
||||
/* internal states used by the parser */
|
||||
class scope:public ofstream
|
||||
{
|
||||
enum SCOPES myscope;
|
||||
public:
|
||||
ofstream &operator<<(ostream &in);
|
||||
enum SCOPES getScope() const {return myscope;}
|
||||
|
||||
scope(enum SCOPES s){myscope=s;}
|
||||
~scope()
|
||||
{}
|
||||
};
|
||||
|
||||
class operands
|
||||
{
|
||||
enum TYPES type;
|
||||
@@ -268,6 +255,7 @@ class label
|
||||
static unordered_map<string, shared_ptr<label> > lookup;
|
||||
public:
|
||||
static void dumpLabels();
|
||||
static void generateEnd();
|
||||
|
||||
unsigned int getID() const {return id;}
|
||||
|
||||
@@ -450,9 +438,7 @@ class printSegment
|
||||
enum SEPARATORS sep;
|
||||
public:
|
||||
void generate();
|
||||
printSegment(shared_ptr<expression>e, enum SEPARATORS s);
|
||||
printSegment(shared_ptr<expression>e) {printSegment(e, S_LINEFEED);}
|
||||
printSegment() {printSegment(NULL);}
|
||||
printSegment(shared_ptr<expression>e=NULL, enum SEPARATORS s=S_LINEFEED);
|
||||
virtual ~printSegment()
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -7,10 +7,11 @@
|
||||
**
|
||||
*/
|
||||
#include "yab2cpp.h"
|
||||
#include "runtime/runtime.h"
|
||||
|
||||
/* static initializers */
|
||||
unordered_map<string, shared_ptr<label> > label::lookup;
|
||||
unsigned int label::nextID;
|
||||
unsigned int label::nextID=START;
|
||||
|
||||
/* base class of all the code structure types */
|
||||
codeType::codeType(enum CODES t)
|
||||
@@ -53,6 +54,11 @@ void label::dumpLabels()
|
||||
varNames << endl;
|
||||
}
|
||||
|
||||
void label::generateEnd()
|
||||
{
|
||||
output_cpp << "state=EXIT;\nbreak;\n";
|
||||
}
|
||||
|
||||
void label::generateJumpTo()
|
||||
{
|
||||
output_cpp << "state=" << this->getID() << ";\nbreak;\n";
|
||||
|
||||
@@ -10,25 +10,9 @@
|
||||
|
||||
/* forward declaration and static initializers */
|
||||
class fn;
|
||||
unsigned int operands::nextID;
|
||||
unsigned int operands::nextID=0;
|
||||
unordered_map<string, unsigned int> constOp::strConst;
|
||||
|
||||
/* scope methods */
|
||||
ofstream &scope::operator<<(ostream &in)
|
||||
{
|
||||
switch (this->myscope)
|
||||
{
|
||||
case S_LOCAL:
|
||||
return funcs_h;
|
||||
case S_GLOBAL:
|
||||
case S_STATIC:
|
||||
return heap_h;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
error(E_INTERNAL);
|
||||
}
|
||||
|
||||
/* methods for operands */
|
||||
enum TYPES operands::getSimpleVarType()
|
||||
{
|
||||
@@ -62,10 +46,8 @@ operands::operands(enum TYPES t)
|
||||
|
||||
void operands::generateBox(enum SCOPES s)
|
||||
{
|
||||
string x;
|
||||
scope y(s);
|
||||
stringstream ss;
|
||||
switch (this->getSimpleVarType())
|
||||
ostringstream ss;
|
||||
switch (this->getType())
|
||||
{
|
||||
case T_INTVAR:
|
||||
ss << "int v";
|
||||
@@ -80,8 +62,19 @@ void operands::generateBox(enum SCOPES s)
|
||||
error(E_TYPE_MISMATCH);
|
||||
}
|
||||
ss << this->getID() << ";\n";
|
||||
ss.str(x);
|
||||
y << x;
|
||||
switch (s)
|
||||
{
|
||||
case S_LOCAL:
|
||||
funcs_h << ss.str();
|
||||
return;
|
||||
case S_GLOBAL:
|
||||
case S_STATIC:
|
||||
heap_h << ss.str();
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
error(E_INTERNAL);
|
||||
}
|
||||
|
||||
string operands::boxName()
|
||||
@@ -94,7 +87,7 @@ string operands::boxName()
|
||||
case T_INTVAR:
|
||||
case T_FLOATVAR:
|
||||
s << 'v' << this->getID();
|
||||
s.str(x);
|
||||
x=s.str();
|
||||
s.clear();
|
||||
return x;
|
||||
break;
|
||||
@@ -108,7 +101,7 @@ void constOp::processConst(unsigned int i)
|
||||
{
|
||||
stringstream me;
|
||||
me << 'k' << i;
|
||||
me.str(box);
|
||||
box=me.str();
|
||||
}
|
||||
|
||||
void constOp::processConst( const string &s)
|
||||
@@ -401,7 +394,6 @@ void variableType::assignment(shared_ptr<expression>value)
|
||||
string arrayType::boxName(list<shared_ptr<operands> >indexes)
|
||||
{
|
||||
ostringstream out;
|
||||
string buf;
|
||||
auto i=indexes.begin();
|
||||
out << 'v' << this->getID();
|
||||
while (i!=indexes.end())
|
||||
@@ -409,15 +401,12 @@ string arrayType::boxName(list<shared_ptr<operands> >indexes)
|
||||
out << '[' << (*i)->boxName() << ']';
|
||||
++i;
|
||||
}
|
||||
out.str(buf);
|
||||
out.clear();
|
||||
return buf;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
string arrayType::generateBox(enum SCOPES s)
|
||||
{
|
||||
ostringstream out;
|
||||
string buf;
|
||||
switch (this->getType())
|
||||
{
|
||||
case T_STRINGCALL_ARRAY:
|
||||
@@ -438,9 +427,7 @@ string arrayType::generateBox(enum SCOPES s)
|
||||
out << '[' << *i << ']';
|
||||
}
|
||||
out << ";\n";
|
||||
out.str(buf);
|
||||
out.clear();
|
||||
return buf;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
arrayType::arrayType(string &name, enum TYPES t, list<unsigned int>dim):
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
/* static initializers */
|
||||
unordered_map<string, shared_ptr<fn> > fn::functions;
|
||||
list<shared_ptr<fn> >fn::callStack;
|
||||
unsigned int fn::nextID;
|
||||
unsigned int fn::nextID=0;
|
||||
|
||||
/* function definitions */
|
||||
void fn::dumpCallStack()
|
||||
|
||||
@@ -31,18 +31,19 @@ void printSegment::generate()
|
||||
output_cpp << "printf(\"%f\", " << op->boxName() << ");\n";
|
||||
break;
|
||||
default:
|
||||
error(E_TYPE_MISMATCH);
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (sep)
|
||||
{
|
||||
case S_LINEFEED:
|
||||
output_cpp << "puts(\"\n\");\n";
|
||||
output_cpp << "puts(\"\\n\");\n";
|
||||
return;
|
||||
case S_SEMICOLON:
|
||||
return;
|
||||
case S_COMMA:
|
||||
output_cpp << "putc('\t');\n";
|
||||
output_cpp << "putc('\\t');\n";
|
||||
return;
|
||||
default:
|
||||
error(E_BAD_SYNTAX);
|
||||
|
||||
Reference in New Issue
Block a user