diff --git a/AST_INC/AST/Expressions/NotExpression.cpp b/AST_INC/AST/Expressions/NotExpression.cpp index 1f14047..e8bd993 100644 --- a/AST_INC/AST/Expressions/NotExpression.cpp +++ b/AST_INC/AST/Expressions/NotExpression.cpp @@ -18,7 +18,7 @@ std::shared_ptr cs6300::NotExpression::type() const } int cs6300::NotExpression::value() const { - return ~m_expr->value(); + return !m_expr->value(); } bool cs6300::NotExpression::isConst() const { diff --git a/AST_INC/AST/ThreeAddressInstruction.cpp b/AST_INC/AST/ThreeAddressInstruction.cpp index bdf4753..4662bc9 100644 --- a/AST_INC/AST/ThreeAddressInstruction.cpp +++ b/AST_INC/AST/ThreeAddressInstruction.cpp @@ -18,8 +18,8 @@ cs6300::ThreeAddressInstruction::ThreeAddressInstruction(std::string c) } cs6300::ThreeAddressInstruction::ThreeAddressInstruction(std::string c, - std::string line, - std::string file) + std::string file, + std::string line) : op(Comment), dest(0), src1(0), src2(0), comment(c) { comment += "(" + file + ":" + line + ")"; @@ -112,7 +112,7 @@ std::ostream& cs6300::operator<<(std::ostream& out, out << "\tmflo $" << i.dest; break; case cs6300::ThreeAddressInstruction::Not: - out << "not $" << i.dest << ", $" << i.src1; + out << "xori $" << i.dest << ", $" << i.src1 << ", 1"; break; case cs6300::ThreeAddressInstruction::Or: out << "or $" << i.dest << ", $" << i.src1 << ", $" << i.src2; diff --git a/CMakeLists.txt b/CMakeLists.txt index 072c235..53ec426 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ include_directories( ${WINDOWS_GNU} ) -set(EXTRA_COMPILE_FLAGS "-g -std=c++0x") +set(EXTRA_COMPILE_FLAGS "-g -std=c++11") #set(LCOV_FLAGS "--coverage") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_COMPILE_FLAGS} ${LCOV_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LCOV_FLAGS}") diff --git a/FrontEnd/FrontEnd.cpp b/FrontEnd/FrontEnd.cpp index 3291c66..706a48d 100644 --- a/FrontEnd/FrontEnd.cpp +++ b/FrontEnd/FrontEnd.cpp @@ -154,7 +154,7 @@ int appendList(FEC& listSrc, int elementIndex) { auto elem = elementSrc.get(elementIndex); - return appendList(listSrc, listIndex, elem); + return (elem) ? appendList(listSrc, listIndex, elem) : listIndex; } template int binaryOp(int a, int b) @@ -750,7 +750,11 @@ void cs6300::AddFunction(int signature, int body) state->getSymTable()->addParameter(param.first, param.second); } auto b = state->statementLists.get(body); - b->push_back(std::make_shared(nullptr)); + + if (b->at(b->size()-1)->ClassName().compare("Return") != 0) + { + b->push_back(std::make_shared(nullptr)); + } auto program = state->getProgram(); program->functions[*sig] = std::make_shared(sig, *b, state->getSymTable()); @@ -766,9 +770,9 @@ void cs6300::AddMain(int body) std::copy(b->begin(), b->end(), std::back_inserter(program->main)); int t = - state->expressions.add(std::make_shared(1)); + state->expressions.add(std::make_shared(true)); int f = - state->expressions.add(std::make_shared(0)); + state->expressions.add(std::make_shared(false)); AddLiteral("true", t); AddLiteral("TRUE", t); AddLiteral("false", f); diff --git a/FrontEnd/scanner.l b/FrontEnd/scanner.l index 4ef1936..a375ea1 100644 --- a/FrontEnd/scanner.l +++ b/FrontEnd/scanner.l @@ -4,9 +4,13 @@ #include "parser.hpp" #include "ProcessLog.hpp" #include "logger.h" + +char* replaceAllNullWithZero(char*); %} %option nounput +%option never-interactive +%option noyywrap %% @@ -73,11 +77,14 @@ write|WRITE {return WRITESY;} [0-9]+[0-9]* {yylval.int_val = strtol(yytext,nullptr,0);return INTSY;} '\\n' {yylval.char_val = '\n';return CHARCONSTSY;} -'\\t' {yylval.char_val = '\t';return CHARCONSTSY;} '\\r' {yylval.char_val = '\r';return CHARCONSTSY;} -'\\?.' {yylval.char_val = yytext[1];return CHARCONSTSY;} +'\\b' {yylval.char_val = '\b';return CHARCONSTSY;} +'\\t' {yylval.char_val = '\t';return CHARCONSTSY;} +'\\f' {yylval.char_val = '\f';return CHARCONSTSY;} +'[ !-\[\]-~]' {yylval.char_val = yytext[1];return CHARCONSTSY;} +'\\[ !-~]' {yylval.char_val = yytext[2];return CHARCONSTSY;} -\"[a-zA-Z0-9~`!@'#$%^&*()_+=\-\[\]{}\\\/><,.:;| ]*\" {yylval.str_val = strdup(yytext); return STRINGSY;} +\"([ !#-~]|\\[ !-~])*\" {yylval.str_val = replaceAllNullWithZero(yytext); return STRINGSY;} \$.*$ {ProcessLog::getInstance()->nextLine();} \n {ProcessLog::getInstance()->nextLine();} @@ -85,3 +92,30 @@ write|WRITE {return WRITESY;} . {LOG(ERROR) << std::string("Unexpected token ")+yytext;} %% + +char* replaceAllNullWithZero(char* str) +{ + char* s = strdup(str); + + int str_i = 0; + int s_i = 0; + while (str[str_i]) + { + if (str[str_i] == '\\' && str[str_i+1] == '0') + { + s[s_i++] = str[++str_i]; + str_i++; + } + else if (str[str_i] == '\\') + { + s[s_i++] = str[str_i++]; + s[s_i++] = str[str_i++]; + } + else + s[s_i++] = str[str_i++]; + } + + s[s_i++] = 0; + return s; +} + diff --git a/Optimizations/FlowGraph.h b/Optimizations/FlowGraph.h index ce00448..d1b0207 100644 --- a/Optimizations/FlowGraph.h +++ b/Optimizations/FlowGraph.h @@ -2,6 +2,7 @@ #define __cpsl__TraverseBasicBlock__ #include "AST/BasicBlock.hpp" +#include namespace cs6300 { diff --git a/Optimizations/MaximizeBlocks/MaximizeBlocks.cpp b/Optimizations/MaximizeBlocks/MaximizeBlocks.cpp index 4bd2661..0a5984d 100644 --- a/Optimizations/MaximizeBlocks/MaximizeBlocks.cpp +++ b/Optimizations/MaximizeBlocks/MaximizeBlocks.cpp @@ -6,39 +6,55 @@ #include "VisitedBlocks.hpp" #include "NumParents.hpp" -void cs6300::maximizeBlocks(cs6300::FlowGraph original) +void cs6300::maximizeBlocks(cs6300::FlowGraph& original) { // traverse the blocks - cs6300::traverse(original.first); - cs6300::traverse(original.second); + auto vb = VisitedBlocks::instance(); + vb->reset(); + buildParentCounts(original.first); + vb->reset(); + combineBlocks(original.first, original); } -void cs6300::traverse(std::shared_ptr block) +void cs6300::buildParentCounts(std::shared_ptr block) { auto vb = VisitedBlocks::instance(); auto np = NumParents::instance(); - if (vb->isVisited(block)) - { - return; - } + if (vb->isVisited(block)) return; if (block->branchTo != nullptr) { - // add parents on the way down... np->addParent(block->branchTo); - traverse(block->branchTo); + buildParentCounts(block->branchTo); } if (block->jumpTo != nullptr) { - // add parents on the way down... np->addParent(block->jumpTo); - traverse(block->jumpTo); + buildParentCounts(block->jumpTo); } +} + +void cs6300::combineBlocks(std::shared_ptr block, FlowGraph& graph) +{ + auto vb = VisitedBlocks::instance(); + auto np = NumParents::instance(); + + if (vb->isVisited(block)) return; + + if (block->branchTo) combineBlocks(block->branchTo, graph); + if (block->jumpTo) combineBlocks(block->jumpTo, graph); + // determine if they can be merged on the way back up... if (block->jumpTo != nullptr && block->branchTo == nullptr && np->getNumParents(block->jumpTo) == 1) { + //Redirect the end of the graph + if (block->jumpTo == graph.second) + { + graph.second = block; + } + // merge jumpTo to this block for (auto inst : block->jumpTo->instructions) { diff --git a/Optimizations/MaximizeBlocks/MaximizeBlocks.hpp b/Optimizations/MaximizeBlocks/MaximizeBlocks.hpp index f1fbefc..4893d1d 100644 --- a/Optimizations/MaximizeBlocks/MaximizeBlocks.hpp +++ b/Optimizations/MaximizeBlocks/MaximizeBlocks.hpp @@ -12,9 +12,10 @@ namespace cs6300 { -void maximizeBlocks(cs6300::FlowGraph); +void maximizeBlocks(FlowGraph&); -void traverse(std::shared_ptr block); +void buildParentCounts(std::shared_ptr block); +void combineBlocks(std::shared_ptr, FlowGraph&); } #endif diff --git a/Testing/UnitTests/ExpressionTest.cpp b/Testing/UnitTests/ExpressionTest.cpp index 05f1304..db5b423 100644 --- a/Testing/UnitTests/ExpressionTest.cpp +++ b/Testing/UnitTests/ExpressionTest.cpp @@ -531,7 +531,7 @@ TEST_CASE("NotExpression", "[expression]") auto exp = R"(BB1: li $1, 15 -not $2, $1 +xori $2, $1, 1 )"; REQUIRE(s == exp); } diff --git a/log/logger.cpp b/log/logger.cpp index 8ccc68c..223ac2d 100644 --- a/log/logger.cpp +++ b/log/logger.cpp @@ -7,13 +7,13 @@ INITIALIZE_EASYLOGGINGPP const char* cpsl_log::getLine() { - return std::to_string(ProcessLog::getInstance()->line()).c_str(); + return strdup(std::to_string(ProcessLog::getInstance()->line()).c_str()); } const char* cpsl_log::getFile() { - return boost::filesystem::basename(&ProcessLog::getInstance()->file()[0]) - .c_str(); + return strdup(boost::filesystem::basename(&ProcessLog::getInstance()->file()[0]) + .c_str()); } const std::string defaultLogFile = "log/log.conf"; diff --git a/tester/Base/count_mix_control.cpsl b/tester/Base/count_mix_control.cpsl index b3a37ac..891a65a 100644 --- a/tester/Base/count_mix_control.cpsl +++ b/tester/Base/count_mix_control.cpsl @@ -1 +1 @@ -2825 +2839 diff --git a/tester/Base/count_mix_expressions.cpsl b/tester/Base/count_mix_expressions.cpsl index fc15416..e2bb11d 100644 --- a/tester/Base/count_mix_expressions.cpsl +++ b/tester/Base/count_mix_expressions.cpsl @@ -1 +1 @@ -1095 +1098 diff --git a/tester/Base/count_nested_if.cpsl b/tester/Base/count_nested_if.cpsl index 920a139..ea90ee3 100644 --- a/tester/Base/count_nested_if.cpsl +++ b/tester/Base/count_nested_if.cpsl @@ -1 +1 @@ -43 +45 diff --git a/tester/Base/count_personnel.cpsl b/tester/Base/count_personnel.cpsl index b3b6f67..6ceb1c6 100644 --- a/tester/Base/count_personnel.cpsl +++ b/tester/Base/count_personnel.cpsl @@ -1 +1 @@ -19209 +19221 diff --git a/tester/Base/count_simple_else.cpsl b/tester/Base/count_simple_else.cpsl index 84df352..8643cf6 100644 --- a/tester/Base/count_simple_else.cpsl +++ b/tester/Base/count_simple_else.cpsl @@ -1 +1 @@ -87 +89 diff --git a/tester/Base/count_simple_elseif.cpsl b/tester/Base/count_simple_elseif.cpsl index abac1ea..21e72e8 100644 --- a/tester/Base/count_simple_elseif.cpsl +++ b/tester/Base/count_simple_elseif.cpsl @@ -1 +1 @@ -47 +48 diff --git a/tester/Base/count_simple_if.cpsl b/tester/Base/count_simple_if.cpsl index f04c001..64bb6b7 100644 --- a/tester/Base/count_simple_if.cpsl +++ b/tester/Base/count_simple_if.cpsl @@ -1 +1 @@ -29 +30 diff --git a/tester/Base/count_simple_recursion.cpsl b/tester/Base/count_simple_recursion.cpsl index f1349af..6fb0715 100644 --- a/tester/Base/count_simple_recursion.cpsl +++ b/tester/Base/count_simple_recursion.cpsl @@ -1 +1 @@ -2753 +2754 diff --git a/tester/Base/count_swap.cpsl b/tester/Base/count_swap.cpsl index 1817215..9ee3415 100644 --- a/tester/Base/count_swap.cpsl +++ b/tester/Base/count_swap.cpsl @@ -1 +1 @@ -254585 +254949 diff --git a/tester/Base/mix_expressions.cpsl b/tester/Base/mix_expressions.cpsl index 7ebf4ce..5e93dd6 100644 --- a/tester/Base/mix_expressions.cpsl +++ b/tester/Base/mix_expressions.cpsl @@ -30,8 +30,8 @@ d 2<=2=1 2<>2=0 2 8 -~-5=4 -~5=-6 +~true=0 +~false=1 Setting A to 5: Setting B to 8: 5 8 diff --git a/tester/TestFiles/mix_expressions.cpsl b/tester/TestFiles/mix_expressions.cpsl index 1f2db1b..c6f4a06 100644 --- a/tester/TestFiles/mix_expressions.cpsl +++ b/tester/TestFiles/mix_expressions.cpsl @@ -40,8 +40,8 @@ BEGIN write(a,' ',b,'\n'); a := 5; b := 15; - write("~-5=",~-5,'\n'); - write("~5=",~5,'\n'); + write("~true=",~true,'\n'); + write("~false=",~false,'\n'); write("Setting A to 5:"); a := 5; write("\nSetting B to 8:"); diff --git a/tester/tester.sh b/tester/tester.sh index d817112..91d34c6 100755 --- a/tester/tester.sh +++ b/tester/tester.sh @@ -29,6 +29,13 @@ trap on_die TERM ret=0 +baseTotal=0 +outTotal=0 +totalPerc=0 +count=0 +best=900 +worst=0 + for file in ${files}; do file=$(basename ${file}) @@ -49,7 +56,7 @@ for file in ${files}; do echo -n "Executing: ${file}..." java -Djava.awt.headless=true -jar ${MARSDIR}${MARSJAR} me ic nc 1000000 ${ASM}${file} 2> stderr.txt > ${RESULTS}${file} - if [ $? -ne 0 ]; then + if [ ! -s ${RESULTS}${file} ]; then echo " Error running: java -jar nc 1000000 ${MARSDIR}${MARSJAR} ${ASM}${file} > ${RESULTS}${file}" cat stderr.txt ret=1 @@ -82,7 +89,32 @@ for file in ${files}; do echo " diff ${RESULTS}${file} ${BASE}${file}" echo ${diff} echo + ret=1 fi + + baseTotal=$((baseTotal + be)) + outTotal=$((outTotal + le)) + totalPerc=$((totalPerc + div)) + count=$((count + 1)) + worst=$((worstdiv?div:best)) + done rm -f stderr.txt + +if [ $ret -ne 1 ]; then + echo + echo "No Errors Found" + echo + totalDiv=$(((outTotal*100)/baseTotal)) + echo "Total Instructions: ${outTotal}/${baseTotal} ${totalDiv}%" + avgPerc=$((totalPerc/count)) + echo "Average of Percentages: ${totalPerc}%/${count} ${avgPerc}%" + echo "Best Improvement Percentage: ${best}%" + echo "Worst Improvement Percentage: ${worst}%" +else + echo + echo "Errors Found" +fi + exit ${ret}