Commit 93cf6508 by Andrew Dahl

Merge branch 'dev_stage8'

Conflicts:
	lib/instructionList.cpp
	lib/parser.y
	lib/symbol.cpp
	test/stage7.tes
parents 225d9c19 2b438a82
......@@ -22,6 +22,8 @@ OBJ=$(SRC:.cpp=.o)
# make options
EXEC=sam-compiler
VERBOSE=verbose
DEBUG=debug
TEST=test
ECHO=/bin/echo
......@@ -46,11 +48,17 @@ default:
"\tmake cleanall \t\t- Cleans up all directories and generated files PLUS temporary files.\n" \
"\n"
all: $(EXEC) $(TEST)
all: $(EXEC)
$(EXEC): $(OBJ)
$(CC) $(LDFLAGS) $(SRC) -o $@
$(VERBOSE): $(OBJ)
$(CC) $(LDFLAGS) -DCOMPILER_VERBOSE $(SRC) -o $(EXEC)
$(DEBUG): $(OBJ)
$(CC) $(LDFLAGS) -DCOMPILER_DEBUG $(SRC) -o $(EXEC)
$(PARSER): $(LIBDIR)/parser.y
$(FLEX) -o $(SCANNER) $(LIBDIR)/scanner.l
$(BISON) $(LIBDIR)/parser.y -o $(PARSER)
......
......@@ -26,10 +26,13 @@ class InstructionList {
int getStackAddress(Symbol* symbol);
void stackPush(Symbol* symbol);
void stackPush(enum Symbol::Type type);
Symbol* stackPop();
Symbol* stackPop(int num = 1);
void levelPush();
int levelPop();
int stackPushFunctionParam(Symbol* sym);
void moveStackPointer(int num);
string toString();
string FunctionToString(Instruction* inst, int varAddrSpace);
void Print();
private:
......
......@@ -18,17 +18,21 @@ class Symbol {
INTEGER,
FLOAT,
INPUT,
VARIABLE
VARIABLE,
FUNCTION,
FUNC_ARG
};
union value_t {
int i;
float f;
Symbol* s; // These will be variables for functions in a string
};
Symbol();
Symbol(const Symbol *symbol);
Symbol(string lexeme, Type valueType, Type returnType);
Symbol(string lexeme, value_t value, Type valueType);
Symbol(string lexeme, value_t value, Type valueType, Type returnType);
Symbol(string lexeme, int value);
Symbol(string lexeme, float value);
......@@ -37,11 +41,15 @@ class Symbol {
string getLexeme() const;
void setValue(int value);
void setValue(float value);
void setValue(Symbol* value);
value_t getValue() const;
void setFunctionValue(Symbol* value);
Symbol* getFunctionValue() const;
void setType(enum Type valueType);
enum Type getType() const;
void setReturnType(enum Type returnType);
enum Type getReturnType() const;
int getArguments(bool isFunction=false);
bool operator==(const Symbol *rhs) const;
string toString() const;
......@@ -51,6 +59,7 @@ private:
value_t value;
Type valueType;
Type returnType;
Symbol* f; // These will be variables for the function
};
#endif /* SYMBOL_H_ */
......@@ -11,34 +11,36 @@
#include <iomanip>
#include <map>
#include <string>
#include <vector>
const int FLOAT_PRECISION = 6;
using std::map;
using std::string;
using std::vector;
class SymbolTable {
public:
SymbolTable(int parent_table = 0);
SymbolTable(int parent_table_num = -1, SymbolTable* parent_table = NULL);
int Count() const;
Symbol* Insert(const Symbol *entry); // Variable or Function insertion
Symbol* Insert(Symbol *entry); // Variable or Function insertion
Symbol* Insert(const int value); // Constant Value insertion
Symbol* Insert(const float value); // Constant Value insertion
Symbol* FindConstant(const int value);
Symbol* FindConstant(const float value);
Symbol* Find(const string lexeme);
void setParentTable(const int parent_table);
void setParentTable(int parent_table_num, SymbolTable* parent_table);
int getParentTable() const;
void Print();
private:
string getLexeme(int i);
string getLexeme(float f);
map<string,Symbol*> table;
int parent_table;
int current_ptr;
SymbolTable* parent_table;
int parent_table_num;
};
#endif /* SYMBOLTABLE_H_ */
......@@ -15,7 +15,7 @@
using std::vector;
// Declare yyparse here so we can use it... the actual function is linked later
int yyparse (vector<SymbolTable*> symbol_table, InstructionList* instructions);
int yyparse (vector<SymbolTable*>* symbol_table, InstructionList* instructions);
Compiler::Compiler(int argc, char *argv[])
{
......@@ -38,8 +38,10 @@ void Compiler::Run()
{
// Initialize our symbol table and instruction list
InstructionList* instructions = new InstructionList();
vector<SymbolTable*> symbol_table;
symbol_table.push_back(new SymbolTable);
vector<SymbolTable*>* symbol_table = new vector<SymbolTable*>();
symbol_table->push_back(new SymbolTable());
symbol_table->at(0)->Insert(new Symbol("readInput", Symbol::INPUT, Symbol::INTEGER));
symbol_table->push_back(new SymbolTable(0, symbol_table->at(0)));
// For each source file we have... at this time, we just have one, so this may never be needed
for (vector<string>::iterator i = this->filenames.begin(); i != this->filenames.end(); i++)
......@@ -52,19 +54,20 @@ void Compiler::Run()
throw CompilerException("yyparse() failed");
}
string output = instructions->toString();
// These two lines are just debug statements
// TODO: Global DEBUG constant
for (unsigned int i = 0; i < symbol_table.size(); i++)
#ifdef COMPILER_VERBOSE
for (unsigned int i = 0; i < symbol_table->size(); i++)
{
std::cerr << std::endl << i << std::endl;
symbol_table[i]->Print();
symbol_table->at(i)->Print();
}
instructions->Print();
#endif
string output = instructions->toString();
#ifdef COMPILER_VERBOSE
instructions->Print();
#endif
// Open the output file and write the generated assembly to it
std::ofstream of;
of.open(this->output.c_str());
......
......@@ -205,6 +205,9 @@ string Instruction::toGenericString() const
case Instruction::FUNCTION_START:
oss << "FUNCTION_START";
break;
case Instruction::VARDECL:
oss << "Variable Declaration";
break;
}
switch(this->arg1_type)
......
......@@ -47,11 +47,13 @@ equals [=]
lparen [(]
rparen [)]
letter [a-zA-Z]
identifier {letter}({letter}|{digit})+
identifier {letter}({letter}|{digit})*
comma [,]
%%
{number} { yylval.inum = atoi(yytext); return NUMBER; }
{float} { yylval.fnum = atof(yytext); return FLOAT; }
"function" { return FUNCTION;}
"readInput" { return USERINPUT; }
"output" { return OUTPUT; }
{identifier} { yylval.name = strdup(yytext); return ID; }
......@@ -64,4 +66,5 @@ identifier {letter}({letter}|{digit})+
{equals} { return EQUALS; }
{newline} { return NEWLINE; }
{whitesp} { /* No action and no return */ }
{comma} { return COMMA; }
......@@ -12,7 +12,8 @@ using std::stringstream;
Symbol::Symbol()
{
this->value.s = NULL;
this->f = NULL;
}
Symbol::Symbol(const Symbol *symbol)
......@@ -22,17 +23,29 @@ Symbol::Symbol(const Symbol *symbol)
Symbol::Symbol(string lexeme, Type valueType, Type returnType)
{
this->value.s = NULL;
this->f = NULL;
this->setType(valueType);
this->setLexeme(lexeme);
this->setReturnType(returnType);
}
Symbol::Symbol(string lexeme, value_t value, Type valueType, Type returnType)
Symbol::Symbol(string lexeme, value_t value, Type valueType)
{
this->setLexeme(lexeme);
this->setType(valueType);
this->value = value;
this->f = NULL;
}
Symbol::Symbol(string lexeme, value_t value, Type valueType, Type returnType)
{
this->setLexeme(lexeme);
this->setType(valueType);
this->setReturnType(returnType);
this->value = value;
this->f = NULL;
}
Symbol::Symbol(string lexeme, int value)
......@@ -40,6 +53,7 @@ Symbol::Symbol(string lexeme, int value)
this->setLexeme(lexeme);
this->setValue(value);
this->setReturnType(Symbol::INTEGER);
this->f = NULL;
}
Symbol::Symbol(string lexeme, float value)
......@@ -47,6 +61,7 @@ Symbol::Symbol(string lexeme, float value)
this->setLexeme(lexeme);
this->setValue(value);
this->setReturnType(Symbol::FLOAT);
this->f = NULL;
}
void Symbol::setLexeme(string lexeme)
......@@ -72,6 +87,21 @@ void Symbol::setValue(float value)
this->setType(Symbol::FLOAT);
}
void Symbol::setValue(Symbol* value)
{
this->value.s = value;
}
void Symbol::setFunctionValue(Symbol* value)
{
this->f = value;
}
Symbol* Symbol::getFunctionValue() const
{
return this->f;
}
Symbol::value_t Symbol::getValue() const
{
return this->value;
......@@ -80,6 +110,8 @@ Symbol::value_t Symbol::getValue() const
void Symbol::setType(enum Type valueType)
{
this->valueType = valueType;
if(valueType == Symbol::VARIABLE)
this->value.s = NULL;
}
enum Symbol::Type Symbol::getType() const
......@@ -92,6 +124,16 @@ void Symbol::setReturnType(enum Symbol::Type returnType)
this->returnType = returnType;
}
int Symbol::getArguments(bool isFunction)
{
if(this->getType() == Symbol::FUNCTION && this->f != NULL && isFunction)
return this->f->getArguments(false);
else if(((this->getType() == Symbol::FUNCTION && !isFunction) || this->getType() == Symbol::VARIABLE) && this->getValue().s != NULL)
return this->getValue().s->getArguments(false) + 1;
return 0;
}
enum Symbol::Type Symbol::getReturnType() const
{
return this->returnType;
......@@ -116,8 +158,40 @@ bool Symbol::operator==(const Symbol *rhs) const
return true;
break;
case Symbol::VARIABLE:
if(rhs->getLexeme() == this->getLexeme())
return true;
if(rhs->getLexeme() == this->getLexeme() &&
rhs->getReturnType() == this->getReturnType())
{
if(rhs->getValue().s != NULL && this->getValue().s != NULL)
{
Symbol a(rhs->getValue().s);
if(a == this->getValue().s)
return true;
}
}
break;
case Symbol::FUNCTION:
if(rhs->getLexeme() == this->getLexeme() &&
rhs->getReturnType() == this->getReturnType())
{
if(rhs->getFunctionValue() != NULL && this->getFunctionValue() != NULL)
{
Symbol a(rhs->getFunctionValue());
if(a == this->getFunctionValue())
return true;
}
}
break;
case Symbol::FUNC_ARG:
if(rhs->getLexeme() == this->getLexeme() &&
rhs->getReturnType() == this->getReturnType())
{
if(rhs->getValue().s != NULL && this->getValue().s != NULL)
{
Symbol a(rhs->getValue().s);
if(a == this->getValue().s)
return true;
}
}
break;
}
}
......@@ -136,11 +210,30 @@ string Symbol::toString() const
oss << "Integer\t" << this->value.i;
break;
case VARIABLE:
oss << "Variable\t" << this->value.i;
oss << "Variable\t";
if(this->value.s != NULL)
oss << this->value.s->toString();
if(this->f != NULL)
oss << this->f->toString();
break;
case FLOAT:
oss << "Float\t" << this->value.f;
break;
case FUNCTION:
oss << "Function\t";
if(this->value.s != NULL)
oss << this->value.s->toString();
if(this->f != NULL)
oss << this->f->toString();
break;
case FUNC_ARG:
oss << "Function Argument\t";
if(this->value.s != NULL)
oss << this->value.s->toString();
if(this->f != NULL)
oss << this->f->toString();
break;
break;
default:
break;
}
......
......@@ -12,11 +12,10 @@
using std::stringstream;
SymbolTable::SymbolTable(int parent_table)
SymbolTable::SymbolTable(int parent_table_num, SymbolTable* parent_table)
{
this->Insert(new Symbol("readInput", Symbol::INPUT, Symbol::INTEGER));
this->parent_table = parent_table;
this->current_ptr = 0;
this->parent_table_num = parent_table_num;
}
int SymbolTable::Count() const
......@@ -24,28 +23,18 @@ int SymbolTable::Count() const
return this->table.size();
}
Symbol* SymbolTable::Insert(const Symbol *entry)
Symbol* SymbolTable::Insert(Symbol *entry)
{
Symbol *tmp = new Symbol(entry);
//Symbol *tmp = new Symbol(entry);
map<string,Symbol*>::iterator it;
it = this->table.find(tmp->getLexeme());
it = this->table.find(entry->getLexeme());
if(it == this->table.end())
this->table.insert( std::pair<string,Symbol*>(tmp->getLexeme(),tmp));
this->table.insert( std::pair<string,Symbol*>(entry->getLexeme(),entry));
else
tmp = it->second;
entry = it->second;
if(tmp->getType() == Symbol::VARIABLE)
{
if(tmp->getReturnType() == Symbol::INTEGER)
this->current_ptr += 4;
else
this->current_ptr += 8;
tmp->setValue(this->current_ptr);
}
return tmp;
return entry;
}
Symbol* SymbolTable::Insert(const int value)
......@@ -74,23 +63,30 @@ Symbol* SymbolTable::Find(const string lexeme)
it = this->table.find(lexeme);
if(it == this->table.end())
return NULL;
{
if(this->parent_table != NULL)
return this->parent_table->Find(lexeme);
else
return NULL;
}
return it->second;
}
void SymbolTable::setParentTable(const int parent_table)
void SymbolTable::setParentTable(int parent_table_num, SymbolTable* parent_table)
{
this->parent_table_num = parent_table_num;
this->parent_table = parent_table;
}
int SymbolTable::getParentTable() const
{
return this->parent_table;
return this->parent_table_num;
}
void SymbolTable::Print()
{
#ifdef COMPILER_VERBOSE
int i = 0;
map<string,Symbol*>::iterator it;
......@@ -110,6 +106,13 @@ void SymbolTable::Print()
case Symbol::INPUT:
std::cerr << it->second->getLexeme();
break;
case Symbol::FUNCTION:
std::cerr << it->second->getLexeme() << " ";
if(it->second->getFunctionValue() != NULL)
std::cerr << it->second->getFunctionValue()->toString();
if(it->second->getValue().s != NULL)
std::cerr << it->second->getValue().s->toString();
break;
}
switch(it->second->getReturnType())
{
......@@ -125,6 +128,9 @@ void SymbolTable::Print()
case Symbol::INPUT:
std::cerr << " Input";
break;
case Symbol::FUNCTION:
std::cerr << " Function";
break;
}
std::cerr << std::endl;
......@@ -132,6 +138,7 @@ void SymbolTable::Print()
}
std::cerr << "Parent Table: " << this->parent_table << std::endl;
#endif
}
string SymbolTable::getLexeme(float f)
......
......@@ -7,18 +7,31 @@
#include <iostream>
#include "../include/compiler.h"
#include "../include/exception.h"
#ifdef COMPILER_DEBUG
#include <vector>
#include "../include/symbolTable.h"
#include "../include/instructionList.h"
int yyparse (vector<SymbolTable*> symbol_table, InstructionList* instructions);
#endif
using namespace std;
int main(int argc, char *argv[]) {
Compiler *application;
try {
application = new Compiler(argc, argv);
application->Run();
} catch (CompilerException e) {
cerr << e.GetMessage() << endl;
#ifndef COMPILER_DEBUG
Compiler *application;
try {
application = new Compiler(argc, argv);
application->Run();
} catch (CompilerException e) {
cerr << e.GetMessage() << endl;
return 1;
}
return 0;
}
#else
InstructionList* instructions = new InstructionList();
vector<SymbolTable*> symbol_table;
symbol_table.push_back(new SymbolTable());
symbol_table[0]->Insert(new Symbol("readInput", Symbol::INPUT, Symbol::INTEGER));
symbol_table.push_back(new SymbolTable(0, symbol_table[0]));
yyparse(symbol_table, instructions);
#endif
return 0;
}
......@@ -12,3 +12,7 @@ var2=50
output var2
output var1
output var4
var5 = readInput
output var5
output readInput
var6 = var5
a=readInput
b=readInput + 1.0
c=readInput + 2.5
function func(a,b,c,d)=a+b+c
function func1(a,b)=a-b
function func2()=0
output readInput + func(func1(readInput,a),2,func2(),0)
output a
output b
output c
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment