Commit f0539f17 by Andrew Dahl

Functions are now handled by the parser. We need to deal with arguments yet...

parent 93187735
......@@ -31,6 +31,7 @@ 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, int value);
Symbol(string lexeme, float value);
......
......@@ -113,6 +113,10 @@ string InstructionList::toString()
* Note: This isn't an issue for functions.
* Why not now? I just want to get this thing working... I'll be back.
* -Andrew
*
* TODO: This needs to be made into a function now... primarily so that we can handle the stack
* variables at the start of functions... so, when we run into a functio 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++)
{
......@@ -301,7 +305,7 @@ string InstructionList::toString()
}
break;
case Instruction::CALL:
oss << "NOT IMPLEMENTED\n";
oss << "CALL "<< temp->getArg1().sym->getLexeme() << "\n";
break;
case Instruction::FUNCTION_START:
// Do we care?
......
......@@ -51,85 +51,128 @@ external_decl: NEWLINE
| error { yyerrok;}
;
function_define: FUNCTION ID LPAREN argument_exp_list RPAREN EQUALS additive_exp { Symbol::value_t symbol_value; symbol_value.s = $4; $$ = symbol_table[level]->Insert(new Symbol($2, symbol_value, Symbol::FUNCTION, $7->getReturnType())); }
function_define: FUNCTION ID LPAREN argument_exp_list RPAREN EQUALS {
Symbol::value_t symbol_value; symbol_value.s = $4;
Symbol* temp = symbol_table[level]->Insert(new Symbol($2, symbol_value, Symbol::FUNCTION));
symbol_table.push_back(new SymbolTable(level, symbol_table[level]));
level = symbol_table.size()-1;
symbol_table[level]->Insert(temp);
instructions->addInstruction(new Instruction(Instruction::FUNCTION_START, temp));
} additive_exp {
Symbol* temp = symbol_table[level]->Find($2);
level = symbol_table[level]->getParentTable();
temp->setReturnType($8->getReturnType());
$$ = temp;
}
;
argument_exp_list: { }
| ID { $$ = symbol_table[level]->Insert(new Symbol($1, Symbol::VARIABLE, Symbol::INTEGER)); }
| argument_exp_list COMMA ID
argument_exp_list: { $$ = new Symbol();}
| ID {
$$ = symbol_table[level]->Insert(new Symbol($1, Symbol::VARIABLE, Symbol::INTEGER));
}
| argument_exp_list COMMA ID { }
;
assignment_exp: additive_exp
| ID EQUALS assignment_exp { Symbol* temp = symbol_table[level]->Insert(new Symbol($1, Symbol::VARIABLE, $3->getReturnType()));
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
instructions->addInstruction(new Instruction(Instruction::MOV, temp));
instructions->addInstruction(new Instruction(Instruction::POP));
| ID EQUALS assignment_exp {
Symbol* temp = symbol_table[level]->Insert(new Symbol($1, Symbol::VARIABLE, $3->getReturnType()));
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
instructions->addInstruction(new Instruction(Instruction::MOV, temp));
instructions->addInstruction(new Instruction(Instruction::POP));
}
;
stat: OUTPUT additive_exp NEWLINE { instructions->addInstruction(new Instruction(Instruction::OUTPUT)); }
| ID EQUALS assignment_exp NEWLINE { Symbol* temp = symbol_table[level]->Insert(new Symbol($1, Symbol::VARIABLE, $3->getReturnType()));
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
instructions->addInstruction(new Instruction(Instruction::MOV, temp));
instructions->addInstruction(new Instruction(Instruction::POP));
}
stat: OUTPUT additive_exp NEWLINE {
instructions->addInstruction(new Instruction(Instruction::OUTPUT));
}
| ID EQUALS assignment_exp NEWLINE {
Symbol* temp = symbol_table[level]->Insert(new Symbol($1, Symbol::VARIABLE, $3->getReturnType()));
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
instructions->addInstruction(new Instruction(Instruction::MOV, temp));
instructions->addInstruction(new Instruction(Instruction::POP));
}
;
additive_exp: additive_exp PLUS mult_exp { instructions->addInstruction(new Instruction(Instruction::ADD));
if($1->getReturnType() == Symbol::FLOAT || $3->getReturnType() == Symbol::FLOAT)
$$ = new Symbol("temp",static_cast<float>(1.0));
else
$$ = new Symbol("temp",1);
additive_exp: additive_exp PLUS mult_exp {
instructions->addInstruction(new Instruction(Instruction::ADD));
if($1->getReturnType() == Symbol::FLOAT || $3->getReturnType() == Symbol::FLOAT)
$$ = new Symbol("temp",static_cast<float>(1.0));
else
$$ = new Symbol("temp",1);
}
| additive_exp MINUS mult_exp {
instructions->addInstruction(new Instruction(Instruction::SUB));
if($1->getReturnType() == Symbol::FLOAT || $3->getReturnType() == Symbol::FLOAT)
$$ = new Symbol("temp",static_cast<float>(1.0));
else
$$ = new Symbol("temp",1);
}
| additive_exp MINUS mult_exp { instructions->addInstruction(new Instruction(Instruction::SUB));
if($1->getReturnType() == Symbol::FLOAT || $3->getReturnType() == Symbol::FLOAT)
$$ = new Symbol("temp",static_cast<float>(1.0));
else
$$ = new Symbol("temp",1);
| mult_exp {
$$ = $1;
}
| mult_exp { $$ = $1; }
;
mult_exp: mult_exp ASTERISK primary_exp { instructions->addInstruction(new Instruction(Instruction::MUL));
if($1->getReturnType() == Symbol::FLOAT || $3->getReturnType() == Symbol::FLOAT)
$$ = new Symbol("temp",static_cast<float>(1.0));
else
$$ = new Symbol("temp",1);
mult_exp: mult_exp ASTERISK primary_exp {
instructions->addInstruction(new Instruction(Instruction::MUL));
if($1->getReturnType() == Symbol::FLOAT || $3->getReturnType() == Symbol::FLOAT)
$$ = new Symbol("temp",static_cast<float>(1.0));
else
$$ = new Symbol("temp",1);
}
| mult_exp SLASH primary_exp { if($3->getType() == Symbol::INTEGER) {
if($3->getValue().i == 0)
yyerror(symbol_table, instructions, "Cannot divide by 0");
} else if($3->getType() == Symbol::FLOAT) {
if($3->getValue().f == 0)
yyerror(symbol_table, instructions, "Cannot divide by 0");
| mult_exp SLASH primary_exp {
if($3->getType() == Symbol::INTEGER) {
if($3->getValue().i == 0)
yyerror(symbol_table, instructions, "Cannot divide by 0");
} else if($3->getType() == Symbol::FLOAT) {
if($3->getValue().f == 0)
yyerror(symbol_table, instructions, "Cannot divide by 0");
}
instructions->addInstruction(new Instruction(Instruction::DIV));
if($1->getReturnType() == Symbol::FLOAT || $3->getReturnType() == Symbol::FLOAT)
$$ = new Symbol("temp",static_cast<float>(1.0));
else
$$ = new Symbol("temp",1);
}
| primary_exp {
$$ = $1;
}
instructions->addInstruction(new Instruction(Instruction::DIV));
if($1->getReturnType() == Symbol::FLOAT || $3->getReturnType() == Symbol::FLOAT)
$$ = new Symbol("temp",static_cast<float>(1.0));
else
$$ = new Symbol("temp",1);
}
| primary_exp { $$ = $1; }
;
primary_exp: LPAREN additive_exp RPAREN { $$ = $2 }
| NUMBER { Symbol* temp = symbol_table[level]->Insert($1);
instructions->addInstruction(new Instruction(Instruction::PUSH, temp));
$$ = temp; }
| FLOAT { Symbol* temp = symbol_table[level]->Insert($1);
primary_exp: LPAREN additive_exp RPAREN {
$$ = $2;
}
| NUMBER {
Symbol* temp = symbol_table[level]->Insert($1);
instructions->addInstruction(new Instruction(Instruction::PUSH, temp));
$$ = temp;
}
| FLOAT {
Symbol* temp = symbol_table[level]->Insert($1);
instructions->addInstruction(new Instruction(Instruction::PUSH, temp));
$$ = temp;
}
| USERINPUT {
instructions->addInstruction(new Instruction(Instruction::INPUT));
$$ = symbol_table[level]->Find("readInput");
}
| ID {
Symbol* temp = symbol_table[level]->Find($1);
if(temp == NULL) {
yyerror(symbol_table, instructions, "Variable not declared yet!");
} else {
instructions->addInstruction(new Instruction(Instruction::PUSH, temp));
$$ = temp; }
| USERINPUT { instructions->addInstruction(new Instruction(Instruction::INPUT));
$$ = symbol_table[level]->Find("readInput"); }
| ID { Symbol* temp = symbol_table[level]->Find($1);
if(temp == NULL) {
yyerror(symbol_table, instructions, "Variable not declared yet!");
} else {
instructions->addInstruction(new Instruction(Instruction::PUSH, temp));
$$ = temp;
$$ = temp;
}
}
| ID LPAREN func_call_args RPAREN {
Symbol* temp = symbol_table[level]->Find($1);
if(temp == NULL) {
yyerror(symbol_table, instructions, "Function not declared yet!");
} else {
instructions->addInstruction(new Instruction(Instruction::CALL, temp));
$$ = temp;
}
| ID LPAREN func_call_args RPAREN { }
}
;
func_call_args: { }
......
......@@ -27,6 +27,13 @@ Symbol::Symbol(string lexeme, Type valueType, Type returnType)
this->setReturnType(returnType);
}
Symbol::Symbol(string lexeme, value_t value, Type valueType)
{
this->setLexeme(lexeme);
this->setType(valueType);
this->value = value;
}
Symbol::Symbol(string lexeme, value_t value, Type valueType, Type returnType)
{
this->setLexeme(lexeme);
......
var1 = 1.0
var2=1.1
var4=2
function func()=1
output var2 + func()
output 1 + 2 + var2 + readInput
output var2
output 1.0 + 2.0 + 3.0 + 4.1
output var2
var4=20.5 - 0.5 + readInput
output var2
var2=50
output var2
output var1
output var4
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