Commit 347091c9 by Andrew Dahl

Fixes #15 - Int and Float Conditionals work. 0 is false, else true!

parent 4245544e
......@@ -34,6 +34,7 @@ public:
bool ExistsInCurrentLevel(const string lexeme);
int getParentTable() const;
void addStackAddress(int size);
void setStackAddress(int size);
int getStackAddress() const;
void Print();
......
......@@ -220,6 +220,9 @@ string Instruction::toGenericString() const
case Instruction::FUNCTION_RETURN:
oss << "FUNCTION_RETURN";
break;
default:
oss << "Not Implemented";
break;
}
switch(this->arg1_type)
......
......@@ -131,7 +131,6 @@ string InstructionList::toString()
map<int, map<int, Instruction*> >::iterator it;
map<int, Instruction*>::iterator itr;
bool isFunction = false;
bool isConditional = false;
// Note: The following is a pointer in case we need to pass it later... Maybe okay to change?
vector<Symbol*>::iterator itvar;
......@@ -169,23 +168,13 @@ string InstructionList::toString()
if(it->second[0]->getOpcode() == Instruction::FUNCTION_START)
{
isFunction = true;
isConditional = false;
oss << "\n\n" << it->second[0]->getArg1().sym->getLexeme() << ":\n"
<< "SUB ESP, " << varAddrSpace << endl
<< "PUSH ESI\n";
}
else if(it->second[0]->getOpcode() == Instruction::CONDITION_IF)
{
isFunction = true;
isConditional = true;
oss << "\n\n" << it->second[0]->getArg1().reg << ":\n"
<< "SUB ESP, " << varAddrSpace << endl
<< "PUSH ESI\n";
}
else
{
isFunction = false;
isConditional = false;
oss << "SUB ESP, " << varAddrSpace << endl
<< "PUSH EDI\n";
}
......@@ -441,13 +430,17 @@ string InstructionList::toString()
// Compare to 0.0
oss << "FLD QWORD [fzero]\n"
<< INSTRUCTION_POP_STACK_TO_FPU
<< "FCOMPP\n";
<< "FCOMPP\n"
<< "FSTSW AX\n"
<< "FWAIT\n"
<< "SAHF\n";
}
else
{
// Compare to 0
oss << "POP EAX\n"
<< "MOV EBX, 0\n";
<< "MOV EBX, 0\n"
<< "CMP EAX, EBX\n";
}
}
......@@ -468,7 +461,16 @@ string InstructionList::toString()
}
break;
case Instruction::JNE:
oss << "JNE " << temp->getArg1().reg << endl;
oss << "JE " << temp->getArg1().reg << "end\n";
break;
case Instruction::JE:
break;
case Instruction::JG:
break;
case Instruction::JL:
break;
case Instruction::CALL:
oss << "PUSH ESI\n"
......@@ -512,6 +514,7 @@ string InstructionList::toString()
break;
case Instruction::CONDITION_IF:
//Placeholder... don't think we do anything for this
oss << temp->getArg1().reg << "end:\n";
break;
case Instruction::VARDECL:
// This is just a placeholder... the only purpose for VARDECL is for determining space needed on the stack
......@@ -641,7 +644,7 @@ string InstructionList::helperMacrosToString()
// getint - Gets an integer from input using scanf
stringstream oss;
oss << ";nasm -f elf <filename>\n"
oss << ";nasm -O3 -f elf <filename>\n"
<< ";gcc -o <executable> <filename>.o -I/lib/ld-linux.so.2 -lc\n"
<< "extern printf\n"
<< "extern scanf\n"
......@@ -732,7 +735,6 @@ int InstructionList::findVarStackSpace(map<int, Instruction*>& list)
{
variables.push_back(newSymbol);
this->stackPush(newSymbol);
newSymbol->setStackAddress(varAddrSpace);
if(newSymbol->getReturnType() == Symbol::FLOAT)
varAddrSpace += 8;
else
......
......@@ -16,7 +16,7 @@
//void yyerror (char const *);
#define yyerror(symbol_table,instructions,msg) hack_yyerror(msg);
void hack_yyerror(char const *);
int level = 1;
int level = 1;
int conditional = 1;
%}
......@@ -36,6 +36,7 @@
%token <name> ID
%type <sym> stat additive_exp mult_exp primary_exp assignment_exp function_define argument_exp_list func_call_args function_decl type_spec
%type <inum> selection_stat
%% /* Grammer Rules and Actions */
......@@ -56,7 +57,7 @@ type_spec: TYPEINT { $$ = new Symbol("temp", Symbol::INTEGER, Symbol::INTEG
| TYPEFLOAT { $$ = new Symbol("temp", Symbol::FLOAT, Symbol::FLOAT); }
;
function_decl: FUNCTION type_spec ID LPAREN {
function_decl: FUNCTION type_spec ID LPAREN {
if(symbol_table->at(level)->ExistsInCurrentLevel($3)) {
yyerror(symbol_table,instructions,"Redeclaration of function");
YYABORT;
......@@ -71,14 +72,16 @@ function_decl: FUNCTION type_spec ID LPAREN {
symbol_table->at(level)->Insert(temp);
instructions->levelPush();
instructions->addInstruction(new Instruction(Instruction::FUNCTION_START, temp));
$$ = temp;
$<sym>$ = temp;
}
}
} argument_exp_list RPAREN {
$<sym>5->setFunctionValue($6);
$$ = $<sym>5;
}
;
function_define: function_decl argument_exp_list RPAREN LCURLY statlist RETURN additive_exp RCURLY {
$1->setFunctionValue($2);
function_define: function_decl LCURLY statlist RETURN additive_exp NEWLINE RCURLY {
instructions->addInstruction(new Instruction(Instruction::FUNCTION_RETURN, $1));
level = symbol_table->at(level)->getParentTable();
instructions->levelPop();
......@@ -99,12 +102,17 @@ argument_exp_list: { $$ = NULL;}
selection_stat: IF additive_exp THEN LCURLY {
instructions->addInstruction(new Instruction(Instruction::CMP, $2));
instructions->addInstruction(new Instruction(Instruction::JNE, conditional));
int size = symbol_table->at(level)->getStackAddress();
symbol_table->push_back(new SymbolTable(level, symbol_table->at(level)));
level = symbol_table->size()-1;
symbol_table->at(level)->setStackAddress(size);
$<inum>$ = conditional;
conditional++;
} statlist RCURLY {
int size = symbol_table->at(level)->getStackAddress();
level = symbol_table->at(level)->getParentTable();
instructions->addInstruction(new Instruction(Instruction::CONDITION_IF));
symbol_table->at(level)->setStackAddress(size);
instructions->addInstruction(new Instruction(Instruction::CONDITION_IF, $<inum>5));
}
;
......
......@@ -48,7 +48,7 @@ equals [=]
lparen [(]
rparen [)]
lcurly {whiteall}?[{]{whiteall}?
rcurly {whiteall}?[}]{whiteall}?
rcurly [}]{whiteall}?
letter [a-zA-Z]
identifier {letter}({letter}|{digit})*
comma [,]
......
......@@ -138,7 +138,7 @@ int Symbol::getArgumentsValue(bool isFunction)
{
if(this->getType() == Symbol::FUNCTION && this->f != NULL && isFunction)
return this->f->getArgumentsValue(false);
else if(((this->getType() == Symbol::FUNCTION && !isFunction) || this->getType() == Symbol::VARIABLE))
else
{
if(this->getValue().s != NULL)
{
......@@ -151,7 +151,7 @@ int Symbol::getArgumentsValue(bool isFunction)
{
if(this->getReturnType() == Symbol::FLOAT)
return 8;
else
else if (this->getReturnType() == Symbol::INTEGER)
return 4;
}
}
......
......@@ -106,6 +106,11 @@ void SymbolTable::addStackAddress(int size)
this->stack_address += size;
}
void SymbolTable::setStackAddress(int size)
{
this->stack_address = size;
}
int SymbolTable::getStackAddress() const
{
return this->stack_address;
......
function int count(int num) {
if num then {
output count(num - 1)
}
return num
}
function float fcount(float fnum) {
if fnum then {
output fcount(fnum - 1)
}
return fnum
}
output count(5)
output fcount(5.0)
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