Commit 4245544e by Andrew Dahl

Some additions for conditionals

parent b1cf7e54
......@@ -30,10 +30,16 @@ class Instruction {
PUSH, /* Integer: PUSH Src Float: FLD Src */
POP, /* Integer: POP Dest Float: FSTP Src */
MOV, /* Not sure if this matters on type... MOV Dest Src */
CMP, /* */
JE, /* Short Jump if equal */
JG, /* Short Jump if greater than */
JL, /* Short Jump if less than */
JNE, /* Short Jump if not zero TEMPORARY!!!! */
CALL, /* CALL Arg */
FUNCTION_START, /* Used to differentiate blocks from functions */
VARDECL,/* Used to determine variable declarations in blocks */
FUNCTION_RETURN
FUNCTION_RETURN, /* */
CONDITION_IF /* */
};
enum arg_type {
......@@ -54,6 +60,7 @@ class Instruction {
Instruction(Opcode opcode, Symbol* arg1, string arg2);
Instruction(Opcode opcode, string arg1, Symbol* arg2);
Instruction(Opcode opcode, string arg1, string arg2);
Instruction(Opcode opcode, int arg1);
Opcode getOpcode() const;
arg_value getArg1() const;
......
......@@ -57,6 +57,15 @@ Instruction::Instruction(Opcode opcode, string arg1, string arg2)
this->setArg2(arg2);
}
Instruction::Instruction(Opcode opcode, int arg1)
{
stringstream oss;
this->setOpcode(opcode);
oss << "conditional" << arg1;
this->setArg1(strdup(oss.str().c_str()));
this->setArg2Type(Instruction::NONE);
}
enum Instruction::Opcode Instruction::getOpcode() const
{
return this->opcode;
......
......@@ -131,6 +131,7 @@ 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;
......@@ -138,7 +139,8 @@ string InstructionList::toString()
oss << "section .data\n"
<< "ifmt: db \"%d\", 10, 0\n"
<< "ffmt: db \"%f\", 10, 0\n"
<< "iinfmt: db \"%d\", 0\n";
<< "iinfmt: db \"%d\", 0\n"
<< "fzero: dq 0.000000\n";
oss << this->floatDeclsToString();
......@@ -164,19 +166,29 @@ string InstructionList::toString()
for(it = this->instructions.begin(); it != this->instructions.end(); it++)
{
varAddrSpace = this->findVarStackSpace(it->second);
if(it->second[0]->getOpcode() != Instruction::FUNCTION_START)
if(it->second[0]->getOpcode() == Instruction::FUNCTION_START)
{
isFunction = false;
oss << "SUB ESP, " << varAddrSpace << endl
<< "PUSH EDI\n";
isFunction = true;
isConditional = false;
oss << "\n\n" << it->second[0]->getArg1().sym->getLexeme() << ":\n"
<< "SUB ESP, " << varAddrSpace << endl
<< "PUSH ESI\n";
}
else
else if(it->second[0]->getOpcode() == Instruction::CONDITION_IF)
{
isFunction = true;
oss << "\n\n" << it->second[0]->getArg1().sym->getLexeme() << ":\n"
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";
}
if(isFunction)
{
......@@ -420,6 +432,44 @@ string InstructionList::toString()
break;
}
break;
case Instruction::CMP:
//Compare two ints, two floats, or an int/float to 0/0.0
if(temp->getArg2Type() == Instruction::NONE)
{
if(this->getTopType() == Symbol::FLOAT)
{
// Compare to 0.0
oss << "FLD QWORD [fzero]\n"
<< INSTRUCTION_POP_STACK_TO_FPU
<< "FCOMPP\n";
}
else
{
// Compare to 0
oss << "POP EAX\n"
<< "MOV EBX, 0\n";
}
}
else
{
// Compare two ints/floats
oss << this->checkTopTwoTypesToString();
if(this->getTopType() == Symbol::FLOAT)
{
// Compare floats
}
else
{
// Compare ints
}
}
break;
case Instruction::JNE:
oss << "JNE " << temp->getArg1().reg << endl;
break;
case Instruction::CALL:
oss << "PUSH ESI\n"
<< "MOV ESI, ESP\n"
......@@ -460,6 +510,9 @@ string InstructionList::toString()
oss << "POP DWORD [tempi]\n";
}
break;
case Instruction::CONDITION_IF:
//Placeholder... don't think we do anything for this
break;
case Instruction::VARDECL:
// This is just a placeholder... the only purpose for VARDECL is for determining space needed on the stack
break;
......@@ -467,12 +520,7 @@ string InstructionList::toString()
}
if(!isFunction)
oss << "ADD ESP, " << varAddrSpace << endl
<< "POP EDI\n"
<< "MOV EAX, 0\n"
<< "RET\n";
else
if(isFunction)
{
// We're storing the return type in tempi/tempf now... don't think this is needed
/*if(this->getTopType() == Symbol::FLOAT)
......@@ -483,6 +531,13 @@ string InstructionList::toString()
<< "POP ESI\n"
<< "RET\n";
}
else
{
oss << "ADD ESP, " << varAddrSpace << endl
<< "POP EDI\n"
<< "MOV EAX, 0\n"
<< "RET\n";
}
}
......@@ -677,6 +732,7 @@ 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
......
......@@ -17,6 +17,7 @@
#define yyerror(symbol_table,instructions,msg) hack_yyerror(msg);
void hack_yyerror(char const *);
int level = 1;
int conditional = 1;
%}
%parse-param { vector<SymbolTable*>* symbol_table }
......@@ -29,7 +30,7 @@
char* name;
}
%token NEWLINE PLUS MINUS SLASH ASTERISK LPAREN RPAREN EQUALS USERINPUT OUTPUT FUNCTION COMMA LCURLY RCURLY RETURN TYPEINT TYPEFLOAT
%token NEWLINE PLUS MINUS SLASH ASTERISK LPAREN RPAREN EQUALS USERINPUT OUTPUT FUNCTION COMMA LCURLY RCURLY RETURN TYPEINT TYPEFLOAT IF THEN
%token <inum> NUMBER
%token <fnum> FLOAT
%token <name> ID
......@@ -95,6 +96,18 @@ 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));
symbol_table->push_back(new SymbolTable(level, symbol_table->at(level)));
level = symbol_table->size()-1;
} statlist RCURLY {
level = symbol_table->at(level)->getParentTable();
instructions->addInstruction(new Instruction(Instruction::CONDITION_IF));
}
;
assignment_exp: additive_exp
| ID EQUALS assignment_exp {
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($1, Symbol::VARIABLE, $3->getReturnType()));
......@@ -156,9 +169,6 @@ stat: OUTPUT additive_exp NEWLINE {
| selection_stat { }
;
selection_stat: IF additive_exp THEN LCURLY stat_list RCURLY { }
;
additive_exp: additive_exp PLUS mult_exp {
instructions->addInstruction(new Instruction(Instruction::ADD));
if($1->getReturnType() == Symbol::FLOAT || $3->getReturnType() == Symbol::FLOAT)
......
......@@ -57,7 +57,7 @@ comma [,]
{number} { yylval.inum = atoi(yytext); return NUMBER; }
{float} { yylval.fnum = atof(yytext); return FLOAT; }
"if" { return IF; }
"then" { return THEN;
"then" { return THEN; }
"function" { return FUNCTION; }
"readInput" { return USERINPUT; }
"output" { return OUTPUT; }
......
......@@ -14,4 +14,4 @@ output func(0,1,2,3.4)
return a
}
output func2(0)
output func(1, 2, 3, 4.5)
output func(1, 2, 3, 0.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