Commit 5aa1e682 by Andrew Dahl

Added a few bison rules to handle exceptions... also, we're aborting after errors now

Conflicts:

	lib/parser.y
parent 93cf6508
Showing with 68 additions and 15 deletions
......@@ -48,16 +48,26 @@ translation_unit: external_decl
external_decl: NEWLINE
| stat { }
| function_define
| error { yyerrok;}
| error { yyerrok; YYABORT;}
;
function_define: FUNCTION ID LPAREN {
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($2, Symbol::FUNCTION, Symbol::INTEGER));
symbol_table->push_back(new SymbolTable(level, symbol_table->at(level)));
level = symbol_table->size()-1;
symbol_table->at(level)->Insert(temp);
instructions->levelPush();
instructions->addInstruction(new Instruction(Instruction::FUNCTION_START, temp));
if(symbol_table->at(level)->ExistsInCurrentLevel($2)) {
yyerror(symbol_table,instructions,"Redeclaration of function");
YYABORT;
} else {
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($2, Symbol::FUNCTION, Symbol::INTEGER));
if(temp->getType() == Symbol::VARIABLE) {
yyerror(symbol_table,instructions,"Function cannot have the same name as a previously declared variable!")
YYABORT;
} else {
symbol_table->push_back(new SymbolTable(level, symbol_table->at(level)));
level = symbol_table->size()-1;
symbol_table->at(level)->Insert(temp);
instructions->levelPush();
instructions->addInstruction(new Instruction(Instruction::FUNCTION_START, temp));
}
}
} argument_exp_list RPAREN EQUALS additive_exp_func NEWLINE {
Symbol* temp = symbol_table->at(level)->Find($2);
temp->setFunctionValue($5);
......@@ -81,9 +91,14 @@ argument_exp_list: { $$ = NULL;}
assignment_exp: additive_exp
| ID EQUALS assignment_exp {
Symbol* temp = symbol_table->at(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));
if(temp->getType() == Symbol::FUNCTION) {
yyerror(symbol_table, instructions, "Function used like variable!");
YYABORT;
} else {
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
instructions->addInstruction(new Instruction(Instruction::MOV, temp));
instructions->addInstruction(new Instruction(Instruction::POP));
}
}
;
......@@ -92,9 +107,14 @@ stat: OUTPUT additive_exp NEWLINE {
}
| ID EQUALS assignment_exp NEWLINE {
Symbol* temp = symbol_table->at(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));
if(temp->getType() == Symbol::FUNCTION) {
yyerror(symbol_table, instructions, "Function used like variable!");
YYABORT;
} else {
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
instructions->addInstruction(new Instruction(Instruction::MOV, temp));
instructions->addInstruction(new Instruction(Instruction::POP));
}
}
;
......@@ -128,9 +148,11 @@ mult_exp: mult_exp ASTERISK primary_exp {
if($3->getType() == Symbol::INTEGER) {
if($3->getValue().i == 0)
yyerror(symbol_table, instructions, "Cannot divide by 0");
YYABORT;
} else if($3->getType() == Symbol::FLOAT) {
if($3->getValue().f == 0)
yyerror(symbol_table, instructions, "Cannot divide by 0");
YYABORT;
}
instructions->addInstruction(new Instruction(Instruction::DIV));
if($1->getReturnType() == Symbol::FLOAT || $3->getReturnType() == Symbol::FLOAT)
......@@ -156,6 +178,16 @@ primary_exp: LPAREN additive_exp RPAREN {
instructions->addInstruction(new Instruction(Instruction::PUSH, temp));
$$ = temp;
}
| MINUS NUMBER {
Symbol* temp = symbol_table->at(level)->Insert((-1 * $2));
instructions->addInstruction(new Instruction(Instruction::PUSH, temp));
$$ = temp;
}
| MINUS FLOAT {
Symbol* temp = symbol_table->at(level)->Insert((-1 * $2));
instructions->addInstruction(new Instruction(Instruction::PUSH, temp));
$$ = temp;
}
| USERINPUT {
instructions->addInstruction(new Instruction(Instruction::INPUT));
$$ = symbol_table->at(level)->Find("readInput");
......@@ -164,6 +196,7 @@ primary_exp: LPAREN additive_exp RPAREN {
Symbol* temp = symbol_table->at(level)->Find($1);
if(temp == NULL) {
yyerror(symbol_table, instructions, "Variable not declared yet!");
YYABORT;
} else if (temp->getType() == Symbol::FUNCTION) {
yyerror(symbol_table, instructions, "Function used like variable!");
YYABORT;
......@@ -176,12 +209,17 @@ primary_exp: LPAREN additive_exp RPAREN {
Symbol* temp = symbol_table->at(level)->Find($1);
if(temp == NULL) {
yyerror(symbol_table, instructions, "Function not declared yet!");
YYABORT;
} else if(temp->getType() != Symbol::FUNCTION) {
yyerror(symbol_table, instructions, "Variable used like function!");
YYABORT;
} else {
Symbol* func = new Symbol(temp);
func->setFunctionValue($3);
if(temp->getArguments(true) != func->getArguments(true)) {
yyerror(symbol_table, instructions, "Incorrect number of arguments given!");
YYABORT;
} else {
instructions->addInstruction(new Instruction(Instruction::CALL, func, temp));
$$ = func;
......@@ -220,9 +258,11 @@ mult_exp_func: mult_exp_func ASTERISK primary_exp_func {
if($3->getType() == Symbol::INTEGER) {
if($3->getValue().i == 0)
yyerror(symbol_table, instructions, "Cannot divide by 0");
YYABORT;
} else if($3->getType() == Symbol::FLOAT) {
if($3->getValue().f == 0)
yyerror(symbol_table, instructions, "Cannot divide by 0");
YYABORT;
}
instructions->addInstruction(new Instruction(Instruction::DIV));
if($1->getReturnType() == Symbol::FLOAT || $3->getReturnType() == Symbol::FLOAT)
......@@ -248,6 +288,16 @@ primary_exp_func: LPAREN additive_exp_func RPAREN {
instructions->addInstruction(new Instruction(Instruction::PUSH, temp));
$$ = temp;
}
| MINUS NUMBER {
Symbol* temp = symbol_table->at(level)->Insert((-1 * $2));
instructions->addInstruction(new Instruction(Instruction::PUSH, temp));
$$ = temp;
}
| MINUS FLOAT {
Symbol* temp = symbol_table->at(level)->Insert((-1 * $2));
instructions->addInstruction(new Instruction(Instruction::PUSH, temp));
$$ = temp;
}
| USERINPUT {
instructions->addInstruction(new Instruction(Instruction::INPUT));
$$ = symbol_table->at(level)->Find("readInput");
......@@ -256,8 +306,10 @@ primary_exp_func: LPAREN additive_exp_func RPAREN {
Symbol* temp = symbol_table->at(level)->Find($1);
if(temp == NULL) {
yyerror(symbol_table, instructions, "Variable not declared yet!");
YYABORT;
} else if (temp->getType() == Symbol::FUNCTION) {
yyerror(symbol_table, instructions, "Function used like variable!");
YYABORT;
} else {
instructions->addInstruction(new Instruction(Instruction::PUSH, temp));
$$ = temp;
......@@ -265,6 +317,7 @@ primary_exp_func: LPAREN additive_exp_func RPAREN {
}
| ID LPAREN func_call_args RPAREN {
yyerror(symbol_table, instructions, "Cannot use function within a function!");
YYABORT;
}
;
......
......@@ -37,7 +37,7 @@ whitesp {delim}+
digit [0-9]
nonzeronumber [1-9]{digit}*
zero [0]
number [-]?{zero}|{nonzeronumber}
number {zero}|{nonzeronumber}
float {number}[.]{digit}+
plus [+]
minus [-]
......
a=readInput
b=readInput + 1.0
c=readInput + 2.5
c=readInput + 2.5
function func(a,b,c,d)=a+b+c
function func1(a,b)=a-b
function func2()=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