started build script and went on a massive bug hunt

This commit is contained in:
Samuel D. Crow
2021-03-16 17:01:28 -05:00
parent 4eb08efc9d
commit 1dae0a4b54
6 changed files with 322 additions and 276 deletions

40
Makefile Normal file
View File

@@ -0,0 +1,40 @@
#Makefile for yab2cpp
#by Samuel D. Crow
#presently architecture-neutral
CC=g++
LD=g++
#release build
#FLAGS=-c -Os -std=c++11
#LDFLAGS=
#debug build
FLAGS=-c -g -Og -std=c++11
LDFLAGS=
AR=ar r
LD=g++
default: yab2cpp
yabDataStructures.o: yabDataStructures.cpp yab2cpp.h
$(CC) $(FLAGS) -o yabDataStructures.o yabDataStructures.cpp
yabCodeStructures.o: yabCodeStructures.cpp yab2cpp.h
$(CC) $(FLAGS) -o yabCodeStructures.o yabCodeStructures.cpp
yabFunctions.o: yabFunctions.cpp yab2cpp.h
$(CC) $(FLAGS) -o yabFunctions.o yabFunctions.cpp
yab2cpp.o: yab2cpp.cpp yab2cpp.h
$(CC) $(FLAGS) -o yab2cpp.o yab2cpp.cpp
BASIC_framework.a: yabDataStructures.o yabCodeStructures.o yabFunctions.o
$(AR) yabDataStructures.o yabCodeStructures.o yabFunctions.o
yab2cpp: BASIC_framework.a yab2cpp.o
$(LD) $(LDFLAGS) -o buildyab2cpp yab2cpp.o -lBASIC_framework
clean:
rm -f *.o yab2cpp BASIC_framework.a

View File

@@ -22,9 +22,10 @@ ofstream logfile;
ofstream varNames; ofstream varNames;
/* private prototypes */ /* private prototypes */
void helpText(string &); void helpText(string);
void setup();
void compile();
void shutDown(); void shutDown();
void logger(string &);
/* process command line parameters */ /* process command line parameters */
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@@ -98,29 +99,35 @@ void setUp()
if (mode & COMPILE) if (mode & COMPILE)
{ {
/* compile mode */ /* compile mode */
output_cpp=new ofstream("build/output.cpp"); output_cpp.open("output/output.cpp");
funcs_h=new ofstream ("functions.h"); funcs_h.open("output/functions.h");
consts_h=new ofstream("consts.h"); consts_h.open("output/consts.h");
heap_h=new ofstream("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"
<< "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 (mode & DEBUG) if (mode & DEBUG)
{ {
varNames=new ofstream("varnames.txt"); varNames.open("varnames.txt");
} }
} }
if (mode & DUMP) if (mode & DUMP)
{ {
/* dump identifier mode */ /* dump identifier mode */
logfile=fopen("parse.log","w"); logfile.open("parse.log");
logger("Setup complete."); logger("Setup complete.");
} }
} }
void error(enum COMPILE_ERRORS e)
{
errorLevel=e;
exit(1);
}
/* write a note in the logfile */ /* write a note in the logfile */
void logger(string &contents) void logger(string s)
{ {
unsigned int count; unsigned int count;
if (mode & DEBUG) if (mode & DEBUG)
@@ -131,14 +138,14 @@ void logger(string &contents)
logfile << '\t'; logfile << '\t';
--count; --count;
} }
logfile << contents << endl; logfile << s << endl;
} }
} }
/* shutdown the compiler and exit */ /* shutdown the compiler and exit */
void shutDown() void shutDown()
{ {
if (errorLevel != E_OK) cerr << "\nERROR: " << COMPILEERRORNAMES[errorLevel] << "\n\n" << endl; if (errorLevel != E_OK) cerr << "\nERROR: " << COMPILE_ERROR_NAMES[errorLevel] << "\n\n" << endl;
if (fn::isCallStackEmpty()) if (fn::isCallStackEmpty())
{ {
logger("Stack was empty"); logger("Stack was empty");
@@ -146,26 +153,22 @@ void shutDown()
else else
{ {
logger("Dumping stack."); logger("Dumping stack.");
if (mode & DUMP && logfile != NULL) if (mode & DUMP && (logfile))
{ {
fn::dumpCallStack(logfile); fn::dumpCallStack();
} }
} }
operands::dumpVars(); operands::dumpVars();
label::dumpLabels(); label::dumpLabels();
output_cpp << "}\n}return state;\n}"<< endl; output_cpp << "}\n}return state;\n}"<< endl;
}
} }
/* open files and compile */ /* open files and compile */
void compile() void compile()
{ {
setUp(); setUp();
/* parse */
ctx = mb_create(NULL);
while(mb_parse(ctx, NULL)){logger("done");}
mb_destroy(ctx);
shutDown(); shutDown();
} }

145
yab2cpp.h
View File

@@ -13,6 +13,8 @@
#include <unordered_map> #include <unordered_map>
#include <memory> #include <memory>
#include <iostream> #include <iostream>
#include <fstream>
#include <sstream>
using namespace std; using namespace std;
@@ -90,7 +92,7 @@ enum TYPES
T_FLOATCALL_ARRAY, T_FLOATCALL_ARRAY,
T_STRINGCALL_ARRAY, T_STRINGCALL_ARRAY,
T_VOIDCALL T_VOIDCALL
} };
/* list of all kinds of other code structures */ /* list of all kinds of other code structures */
enum CODES enum CODES
{ {
@@ -194,6 +196,7 @@ enum OPERATORS
/* global prototype */ /* global prototype */
void error(enum COMPILE_ERRORS err); void error(enum COMPILE_ERRORS err);
void logger(string s);
/* internal states used by the parser */ /* internal states used by the parser */
class operands class operands
@@ -201,21 +204,23 @@ class operands
enum TYPES type; enum TYPES type;
unsigned int id; unsigned int id;
static unsigned int nextID; static unsigned int nextID;
static unordered_map<string, operands *> globals; static unordered_map<string, shared_ptr<operands>> globals;
static unordered_map<string, unsigned int> strConst; static unordered_map<string, unsigned int> strConst;
/* private constructor for parameter passing only */
explicit operands(unsigned int id, enum TYPES t);
public: public:
enum TYPES getType() const {return type;} enum TYPES getType() const {return type;}
unsigned int getID() const {return id;} unsigned int getID() const {return id;}
static operands *findGlobal(string &s); static shared_ptr<operands>findGlobal(string &s);
static void dumpVars(ostream &out); static void dumpVars();
static unsigned int getOrCreateStr(string &s); static shared_ptr<operands>getOrCreateStr(string s);
static operands *createConst(string &s, enum TYPES t); static shared_ptr<operands>createConst(string s, enum TYPES t);
static operands *getOrCreateGlobal(string &s, enum TYPES t); static shared_ptr<operands>getOrCreateGlobal(string &s, enum TYPES t);
enum TYPES getSimpleVarType(); enum TYPES getSimpleVarType();
void generateBox(ostream &scope); void generateBox(ostream &scope);
virtual string &boxName(); virtual string boxName();
enum TYPES coerceTypes(); enum TYPES coerceTypes();
explicit operands(enum TYPES t); explicit operands(enum TYPES t);
@@ -226,27 +231,27 @@ public:
/* expression can be terminal or non-terminal */ /* expression can be terminal or non-terminal */
class expression class expression
{ {
operands *op; shared_ptr<operands>op;
expression *left; shared_ptr<expression>left;
expression *right; shared_ptr<expression>right;
enum OPERATORS oper; enum OPERATORS oper;
public: public:
enum OPERATORS getOp() const {return oper;} enum OPERATORS getOp() const {return oper;}
expression *getLeft() const {return left;} shared_ptr<expression>getLeft() const {return left;}
expression *getRight() const {return right;} shared_ptr<expression>getRight() const {return right;}
bool isBinOp(); bool isBinOp();
operands *evaluate(); shared_ptr<operands>evaluate();
operands *stringEval(); shared_ptr<operands>stringEval(shared_ptr<operands>l, shared_ptr<operands>r);
/* r is NULL for unary operators */ /* r is NULL for unary operators */
expression(expression *l, enum OPERATORS o, expression *r=NULL) expression(shared_ptr<expression>l, enum OPERATORS o, shared_ptr<expression>r=NULL)
{ {
this->left=l; this->left=l;
this->right=r; this->right=r;
this->oper=o; this->oper=o;
} }
expression(operands x) expression(shared_ptr<operands>x)
{ {
op=x; op=x;
oper=O_TERM; oper=O_TERM;
@@ -259,11 +264,11 @@ public:
class codeType class codeType
{ {
enum CODES type; enum CODES type;
static list<codeType *> nesting; static list<shared_ptr<codeType> >nesting;
public: public:
enum CODES getType() const {return this->type;} enum CODES getType() const {return this->type;}
static codeType *getCurrent(); static shared_ptr<codeType> getCurrent();
virtual void close(); virtual void close();
virtual void generateBreak()=0; virtual void generateBreak()=0;
@@ -277,25 +282,27 @@ class label
{ {
unsigned int id; unsigned int id;
static unsigned int nextID; static unsigned int nextID;
static unordered_map<string, label *> lookup; static unordered_map<string, shared_ptr<label> > lookup;
public: public:
static dumpLabels(ostream &v); static void dumpLabels();
unsigned int getID() const {return id;} unsigned int getID() const {return id;}
void generateJumpTo(); void generateJumpTo();
void generateOnNSkip(list<shared_ptr<label> >dest); /* pass generateOnNSkip as second paramater
void generateOnNTo(expression *e); to generateOnNTo or generateOnNSub */
void generateCondJump(expression *e); unsigned int generateOnNSkip(list<shared_ptr<label> >&dest);
static void generateOnNTo(shared_ptr<expression>e, unsigned int skip);
void generateCondJump(shared_ptr<expression>e);
void generate(); void generate();
static label *find(string &s); static shared_ptr<label>find(string &s);
label(){this->id = ++nextID;} label(){this->id = ++nextID;}
label(string &s) label(string &s)
{ {
label(); label();
lookup[s]=this; lookup[s]=shared_ptr<label>(this);
} }
virtual ~label() virtual ~label()
@@ -303,77 +310,82 @@ public:
}; };
/* if statement */ /* if statement */
class conditional:public codeType class ifStatement:public codeType
{ {
label *redo; /* for continue command */ shared_ptr<label>redo; /* for continue command */
label *done; /* for break or after "then" condition */ shared_ptr<label>done; /* for break or after "then" condition */
label *chain; /* For elsif command */ shared_ptr<label>chain; /* For elsif command */
public: public:
void generateContinue(); void generateContinue();
virtual void generateBreak() override; virtual void generateBreak() override;
void alternative(expression *e=NULL); /* enable else or elsif condition */ void alternative(shared_ptr<expression>e=NULL); /* enable else or elsif condition */
virtual void close() override; /* end if */ virtual void close() override; /* end if */
explicit conditional(expression *e); explicit ifStatement(shared_ptr<expression>e);
virtual ~conditional(); virtual ~ifStatement()
{}
}; };
/* looping constructs */ /* looping constructs */
class repeatLoop:public codeType class repeatLoop:public codeType
{ {
label *loopStart; shared_ptr<label>loopStart;
label *loopEnd; shared_ptr<label>loopEnd;
public: public:
virtual void generateBreak() override; virtual void generateBreak() override;
virtual void close(expression *e) override; virtual void close(shared_ptr<expression>e);
explicit repeatLoop(); explicit repeatLoop();
virtual ~repeatLoop(); virtual ~repeatLoop()
{}
}; };
class doLoop:public codeType class doLoop:public codeType
{ {
label *loopStart; shared_ptr<label>loopStart;
label *loopEnd; shared_ptr<label>loopEnd;
public: public:
virtual void generateBreak() override; virtual void generateBreak() override;
virtual void close() override; virtual void close() override;
explicit doLoop(); explicit doLoop();
virtual ~doLoop(); virtual ~doLoop()
{}
}; };
class whileLoop:public codeType class whileLoop:public codeType
{ {
label *loopContinue; shared_ptr<label>loopContinue;
label *loopStart; shared_ptr<label>loopStart;
label *loopEnd; shared_ptr<label>loopEnd;
expression *cond; shared_ptr<expression>cond;
public: public:
virtual void generateBreak() override; virtual void generateBreak() override;
virtual void close() override; virtual void close() override;
explicit whileLoop(expression *e); explicit whileLoop(shared_ptr<expression>e);
virtual ~whileLoop(); virtual ~whileLoop()
{}
}; };
class variable:public operands class variable:public operands
{ {
ostream &myScope; ostream &myScope;
public: public:
static shared_ptr<variable>getOrCreateVarName(string &name, enum TYPES t); static shared_ptr<variable>getOrCreateVar(string &name, enum TYPES t);
void assignment(expression *value); void assignment(shared_ptr<expression>value);
explicit variable(ostream &scope, string &name, enum TYPES t); explicit variable(ostream &scope, string &name, enum TYPES t);
virtual variable() variable();
~variable()
{} {}
} };
class arrayType:public variable class arrayType:public variable
{ {
list<unsigned int> dimensions; list<unsigned int> dimensions;
public: public:
virtual string &boxName(list<unsigned int>indexes) override; virtual string &boxName(list<unsigned int>indexes);
explicit arrayType(string &name, enum TYPES t, list<unsigned int>dim);/*:variable(scope, name, t);*/ explicit arrayType(string &name, enum TYPES t, list<unsigned int>dim);/*:variable(scope, name, t);*/
virtual ~arrayType() virtual ~arrayType()
@@ -382,16 +394,16 @@ public:
class forLoop:public codeType class forLoop:public codeType
{ {
variable *var; shared_ptr<variable>var;
variable *startTemp; shared_ptr<variable>startTemp;
variable *stopTemp; shared_ptr<variable>stopTemp;
whileLoop *infrastructure; whileLoop *infrastructure;
expression *step; shared_ptr<expression>step;
public: public:
virtual void generateBreak(); virtual void generateBreak();
virtual void close(); virtual void close();
explicit forLoop(variable *v, expression *start, expression *stop, expression *stepVal=NULL); explicit forLoop(shared_ptr<variable>v, shared_ptr<expression>start, shared_ptr<expression>stop, shared_ptr<expression>stepVal=NULL);
virtual ~forLoop(); virtual ~forLoop();
}; };
@@ -408,22 +420,23 @@ class fn:codeType
shared_ptr<label>startAddr; shared_ptr<label>startAddr;
shared_ptr<label>ret; shared_ptr<label>ret;
/* private constructor used by generateGosub and generateOnNSub*/ /* private constructor used by generateGosub and generateOnNSub*/
fn(label *gosub); fn(shared_ptr<label>gosub);
public: public:
static variable *getOrCreateVar(enum TYPES t, string &s, bool stat); static shared_ptr<variable>getOrCreateVar(enum TYPES t, string &s, bool stat);
static void dumpCallStack(); static void dumpCallStack();
static bool isCallStackEmpty(){return callStack.begin()==callStack.end();}
static shared_ptr<fn>getCurrentSub(); static shared_ptr<fn>getCurrentSub();
static shared_ptr<fn>getSub(string &name); static shared_ptr<fn>getSub(string &name);
static void generateGosub(shared_ptr<label> sub); static void generateGosub(shared_ptr<label> sub);
/* must be called after label::generateOnNSkip */ /* must be called after label::generateOnNSkip */
static void generateOnNSub(expression *e); static void generateOnNSub(shared_ptr<expression>e, unsigned int skip);
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<variable>);
operands *generateCall(string &name, list<shared_ptr<operands> >&paramList); shared_ptr<operands>generateCall(string &name, list<shared_ptr<operands> >paramList);
operands *generateReturn(expression *expr); shared_ptr<operands>generateReturn(shared_ptr<expression>expr);
void generateReturn(); void generateReturn();
virtual void generateBreak(); virtual void generateBreak();
virtual void close(); virtual void close();
@@ -436,15 +449,15 @@ public:
/* The next two structures are used to implement the PRINT statement. */ /* The next two structures are used to implement the PRINT statement. */
class printSegments class printSegments
{ {
expression *cargo; shared_ptr<expression>cargo;
enum SEPARATORS kind; enum SEPARATORS kind;
public: public:
printSegments(expression *e, enum SEPARATORS k) printSegments(shared_ptr<expression>e, enum SEPARATORS k)
{ {
this->cargo=e; this->cargo=e;
this->kind=k; this->kind=k;
} }
printSegments(expression *e) {printSegments(e, S_LINEFEED);} printSegments(shared_ptr<expression>e) {printSegments(e, S_LINEFEED);}
printSegments() {printSegments(NULL);} printSegments() {printSegments(NULL);}
virtual ~printSegments() virtual ~printSegments()
{} {}
@@ -452,7 +465,7 @@ public:
struct printStatement struct printStatement
{ {
list<printSegments *> segments; list<shared_ptr<printSegments> >segments;
}; };
#endif #endif

View File

@@ -11,13 +11,13 @@
/* base class of all the code structure types */ /* base class of all the code structure types */
codeType::codeType(enum CODES t) codeType::codeType(enum CODES t)
{ {
nesting.push_back(this); nesting.push_back(shared_ptr<codeType>(this));
this->type=t; this->type=t;
} }
codeType *codeType::getCurrent() shared_ptr<codeType> codeType::getCurrent()
{ {
return nesting.back; return nesting.back();
} }
void codeType::close() void codeType::close()
@@ -26,7 +26,7 @@ void codeType::close()
} }
/* label definitions and helper routines */ /* label definitions and helper routines */
label *label::find(string &s) shared_ptr<label>label::find(string &s)
{ {
auto ret=lookup.find(s); auto ret=lookup.find(s);
return(ret==lookup.end()?NULL:ret->second); return(ret==lookup.end()?NULL:ret->second);
@@ -47,14 +47,15 @@ void label::generateJumpTo()
output_cpp << "state=" << this->getID() << ";\nbreak;\n"; output_cpp << "state=" << this->getID() << ";\nbreak;\n";
} }
void label::generateOnNSkip(list<shared_ptr<label> >dest) /* pass this as second parameter to generateOnNTo or generateOnNSub */
unsigned int label::generateOnNSkip(list<shared_ptr<label> >&dest)
{ {
if (dest->size()<2) if (dest.size()<2)
{ {
errorLevel=E_BAD_SYNTAX; errorLevel=E_BAD_SYNTAX;
exit(1); exit(1);
} }
auto iter=dest.start(); auto iter=dest.begin();
consts_h << "j" << this->getID() << "[]={" << *iter; consts_h << "j" << this->getID() << "[]={" << *iter;
++iter; ++iter;
while(iter!=dest.end()) while(iter!=dest.end())
@@ -62,30 +63,29 @@ void label::generateOnNSkip(list<shared_ptr<label> >dest)
consts_h << ", " << *iter; consts_h << ", " << *iter;
++iter; ++iter;
} }
consts_h << "}\njs" << this->getID()<< "=" << dest->size() << ";\n"; consts_h << "}\njs" << this->getID()<< "=" << dest.size() << ";\n";
return this->getID();
} }
void label::generateOnNTo(expression *e) void label::generateOnNTo(shared_ptr<expression>e, unsigned int skip)
{ {
operands *o=e->evaluate(); shared_ptr<operands>o=e->evaluate();
if (o->getType()==T_INT||o->getType()==T_INTVAR) if (o->getType()==T_INT||o->getType()==T_INTVAR)
{ {
output_cpp<< "if(" << o->boxName() << ">=0 && " output_cpp<< "if(" << o->boxName() << ">=0 && "
<< o->boxName() << "<js" << this->getID() << ")state=j[" << o->boxName() << "<js" << skip << ")state=j["
<< o->boxName() << "];\nbreak;\n"; << o->boxName() << "];\nbreak;\n";
} }
delete e;
} }
void label::generateCondJump(expression *e) void label::generateCondJump(shared_ptr<expression>e)
{ {
operands *o=e->evaluate(); shared_ptr<operands>o=e->evaluate();
if (o->getType()==T_INT||o->getType()==T_INTVAR) if (o->getType()==T_INT||o->getType()==T_INTVAR)
{ {
output_cpp<< "if(" << o->boxName() output_cpp<< "if(" << o->boxName()
<< "!=0)state=" << this->getID() << ";\nbreak;\n"; << "!=0)state=" << this->getID() << ";\nbreak;\n";
} }
delete e;
} }
void label::generate() void label::generate()
@@ -93,43 +93,42 @@ void label::generate()
output_cpp<< "case " << this->getID() <<":\n"; output_cpp<< "case " << this->getID() <<":\n";
} }
/* conditional definition */ /* ifStatement definition */
conditional::conditional(expression *e):codeType(T_IF) ifStatement::ifStatement(shared_ptr<expression>e):codeType(T_IF)
{ {
this->redo=new label(); this->redo=shared_ptr<label>(new label());
redo->generate(); redo->generate();
this->done=new label(); this->done=shared_ptr<label>(new label());
expression *f=new expression(e,O_NOT); shared_ptr<expression>f=shared_ptr<expression>(new expression(e,O_NOT));
this->chain=new label(); this->chain=shared_ptr<label>(new label());
chain->generateCondJump(f); chain->generateCondJump(f);
} }
void conditional::generateBreak() void ifStatement::generateBreak()
{ {
done->generateJumpTo(); done->generateJumpTo();
} }
void conditional::generateContinue() void ifStatement::generateContinue()
{ {
redo->generateJumpTo(); redo->generateJumpTo();
} }
void conditional::alternative(expression *e=NULL) void ifStatement::alternative(shared_ptr<expression>e=NULL)
{ {
done->generateJumpTo(); done->generateJumpTo();
this->chain->generate(); this->chain->generate();
delete this->chain;
this->chain=NULL; this->chain=NULL;
if(e!=NULL) if(e!=NULL)
{ {
this->chain=new label(); this->chain=shared_ptr<label>(new label());
expression *f=new expression(e,O_NOT); shared_ptr<expression>f=shared_ptr<expression>(new expression(e,O_NOT));
chain->generateJumpCond(f); chain->generateCondJump(f);
} }
} }
void conditional::close() void ifStatement::close()
{ {
if(this->chain) if(this->chain)
{ {
@@ -140,17 +139,11 @@ void conditional::close()
this->done->generate(); this->done->generate();
} }
conditional::~conditional()
{
delete this->done;
delete this->redo;
}
/* Loop definitions */ /* Loop definitions */
repeatLoop::repeatLoop():codeType(T_REPEATLOOP) repeatLoop::repeatLoop():codeType(T_REPEATLOOP)
{ {
this->loopStart=new label(); this->loopStart=shared_ptr<label>(new label());
this->loopEnd=new label(); this->loopEnd=shared_ptr<label>(new label());
loopStart->generate(); loopStart->generate();
} }
@@ -159,23 +152,17 @@ void repeatLoop::generateBreak()
loopEnd->generateJumpTo(); loopEnd->generateJumpTo();
} }
void repeatLoop::close(expression *e) void repeatLoop::close(shared_ptr<expression>e)
{ {
expression *f=new expression(e, O_NOT); shared_ptr<expression>f=shared_ptr<expression>(new expression(e, O_NOT));
loopStart->generateCondJump(f); loopStart->generateCondJump(f);
loopEnd->generate(); loopEnd->generate();
} }
repeatLoop::~repeatLoop()
{
delete loopStart;
delete loopEnd;
}
doLoop::doLoop():codeType(T_DOLOOP) doLoop::doLoop():codeType(T_DOLOOP)
{ {
this->loopStart=new label(); this->loopStart=shared_ptr<label>(new label());
this->loopEnd=new label(); this->loopEnd=shared_ptr<label>(new label());
loopStart->generate(); loopStart->generate();
} }
@@ -190,16 +177,11 @@ void doLoop::close()
this->loopEnd->generate(); this->loopEnd->generate();
} }
doLoop::~doLoop() whileLoop::whileLoop(shared_ptr<expression>e):codeType(T_WHILELOOP)
{ delete loopStart;
delete loopEnd;
}
whileLoop::whileLoop(expression *e):codeType(T_WHILELOOP)
{ {
loopContinue=new label(); loopContinue=shared_ptr<label>(new label());
loopStart=new label(); loopStart=shared_ptr<label>(new label());
loopEnd=new label(); loopEnd=shared_ptr<label>(new label());
cond=e; cond=e;
loopStart->generateJumpTo(); loopStart->generateJumpTo();
loopContinue->generate(); loopContinue->generate();
@@ -213,42 +195,44 @@ void whileLoop::generateBreak()
void whileLoop::close() void whileLoop::close()
{ {
loopStart->generate(); loopStart->generate();
loopContinue->generateJumpCond(cond); loopContinue->generateCondJump(cond);
loopEnd->generate(); loopEnd->generate();
} }
whileLoop::~whileLoop() forLoop::forLoop(shared_ptr<variable>v,
{ shared_ptr<expression>start, shared_ptr<expression>stop,
delete loopStart; shared_ptr<expression>stepVal=NULL):codeType(T_FORLOOP)
delete loopContinue;
delete loopEnd;
}
forLoop::forLoop(variable *v, expression *start, expression *stop, expression *stepVal=NULL):codeType(T_FORLOOP)
{ {
/*v=start; /*v=start;
stopTemp=stop;*/ stopTemp=stop;*/
v->assignment(start); v->assignment(start);
stopTemp->assignment(stop); stopTemp->assignment(stop);
/* if (v<stopTemp) */ /* if (v<stopTemp) */
conditional *c=new conditional(new expression(new expression(v), O_LESS, new expression(stopTemp))); shared_ptr<ifStatement>c=shared_ptr<ifStatement>(new ifStatement(
shared_ptr<expression>(new expression(shared_ptr<expression>(new expression(v)),
O_LESS, shared_ptr<expression>(new expression(stopTemp))))));
/* startTemp=v;*/ /* startTemp=v;*/
startTemp->assignment(new expression(v)); startTemp->assignment(shared_ptr<expression>(new expression(v)));
/* else */ /* else */
c->alternative(); c->alternative();
/* startTemp=stopTemp; /* startTemp=stopTemp;
stopTemp=v;*/ stopTemp=v;*/
startTemp->assignment(new expression(stopTemp)); startTemp->assignment(shared_ptr<expression>(new expression(stopTemp)));
stopTemp->assignment(new expression(v)); stopTemp->assignment(shared_ptr<expression>(new expression(v)));
/* endif */ /* endif */
c->close(); c->close();
delete c;
/* while (v<=stopTemp && v>=startTemp) */ /* while (v<=stopTemp && v>=startTemp) */
expression *stopper1=new expression(new expression(v), O_LESS_EQUAL, new expression(stopTemp)); shared_ptr<expression>stopper1=shared_ptr<expression>(new expression(
expression *stopper2=new expression(new expression(v), O_GREATER_EQUAL, new expression(startTemp)); shared_ptr<expression>(new expression(v)), O_LESS_EQUAL,
expression *stopper=new expression(stopper1, O_AND, stopper2); shared_ptr<expression>(new expression(stopTemp))));
this->infrastructure=new whileLoop(new expression(stopper, O_UNEQUAL, shared_ptr<expression>stopper2=shared_ptr<expression>(new expression(
new expression(operands::createConst("0", T_INT)))); shared_ptr<expression>(new expression(v)), O_GREATER_EQUAL,
shared_ptr<expression>(new expression(startTemp))));
shared_ptr<expression>stopper=shared_ptr<expression>(new expression(
stopper1, O_AND, stopper2));
this->infrastructure=new whileLoop(shared_ptr<expression>(new expression(
stopper, O_UNEQUAL, shared_ptr<expression>(new expression(
operands::createConst(string("0"), T_INT))))));
if (stepVal) if (stepVal)
{ {
step=stepVal; step=stepVal;
@@ -256,7 +240,7 @@ forLoop::forLoop(variable *v, expression *start, expression *stop, expression *s
else else
{ {
/* if not present "step" is assumed to be 1 */ /* if not present "step" is assumed to be 1 */
step=new expression(operands::createConst("1", T_INT)); step=shared_ptr<expression>(new expression(operands::createConst("1", T_INT)));
} }
} }
@@ -267,8 +251,9 @@ void forLoop::generateBreak()
void forLoop::close() void forLoop::close()
{ {
/* v=v+step; */ /* var=var+step; */
expression *stepper=new expression(new expression(v), O_PLUS, step); shared_ptr<expression>stepper=shared_ptr<expression>(new expression(
v->assignment(stepper) shared_ptr<expression>(new expression(var)), O_PLUS, step));
var->assignment(stepper);
infrastructure->close(); infrastructure->close();
} }

View File

@@ -8,8 +8,10 @@
*/ */
#include "yab2cpp.h" #include "yab2cpp.h"
class fn;
/* methods for operands */ /* methods for operands */
static operands *findGlobal(string &s) shared_ptr<operands>operands::findGlobal(string &s)
{ {
auto iter=operands::globals.find(s); auto iter=operands::globals.find(s);
if (iter==operands::globals.end()) if (iter==operands::globals.end())
@@ -19,7 +21,7 @@ static operands *findGlobal(string &s)
return iter->second; return iter->second;
} }
static void operands::dumpVars() void operands::dumpVars()
{ {
varNames << "Global Variables\n"; varNames << "Global Variables\n";
for(auto iter=globals.begin(); iter!=globals.end(); ++iter) for(auto iter=globals.begin(); iter!=globals.end(); ++iter)
@@ -29,19 +31,22 @@ static void operands::dumpVars()
varNames << endl; varNames << endl;
} }
unsigned int operands::getOrCreateStr(string &s) shared_ptr<operands> operands::getOrCreateStr(string s)
{ {
auto iter=constStr.find(s); auto iter=operands::strConst.find(s);
if (iter!=constStr.end()) return iter->second; if (iter!=operands::strConst.end())
{
return shared_ptr<operands>(new operands(iter->second, T_STRING));
}
++nextID; ++nextID;
consts_h << "const string k" << nextID << "=\"" << s << "\";\n"; consts_h << "const string k" << nextID << "=\"" << s << "\";\n";
constStr[s]=nextID; operands::strConst[s]=nextID;
return nextID; return shared_ptr<operands>(new operands(nextID, T_STRING));
} }
unsigned int operands::createConst(string &s, enum TYPES t) shared_ptr<operands>operands::createConst(string s, enum TYPES t)
{ {
operands *me=new operands(t); shared_ptr<operands>me=shared_ptr<operands>(new operands(t));
if (t==T_INT) if (t==T_INT)
{ {
consts_h << "const int k"; consts_h << "const int k";
@@ -64,7 +69,7 @@ unsigned int operands::createConst(string &s, enum TYPES t)
enum TYPES operands::getSimpleVarType() enum TYPES operands::getSimpleVarType()
{ {
switch type switch (this->getType())
{ {
case T_FLOAT: case T_FLOAT:
case T_FLOATCALL_ARRAY: case T_FLOATCALL_ARRAY:
@@ -111,29 +116,31 @@ void operands::generateBox(ostream &scope)
scope << this->getID() << ";\n"; scope << this->getID() << ";\n";
} }
operands *operands::getOrCreateGlobal(string &s, enum TYPES t) shared_ptr<operands>operands::getOrCreateGlobal(string &s, enum TYPES t)
{ {
operands op*=operands::globals->find(s); auto op=globals.find(s);
if (op==globals.end()) if (op==globals.end())
{ {
op=new variable(heap_h, s, t); return shared_ptr<variable>(new variable(heap_h, s, t));
} }
return op; return op->second;
} }
void operands::boxName(ostream &scope) string operands::boxName()
{ {
ostringstream s;
switch (this->getType()) switch (this->getType())
{ {
case T_STRINGVAR: case T_STRINGVAR:
case T_INTVAR: case T_INTVAR:
case T_FLOATVAR: case T_FLOATVAR:
s << 'v' << this->getID();
return s.str();
break; break;
default: default:
error(E_INTERNAL); error(E_INTERNAL);
} }
scope << "v" << this->getID();
} }
/* expression parsing routines */ /* expression parsing routines */
@@ -141,7 +148,7 @@ void operands::boxName(ostream &scope)
/* binary vs. unary ops */ /* binary vs. unary ops */
bool expression::isBinOp() bool expression::isBinOp()
{ {
switch this->getOp() switch (this->getOp())
{ {
case O_NEGATE: case O_NEGATE:
case O_NOT: case O_NOT:
@@ -153,10 +160,11 @@ bool expression::isBinOp()
return true; return true;
} }
operands *expression::evaluate() shared_ptr<operands>expression::evaluate()
{ {
if (this->getOp()==O_TERM) return op; if (this->getOp()==O_TERM) return op;
operands *l, *r; shared_ptr<operands>l;
shared_ptr<operands>r;
enum TYPES t; enum TYPES t;
ostream &scope=scopeGlobal?heap_h:funcs_h; ostream &scope=scopeGlobal?heap_h:funcs_h;
l=this->getLeft()->evaluate(); l=this->getLeft()->evaluate();
@@ -167,12 +175,12 @@ operands *expression::evaluate()
enum TYPES rt=r->getSimpleVarType(); enum TYPES rt=r->getSimpleVarType();
if (lt==T_INTVAR && rt==T_FLOATVAR) if (lt==T_INTVAR && rt==T_FLOATVAR)
{ {
l=new expression(new expression(l), O_INT_TO_FLOAT)->evaluate(); l=shared_ptr<operands>((new expression(shared_ptr<expression>(new expression(l)), O_INT_TO_FLOAT))->evaluate());
lt=T_FLOATVAR; lt=T_FLOATVAR;
} }
if (lt==T_FLOATVAR && rt==T_INTVAR) if (lt==T_FLOATVAR && rt==T_INTVAR)
{ {
r=new expression(new expression(r), O_INT_TO_FLOAT)->evaluate(); r=shared_ptr<operands>((new expression(shared_ptr<expression>(new expression(r)), O_INT_TO_FLOAT))->evaluate());
rt=T_FLOATVAR; rt=T_FLOATVAR;
} }
if (lt!=rt)error(E_TYPE_MISMATCH); if (lt!=rt)error(E_TYPE_MISMATCH);
@@ -183,96 +191,96 @@ operands *expression::evaluate()
t=l->getSimpleVarType(); t=l->getSimpleVarType();
r=NULL; r=NULL;
} }
if (t==T_STRINGVAR) return expression::stringEval(); if (t==T_STRINGVAR) return expression::stringEval(l, r);
switch (this->getOp()) switch (this->getOp())
{ {
case O_INVERT: case O_INVERT:
this->op=new operands(t); this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "= ~" << l->boxName() << ";\n"; output_cpp << this->op->boxName() << "= ~" << l->boxName() << ";\n";
break; break;
case O_NEGATE: case O_NEGATE:
this->op=new operands(t); this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "= -" << l->boxName() << ";\n"; output_cpp << this->op->boxName() << "= -" << l->boxName() << ";\n";
break; break;
case O_NOT: case O_NOT:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH); if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=new operands(T_INTVAR); this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "= !" << l->boxName() << ";\n"; output_cpp << this->op->boxName() << "= !" << l->boxName() << ";\n";
break; break;
case O_INT_TO_FLOAT: /*Note: this duplicates functionality of variable assignment */ case O_INT_TO_FLOAT: /*Note: this duplicates functionality of variable assignment */
this->op=new operands(T_FLOATVAR); this->op=shared_ptr<operands>(new operands(T_FLOATVAR));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "= const_cast<double>(" output_cpp << this->op->boxName() << "= const_cast<double>("
<< l->boxName() << ");\n"; << l->boxName() << ");\n";
/* TODO: Check for divide by zero error and modulo zero error */ /* TODO: Check for divide by zero error and modulo zero error */
case O_REMAINDER: case O_REMAINDER:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH); if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=new operands(T_INTVAR); this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "%" << r->boxName() << ";\n"; output_cpp << this->op->boxName() << "=" << l->boxName() << "%" << r->boxName() << ";\n";
break; break;
case O_DIVIDE: case O_DIVIDE:
this->op=new operands(t); this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "/" << r->boxName() << ";\n"; output_cpp << this->op->boxName() << "=" << l->boxName() << "/" << r->boxName() << ";\n";
break; break;
case O_PLUS: case O_PLUS:
this->op=new operands(t); this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "+" << r->boxName() << ";\n"; output_cpp << this->op->boxName() << "=" << l->boxName() << "+" << r->boxName() << ";\n";
break; break;
case O_MINUS: case O_MINUS:
this->op=new operands(t); this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "-" << r->boxName() << ";\n"; output_cpp << this->op->boxName() << "=" << l->boxName() << "-" << r->boxName() << ";\n";
break; break;
case O_MULTIPLY: case O_MULTIPLY:
this->op=new operands(t); this->op=shared_ptr<operands>(new operands(t));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "*" << r->boxName() << ";\n"; output_cpp << this->op->boxName() << "=" << l->boxName() << "*" << r->boxName() << ";\n";
break; break;
case O_OR: case O_OR:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH); if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=new operands(T_INTVAR); this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "|" << r->boxName() << ";\n"; output_cpp << this->op->boxName() << "=" << l->boxName() << "|" << r->boxName() << ";\n";
break; break;
case O_AND: case O_AND:
if (t!=T_INTVAR) error(E_TYPE_MISMATCH); if (t!=T_INTVAR) error(E_TYPE_MISMATCH);
this->op=new operands(T_INTVAR); this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=" << l->boxName() << "&" << r->boxName() << ";\n"; output_cpp << this->op->boxName() << "=" << l->boxName() << "&" << r->boxName() << ";\n";
break; break;
case O_GREATER: case O_GREATER:
this->op=new operands(T_INTVAR); this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=(" << l->boxName() << ">" << r->boxName() << ")?-1:0;\n"; output_cpp << this->op->boxName() << "=(" << l->boxName() << ">" << r->boxName() << ")?-1:0;\n";
break; break;
case O_LESS: case O_LESS:
this->op=new operands(T_INTVAR); this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=(" << l->boxName() << "<" << r->boxName() << ")?-1:0;\n"; output_cpp << this->op->boxName() << "=(" << l->boxName() << "<" << r->boxName() << ")?-1:0;\n";
break; break;
case O_GREATER_EQUAL: case O_GREATER_EQUAL:
this->op=new operands(T_INTVAR); this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=(" << l->boxName() << ">=" << r->boxName() << ")?-1:0;\n"; output_cpp << this->op->boxName() << "=(" << l->boxName() << ">=" << r->boxName() << ")?-1:0;\n";
break; break;
case O_LESS_EQUAL: case O_LESS_EQUAL:
this->op=new operands(T_INTVAR); this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=(" << l->boxName() << "<=" << r->boxName() << ")?-1:0;\n"; output_cpp << this->op->boxName() << "=(" << l->boxName() << "<=" << r->boxName() << ")?-1:0;\n";
break; break;
case O_EQUAL: case O_EQUAL:
this->op=new operands(T_INTVAR); this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=(" << l->boxName() << "==" << r->boxName() << ")?-1:0;\n"; output_cpp << this->op->boxName() << "=(" << l->boxName() << "==" << r->boxName() << ")?-1:0;\n";
break; break;
case O_UNEQUAL: case O_UNEQUAL:
this->op=new operands(T_INTVAR); this->op=shared_ptr<operands>(new operands(T_INTVAR));
this->op->generateBox(scope); this->op->generateBox(scope);
output_cpp << this->op->boxName() << "=(" << l->boxName() << "!=" << r->boxName() << ")?-1:0;\n"; output_cpp << this->op->boxName() << "=(" << l->boxName() << "!=" << r->boxName() << ")?-1:0;\n";
break; break;
@@ -282,80 +290,46 @@ operands *expression::evaluate()
break; break;
} }
/* convert expression into single operand */ /* convert expression into single operand */
delete this->left;
this->left=NULL;
if (r)
{
delete this->right;
this->right=NULL;
}
this->oper=O_TERM; this->oper=O_TERM;
return this->op; return this->op;
} }
operands * expression::stringEval(ostream &scope, operands *l, operands *r) shared_ptr<operands> expression::stringEval(shared_ptr<operands>l, shared_ptr<operands>r)
{ {
if (this->getOp()==O_STRING_CONCAT) if (this->getOp()==O_STRING_CONCAT)
{ {
this->op=new operands(T_STRINGVAR); this->op=shared_ptr<operands>(new operands(T_STRINGVAR));
this->op->generateBox(scope); this->op->generateBox(scopeGlobal?heap_h:funcs_h);
output_cpp << this->op->boxName() << "=" l->boxName() << "+" << r->boxName(); output_cpp << this->op->boxName() << "=" << l->boxName() << "+" << r->boxName();
}
else
{
errorLevel=E_INTERNAL;
exit(1);
} }
else error(E_INTERNAL);
/* convert expression into single operand */ /* convert expression into single operand */
delete this->left;
this->left=NULL;
if (r)
{
delete this->right;
this->right=NULL;
}
this->oper=O_TERM; this->oper=O_TERM;
return this->op; return this->op;
} }
expression::~expression()
{
if(this->getOp()==O_TERM)
{
delete this->op;
}
else
{
delete this->left;
if (this->isBinOp())
{
delete this->right;
}
}
}
/* variable definitions */ /* variable definitions */
variable::variable(ostream &scope, string &name, enum TYPES t):operands(t) variable::variable(ostream &scope, string &name, enum TYPES t):operands(t)
{ {
this->generateBox(scope); /*TODO: FINISH THIS*/ this->generateBox(scope); /*TODO: FINISH THIS*/
} }
variable *variable::getOrCreateVarName(string &name, enum TYPES t) shared_ptr<variable> variable::getOrCreateVar(string &name, enum TYPES t)
{ {
if (!scopeGlobal) if (!scopeGlobal)
{ {
return fn::getOrCreateVar(t, name, false); return fn::getOrCreateVar(t, name, false);
} }
/* TODO: verify if type is compatible */ /* TODO: verify if type is compatible */
shared_ptr<operands>op=operands::getOrCreateGlobal(name); shared_ptr<operands>op=operands::getOrCreateGlobal(name, t);
shared_ptr<variable>v=new variable(); shared_ptr<variable>v=shared_ptr<variable>(new variable());
v->assignment(new expression(op)); v->assignment(shared_ptr<expression>(new expression(op)));
return v; return v;
} }
void variable::assignment(expression *value) void variable::assignment(shared_ptr<expression>value)
{ {
operands *op=value->evaluate(); shared_ptr<operands>op=value->evaluate();
enum TYPES t=op->getSimpleVarType(); enum TYPES t=op->getSimpleVarType();
switch (this->getType()) switch (this->getType())
{ {

View File

@@ -8,25 +8,27 @@
*/ */
#include "yab2cpp.h" #include "yab2cpp.h"
class label;
/* function definitions */ /* function definitions */
fn *fn::getCurrentSub() shared_ptr<fn>fn::getCurrentSub()
{ {
return callStack.back; return callStack.back();
} }
void fn::generateOnNSub(expression *e) void fn::generateOnNSub(shared_ptr<expression>e, unsigned int skip)
{ {
shared_ptr<label>r=new label(); shared_ptr<label>r=shared_ptr<label>(new label());
shared_ptr<fn> self=new fn(r); shared_ptr<fn> self=shared_ptr<fn>(new fn(r));
fn::callStack.push_back(self); fn::callStack.push_back(self);
label::generateOnNTo(e); label::generateOnNTo(e, skip);
r->generate(); r->generate();
} }
void fn::generateGosub(shared_ptr<label> sub) void fn::generateGosub(shared_ptr<label> sub)
{ {
shared_ptr<label>r=new label(); shared_ptr<label>r=shared_ptr<label>(new label());
shared_ptr<fn> self=new fn(r); shared_ptr<fn> self=shared_ptr<fn>(new fn(r));
fn::callStack.push_back(self); fn::callStack.push_back(self);
sub->generateJumpTo(); sub->generateJumpTo();
r->generate(); r->generate();
@@ -39,50 +41,79 @@ fn::fn(shared_ptr<label>gosub):codeType(T_GOSUB)
shared_ptr<fn> fn::getSub(string &name) shared_ptr<fn> fn::getSub(string &name)
{ {
auto iter=fn::functions.find(name) auto iter=fn::functions.find(name);
if(iter==fn::functions.end()) return NULL; if(iter==fn::functions.end()) return NULL;
return iter->second; return iter->second;
} }
operands *fn::generateCall(string &name, list<shared_ptr<operands> >&paramList) shared_ptr<operands>fn::generateCall(string &name,
list<shared_ptr<operands> >paramList)
{ {
auto v=params.begin(); auto v=params.begin();
shared_ptr<operands>current; shared_ptr<operands>current;
shared_ptr<fn>g=fn::getSub(name); shared_ptr<fn>g=fn::getSub(name);
if (g==NULL) if (g==NULL)
{ {
errorLevel=E_SUBROUTINE_NOT_FOUND; error(E_SUBROUTINE_NOT_FOUND);
exit(1);
} }
if (paramList.size()>params.size()) if (paramList.size()>params.size())
{ {
errorLevel=E_TOO_MANY_PARAMETERS; error(E_TOO_MANY_PARAMETERS);
exit(1);
} }
output_cpp << "struct *f" << /* TODO: finish this */ /* TODO CHECK THIS */
<< "= new struct f" << g->getID(); output_cpp << "struct f" << g->getID()
<< "*sub" << this->getID()
<< "= new struct f" << g->getID()
<< "();\n";
while(paramList.size()>0) while(paramList.size()>0)
{ {
current=paramList.front; current= paramList.front();
paramList.pop_front(); paramList.pop_front();
if(current->getSimpleVarType()!=*v->getType()) if(current->getSimpleVarType()!=(*v)->getType())
{ {
errorLevel=E_TYPE_MISMATCH; error(E_TYPE_MISMATCH);
exit(1); }
(*v)->assignment(shared_ptr<expression>(
new expression(current)));
++v;
}
/* pad remaining unassigned variables with empty values */
while (v!=params.end())
{
switch ((*v)->getType())
{
case T_FLOATVAR:
(*v)->assignment(shared_ptr<expression>(
new expression(
operands::createConst("0.0", T_FLOAT)
)));
break;
case T_INTVAR:
(*v)->assignment(shared_ptr<expression>(
new expression(
operands::createConst("0", T_INT)
)));
break;
case T_STRINGVAR:
(*v)->assignment(shared_ptr<expression>(
new expression(
operands::getOrCreateStr(string("")
))));
default:
error(E_TYPE_MISMATCH);
} }
*v->assignment(new expression(current));
++v; ++v;
} }
return g->/*TODO FINISH THIS*/ return g->/*TODO FINISH THIS*/
} }
void fn::generateReturn() void fn::generateReturn()
{ {
shared_ptr<fn>c=fn::getCurrent(); shared_ptr<fn>c=getCurrentSub();
switch(c->getType()) switch(c->getType())
{ {
case T_UNKNOWNFUNC: case T_UNKNOWNFUNC:
/* set return type to NONE */
this->kind=T_NONE; this->kind=T_NONE;
/*fallthrough*/ /*fallthrough*/
case T_GOSUB: case T_GOSUB:
@@ -95,9 +126,9 @@ void fn::generateReturn()
} }
} }
operands *fn::generateReturn(expression *expr) shared_ptr<operands>fn::generateReturn(shared_ptr<expression>expr)
{ {
operands *out=expr->evaluate(); shared_ptr<operands>out=expr->evaluate();
this->kind=out->getSimpleVarType(); this->kind=out->getSimpleVarType();
this->ret->generateJumpTo(); this->ret->generateJumpTo();
fn::callStack.pop_back(); fn::callStack.pop_back();
@@ -153,7 +184,7 @@ void fn::close()
(t==T_UNKNOWNFUNC||t==T_VOIDFUNC)) (t==T_UNKNOWNFUNC||t==T_VOIDFUNC))
{ {
/* generate a typeless return */ /* generate a typeless return */
this->generateReturn() this->generateReturn();
} }
funcs_h << "};\n"; funcs_h << "};\n";
fn::locals.clear(); fn::locals.clear();
@@ -165,10 +196,10 @@ void fn::close()
fn::fn(string &s, enum CODES t):codeType(t) fn::fn(string &s, enum CODES t):codeType(t)
{ {
if (!scopeGlobal) error(E_END_FUNCTION); if (!scopeGlobal) error(E_END_FUNCTION);
if (fn::functions->find(s)!=fn::functions.end()) error(E_DUPLICATE_SYMBOL); if (fn::functions.find(s)!=fn::functions.end()) error(E_DUPLICATE_SYMBOL);
this->id= ++nextID; this->id= ++nextID;
funcs_h << "struct f" << this->id <<"\n{\n"; funcs_h << "struct f" << this->id <<"\n{\n";
this->ret=new label(); this->ret=shared_ptr<label>(new label());
fn::functions[s]=this; fn::functions[s]=this;
scopeGlobal=false; scopeGlobal=false;
} }