-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' of https://github.com/LangProc/langproc-2018-c…
…w-familyDAG into develop
- Loading branch information
Showing
39 changed files
with
481 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#ifndef switchCondition_hpp | ||
#define switchCondition_hpp | ||
|
||
#include <vector> | ||
#include <string> | ||
#include <iostream> | ||
#include <memory> | ||
#include "statement.hpp" | ||
#include "rvalue.hpp" | ||
#include "utils.hpp" | ||
|
||
class SwitchCase; | ||
typedef const SwitchCase *SwitchCasePtr; | ||
|
||
class SwitchCase : public Statement | ||
{ | ||
public: | ||
SwitchCase(StatementPtr condition, StatementPtr scopeBlock); | ||
virtual void generateIL(std::vector<Instr> &instrs, ILContext &context, std::string destReg) const override; | ||
StatementPtr getCondition() const; //the thing for the case that it needs to equal to | ||
StatementPtr getScopeBlock() const; //execution block | ||
|
||
protected: | ||
virtual void printC(std::ostream &os) const override; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#ifndef switchDefault_hpp | ||
#define switchDefault_hpp | ||
|
||
#include <vector> | ||
#include <string> | ||
#include <iostream> | ||
#include <memory> | ||
#include "switchCase.hpp" | ||
|
||
class SwitchDefault; | ||
typedef const SwitchDefault* SwitchDefaultPtr; | ||
|
||
class SwitchDefault : public SwitchCase | ||
{ | ||
public: | ||
SwitchDefault(StatementPtr scopeBlock); | ||
void generateIL(std::vector<Instr> &instrs, ILContext &context, std::string destReg) const override; | ||
|
||
protected: | ||
void printC(std::ostream &os) const override; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#ifndef switch_hpp | ||
#define switch_hpp | ||
|
||
#include <vector> | ||
#include <string> | ||
#include <iostream> | ||
#include <memory> | ||
#include "statement.hpp" | ||
#include "scopeBlock.hpp" | ||
|
||
#include "utils.hpp" | ||
|
||
class SwitchStatement; | ||
typedef const SwitchStatement* SwitchStatementPtr; | ||
|
||
class SwitchStatement : public Statement | ||
{ | ||
public: | ||
SwitchStatement(StatementPtr caseExpr, StatementPtr switchBlock); | ||
void generateIL(std::vector<Instr> &instrs, ILContext &context, std::string destReg) const override; | ||
|
||
protected: | ||
StatementPtr getCase() const; //as in the a in switch(a) | ||
StatementPtr getSwitchBlock() const; //contains cases and maybe default. just a regular scope block | ||
|
||
void printC(std::ostream &os) const override; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#include "switchCase.hpp" | ||
|
||
SwitchCase::SwitchCase(StatementPtr condition, StatementPtr scopeBlock) | ||
{ | ||
branches.push_back(condition); | ||
branches.push_back(scopeBlock); | ||
} | ||
|
||
StatementPtr SwitchCase::getCondition() const | ||
{ | ||
return branches[0]; | ||
} | ||
StatementPtr SwitchCase::getScopeBlock() const | ||
{ | ||
return branches[1]; | ||
} | ||
void SwitchCase::printC(std::ostream &os) const | ||
{ | ||
os << "case " << getCondition() << ": " << getScopeBlock(); //wont technically be correct as scope block in case doesn't have {} but doesn't really matter for printing | ||
} | ||
|
||
void SwitchCase::generateIL(std::vector<Instr> &instrs, ILContext &context, std::string destReg) const | ||
{ | ||
RValuePtr rvalue = Utils::tryCast<RValue>(getCondition(), "condition of switch case must be an rvalue"); | ||
if (!rvalue->isConstant()) { throw "condition of switch case must be a constant"; } | ||
|
||
int caseConstant = rvalue->evalConst(); | ||
instrs.push_back(Instr("li", destReg, std::to_string(caseConstant)));//switch case returned through destReg | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#include "switchDefault.hpp" | ||
#include "integerLiteral.hpp" | ||
|
||
SwitchDefault::SwitchDefault(StatementPtr scopeBlock) : SwitchCase(new IntegerLiteral(1), scopeBlock) | ||
{ | ||
|
||
} | ||
|
||
void SwitchDefault::printC(std::ostream &os) const | ||
{ | ||
os << "default: " << getScopeBlock(); | ||
} | ||
|
||
void SwitchDefault::generateIL(std::vector<Instr> &instrs, ILContext &context, std::string destReg) const | ||
{ | ||
//do nothing - there is no constant to evaluate and scope block generated from switch statement loop | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
#include "switchStatement.hpp" | ||
#include "switchCase.hpp" | ||
#include "switchDefault.hpp" | ||
|
||
SwitchStatement::SwitchStatement(StatementPtr caseExpr, StatementPtr switchBlock) | ||
{ | ||
branches.push_back(caseExpr); | ||
branches.push_back(switchBlock); | ||
} | ||
|
||
StatementPtr SwitchStatement::getCase() const | ||
{ | ||
return branches[0]; | ||
} | ||
StatementPtr SwitchStatement::getSwitchBlock() const | ||
{ | ||
return branches[1]; | ||
} | ||
void SwitchStatement::printC(std::ostream &os) const | ||
{ | ||
os << "switch (" << getCase() << ")" << getSwitchBlock(); //getSwitchBlock is a regular scope block | ||
} | ||
|
||
void SwitchStatement::generateIL(std::vector<Instr> &instrs, ILContext &context, std::string destReg) const | ||
{ | ||
ScopeBlockPtr switchBlock = Utils::tryCast<ScopeBlock>(getSwitchBlock(), "switch block must be a scope block"); //just to get access to branches | ||
std::vector<StatementPtr> switchBlockBranches = switchBlock->getBranches(); | ||
std::string switchEnd_lb = context.makeLabelName("switchEnd"); //the a in switch (a) | ||
context.pushLoopLabels("NULL", switchEnd_lb); | ||
|
||
//we could set up labels and scope blocks first, the branch past all that, then beq back...nah would mess up at the end. | ||
|
||
//first set up beq's for switch cases | ||
//keep track of labels being created, maybe ith a map of nodeid : label ? | ||
std::vector<std::string> labels; | ||
Instr branchToDefaultInstr; | ||
bool hasDefault = false; | ||
for (size_t i = 0; i < switchBlockBranches.size(); i++) | ||
{ | ||
try | ||
{ //is a switch case (or default) | ||
SwitchCasePtr switchCase = Utils::tryCast<SwitchCase>(switchBlockBranches[i], "node is not a switch case"); | ||
std::string switchCaseReg = context.makeName("switchCase"); //the a in switch (a) | ||
std::string case_lb = context.makeLabelName("case_lb"); | ||
|
||
try | ||
{ //is default | ||
Utils::tryCast<SwitchDefault>(switchBlockBranches[i], "node is not a default class"); | ||
hasDefault = true; | ||
branchToDefaultInstr = Instr("b", case_lb); | ||
} | ||
catch (std::string) | ||
{ //is not default | ||
getCase()->generateIL(instrs, context, switchCaseReg); | ||
switchCase->generateIL(instrs, context, "$t0"); //switch case generateIL just returns the condition constant | ||
instrs.push_back(Instr("beq", case_lb, switchCaseReg, "$t0")); | ||
} | ||
labels.push_back(case_lb); //even if it's from default, it should stay in place as if there is no break it can continue executing the other lines | ||
} | ||
catch (std::string) | ||
{ //not a switch case or default | ||
} | ||
} | ||
if (hasDefault) | ||
{ | ||
instrs.push_back(branchToDefaultInstr); | ||
} | ||
instrs.push_back(Instr("b", switchEnd_lb)); | ||
|
||
//now set up the branch labels with the corresponding block IL | ||
int labelIndex = 0; | ||
bool deadCode = true; | ||
for (size_t i = 0; i < switchBlockBranches.size(); i++) | ||
{ | ||
//if there is corresponding label for node, make label | ||
try | ||
{ //is a switch case or default | ||
SwitchCasePtr switchCase = Utils::tryCast<SwitchCase>(switchBlockBranches[i], "node is not a switch case"); | ||
deadCode = false; | ||
std::string label = labels[labelIndex++]; | ||
instrs.push_back(Instr::makeLabel(label)); | ||
switchCase->getScopeBlock()->generateIL(instrs, context, destReg); | ||
//need to somehow store the label for later us | ||
} | ||
catch (std::string) | ||
{ //not a switch case or default | ||
if (!deadCode) | ||
{ | ||
switchBlockBranches[i]->generateIL(instrs, context, destReg); | ||
} | ||
} | ||
} | ||
instrs.push_back(Instr::makeLabel(switchEnd_lb)); | ||
context.popLoopLabels(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include "il2mips.hpp" | ||
|
||
void IL2MIPS::beq(Instr instr, MIPSContext &context) | ||
{ | ||
context.addBranchInstr(Instr("beq", instr.input1, instr.input2, instr.dest), instr.label); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include "il2mips.hpp" | ||
|
||
void IL2MIPS::bne(Instr instr, MIPSContext &context) | ||
{ | ||
context.addBranchInstr(Instr("bne", instr.input1, instr.input2, instr.dest), instr.label); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.