Commit eb08bae5 by Andrew Dahl

Fixes #14 - Types with warnings

parent 2e4c7732
......@@ -208,6 +208,9 @@ string Instruction::toGenericString() const
case Instruction::VARDECL:
oss << "Variable Declaration";
break;
case Instruction::FUNCTION_RETURN:
oss << "FUNCTION_RETURN";
break;
}
switch(this->arg1_type)
......
......@@ -15,7 +15,6 @@ InstructionList::InstructionList ()
void InstructionList::addInstruction(Instruction* instruction)
{
std::cerr << this->levelStack.back() << endl;
this->instructions[this->levelStack.back()].insert( pair<int, Instruction*>(this->instructions[this->levelStack.back()].size(), instruction) );
}
......@@ -75,10 +74,10 @@ Symbol* InstructionList::stackPop(int num)
void InstructionList::levelPush()
{
std::cerr << "level push " << this->instructions.size() << " + " << ((this->instructions[0].size() == 0) ? 1 : 0) << std::endl;
this->levelStack.push_back(this->instructions.size());
for(int i = 0; i < this->levelStack.size(); i++)
std::cerr << "Level: " << this->levelStack[i] << endl;
if(this->instructions.size() == 0)
this->levelStack.push_back(1);
else
this->levelStack.push_back(this->instructions.size()+1);
}
int InstructionList::levelPop()
......@@ -161,19 +160,18 @@ string InstructionList::toString()
* variables at the start of functions... so, when we run into a function or a block, we'll need
* to call this function so that it allocates all the required stuff...
*/
for(it = this->instructions.begin(); it != this->instructions.end(); it++)
{
varAddrSpace = this->findVarStackSpace(it->second);
if(it->second[0]->getOpcode() != Instruction::FUNCTION_START)
{
std::cerr << "IS NOT A FUNCTION\n";
isFunction = false;
oss << "SUB ESP, " << varAddrSpace << endl
<< "PUSH EDI\n";
}
else
{
std::cerr << "IS A FUNCTION\n";
isFunction = true;
oss << "\n\n" << it->second[0]->getArg1().sym->getLexeme() << ":\n"
<< "SUB ESP, " << varAddrSpace << endl
......@@ -185,14 +183,13 @@ string InstructionList::toString()
Symbol* temp = it->second[0]->getArg1().sym->getFunctionValue();
vector<Symbol *> symArr;
for(int i = 0; i <= it->second[0]->getArg1().sym->getArguments(true); i++)
for(int i = 1; i <= it->second[0]->getArg1().sym->getArguments(true); i++)
{
symArr.push_back(temp);
temp = temp->getValue().s;
}
int varAddr = 4;
//for(int i = symArr.size() - 1; i != -1; i--)
for(unsigned int i = 0; i < symArr.size(); i++)
{
if(symArr[i]->getReturnType() == Symbol::FLOAT)
......@@ -212,9 +209,9 @@ string InstructionList::toString()
}
else
oss << "MOV EDI, ESP\n";
for(itr = it->second.begin(); itr != it->second.end(); itr++)
{
std::cerr << itr->second->toGenericString() << std::endl;
temp = itr->second;
//TODO: Some seriously awesome stuff
......@@ -310,7 +307,6 @@ string InstructionList::toString()
case Instruction::PUSH:
if(temp->getArg1Type() == Instruction::SYMBOL)
{
//oss << temp->getArg1().sym->toString() << endl;
switch(temp->getArg1().sym->getType())
{
case Symbol::FLOAT:
......
......@@ -127,6 +127,8 @@ stat: OUTPUT additive_exp NEWLINE {
yyerror(symbol_table, instructions, "Function used like variable!");
YYABORT;
} else {
if($1->getReturnType() == Symbol::INTEGER && $4->getReturnType() == Symbol::FLOAT)
fprintf(stderr, "WARNING: <int> = <float> will result in loss of precision!\n");
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
instructions->addInstruction(new Instruction(Instruction::MOV, temp));
instructions->addInstruction(new Instruction(Instruction::POP));
......@@ -140,6 +142,8 @@ stat: OUTPUT additive_exp NEWLINE {
yyerror(symbol_table, instructions, "Function used like variable!");
YYABORT;
} else {
if(temp->getReturnType() == Symbol::INTEGER && $3->getReturnType() == Symbol::FLOAT)
fprintf(stderr, "WARNING: <int> = <float> will result in loss of precision!\n");
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
instructions->addInstruction(new Instruction(Instruction::MOV, temp));
instructions->addInstruction(new Instruction(Instruction::POP));
......@@ -254,6 +258,20 @@ primary_exp: LPAREN additive_exp RPAREN {
yyerror(symbol_table, instructions, "Incorrect number of arguments given!");
YYABORT;
} else {
int j = temp->getArguments(true);
Symbol* symA = temp->getFunctionValue();
Symbol* symB = func->getFunctionValue();
for(int i = 0; i < j; i++)
{
if(symA->getReturnType() != symB->getReturnType())
{
yyerror(symbol_table, instructions, "Wrong type in function call");
YYABORT;
}
symA = symA->getValue().s;
symB = symB->getValue().s;
}
instructions->addInstruction(new Instruction(Instruction::CALL, func, temp));
$$ = func;
}
......
......@@ -127,7 +127,7 @@ void Symbol::setReturnType(enum Symbol::Type returnType)
int Symbol::getArguments(bool isFunction)
{
if(this->getType() == Symbol::FUNCTION && this->f != NULL && isFunction)
return this->f->getArguments(false);
return this->f->getArguments(false) + 1;
else if(((this->getType() == Symbol::FUNCTION && !isFunction) || this->getType() == Symbol::VARIABLE) && this->getValue().s != NULL)
return this->getValue().s->getArguments(false) + 1;
......
function float func(int a,int b,int c,float d){
int e = d
float e = d
int f = 20
output a
output b
......
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