Commit 20a1c943 by Andrew Dahl

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

Conflicts:

	lib/parser.y
parent d1d0b370
Showing with 25 additions and 5 deletions
......@@ -48,16 +48,18 @@ translation_unit: external_decl
external_decl: NEWLINE
| stat { }
| function_define
| error { yyerrok;}
| error { yyerrok; YYABORT;}
;
function_define: FUNCTION ID LPAREN {
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;
......@@ -91,6 +93,7 @@ assignment_exp: additive_exp
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($1, Symbol::VARIABLE, $3->getReturnType()));
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));
......@@ -106,6 +109,7 @@ stat: OUTPUT additive_exp NEWLINE {
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($1, Symbol::VARIABLE, $3->getReturnType()));
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));
......@@ -144,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)
......@@ -172,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");
......@@ -180,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;
......@@ -192,14 +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!");
} else if (temp->getType() != Symbol::FUNCTION) {
yyerror(symbol_table, instructions, "Variable used as Function!");
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;
......
......@@ -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