diff --git a/.gitignore b/.gitignore index 6020296..4938d55 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,9 @@ bison.output yab *.o *.so +*.log .vscode/* yab2cpp tester output/* +runtime/main diff --git a/Makefile b/Makefile index 4ee2ae2..5a51f8c 100644 --- a/Makefile +++ b/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 \ No newline at end of file + rm -rf build/* output/* yab2cpp tester + \ No newline at end of file diff --git a/runtime/Makefile b/runtime/Makefile new file mode 100644 index 0000000..b254864 --- /dev/null +++ b/runtime/Makefile @@ -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 \ No newline at end of file diff --git a/runtime/main.cpp b/runtime/main.cpp new file mode 100644 index 0000000..a212d59 --- /dev/null +++ b/runtime/main.cpp @@ -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; +} diff --git a/runtime/runtime.h b/runtime/runtime.h new file mode 100644 index 0000000..2651161 --- /dev/null +++ b/runtime/runtime.h @@ -0,0 +1,22 @@ +/* +** Practice runtime header for Yab2Cpp +** +** by Samuel D. Crow +*/ +#ifndef YAB_RUNTIME +#define YAB_RUTTIME + +#include +using namespace std; + +enum STATES:unsigned int +{ + EXIT, + UNDEFINED_STATE_ERROR, + START +}; + +/* function prototype */ +unsigned int run(); + +#endif diff --git a/tester.cpp b/tester.cpp index 5d50903..9dd57c8 100644 --- a/tester.cpp +++ b/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!" <\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_ptrprint=shared_ptr( new printSegment(shared_ptr(new expression(v)))); print->generate(); + label::generateEnd(); } /* open files and compile */ @@ -266,4 +287,3 @@ void compile() shutDown(); } - diff --git a/yab2cpp.h b/yab2cpp.h index 4932277..7a19bdb 100644 --- a/yab2cpp.h +++ b/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 > 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_ptre, enum SEPARATORS s); - printSegment(shared_ptre) {printSegment(e, S_LINEFEED);} - printSegment() {printSegment(NULL);} + printSegment(shared_ptre=NULL, enum SEPARATORS s=S_LINEFEED); virtual ~printSegment() {} }; diff --git a/yabCodeStructures.cpp b/yabCodeStructures.cpp index a502151..943380c 100644 --- a/yabCodeStructures.cpp +++ b/yabCodeStructures.cpp @@ -7,10 +7,11 @@ ** */ #include "yab2cpp.h" +#include "runtime/runtime.h" /* static initializers */ unordered_map > 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"; diff --git a/yabDataStructures.cpp b/yabDataStructures.cpp index 95fc718..b3099a8 100644 --- a/yabDataStructures.cpp +++ b/yabDataStructures.cpp @@ -10,25 +10,9 @@ /* forward declaration and static initializers */ class fn; -unsigned int operands::nextID; +unsigned int operands::nextID=0; unordered_map 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_ptrvalue) string arrayType::boxName(list >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 >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, listdim): diff --git a/yabFunctions.cpp b/yabFunctions.cpp index ca8cdcd..4d7e3de 100644 --- a/yabFunctions.cpp +++ b/yabFunctions.cpp @@ -11,7 +11,7 @@ /* static initializers */ unordered_map > fn::functions; list >fn::callStack; -unsigned int fn::nextID; +unsigned int fn::nextID=0; /* function definitions */ void fn::dumpCallStack() diff --git a/yabIO.cpp b/yabIO.cpp index 595c14b..1fb1eb8 100644 --- a/yabIO.cpp +++ b/yabIO.cpp @@ -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);