added printSegment class and started tester for framework

This commit is contained in:
Samuel D. Crow
2021-03-24 12:47:00 -05:00
parent f0ad605119
commit 7c5bf76778
8 changed files with 380 additions and 55 deletions

2
.gitignore vendored
View File

@@ -7,3 +7,5 @@ yab
*.so *.so
.vscode/* .vscode/*
yab2cpp yab2cpp
tester
output/*

View File

@@ -6,19 +6,24 @@ LFLAGS :=
ODIR := build ODIR := build
YABCODESTRUCTURES_SOURCE_DEPS := yabCodeStructures.cpp yab2cpp.h yab2cpp.cpp YABCODESTRUCTURES_SOURCE_DEPS := yabCodeStructures.cpp yab2cpp.h yab2cpp.cpp tester.cpp
YAB2CPP_SOURCE_DEPS := yab2cpp.cpp yab2cpp.h YAB2CPP_SOURCE_DEPS := yab2cpp.cpp yab2cpp.h tester.cpp
YABDATASTRUCTURES_SOURCE_DEPS := yabDataStructures.cpp yab2cpp.h yab2cpp.cpp YABDATASTRUCTURES_SOURCE_DEPS := yabDataStructures.cpp yab2cpp.h yab2cpp.cpp tester.cpp
YABFUNCTIONS_SOURCE_DEPS := yabFunctions.cpp yab2cpp.h yab2cpp.cpp YABFUNCTIONS_SOURCE_DEPS := yabFunctions.cpp yab2cpp.h yab2cpp.cpp tester.cpp
YABIO_SOURCE_DEPS := yab2cpp.h yab2cpp.cpp tester.cpp
all: binaries all: binaries
$(ODIR): $(ODIR):
@mkdir $(ODIR) @mkdir $(ODIR)
binaries: bin_yab2cpp binaries: bin_yab2cpp bin_tester
YAB2CPP_OBJECT_DEPS := $(ODIR)/yabCodeStructures.o $(ODIR)/yabFunctions.o $(ODIR)/yabDataStructures.o $(ODIR)/yab2cpp.o 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)
$(CC) -o tester $(TESTER_OBJECT_DEPS) $(LFLAGS)
bin_yab2cpp: $(ODIR) $(YAB2CPP_OBJECT_DEPS) bin_yab2cpp: $(ODIR) $(YAB2CPP_OBJECT_DEPS)
$(CC) -o yab2cpp $(YAB2CPP_OBJECT_DEPS) $(LFLAGS) $(CC) -o yab2cpp $(YAB2CPP_OBJECT_DEPS) $(LFLAGS)
@@ -26,9 +31,15 @@ bin_yab2cpp: $(ODIR) $(YAB2CPP_OBJECT_DEPS)
$(ODIR)/yabCodeStructures.o: $(ODIR) $(YABCODESTRUCTURES_SOURCE_DEPS) $(ODIR)/yabCodeStructures.o: $(ODIR) $(YABCODESTRUCTURES_SOURCE_DEPS)
$(CC) -c $(CFLAGS) yabCodeStructures.cpp -o $(ODIR)/yabCodeStructures.o $(CC) -c $(CFLAGS) yabCodeStructures.cpp -o $(ODIR)/yabCodeStructures.o
$(ODIR)/tester.o: $(ODIR) $(YAB2CPP_SOURCE_DEPS)
$(CC) -c $(CFLAGS) tester.cpp -o $(ODIR)/tester.o
$(ODIR)/yab2cpp.o: $(ODIR) $(YAB2CPP_SOURCE_DEPS) $(ODIR)/yab2cpp.o: $(ODIR) $(YAB2CPP_SOURCE_DEPS)
$(CC) -c $(CFLAGS) yab2cpp.cpp -o $(ODIR)/yab2cpp.o $(CC) -c $(CFLAGS) yab2cpp.cpp -o $(ODIR)/yab2cpp.o
$(ODIR)/yabIO.o: $(ODIR) $(YABIO_SOURCE_DEPS)
$(CC) -c $(CFLAGS) yabIO.cpp -o $(ODIR)/yabIO.o
$(ODIR)/yabDataStructures.o: $(ODIR) $(YABDATASTRUCTURES_SOURCE_DEPS) $(ODIR)/yabDataStructures.o: $(ODIR) $(YABDATASTRUCTURES_SOURCE_DEPS)
$(CC) -c $(CFLAGS) yabDataStructures.cpp -o $(ODIR)/yabDataStructures.o $(CC) -c $(CFLAGS) yabDataStructures.cpp -o $(ODIR)/yabDataStructures.o
@@ -37,4 +48,4 @@ $(ODIR)/yabFunctions.o: $(ODIR) $(YABFUNCTIONS_SOURCE_DEPS)
.PHONY: clean .PHONY: clean
clean: clean:
rm -rf build/* yab2cpp rm -rf build/* yab2cpp tester

269
tester.cpp Normal file
View File

@@ -0,0 +1,269 @@
/*
** Tester.cpp
**
** Transpiler framework tester
** by Samuel D. Crow
**
** Based on Yab
**
*/
#include "yab2cpp.h"
#include <cassert>
unordered_map<string, shared_ptr<variableType> >globals;
unordered_map<string, shared_ptr<variableType> >locals;
unordered_map<string, shared_ptr<variableType> >statics;
/* These correspond to the enum COMPILE_ERRORS. */
const char *COMPILE_ERROR_NAMES[]={
"no error",
"incorrect syntax",
"wrong type",
"failed allocation",
"stack underflow",
"internal compiler error",
"duplicated label",
"previous subroutine didn't end",
"value returned from gosub call",
"undefined subroutine name",
"too many parameters in function call",
"value cannot be assigned"
};
/* These correspond to the types of enum TYPES. */
const string TYPENAMES[]={
"unknown",
"none",
"string constant",
"integer constant",
"floating point constant",
"string variable",
"integer variable",
"floating point variable",
"string array or function",
"integer array or function",
"floating point array or function",
"string array or function",
"function"
};
const string CODETYPES[]={
"print sequence",
"print segment",
"while loop",
"for loop",
"repeat loop",
"do loop",
"if statement",
"procedure statement",
"function statement",
"assignment",
"label",
"parameter list or array index",
"data item",
"function returning string",
"function returning floating point",
"function returning integer",
"function returning nothing",
"function"
};
enum COMPILE_ERRORS errorLevel=E_OK;
unsigned int indentLevel=0;
bool scopeGlobal=true;
bool COMPILE=false;
bool DUMP=false;
bool DEBUG=false;
bool TRACE=false;
ifstream src;
ofstream output_cpp;
ofstream funcs_h;
ofstream heap_h;
ofstream consts_h;
ofstream logfile;
ofstream varNames;
/* private prototypes */
void helpText(const string);
void setup();
void compile();
void shutDown();
/* process command line parameters */
int main(int argc, char *argv[])
{
atexit(shutDown);
switch (argc)
{
case 1:
COMPILE=true;
cout << "\nCompile initiated." << endl;
compile();
break;
case 2:
if (argv[1][0]=='-')
{
switch (argv[1][1])
{
case 'd':
cout << "\nIdentifier dump initiated." << endl;
DUMP=true;
compile();
break;
case 'v':
cout << "\n" << argv[0] << " version "
<< VER_MAJOR << "." << VER_MINOR << "." << VER_RELEASE << endl;
break;
case 'V':
cout << "\nVerbose compile initiated." << endl;
DUMP=true;
COMPILE=true;
compile();
break;
case 'D':
cout << "\nCompiler debug and dump mode initiated." << endl;
DUMP=true;
DEBUG=true;
compile();
break;
case 'G':
cout << "\nDebug, dump and compile initiated." << endl;
DUMP=true;
DEBUG=true;
COMPILE=true;
compile();
break;
case 't':
cout << "\nDebug, dump and trace initiated." << endl;
DEBUG=true;
DUMP=true;
TRACE=true;
compile();
break;
default:
helpText(argv[0]);
break;
}
}
break;
default:
helpText(argv[0]);
break;
}
return 0;
}
/* print the help text to stdout */
void helpText(const string commandname)
{
cout << commandname << "[-d|D|V|v|G|t] < filename.mb\n" <<
"Compiles filename.mb by default unless a flag is specified.\n" <<
"\n The optional flags are as follows:\n" <<
"-d is a dump of build to the parse.log file.\n" <<
"-D is a dump of identifiers and logged build.\n" <<
"-V is for a verbose build where the compiler logs and compiles.\n" <<
"-v prints the version and exits.\n" <<
"-t activates dump, debug and trace\n" <<
"-G activates dump, debug and compile all at once.\n" << endl;
}
/* open files and initialize them*/
void setUp()
{
if (COMPILE)
{
/* compile mode */
output_cpp.open("output/output.cpp");
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"
<< "#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");
}
}
if (DEBUG)
{
/* dump identifier mode */
logfile.open("parse.log");
logger("Setup complete.");
}
}
[[noreturn]] void error(enum COMPILE_ERRORS e)
{
errorLevel=e;
exit(1);
}
void indent()
{
unsigned int count=indentLevel;
while (count > 0)
{
logfile << '\t';
--count;
}
}
/* write a note in the logfile */
void logger(string s)
{
if (DEBUG)
{
indent();
logfile << s << endl;
}
}
/* shutdown the compiler and exit */
void shutDown()
{
if (errorLevel != E_OK) cerr << "\nERROR: "
<< COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl;
logger("Dumping stack.");
if (DUMP && (logfile))
{
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;
label::dumpLabels();
output_cpp << "}\n}return state;\n}"<< endl;
}
void testInt()
{
string name="v";
shared_ptr<variableType>v=
variableType::getOrCreateVar(name, T_INTVAR);
v->assignment(shared_ptr<expression>(new expression(
shared_ptr<operands>(new constOp("2", T_INT)))));
shared_ptr<printSegment>print=shared_ptr<printSegment>(
new printSegment(shared_ptr<expression>(new expression(v))));
print->generate();
}
/* open files and compile */
void compile()
{
setUp();
testInt();
shutDown();
}

View File

@@ -8,9 +8,9 @@
*/ */
#include "yab2cpp.h" #include "yab2cpp.h"
unordered_map<string, shared_ptr<variable> >globals; unordered_map<string, shared_ptr<variableType> >globals;
unordered_map<string, shared_ptr<variable> >locals; unordered_map<string, shared_ptr<variableType> >locals;
unordered_map<string, shared_ptr<variable> >statics; unordered_map<string, shared_ptr<variableType> >statics;
/* These correspond to the enum COMPILE_ERRORS. */ /* These correspond to the enum COMPILE_ERRORS. */
const char *COMPILE_ERROR_NAMES[]={ const char *COMPILE_ERROR_NAMES[]={
@@ -179,6 +179,7 @@ void setUp()
heap_h.open("output/heap.h"); heap_h.open("output/heap.h");
output_cpp << "#include <runtime.h>\n#include \"consts.h\"\n" output_cpp << "#include <runtime.h>\n#include \"consts.h\"\n"
<< "#include \"heap.h\"\n#include \"functions.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" << "unsigned int state=start;\nint run(){\nwhile (state>=start){\n"
<< "switch(state){\ncase start:" << endl; << "switch(state){\ncase start:" << endl;
if (DUMP) if (DUMP)

View File

@@ -22,16 +22,16 @@ using namespace std;
#define VER_MINOR 0 #define VER_MINOR 0
#define VER_RELEASE 1 #define VER_RELEASE 1
class variable; class variableType;
extern ofstream output_cpp; extern ofstream output_cpp;
extern ofstream funcs_h; extern ofstream funcs_h;
extern ofstream heap_h; extern ofstream heap_h;
extern ofstream consts_h; extern ofstream consts_h;
extern ofstream logfile; extern ofstream logfile;
extern ofstream varNames; extern ofstream varNames;
extern unordered_map<string, shared_ptr<variable> >globals; extern unordered_map<string, shared_ptr<variableType> >globals;
extern unordered_map<string, shared_ptr<variable> >locals; extern unordered_map<string, shared_ptr<variableType> >locals;
extern unordered_map<string, shared_ptr<variable> >statics; extern unordered_map<string, shared_ptr<variableType> >statics;
extern const string CODETYPES[]; extern const string CODETYPES[];
extern const string TYPENAMES[]; extern const string TYPENAMES[];
@@ -67,7 +67,7 @@ extern bool DUMP;
extern bool DEBUG; extern bool DEBUG;
extern bool TRACE; extern bool TRACE;
/* list of all variable and constant types */ /* list of all variableType and constant types */
enum TYPES enum TYPES
{ {
T_UNKNOWN=0, T_UNKNOWN=0,
@@ -245,7 +245,7 @@ public:
op=x; op=x;
oper=O_TERM; oper=O_TERM;
} }
/*TODO: Recycle temporary variables when not in debug mode*/ /*TODO: Recycle temporary variableTypes when not in debug mode*/
virtual ~expression() virtual ~expression()
{} {}
}; };
@@ -357,21 +357,21 @@ public:
{} {}
}; };
class variable:public operands class variableType:public operands
{ {
enum SCOPES myScope; enum SCOPES myScope;
public: public:
static shared_ptr<variable>getOrCreateVar(string &name, enum TYPES t); static shared_ptr<variableType>getOrCreateVar(string &name, enum TYPES t);
void assignment(shared_ptr<expression>value); void assignment(shared_ptr<expression>value);
/* always call generateBox() after new variable() */ /* always call generateBox() after new variableType() */
variable(enum SCOPES s, string &name, enum TYPES t); variableType(enum SCOPES s, string &name, enum TYPES t);
variable(); variableType();
~variable() ~variableType()
{} {}
}; };
class arrayType:public variable class arrayType:public variableType
{ {
list<unsigned int> dimensions; list<unsigned int> dimensions;
public: public:
@@ -383,23 +383,23 @@ public:
shared_ptr<expression>value); shared_ptr<expression>value);
explicit arrayType(string &name, enum TYPES t, list<unsigned int>dim); explicit arrayType(string &name, enum TYPES t, list<unsigned int>dim);
/*:variable(scope, name, t);*/ /*:variableType(scope, name, t);*/
virtual ~arrayType() virtual ~arrayType()
{} {}
}; };
class forLoop:public codeType class forLoop:public codeType
{ {
shared_ptr<variable>var; shared_ptr<variableType>var;
shared_ptr<variable>startTemp; shared_ptr<variableType>startTemp;
shared_ptr<variable>stopTemp; shared_ptr<variableType>stopTemp;
shared_ptr<whileLoop>infrastructure; shared_ptr<whileLoop>infrastructure;
shared_ptr<expression>step; shared_ptr<expression>step;
public: public:
virtual void generateBreak(); virtual void generateBreak();
virtual void close(); virtual void close();
explicit forLoop(shared_ptr<variable>v, shared_ptr<expression>start, explicit forLoop(shared_ptr<variableType>v, shared_ptr<expression>start,
shared_ptr<expression>stop, shared_ptr<expression>stepVal=NULL); shared_ptr<expression>stop, shared_ptr<expression>stepVal=NULL);
virtual ~forLoop() virtual ~forLoop()
{} {}
@@ -410,7 +410,7 @@ class fn:codeType
static unordered_map<string, shared_ptr<fn> > functions; static unordered_map<string, shared_ptr<fn> > functions;
static list<shared_ptr<fn> > callStack; static list<shared_ptr<fn> > callStack;
static unsigned int nextID; static unsigned int nextID;
list<shared_ptr<variable> >params; list<shared_ptr<variableType> >params;
string funcName; string funcName;
unsigned int id; unsigned int id;
enum TYPES kind; enum TYPES kind;
@@ -430,7 +430,7 @@ public:
unsigned int getID() const {return this->id;} unsigned int getID() const {return this->id;}
int getNumParams() const {return this->params.size();} int getNumParams() const {return this->params.size();}
void addParameter(shared_ptr<variable>); void addParameter(shared_ptr<variableType>);
shared_ptr<operands>generateCall(string &name, shared_ptr<operands>generateCall(string &name,
list<shared_ptr<operands> >&paramList); list<shared_ptr<operands> >&paramList);
@@ -444,26 +444,17 @@ public:
{} {}
}; };
/* The next two structures are used to implement the PRINT statement. */ class printSegment
class printSegments
{ {
shared_ptr<expression>cargo; shared_ptr<expression>cargo;
enum SEPARATORS kind; enum SEPARATORS sep;
public: public:
printSegments(shared_ptr<expression>e, enum SEPARATORS k) void generate();
{ printSegment(shared_ptr<expression>e, enum SEPARATORS s);
this->cargo=e; printSegment(shared_ptr<expression>e) {printSegment(e, S_LINEFEED);}
this->kind=k; printSegment() {printSegment(NULL);}
} virtual ~printSegment()
printSegments(shared_ptr<expression>e) {printSegments(e, S_LINEFEED);}
printSegments() {printSegments(NULL);}
virtual ~printSegments()
{} {}
}; };
struct printStatement
{
list<shared_ptr<printSegments> >segments;
};
#endif #endif

View File

@@ -203,7 +203,7 @@ void whileLoop::close()
loopEnd->generate(); loopEnd->generate();
} }
forLoop::forLoop(shared_ptr<variable>v, forLoop::forLoop(shared_ptr<variableType>v,
shared_ptr<expression>start, shared_ptr<expression>stop, shared_ptr<expression>start, shared_ptr<expression>stop,
shared_ptr<expression>stepVal):codeType(T_FORLOOP) shared_ptr<expression>stepVal):codeType(T_FORLOOP)
{ {

View File

@@ -330,7 +330,7 @@ shared_ptr<operands>expression::evaluate()
} }
/* variable definitions */ /* variable definitions */
variable::variable(enum SCOPES s, string &name, enum TYPES t):operands(t) variableType::variableType(enum SCOPES s, string &name, enum TYPES t):operands(t)
{ {
this->myScope=s; this->myScope=s;
switch (s) switch (s)
@@ -338,23 +338,23 @@ variable::variable(enum SCOPES s, string &name, enum TYPES t):operands(t)
case S_LOCAL: case S_LOCAL:
if(locals.find(name)!=locals.end() || if(locals.find(name)!=locals.end() ||
statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL); statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL);
locals[name]=shared_ptr<variable>(this); locals[name]=shared_ptr<variableType>(this);
break; break;
case S_GLOBAL: case S_GLOBAL:
if(globals.find(name)!=globals.end()) error(E_DUPLICATE_SYMBOL); if(globals.find(name)!=globals.end()) error(E_DUPLICATE_SYMBOL);
globals[name]=shared_ptr<variable>(this); globals[name]=shared_ptr<variableType>(this);
break; break;
case S_STATIC: case S_STATIC:
if(locals.find(name)!=locals.end() || if(locals.find(name)!=locals.end() ||
statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL); statics.find(name)!=statics.end() ) error(E_DUPLICATE_SYMBOL);
statics[name]=shared_ptr<variable>(this); statics[name]=shared_ptr<variableType>(this);
break; break;
default: default:
error(E_INTERNAL); error(E_INTERNAL);
} }
} }
shared_ptr<variable> variable::getOrCreateVar(string &name, enum TYPES t) shared_ptr<variableType> variableType::getOrCreateVar(string &name, enum TYPES t)
{ {
if (!scopeGlobal) if (!scopeGlobal)
{ {
@@ -364,13 +364,13 @@ shared_ptr<variable> variable::getOrCreateVar(string &name, enum TYPES t)
if(i!=statics.end())return i->second; if(i!=statics.end())return i->second;
} }
if (globals.find(name)!=globals.end())return globals[name]; if (globals.find(name)!=globals.end())return globals[name];
shared_ptr<variable>v=shared_ptr<variable>(new variable( shared_ptr<variableType>v=shared_ptr<variableType>(new variableType(
scopeGlobal?S_GLOBAL:S_LOCAL, name, t)); scopeGlobal?S_GLOBAL:S_LOCAL, name, t));
v->generateBox(scopeGlobal?S_GLOBAL:S_LOCAL); v->generateBox(scopeGlobal?S_GLOBAL:S_LOCAL);
return v; return v;
} }
void variable::assignment(shared_ptr<expression>value) void variableType::assignment(shared_ptr<expression>value)
{ {
shared_ptr<operands>op=value->evaluate(); shared_ptr<operands>op=value->evaluate();
enum TYPES t=op->getSimpleVarType(); enum TYPES t=op->getSimpleVarType();
@@ -444,7 +444,7 @@ string arrayType::generateBox(enum SCOPES s)
} }
arrayType::arrayType(string &name, enum TYPES t, list<unsigned int>dim): arrayType::arrayType(string &name, enum TYPES t, list<unsigned int>dim):
variable(S_GLOBAL, name, t) variableType(S_GLOBAL, name, t)
{ {
this->dimensions=dim; this->dimensions=dim;
} }

51
yabIO.cpp Normal file
View File

@@ -0,0 +1,51 @@
/*
** Yab2Cpp
**
** Transpiler by Samuel D. Crow
**
** based on Yab
**
*/
#include "yab2cpp.h"
printSegment::printSegment(shared_ptr<expression>e, enum SEPARATORS s)
{
cargo=e;
sep=s;
}
void printSegment::generate()
{
if (cargo!=NULL)
{
shared_ptr<operands>op=cargo->evaluate();
switch (op->getSimpleVarType())
{
case T_STRINGVAR:
output_cpp << "printf(\"%s\", " << op->boxName() << ");\n";
break;
case T_INTVAR:
output_cpp << "printf(\"%d\", " << op->boxName() << ");\n";
break;
case T_FLOATVAR:
output_cpp << "printf(\"%f\", " << op->boxName() << ");\n";
break;
default:
break;
}
}
switch (sep)
{
case S_LINEFEED:
output_cpp << "puts(\"\n\");\n";
return;
case S_SEMICOLON:
return;
case S_COMMA:
output_cpp << "putc('\t');\n";
return;
default:
error(E_BAD_SYNTAX);
break;
}
}