Commit 1633fd31 by Andrew Dahl

Fixes #18 - Globals now work

parent e377a9df
......@@ -39,7 +39,7 @@ void Compiler::Run()
// Initialize our symbol table and instruction list
InstructionList* instructions = new InstructionList();
vector<SymbolTable*>* symbol_table = new vector<SymbolTable*>();
symbol_table->push_back(new SymbolTable());
symbol_table->push_back(new SymbolTable(-1, NULL));
symbol_table->at(0)->Insert(new Symbol("readInput", Symbol::INPUT, Symbol::INTEGER));
symbol_table->push_back(new SymbolTable(0, symbol_table->at(0)));
......
......@@ -30,7 +30,7 @@
char* name;
}
%token NEWLINE PLUS MINUS SLASH ASTERISK LPAREN RPAREN EQUALS USERINPUT OUTPUT FUNCTION COMMA LCURLY RCURLY RETURN TYPEINT TYPEFLOAT IF THEN EQUALTO GREATERTHAN LESSTHAN WHILE DO
%token NEWLINE PLUS MINUS SLASH ASTERISK LPAREN RPAREN EQUALS USERINPUT OUTPUT FUNCTION COMMA LCURLY RCURLY RETURN TYPEINT TYPEFLOAT IF THEN EQUALTO GREATERTHAN LESSTHAN WHILE DO GLOBAL
%token <inum> NUMBER
%token <fnum> FLOAT
%token <name> ID
......@@ -177,18 +177,63 @@ stat: OUTPUT additive_exp NEWLINE {
instructions->addInstruction(new Instruction(Instruction::OUTPUT));
}
| type_spec ID EQUALS assignment_exp NEWLINE {
if(symbol_table->at(level)->ExistsInCurrentLevel($2)) {
if(level == 1 && symbol_table->at(0)->ExistsInCurrentLevel($2)) {
yyerror(symbol_table, instructions, "Redeclaration of variable!");
YYABORT;
} else {
if(symbol_table->at(level)->ExistsInCurrentLevel($2)) {
yyerror(symbol_table,instructions,"Redeclaration of variable");
YYABORT;
} else {
Symbol* temp;
if(level == 1)
{
temp = symbol_table->at(0)->Insert(new Symbol($2, Symbol::VARIABLE, $1->getReturnType()));
symbol_table->at(level)->Insert(temp);
}
else
temp = symbol_table->at(level)->Insert(new Symbol($2, Symbol::VARIABLE, $1->getReturnType()));
if(temp->getType() == Symbol::FUNCTION) {
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));
}
}
}
}
| GLOBAL type_spec ID EQUALS assignment_exp NEWLINE {
if(level == 1 && symbol_table->at(0)->ExistsInCurrentLevel($3)) {
yyerror(symbol_table,instructions,"Redeclaration of variable");
YYABORT;
} else {
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($2, Symbol::VARIABLE, $1->getReturnType()));
if(temp->getType() == Symbol::FUNCTION) {
Symbol* temp;
if(level != 1) {
temp = symbol_table->at(0)->Find($3);
if(temp != NULL)
symbol_table->at(level)->Insert(temp);
}
else
{
temp = symbol_table->at(0)->Insert(new Symbol($3, Symbol::VARIABLE, $2->getReturnType()));
symbol_table->at(level)->Insert(temp);
}
if(temp == NULL) {
yyerror(symbol_table, instructions, "Global variable does not exist!");
YYABORT;
}
else if(temp->getType() == Symbol::FUNCTION) {
yyerror(symbol_table, instructions, "Function used like variable!");
YYABORT;
} else {
if($1->getReturnType() == Symbol::INTEGER && $4->getReturnType() == Symbol::FLOAT)
if($2->getReturnType() == Symbol::INTEGER && $5->getReturnType() == Symbol::FLOAT)
fprintf(stderr, "WARNING: <int> = <float> will result in loss of precision!\n");
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
if(level == 1)
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
instructions->addInstruction(new Instruction(Instruction::MOV, temp));
instructions->addInstruction(new Instruction(Instruction::POP));
}
......
......@@ -67,6 +67,7 @@ comma [,]
"readInput" { return USERINPUT; }
"output" { return OUTPUT; }
"return" { return RETURN; }
"global" { return GLOBAL; }
"int" { return TYPEINT; }
"float" { return TYPEFLOAT; }
{identifier} { yylval.name = strdup(yytext); return ID; }
......
......@@ -147,7 +147,7 @@ int Symbol::getArgumentsValue(bool isFunction)
else
return this->getValue().s->getArgumentsValue() + 4;
}
else
else if(this->getType() != Symbol::FUNCTION)
{
if(this->getReturnType() == Symbol::FLOAT)
return 8;
......
......@@ -32,7 +32,7 @@ Symbol* SymbolTable::Insert(Symbol *entry)
if(it == this->table.end())
{
if(this->parent_table_num == GLOBAL_PARENT_TABLE)
if(this->parent_table_num == -1)
entry->setGlobal(true);
this->table.insert( std::pair<string,Symbol*>(entry->getLexeme(),entry));
if(entry->getType() == Symbol::VARIABLE)
......@@ -77,7 +77,7 @@ Symbol* SymbolTable::Find(const string lexeme)
if(it == this->table.end())
{
if(this->parent_table != NULL)
if(this->parent_table != NULL && this->parent_table_num != GLOBAL_PARENT_TABLE)
return this->parent_table->Find(lexeme);
else
return NULL;
......
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
}
output a
output b
output 100
output func()
output a
output b
output 300
output func1()
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