Commit 21efe2aa by Andrew Dahl

Fixes #19 Main function is now required and the starting point

parent 1633fd31
......@@ -556,6 +556,7 @@ string InstructionList::toString()
}
else
{
oss << "CALL start\n";
oss << "ADD ESP, " << varAddrSpace << endl
<< "POP EDI\n"
<< "MOV EAX, 0\n"
......
......@@ -18,6 +18,8 @@
void hack_yyerror(char const *);
int level = 1;
int conditional = 1;
bool inFunction = false;
bool mainExists = false;
%}
%parse-param { vector<SymbolTable*>* symbol_table }
......@@ -40,7 +42,15 @@
%% /* Grammer Rules and Actions */
program: translation_unit { if(yynerrs != 0) { YYABORT; } }
program: translation_unit {
if(yynerrs != 0) {
YYABORT;
}
if(!mainExists) {
yyerror(symbol_table, instructions, "Main does not exist!");
YYABORT;
}
}
;
translation_unit: external_decl
......@@ -62,6 +72,10 @@ function_decl: FUNCTION type_spec ID LPAREN {
yyerror(symbol_table,instructions,"Redeclaration of function");
YYABORT;
} else {
if(strcmp($3,"main") == 0) {
mainExists = true;
$3 = strdup("start");
}
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($3, Symbol::FUNCTION, $2->getReturnType()));
if(temp->getType() == Symbol::VARIABLE) {
yyerror(symbol_table,instructions,"Function cannot have the same name as a previously declared variable!")
......@@ -72,6 +86,7 @@ function_decl: FUNCTION type_spec ID LPAREN {
symbol_table->at(level)->Insert(temp);
instructions->levelPush();
instructions->addInstruction(new Instruction(Instruction::FUNCTION_START, temp));
inFunction = true;
$<sym>$ = temp;
}
}
......@@ -85,6 +100,7 @@ function_define: function_decl LCURLY statlist RETURN additive_exp NEWLINE RCURL
instructions->addInstruction(new Instruction(Instruction::FUNCTION_RETURN, $1));
level = symbol_table->at(level)->getParentTable();
instructions->levelPop();
inFunction = false;
$$ = $1;
}
;
......@@ -124,6 +140,10 @@ comparison_operator: additive_exp {
;
selection_stat: IF comparison_operator THEN LCURLY {
if(!inFunction) {
yyerror(symbol_table, instructions, "If statement not allowed outside of functions!");
YYABORT;
}
int size = symbol_table->at(level)->getStackAddress();
symbol_table->push_back(new SymbolTable(level, symbol_table->at(level)));
level = symbol_table->size()-1;
......@@ -139,6 +159,10 @@ selection_stat: IF comparison_operator THEN LCURLY {
;
iteration_stat: WHILE {
if(!inFunction) {
yyerror(symbol_table, instructions, "While loops not allowed outside of functions!");
YYABORT;
}
instructions->addInstruction(new Instruction(Instruction::LOOP_START, conditional));
} comparison_operator DO LCURLY {
int size = symbol_table->at(level)->getStackAddress();
......@@ -174,6 +198,10 @@ statlist:
;
stat: OUTPUT additive_exp NEWLINE {
if(!inFunction) {
yyerror(symbol_table, instructions, "Output not allowed outside of functions!");
YYABORT;
}
instructions->addInstruction(new Instruction(Instruction::OUTPUT));
}
| type_spec ID EQUALS assignment_exp NEWLINE {
......
global int a = 0
global int b = 10
function int func() {
global int a = 20
global int b = 30
output a
output b
return 200
}
function int func1() {
int a = 40
int b = 50
output a
output b
return 400
}
function int main() {
output func()
output func1()
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