Commit 8c0becd9 by Andrew Dahl

Ref #20 - New setup for variables on the stack is working

Basically, this new setup involves an array at the beginning of the stack that holds pointers to each function where variables are declared.  So, in the event func3 wants to use func1's variables, it just has to see which index the variable is in (stored in Symbol) and then get the stack address from that pointer (also in Symbol). Oy!
parent 21efe2aa
......@@ -33,6 +33,8 @@ class InstructionList {
void moveStackPointer(int num);
string toString();
string FunctionToString(Instruction* inst, int varAddrSpace);
void setScopeAddress(int address);
int getScopeAddress() const;
void Print();
private:
......@@ -47,6 +49,7 @@ class InstructionList {
map<int, map<int, Instruction*> > instructions;
vector<Symbol*> stack;
vector<int> levelStack;
int scope_address;
};
#endif /* INSTRUCTIONLIST_H_ */
......@@ -31,9 +31,9 @@ class Symbol {
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, Type valueType, Type returnType, int address);
Symbol(string lexeme, value_t value, Type valueType, int address);
Symbol(string lexeme, value_t value, Type valueType, Type returnType, int address);
Symbol(string lexeme, int value);
Symbol(string lexeme, float value);
......@@ -54,6 +54,8 @@ class Symbol {
bool operator==(const Symbol *rhs) const;
void setStackAddress(int address);
int getStackAddress() const;
void setScopeAddress(int address);
int getScopeAddress() const;
void setGlobal(bool global);
bool getGlobal() const;
......@@ -66,6 +68,7 @@ private:
Type returnType;
Symbol* f; // These will be variables for the function
int stack_address;
int scope_address;
bool is_global;
};
......
......@@ -26,6 +26,7 @@ public:
int Count() const;
Symbol* Insert(Symbol *entry); // Variable or Function insertion
Symbol* InsertGlobal(Symbol *entry);
Symbol* Insert(const int value); // Constant Value insertion
Symbol* Insert(const float value); // Constant Value insertion
Symbol* FindConstant(const int value);
......
......@@ -40,7 +40,7 @@ void Compiler::Run()
InstructionList* instructions = new InstructionList();
vector<SymbolTable*>* symbol_table = new vector<SymbolTable*>();
symbol_table->push_back(new SymbolTable(-1, NULL));
symbol_table->at(0)->Insert(new Symbol("readInput", Symbol::INPUT, Symbol::INTEGER));
symbol_table->at(0)->Insert(new Symbol("readInput", Symbol::INPUT, Symbol::INTEGER, 0));
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
......@@ -60,7 +60,6 @@ void Compiler::Run()
std::cerr << std::endl << i << std::endl;
symbol_table->at(i)->Print();
}
instructions->Print();
#endif
string output = instructions->toString();
......
......@@ -58,7 +58,7 @@ void InstructionList::stackPush(Symbol* symbol)
void InstructionList::stackPush(enum Symbol::Type type)
{
this->stack.push_back(new Symbol("temp",type,type));
this->stack.push_back(new Symbol("temp",type,type, 0));
}
Symbol* InstructionList::stackPop(int num)
......@@ -169,14 +169,16 @@ string InstructionList::toString()
{
isFunction = true;
oss << "\n\n" << it->second[0]->getArg1().sym->getLexeme() << ":\n"
<< "SUB ESP, " << varAddrSpace << endl
<< "PUSH ESI\n";
<< "SUB ESP, " << varAddrSpace << endl;
}
else
{
isFunction = false;
oss << "SUB ESP, " << varAddrSpace << endl
<< "PUSH EDI\n";
oss << "PUSH EDI\n"
<< "MOV EDI, ESP\n"
<< "SUB ESP, " << this->getScopeAddress() << endl
<< "SUB ESP, " << varAddrSpace << endl;
}
if(isFunction)
......@@ -206,10 +208,10 @@ string InstructionList::toString()
}
}
oss << "MOV ESI, ESP\n";
oss << "MOV [EDI-" << it->second[0]->getArg1().sym->getScopeAddress() << "], ESP\n";
}
else
oss << "MOV EDI, ESP\n";
oss << "MOV [EDI-4], ESP\n";
for(itr = it->second.begin(); itr != it->second.end(); itr++)
{
......@@ -318,22 +320,12 @@ string InstructionList::toString()
oss << "PUSH " << temp->arg1ToString() << endl;
break;
case Symbol::VARIABLE:
if(temp->getArg1().sym->getGlobal())
{
if(temp->getArg1().sym->getReturnType() == Symbol::FLOAT) {
oss << "PUSH DWORD [EDI+" << (temp->getArg1().sym->getStackAddress() + 4) << "]\n";
oss << "PUSH DWORD [EDI+" << (temp->getArg1().sym->getStackAddress()) << "]\n";
} else
oss << "PUSH DWORD [EDI+" << temp->getArg1().sym->getStackAddress() << "]\n";
}
else
{
if(temp->getArg1().sym->getReturnType() == Symbol::FLOAT) {
oss << "PUSH DWORD [ESI+" << (temp->getArg1().sym->getStackAddress() + 4) << "]\n";
oss << "PUSH DWORD [ESI+" << (temp->getArg1().sym->getStackAddress()) << "]\n";
} else
oss << "PUSH DWORD [ESI+" << temp->getArg1().sym->getStackAddress() << "]\n";
}
oss << "MOV ESI, [EDI-" << temp->getArg1().sym->getScopeAddress() << "]\n";
if(temp->getArg1().sym->getReturnType() == Symbol::FLOAT) {
oss << "PUSH DWORD [ESI+" << (temp->getArg1().sym->getStackAddress() + 4) << "]\n";
oss << "PUSH DWORD [ESI+" << (temp->getArg1().sym->getStackAddress()) << "]\n";
} else
oss << "PUSH DWORD [ESI+" << temp->getArg1().sym->getStackAddress() << "]\n";
break;
default:
oss << "NOT IMPLEMENTED\n";
......@@ -368,22 +360,17 @@ string InstructionList::toString()
<< INSTRUCTION_CONVERT_INT_TO_FPU
<< INSTRUCTION_POP_FPU_TO_STACK
<< "POP EAX\n"
<< "POP EBX\n";
if(temp->getArg1().sym->getGlobal())
oss << "MOV [EDI+" << temp->getArg1().sym->getStackAddress() << "], EAX\n"
<< "MOV [EDI+" << (temp->getArg1().sym->getStackAddress() + 4) << "], EBX\n";
else
oss << "MOV [ESI+" << temp->getArg1().sym->getStackAddress() << "], EAX\n"
<< "MOV [ESI+" << (temp->getArg1().sym->getStackAddress() + 4) << "], EBX\n";
oss << "PUSH EDX\n";
<< "POP EBX\n"
<< "MOV ESI, [EDI-" << temp->getArg1().sym->getScopeAddress() << "]\n"
<< "MOV [ESI+" << temp->getArg1().sym->getStackAddress() << "], EAX\n"
<< "MOV [ESI+" << (temp->getArg1().sym->getStackAddress() + 4) << "], EBX\n"
<< "PUSH EDX\n";
break;
default:
oss << "POP EAX\n";
if(temp->getArg1().sym->getGlobal())
oss << "MOV [EDI+" << (temp->getArg1().sym->getStackAddress()) << "], EAX\n";
else
oss << "MOV [ESI+" << (temp->getArg1().sym->getStackAddress()) << "], EAX\n";
oss << "PUSH EAX\n";
oss << "POP EAX\n"
<< "MOV ESI, [EDI-" << temp->getArg1().sym->getScopeAddress() << "]\n"
<< "MOV [ESI+" << (temp->getArg1().sym->getStackAddress()) << "], EAX\n"
<< "PUSH EAX\n";
break;
}
break;
......@@ -394,23 +381,18 @@ string InstructionList::toString()
//Convert float to int and mov
oss << "FLD QWORD [ESP]\n"
<< INSTRUCTION_CONVERT_FLOAT_TO_INT
<< "POP EAX\n";
if(temp->getArg1().sym->getGlobal())
oss << "MOV [EDI+" << temp->getArg1().sym->getStackAddress() << "], EAX\n";
else
oss << "MOV [ESI+" << temp->getArg1().sym->getStackAddress() << "], EAX\n";
<< "POP EAX\n"
<< "MOV ESI, [EDI-" << temp->getArg1().sym->getScopeAddress() << "]\n"
<< "MOV [ESI+" << temp->getArg1().sym->getStackAddress() << "], EAX\n";
break;
default:
//Move
oss << "POP EAX\n"
<< "POP EBX\n";
if(temp->getArg1().sym->getGlobal())
oss << "MOV [EDI+" << (temp->getArg1().sym->getStackAddress()) << "], EAX\n"
<< "MOV [EDI+" << (temp->getArg1().sym->getStackAddress() + 4) << "], EBX\n";
else
oss << "MOV [ESI+" << (temp->getArg1().sym->getStackAddress()) << "], EAX\n"
<< "MOV [ESI+" << (temp->getArg1().sym->getStackAddress() + 4) << "], EBX\n";
oss << "PUSH EBX\n"
<< "POP EBX\n"
<< "MOV ESI, [EDI-" << temp->getArg1().sym->getScopeAddress() << "]\n"
<< "MOV [ESI+" << (temp->getArg1().sym->getStackAddress()) << "], EAX\n"
<< "MOV [ESI+" << (temp->getArg1().sym->getStackAddress() + 4) << "], EBX\n"
<< "PUSH EBX\n"
<< "PUSH EAX\n";
break;
}
......@@ -493,13 +475,13 @@ string InstructionList::toString()
this->stackPop(temp->getArg1().sym->getArguments(true));
if(temp->getArg1().sym->getReturnType() == Symbol::FLOAT)
{
this->stackPush(new Symbol("temp", Symbol::FLOAT, Symbol::FLOAT));
this->stackPush(new Symbol("temp", Symbol::FLOAT, Symbol::FLOAT, 0));
oss << "FLD QWORD [tempf]\n"
<< INSTRUCTION_POP_FPU_TO_STACK;
}
else
{
this->stackPush(new Symbol("temp", Symbol::INTEGER, Symbol::INTEGER));
this->stackPush(new Symbol("temp", Symbol::INTEGER, Symbol::INTEGER, 0));
oss << "PUSH DWORD [tempi]\n";
}
break;
......@@ -551,13 +533,13 @@ string InstructionList::toString()
else
oss << "POP EBX\n";*/
oss << "ADD ESP, " << varAddrSpace + temp->getArg1().sym->getArgumentsValue(true) << endl
<< "POP ESI\n"
<< "RET\n";
}
else
{
oss << "CALL start\n";
oss << "ADD ESP, " << varAddrSpace << endl
<< "ADD ESP, " << this->getScopeAddress() << endl
<< "POP EDI\n"
<< "MOV EAX, 0\n"
<< "RET\n";
......@@ -766,3 +748,13 @@ int InstructionList::findVarStackSpace(map<int, Instruction*>& list)
return varAddrSpace;
}
void InstructionList::setScopeAddress(int address)
{
this->scope_address = address;
}
int InstructionList::getScopeAddress() const
{
return this->scope_address;
}
......@@ -50,6 +50,8 @@ program: translation_unit {
yyerror(symbol_table, instructions, "Main does not exist!");
YYABORT;
}
instructions->setScopeAddress((symbol_table->size() - 1) * 4);
}
;
......@@ -63,8 +65,8 @@ external_decl: NEWLINE
| error { yyerrok; YYABORT;}
;
type_spec: TYPEINT { $$ = new Symbol("temp", Symbol::INTEGER, Symbol::INTEGER); }
| TYPEFLOAT { $$ = new Symbol("temp", Symbol::FLOAT, Symbol::FLOAT); }
type_spec: TYPEINT { $$ = new Symbol("temp", Symbol::INTEGER, Symbol::INTEGER, (level * 4)); }
| TYPEFLOAT { $$ = new Symbol("temp", Symbol::FLOAT, Symbol::FLOAT, (level * 4)); }
;
function_decl: FUNCTION type_spec ID LPAREN {
......@@ -76,7 +78,7 @@ function_decl: FUNCTION type_spec ID LPAREN {
mainExists = true;
$3 = strdup("start");
}
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($3, Symbol::FUNCTION, $2->getReturnType()));
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($3, Symbol::FUNCTION, $2->getReturnType(), ((symbol_table->size()) * 4)));
if(temp->getType() == Symbol::VARIABLE) {
yyerror(symbol_table,instructions,"Function cannot have the same name as a previously declared variable!")
YYABORT;
......@@ -107,11 +109,11 @@ function_define: function_decl LCURLY statlist RETURN additive_exp NEWLINE RCURL
argument_exp_list: { $$ = NULL;}
| type_spec ID {
$$ = (symbol_table->at(level))->Insert(new Symbol($2, Symbol::VARIABLE, $1->getReturnType()));
$$ = (symbol_table->at(level))->Insert(new Symbol($2, Symbol::VARIABLE, $1->getReturnType(), (level * 4)));
}
| argument_exp_list COMMA type_spec ID {
Symbol::value_t symbol_value; symbol_value.s = $1;
$$ = symbol_table->at(level)->Insert(new Symbol($4, symbol_value, Symbol::VARIABLE, $3->getReturnType()));
$$ = symbol_table->at(level)->Insert(new Symbol($4, symbol_value, Symbol::VARIABLE, $3->getReturnType(), (level * 4)));
}
;
......@@ -180,7 +182,7 @@ iteration_stat: WHILE {
assignment_exp: additive_exp
| ID EQUALS assignment_exp {
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($1, Symbol::VARIABLE, $3->getReturnType()));
Symbol* temp = symbol_table->at(level)->Find($1);
if(temp->getType() == Symbol::FUNCTION) {
yyerror(symbol_table, instructions, "Function used like variable!");
YYABORT;
......@@ -216,11 +218,11 @@ stat: OUTPUT additive_exp NEWLINE {
Symbol* temp;
if(level == 1)
{
temp = symbol_table->at(0)->Insert(new Symbol($2, Symbol::VARIABLE, $1->getReturnType()));
temp = symbol_table->at(0)->Insert(new Symbol($2, Symbol::VARIABLE, $1->getReturnType(), 4));
symbol_table->at(level)->Insert(temp);
}
else
temp = symbol_table->at(level)->Insert(new Symbol($2, Symbol::VARIABLE, $1->getReturnType()));
temp = symbol_table->at(level)->Insert(new Symbol($2, Symbol::VARIABLE, $1->getReturnType(), (level * 4)));
if(temp->getType() == Symbol::FUNCTION) {
yyerror(symbol_table, instructions, "Function used like variable!");
YYABORT;
......@@ -243,11 +245,11 @@ stat: OUTPUT additive_exp NEWLINE {
if(level != 1) {
temp = symbol_table->at(0)->Find($3);
if(temp != NULL)
symbol_table->at(level)->Insert(temp);
symbol_table->at(level)->InsertGlobal(temp);
}
else
{
temp = symbol_table->at(0)->Insert(new Symbol($3, Symbol::VARIABLE, $2->getReturnType()));
temp = symbol_table->at(0)->Insert(new Symbol($3, Symbol::VARIABLE, $2->getReturnType(), 4));
symbol_table->at(level)->Insert(temp);
}
if(temp == NULL) {
......@@ -389,6 +391,7 @@ primary_exp: LPAREN additive_exp RPAREN {
func->setFunctionValue($3);
if(temp->getArguments(true) != func->getArguments(true)) {
fprintf(stderr, "%d = %d\n", temp->getArguments(true), func->getArguments(true));
yyerror(symbol_table, instructions, "Incorrect number of arguments given!");
YYABORT;
} else {
......
......@@ -18,34 +18,37 @@ Symbol::Symbol()
Symbol::Symbol(const Symbol *symbol)
{
*this = Symbol(symbol->getLexeme(), symbol->getValue(), symbol->getType(), symbol->getReturnType());
*this = Symbol(symbol->getLexeme(), symbol->getValue(), symbol->getType(), symbol->getReturnType(), symbol->getScopeAddress());
this->setStackAddress(symbol->getStackAddress());
}
Symbol::Symbol(string lexeme, Type valueType, Type returnType)
Symbol::Symbol(string lexeme, Type valueType, Type returnType, int address)
{
this->value.s = NULL;
this->f = NULL;
this->setType(valueType);
this->setLexeme(lexeme);
this->setReturnType(returnType);
this->setScopeAddress(address);
}
Symbol::Symbol(string lexeme, value_t value, Type valueType)
Symbol::Symbol(string lexeme, value_t value, Type valueType, int address)
{
this->setLexeme(lexeme);
this->setType(valueType);
this->value = value;
this->f = NULL;
this->setScopeAddress(address);
}
Symbol::Symbol(string lexeme, value_t value, Type valueType, Type returnType)
Symbol::Symbol(string lexeme, value_t value, Type valueType, Type returnType, int address)
{
this->setLexeme(lexeme);
this->setType(valueType);
this->setReturnType(returnType);
this->value = value;
this->f = NULL;
this->setScopeAddress(address);
}
Symbol::Symbol(string lexeme, int value)
......@@ -234,6 +237,16 @@ int Symbol::getStackAddress() const
return this->stack_address;
}
void Symbol::setScopeAddress(int address)
{
this->scope_address = address;
}
int Symbol::getScopeAddress() const
{
return this->scope_address;
}
void Symbol::setGlobal(bool global)
{
this->is_global = global;
......@@ -260,7 +273,7 @@ string Symbol::toString() const
oss << this->value.s->toString();
if(this->f != NULL)
oss << this->f->toString();
oss << " " << this->getStackAddress();
oss << " " << this->getStackAddress() << " Scope: " << this->getScopeAddress();
break;
case FLOAT:
oss << "Float\t" << this->value.f;
......@@ -271,6 +284,7 @@ string Symbol::toString() const
oss << this->value.s->toString();
if(this->f != NULL)
oss << this->f->toString();
oss << " Scope: " << this->getScopeAddress();
break;
case FUNC_ARG:
oss << "Function Argument\t";
......
......@@ -50,6 +50,12 @@ Symbol* SymbolTable::Insert(Symbol *entry)
return entry;
}
Symbol* SymbolTable::InsertGlobal(Symbol *entry)
{
this->table.insert( std::pair<string,Symbol*>(entry->getLexeme(),entry));
return entry;
}
Symbol* SymbolTable::Insert(const int value)
{
return this->Insert(new Symbol(this->getLexeme(value), value));
......@@ -130,7 +136,7 @@ void SymbolTable::Print()
{
case Symbol::INTEGER:
case Symbol::VARIABLE:
std::cerr << it->second->getLexeme() << " " << it->second->getValue().i << " " << it->second->getStackAddress();
std::cerr << it->second->getLexeme() << " " << it->second->getValue().i << " " << it->second->getStackAddress() << " Scope: " << it->second->getScopeAddress();
break;
case Symbol::FLOAT:
std::cerr << it->second->getLexeme() << " " << it->second->getValue().f;
......@@ -139,7 +145,7 @@ void SymbolTable::Print()
std::cerr << it->second->getLexeme();
break;
case Symbol::FUNCTION:
std::cerr << it->second->getLexeme() << " ";
std::cerr << it->second->getLexeme() << " Scope: " << it->second->getScopeAddress() << " ";
if(it->second->getFunctionValue() != NULL)
std::cerr << it->second->getFunctionValue()->toString();
if(it->second->getValue().s != NULL)
......
global int a = 0
global int b = 10
function int func() {
function int func(int arg8, float farg8) {
global int a = 20
global int b = 30
int c = 40
output a
output b
output c
output arg8
output farg8
return 200
}
function int func1() {
int a = 40
int b = 50
function int func1(int arg12, float farg12) {
int a = 70
int b = 80
output a
output b
output arg12
output farg12
return 400
}
function int main() {
output func()
output func1()
int c = 600
output func(50, 60.0)
output func1(90, 100.0)
output c
return 20
}
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