aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2017-03-22 22:34:24 +0000
committerYann Herklotz <ymherklotz@gmail.com>2017-03-22 22:34:24 +0000
commitffb5df0e59d93fd5322ef02e337f713ed56c262f (patch)
tree7c93e278d8b005b94aaab1fa171f3c9644fefac4
parent561b76bdebd584d03d4e451375777651a9d74017 (diff)
downloadCompiler-ffb5df0e59d93fd5322ef02e337f713ed56c262f.tar.gz
Compiler-ffb5df0e59d93fd5322ef02e337f713ed56c262f.zip
Switch working
-rw-r--r--21
-rw-r--r--c_compiler/include/statement.hpp137
-rw-r--r--c_compiler/src/c_lexer.flex3
-rw-r--r--c_compiler/src/c_parser.y22
-rw-r--r--c_compiler/src/statement.cpp377
-rwxr-xr-xrun_test_deliverable.sh6
-rw-r--r--test_deliverable/testcases/test_SWITCH.c18
-rw-r--r--test_deliverable/testcases/test_SWITCHDEF.c19
-rw-r--r--test_deliverable/testcases/test_SWITCHDEF_driver.c6
-rw-r--r--test_deliverable/testcases/test_SWITCH_driver.c6
10 files changed, 508 insertions, 87 deletions
diff --git a/2 b/2
new file mode 100644
index 0000000..425dd20
--- /dev/null
+++ b/2
@@ -0,0 +1 @@
+Error : Linker returned error message.
diff --git a/c_compiler/include/statement.hpp b/c_compiler/include/statement.hpp
index ba12911..a34e22d 100644
--- a/c_compiler/include/statement.hpp
+++ b/c_compiler/include/statement.hpp
@@ -19,19 +19,64 @@ protected:
StatementPtr next_statement_;
public:
- Statement(Statement* statement = nullptr);
+ Statement(Statement *statement = nullptr);
virtual void print() const = 0;
virtual void printXml() const = 0;
- virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const = 0;
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const = 0;
- virtual void countVariables(unsigned& var_count) const = 0;
- virtual void countArguments(unsigned& argument_count) const = 0;
- virtual void countExpressionDepth(unsigned& depth_count) const = 0;
+ virtual void countVariables(unsigned &var_count) const = 0;
+ virtual void countArguments(unsigned &argument_count) const = 0;
+ virtual void countExpressionDepth(unsigned &depth_count) const = 0;
- void linkStatement(Statement* next);
+ virtual int constantFold() const;
+ virtual StatementPtr getStatementList() const;
+ virtual ExpressionPtr getExpression() const;
+ virtual bool isDefault() const;
+
+ void linkStatement(Statement *next);
+ StatementPtr getNext() const;
};
+class LabelStatement : public Statement
+{
+private:
+ std::string label_;
+ StatementPtr statement_;
+
+public:
+ LabelStatement(const std::string &label, Statement *statement);
+
+ virtual void print() const;
+ virtual void printXml() const;
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
+
+ virtual void countVariables(unsigned &var_count) const;
+ virtual void countArguments(unsigned &argument_count) const;
+ virtual void countExpressionDepth(unsigned &depth_count) const;
+};
+
+class CaseStatement : public Statement
+{
+private:
+ ExpressionPtr constant_expression_;
+ StatementPtr statement_;
+ bool default_;
+
+public:
+ CaseStatement(Statement *statement, Expression *constant_expression_ = nullptr, const bool &_default = false);
+
+ virtual void print() const;
+ virtual void printXml() const;
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
+
+ virtual void countVariables(unsigned &var_count) const;
+ virtual void countArguments(unsigned &argument_count) const;
+ virtual void countExpressionDepth(unsigned &depth_count) const;
+ virtual int constantFold() const;
+ virtual ExpressionPtr getExpression() const;
+ virtual bool isDefault() const;
+};
class CompoundStatement : public Statement
{
@@ -40,55 +85,69 @@ protected:
StatementPtr statement_;
public:
- CompoundStatement(Declaration* declaration = nullptr, Statement* statement = nullptr);
- CompoundStatement(Statement* statement);
+ CompoundStatement(Declaration *declaration = nullptr, Statement *statement = nullptr);
+ CompoundStatement(Statement *statement);
virtual void print() const;
virtual void printXml() const;
- virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
- virtual void countVariables(unsigned& var_count) const;
- virtual void countArguments(unsigned& argument_count) const;
- virtual void countExpressionDepth(unsigned& depth_count) const;
+ virtual void countVariables(unsigned &var_count) const;
+ virtual void countArguments(unsigned &argument_count) const;
+ virtual void countExpressionDepth(unsigned &depth_count) const;
+ virtual StatementPtr getStatementList() const;
};
-
class IfElseStatement : public Statement
{
-protected:
+private:
ExpressionPtr condition_;
StatementPtr if_;
StatementPtr else_;
public:
- IfElseStatement(Expression* condition, Statement* _if, Statement* _else = nullptr);
+ IfElseStatement(Expression *condition, Statement *_if, Statement *_else = nullptr);
virtual void print() const;
virtual void printXml() const;
- virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
- virtual void countVariables(unsigned& var_count) const;
- virtual void countArguments(unsigned& argument_count) const;
- virtual void countExpressionDepth(unsigned& depth_count) const;
+ virtual void countVariables(unsigned &var_count) const;
+ virtual void countArguments(unsigned &argument_count) const;
+ virtual void countExpressionDepth(unsigned &depth_count) const;
};
+class SwitchStatement : public Statement
+{
+private:
+ ExpressionPtr condition_;
+ StatementPtr statement_;
+public:
+ SwitchStatement(Expression *condition, Statement *statement);
+ virtual void print() const;
+ virtual void printXml() const;
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
+
+ virtual void countVariables(unsigned &var_count) const;
+ virtual void countArguments(unsigned &argument_count) const;
+ virtual void countExpressionDepth(unsigned &depth_count) const;
+};
class ExpressionStatement : public Statement
{
protected:
ExpressionPtr expression_;
public:
- ExpressionStatement(Expression* expression = nullptr);
+ ExpressionStatement(Expression *expression = nullptr);
virtual void print() const;
virtual void printXml() const;
- virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
- virtual void countVariables(unsigned& var_count) const;
- virtual void countArguments(unsigned& argument_count) const;
- virtual void countExpressionDepth(unsigned& depth_count) const;
+ virtual void countVariables(unsigned &var_count) const;
+ virtual void countArguments(unsigned &argument_count) const;
+ virtual void countExpressionDepth(unsigned &depth_count) const;
};
-
class JumpStatement : public Statement
{
public:
@@ -102,19 +161,18 @@ public:
virtual void countExpressionDepth(unsigned &depth_count) const;
};
-
class ReturnStatement : public JumpStatement
{
private:
ExpressionPtr expression_;
public:
- ReturnStatement(Expression* expression = nullptr);
+ ReturnStatement(Expression *expression = nullptr);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
- virtual void countVariables(unsigned& var_count) const;
- virtual void countArguments(unsigned& argument_count) const;
- virtual void countExpressionDepth(unsigned& depth_count) const;
+ virtual void countVariables(unsigned &var_count) const;
+ virtual void countArguments(unsigned &argument_count) const;
+ virtual void countExpressionDepth(unsigned &depth_count) const;
};
class BreakStatement : public JumpStatement
@@ -143,22 +201,21 @@ public:
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &) const;
};
-
class IterationStatement : public Statement
{
protected:
ExpressionPtr condition_;
StatementPtr statement_;
public:
- IterationStatement(Expression* condition, Statement* statement);
+ IterationStatement(Expression *condition, Statement *statement);
virtual void print() const;
virtual void printXml() const;
- virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const = 0;
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const = 0;
- virtual void countVariables(unsigned& var_count) const;
- virtual void countArguments(unsigned& argument_count) const;
- virtual void countExpressionDepth(unsigned& depth_count) const;
+ virtual void countVariables(unsigned &var_count) const;
+ virtual void countArguments(unsigned &argument_count) const;
+ virtual void countExpressionDepth(unsigned &depth_count) const;
};
class WhileLoop : public IterationStatement
@@ -166,9 +223,9 @@ class WhileLoop : public IterationStatement
private:
bool is_while_;
public:
- WhileLoop(Expression* condition, Statement* statement, const bool &is_while = true);
+ WhileLoop(Expression *condition, Statement *statement, const bool &is_while = true);
- virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
};
class ForLoop : public IterationStatement
@@ -177,9 +234,9 @@ private:
ExpressionPtr initializer_;
ExpressionPtr incrementer_;
public:
- ForLoop(Expression* initializer, Expression* condition, Expression* incrementer, Statement* statement);
+ ForLoop(Expression *initializer, Expression *condition, Expression *incrementer, Statement *statement);
- virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
};
diff --git a/c_compiler/src/c_lexer.flex b/c_compiler/src/c_lexer.flex
index 2547c5a..0530df0 100644
--- a/c_compiler/src/c_lexer.flex
+++ b/c_compiler/src/c_lexer.flex
@@ -50,6 +50,9 @@ ALL .
(continue) { return T_CONTINUE; }
(break) { return T_BREAK; }
(goto) { return T_GOTO; }
+(case) { return T_CASE; }
+(default) { return T_DEFAULT; }
+(switch) { return T_SWITCH; }
[;] { return T_SC; }
[,] { return T_CMA; }
diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y
index 79d8902..b6e8159 100644
--- a/c_compiler/src/c_parser.y
+++ b/c_compiler/src/c_parser.y
@@ -37,15 +37,11 @@ void yyerror(const char *);
%token T_IDENTIFIER T_SC T_CMA T_LRB T_LCB T_RCB T_LSB T_RSB T_QU T_COL T_LOG_OR
T_LOG_AND T_OR T_XOR T_AND T_EQUALITY_OP T_REL_OP T_SHIFT_OP T_MULT T_DIV
T_REM T_TILDE T_NOT T_DOT T_ARROW T_INCDEC T_ADDSUB_OP T_ASSIGN_OPER T_EQ
- T_SIZEOF T_INT_CONST T_IF T_WHILE T_DO T_FOR T_RETURN
-
+ T_SIZEOF T_INT_CONST T_IF T_WHILE T_DO T_FOR T_RETURN
T_VOID T_CHAR T_SHORT T_INT T_LONG T_FLOAT T_DOUBLE T_SIGNED T_UNSIGNED
-
T_TYPEDEF T_EXTERN T_STATIC T_AUTO T_REGISTER
-
- T_CONST T_VOLATILE
-
- T_GOTO T_BREAK T_CONTINUE
+ T_CONST T_VOLATILE T_GOTO T_BREAK T_CONTINUE
+ T_CASE T_DEFAULT T_SWITCH
%nonassoc T_RRB
%nonassoc T_ELSE
@@ -59,7 +55,7 @@ void yyerror(const char *);
%type <statement> StatementList Statement CompoundStatement CompoundStatement_2
SelectionStatement
- ExpressionStatement JumpStatement IterationStatement
+ ExpressionStatement JumpStatement IterationStatement LabeledStatement
%type <declaration> ParameterList Parameter DeclarationList Declaration InitDeclaratorList
InitDeclarator
@@ -210,13 +206,20 @@ StatementList:
| StatementList Statement { $2->linkStatement($$); $$ = $2; }
;
-Statement: CompoundStatement { $$ = $1; }
+Statement: LabeledStatement { $$ = $1; }
+ | CompoundStatement { $$ = $1; }
| SelectionStatement { $$ = $1; }
| ExpressionStatement { $$ = $1; }
| JumpStatement { $$ = $1; }
| IterationStatement { $$ = $1; }
;
+LabeledStatement:
+ T_IDENTIFIER T_COL Statement { $$ = new LabelStatement(*$1, $3); }
+ | T_CASE ConditionalExpression T_COL Statement { $$ = new CaseStatement($4, $2); }
+ | T_DEFAULT T_COL Statement { $$ = new CaseStatement($3, nullptr, true); }
+ ;
+
CompoundStatement:
T_LCB CompoundStatement_2 { $$ = $2; }
;
@@ -231,6 +234,7 @@ CompoundStatement_2:
SelectionStatement:
T_IF T_LRB Expression T_RRB Statement { $$ = new IfElseStatement($3, $5); }
| T_IF T_LRB Expression T_RRB Statement T_ELSE Statement { $$ = new IfElseStatement($3, $5, $7); }
+ | T_SWITCH T_LRB Expression T_RRB Statement { $$ = new SwitchStatement($3, $5); }
;
ExpressionStatement:
diff --git a/c_compiler/src/statement.cpp b/c_compiler/src/statement.cpp
index 5eb3687..f2fff49 100644
--- a/c_compiler/src/statement.cpp
+++ b/c_compiler/src/statement.cpp
@@ -1,28 +1,196 @@
#include "statement.hpp"
#include <cstdio>
+#include <exception>
+#include <vector>
// General base Statement definition
-Statement::Statement(Statement* statement)
+Statement::Statement(Statement *statement)
: next_statement_(statement)
{}
-void Statement::linkStatement(Statement* next)
+int Statement::constantFold() const
+{
+ throw std::runtime_error("Error : not implemented");
+}
+
+StatementPtr Statement::getStatementList() const
+{
+ throw std::runtime_error("Error : not implemented");
+}
+
+ExpressionPtr Statement::getExpression() const
+{
+ return nullptr;
+}
+
+bool Statement::isDefault() const
+{
+ return false;
+}
+
+void Statement::linkStatement(Statement *next)
{
StatementPtr statement_ptr(next);
next_statement_ = statement_ptr;
}
+StatementPtr Statement::getNext() const
+{
+ return next_statement_;
+}
+
+
+// Label Statement definition
+
+LabelStatement::LabelStatement(const std::string &label, Statement *statement)
+ : label_(label), statement_(statement)
+{}
+
+void LabelStatement::print() const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->print();
+
+ printf("Label Statement\n");
+}
+
+void LabelStatement::printXml() const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->printXml();
+}
+
+VariableStackBindings LabelStatement::printAsm(VariableStackBindings bindings, unsigned &label_count) const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->printAsm(bindings, label_count);
+
+ printf("%s:\n", label_.c_str());
+
+ return bindings;
+}
+
+void LabelStatement::countVariables(unsigned &var_count) const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->countVariables(var_count);
+
+ statement_->countVariables(var_count);
+}
+
+void LabelStatement::countArguments(unsigned &argument_count) const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->countArguments(argument_count);
+
+ statement_->countArguments(argument_count);
+}
+
+void LabelStatement::countExpressionDepth(unsigned &depth_count) const
+{
+ unsigned previous_depth_count = depth_count;
+ if(next_statement_ != nullptr)
+ {
+ next_statement_->countExpressionDepth(depth_count);
+ if(previous_depth_count > depth_count)
+ depth_count = previous_depth_count;
+ previous_depth_count = depth_count;
+ }
+
+ statement_->countExpressionDepth(depth_count);
+ if(previous_depth_count > depth_count)
+ depth_count = previous_depth_count;
+}
+
+
+// Case Statement definition
+
+CaseStatement::CaseStatement(Statement *statement, Expression *constant_expression, const bool &_default)
+ : constant_expression_(constant_expression), statement_(statement), default_(_default)
+{}
+
+void CaseStatement::print() const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->print();
+
+ printf("Case Statement\n");
+}
+
+void CaseStatement::printXml() const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->printXml();
+}
+
+VariableStackBindings CaseStatement::printAsm(VariableStackBindings bindings, unsigned &label_count) const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->printAsm(bindings, label_count);
+
+ statement_->printAsm(bindings, label_count);
+
+ return bindings;
+}
+
+void CaseStatement::countVariables(unsigned &var_count) const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->countVariables(var_count);
+
+ statement_->countVariables(var_count);
+}
+
+void CaseStatement::countArguments(unsigned &argument_count) const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->countArguments(argument_count);
+
+ statement_->countArguments(argument_count);
+}
+
+void CaseStatement::countExpressionDepth(unsigned &depth_count) const
+{
+ unsigned previous_depth_count = depth_count;
+ if(next_statement_ != nullptr)
+ {
+ next_statement_->countExpressionDepth(depth_count);
+ if(previous_depth_count > depth_count)
+ depth_count = previous_depth_count;
+ previous_depth_count = depth_count;
+ }
+
+ statement_->countExpressionDepth(depth_count);
+ if(previous_depth_count > depth_count)
+ depth_count = previous_depth_count;
+}
+
+int CaseStatement::constantFold() const
+{
+ return constant_expression_->constantFold();
+}
+
+ExpressionPtr CaseStatement::getExpression() const
+{
+ return constant_expression_;
+}
+
+bool CaseStatement::isDefault() const
+{
+ return default_;
+}
+
// Compound Statement definition
-CompoundStatement::CompoundStatement(Declaration* declaration, Statement* statement)
+CompoundStatement::CompoundStatement(Declaration *declaration, Statement *statement)
: Statement(), declaration_(declaration), statement_(statement)
{}
-CompoundStatement::CompoundStatement(Statement* statement)
+CompoundStatement::CompoundStatement(Statement *statement)
: statement_(statement)
{}
@@ -51,7 +219,7 @@ void CompoundStatement::printXml() const
printf("</Scope>\n");
}
-VariableStackBindings CompoundStatement::printAsm(VariableStackBindings bindings, unsigned& label_count) const
+VariableStackBindings CompoundStatement::printAsm(VariableStackBindings bindings, unsigned &label_count) const
{
VariableStackBindings outer_scope_bindings = bindings;
@@ -67,7 +235,7 @@ VariableStackBindings CompoundStatement::printAsm(VariableStackBindings bindings
return outer_scope_bindings;
}
-void CompoundStatement::countVariables(unsigned& var_count) const
+void CompoundStatement::countVariables(unsigned &var_count) const
{
DeclarationPtr declaration = declaration_;
@@ -92,7 +260,7 @@ void CompoundStatement::countVariables(unsigned& var_count) const
}
}
-void CompoundStatement::countArguments(unsigned& argument_count) const
+void CompoundStatement::countArguments(unsigned &argument_count) const
{
if(next_statement_ != nullptr)
next_statement_->countArguments(argument_count);
@@ -120,10 +288,15 @@ void CompoundStatement::countExpressionDepth(unsigned &depth_count) const
}
}
+StatementPtr CompoundStatement::getStatementList() const
+{
+ return statement_;
+}
-// Selection Statement definition
-IfElseStatement::IfElseStatement(Expression* condition, Statement* _if, Statement* _else)
+// If Else Statement definition
+
+IfElseStatement::IfElseStatement(Expression *condition, Statement *_if, Statement *_else)
: Statement(), condition_(condition), if_(_if), else_(_else) {}
void IfElseStatement::print() const
@@ -146,7 +319,7 @@ void IfElseStatement::printXml() const
else_->printXml();
}
-VariableStackBindings IfElseStatement::printAsm(VariableStackBindings bindings, unsigned& label_count) const
+VariableStackBindings IfElseStatement::printAsm(VariableStackBindings bindings, unsigned &label_count) const
{
if(next_statement_ != nullptr)
next_statement_->printAsm(bindings, label_count);
@@ -168,7 +341,7 @@ VariableStackBindings IfElseStatement::printAsm(VariableStackBindings bindings,
return bindings;
}
-void IfElseStatement::countVariables(unsigned& var_count) const
+void IfElseStatement::countVariables(unsigned &var_count) const
{
if(next_statement_ != nullptr)
next_statement_->countVariables(var_count);
@@ -180,7 +353,7 @@ void IfElseStatement::countVariables(unsigned& var_count) const
else_->countVariables(var_count);
}
-void IfElseStatement::countArguments(unsigned& argument_count) const
+void IfElseStatement::countArguments(unsigned &argument_count) const
{
if(next_statement_ != nullptr)
next_statement_->countArguments(argument_count);
@@ -192,7 +365,7 @@ void IfElseStatement::countArguments(unsigned& argument_count) const
else_->countArguments(argument_count);
}
-void IfElseStatement::countExpressionDepth(unsigned& depth_count) const
+void IfElseStatement::countExpressionDepth(unsigned &depth_count) const
{
unsigned previous_depth_count = depth_count;
@@ -223,19 +396,155 @@ void IfElseStatement::countExpressionDepth(unsigned& depth_count) const
}
}
+
+// Switch Statement definition
+
+SwitchStatement::SwitchStatement(Expression *condition, Statement *statement)
+ : condition_(condition), statement_(statement)
+{}
+
+void SwitchStatement::print() const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->print();
+
+ printf("Switch Statement\n");
+ condition_->print();
+ statement_->print();
+}
+
+void SwitchStatement::printXml() const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->printXml();
+
+ condition_->printXml();
+ statement_->printXml();
+}
+
+VariableStackBindings SwitchStatement::printAsm(VariableStackBindings bindings, unsigned &label_count) const
+{
+ unsigned switch_count = label_count++;
+
+ if(next_statement_ != nullptr)
+ next_statement_->printAsm(bindings, label_count);
+
+ condition_->printAsm(bindings, label_count);
+
+ StatementPtr case_statement_list = statement_->getStatementList();
+ std::vector<StatementPtr> case_statement_vector;
+
+ bindings.breakLabel("$"+std::to_string(switch_count)+"_break_switch");
+
+ while(case_statement_list != nullptr)
+ {
+ case_statement_vector.push_back(case_statement_list);
+ case_statement_list = case_statement_list->getNext();
+ }
+
+ bool is_default = false;
+
+ for(auto itr = case_statement_vector.rbegin(); itr != case_statement_vector.rend(); ++itr)
+ {
+ if((*itr)->getExpression() != nullptr)
+ {
+ int jump_label = (*itr)->constantFold();
+ printf("\tli\t$3,%d\n\tbeq\t$2,$3,$%d_%d_switch\n\tnop\n",
+ jump_label, switch_count, jump_label);
+ }
+ if(!is_default)
+ {
+ is_default = (*itr)->isDefault();
+ }
+ }
+
+ if(is_default)
+ printf("\tb\t$%d_default_switch\n\tnop\n", switch_count);
+
+ for(auto itr = case_statement_vector.rbegin(); itr != case_statement_vector.rend(); ++itr)
+ {
+ if((*itr)->getExpression() != nullptr)
+ printf("$%d_%d_switch:\n", switch_count, (*itr)->constantFold());
+
+ if((*itr)->isDefault())
+ printf("$%d_default_switch:\n", switch_count);
+
+ (*itr)->printAsm(bindings, label_count);
+ }
+
+ printf("$%d_break_switch:\n", switch_count);
+ return bindings;
+}
+
+void SwitchStatement::countVariables(unsigned &label_count) const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->countVariables(label_count);
+
+ statement_->countVariables(label_count);
+}
+
+void SwitchStatement::countArguments(unsigned &argument_count) const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->countArguments(argument_count);
+
+ statement_->countArguments(argument_count);
+ unsigned previous_argument_count = argument_count;
+ condition_->countArguments(argument_count);
+
+ if(previous_argument_count > argument_count)
+ argument_count = previous_argument_count;
+}
+
+void SwitchStatement::countExpressionDepth(unsigned &depth_count) const
+{
+ unsigned previous_depth_count = depth_count;
+
+ if(next_statement_ != nullptr)
+ {
+ next_statement_->countExpressionDepth(depth_count);
+ if(previous_depth_count > depth_count)
+ depth_count = previous_depth_count;
+ previous_depth_count = depth_count;
+ }
+
+ depth_count = 1;
+ statement_->countExpressionDepth(depth_count);
+ if(previous_depth_count > depth_count)
+ depth_count = previous_depth_count;
+ previous_depth_count = depth_count;
+
+ depth_count = 1;
+ condition_->expressionDepth(depth_count);
+ if(previous_depth_count > depth_count)
+ depth_count = previous_depth_count;
+}
+
+
// Expression Statement definition
-ExpressionStatement::ExpressionStatement(Expression* expr)
+ExpressionStatement::ExpressionStatement(Expression *expr)
: Statement(), expression_(expr)
{}
void ExpressionStatement::print() const
-{}
+{
+ if(next_statement_ != nullptr)
+ next_statement_->print();
+
+ printf("Expression Statement\n");
+ if(expression_ != nullptr)
+ expression_->print();
+}
void ExpressionStatement::printXml() const
-{}
+{
+ if(next_statement_ != nullptr)
+ next_statement_->printXml();
+}
-VariableStackBindings ExpressionStatement::printAsm(VariableStackBindings bindings, unsigned& label_count) const
+VariableStackBindings ExpressionStatement::printAsm(VariableStackBindings bindings, unsigned &label_count) const
{
if(next_statement_ != nullptr)
next_statement_->printAsm(bindings, label_count);
@@ -246,13 +555,13 @@ VariableStackBindings ExpressionStatement::printAsm(VariableStackBindings bindin
return bindings;
}
-void ExpressionStatement::countVariables(unsigned& var_count) const
+void ExpressionStatement::countVariables(unsigned &var_count) const
{
if(next_statement_ != nullptr)
next_statement_->countVariables(var_count);
}
-void ExpressionStatement::countArguments(unsigned& argument_count) const
+void ExpressionStatement::countArguments(unsigned &argument_count) const
{
if(next_statement_ != nullptr)
next_statement_->countArguments(argument_count);
@@ -266,7 +575,7 @@ void ExpressionStatement::countArguments(unsigned& argument_count) const
argument_count = tmp_argument_count;
}
-void ExpressionStatement::countExpressionDepth(unsigned& depth_count) const
+void ExpressionStatement::countExpressionDepth(unsigned &depth_count) const
{
unsigned previous_depth_count = depth_count;
@@ -320,11 +629,11 @@ void JumpStatement::countExpressionDepth(unsigned &depth_count) const
// Return statement definition
-ReturnStatement::ReturnStatement(Expression* expression)
+ReturnStatement::ReturnStatement(Expression *expression)
: expression_(expression)
{}
-VariableStackBindings ReturnStatement::printAsm(VariableStackBindings bindings, unsigned& label_count) const
+VariableStackBindings ReturnStatement::printAsm(VariableStackBindings bindings, unsigned &label_count) const
{
if(next_statement_ != nullptr)
next_statement_->printAsm(bindings, label_count);
@@ -337,13 +646,13 @@ VariableStackBindings ReturnStatement::printAsm(VariableStackBindings bindings,
return bindings;
}
-void ReturnStatement::countVariables(unsigned& var_count) const
+void ReturnStatement::countVariables(unsigned &var_count) const
{
if(next_statement_ != nullptr)
next_statement_->countVariables(var_count);
}
-void ReturnStatement::countArguments(unsigned& argument_count) const
+void ReturnStatement::countArguments(unsigned &argument_count) const
{
if(next_statement_ != nullptr)
next_statement_->countArguments(argument_count);
@@ -357,7 +666,7 @@ void ReturnStatement::countArguments(unsigned& argument_count) const
argument_count = tmp_argument_count;
}
-void ReturnStatement::countExpressionDepth(unsigned& depth_count) const
+void ReturnStatement::countExpressionDepth(unsigned &depth_count) const
{
unsigned previous_depth_count = depth_count;
@@ -418,7 +727,7 @@ VariableStackBindings GotoStatement::printAsm(VariableStackBindings bindings, un
// Iteration Statement definition
-IterationStatement::IterationStatement(Expression* condition, Statement* statement)
+IterationStatement::IterationStatement(Expression *condition, Statement *statement)
: condition_(condition), statement_(statement)
{}
@@ -434,7 +743,7 @@ void IterationStatement::printXml() const
statement_->printXml();
}
-void IterationStatement::countVariables(unsigned& var_count) const
+void IterationStatement::countVariables(unsigned &var_count) const
{
if(next_statement_ != nullptr)
next_statement_->countVariables(var_count);
@@ -443,7 +752,7 @@ void IterationStatement::countVariables(unsigned& var_count) const
statement_->countVariables(var_count);
}
-void IterationStatement::countArguments(unsigned& argument_count) const
+void IterationStatement::countArguments(unsigned &argument_count) const
{
if(next_statement_ != nullptr)
next_statement_->countArguments(argument_count);
@@ -452,7 +761,7 @@ void IterationStatement::countArguments(unsigned& argument_count) const
statement_->countArguments(argument_count);
}
-void IterationStatement::countExpressionDepth(unsigned& depth_count) const
+void IterationStatement::countExpressionDepth(unsigned &depth_count) const
{
unsigned previous_depth_count = depth_count;
@@ -478,12 +787,11 @@ void IterationStatement::countExpressionDepth(unsigned& depth_count) const
// While Loop definition
-WhileLoop::WhileLoop(Expression* condition, Statement* statement, const bool &is_while)
+WhileLoop::WhileLoop(Expression *condition, Statement *statement, const bool &is_while)
: IterationStatement(condition, statement), is_while_(is_while)
{}
-VariableStackBindings WhileLoop::printAsm(VariableStackBindings bindings,
- unsigned& label_count) const
+VariableStackBindings WhileLoop::printAsm(VariableStackBindings bindings, unsigned &label_count) const
{
if(next_statement_ != nullptr)
next_statement_->printAsm(bindings, label_count);
@@ -506,12 +814,11 @@ VariableStackBindings WhileLoop::printAsm(VariableStackBindings bindings,
return initial_bindings;
}
-ForLoop::ForLoop(Expression* initializer, Expression* condition,
- Expression* incrementer, Statement* statement)
+ForLoop::ForLoop(Expression *initializer, Expression *condition, Expression *incrementer, Statement *statement)
: IterationStatement(condition, statement), initializer_(initializer), incrementer_(incrementer)
{}
-VariableStackBindings ForLoop::printAsm(VariableStackBindings bindings, unsigned& label_count) const
+VariableStackBindings ForLoop::printAsm(VariableStackBindings bindings, unsigned &label_count) const
{
if(next_statement_ != nullptr)
next_statement_->printAsm(bindings, label_count);
diff --git a/run_test_deliverable.sh b/run_test_deliverable.sh
index 1c6e2ba..03770a0 100755
--- a/run_test_deliverable.sh
+++ b/run_test_deliverable.sh
@@ -29,21 +29,21 @@ for DRIVER in test_deliverable/testcases/*_driver.c ; do
# Compile driver with normal GCC
mips-linux-gnu-gcc -c $DRIVER -o working/${NAME}_driver.o 2> working/${NAME}_driver.compile.stderr
if [[ $? -ne 0 ]]; then
- >&2 printf "\e[1;31mError\e[0m : Couldn't compile driver program using GCC.\n"
+ printf "\e[1;31mError\e[0m : Couldn't compile driver program using GCC.\n"
continue
fi
# Compile test function with compiler under test to assembly
cat $TESTCODE | $COMPILER > working/$NAME.s 2> working/${NAME}.compile.stderr
if [[ $? -ne 0 ]]; then
- >&2 printf "\e[1;31mError\e[0m : Compiler returned error message.\n"
+ printf "\e[1;31mError\e[0m : Compiler returned error message.\n"
continue
fi
# Link driver object and assembly into executable
mips-linux-gnu-gcc -static working/${NAME}.s working/${NAME}_driver.o -o working/${NAME}.elf 2> working/${NAME}.link.stderr
if [[ $? -ne 0 ]]; then
- >&2 printf "\e[1;31mError\e[0m : Linker returned error message.\n"
+ printf "\e[1;31mError\e[0m : Linker returned error message.\n"
continue
fi
diff --git a/test_deliverable/testcases/test_SWITCH.c b/test_deliverable/testcases/test_SWITCH.c
new file mode 100644
index 0000000..e498a31
--- /dev/null
+++ b/test_deliverable/testcases/test_SWITCH.c
@@ -0,0 +1,18 @@
+int switch_(int a, int b)
+{
+ switch(a)
+ {
+ case 0:
+ a = 5;
+ break;
+ case 1:
+ a = b+5;
+ break;
+ case 9:
+ b = 4;
+ break;
+ }
+
+ b = a;
+ return b;
+}
diff --git a/test_deliverable/testcases/test_SWITCHDEF.c b/test_deliverable/testcases/test_SWITCHDEF.c
new file mode 100644
index 0000000..1d0bb78
--- /dev/null
+++ b/test_deliverable/testcases/test_SWITCHDEF.c
@@ -0,0 +1,19 @@
+int switchdef(int a)
+{
+ switch(a)
+ {
+ case 0:
+ return 38;
+ case 1:
+ return 2;
+ case 2:
+ a = 64;
+ a += 23;
+ a %= 23;
+ default:
+ a -= 4;
+ break;
+ }
+
+ return a;
+}
diff --git a/test_deliverable/testcases/test_SWITCHDEF_driver.c b/test_deliverable/testcases/test_SWITCHDEF_driver.c
new file mode 100644
index 0000000..091a2dd
--- /dev/null
+++ b/test_deliverable/testcases/test_SWITCHDEF_driver.c
@@ -0,0 +1,6 @@
+int switchdef(int);
+
+int main()
+{
+ return ( 14 == switchdef(2) );
+}
diff --git a/test_deliverable/testcases/test_SWITCH_driver.c b/test_deliverable/testcases/test_SWITCH_driver.c
new file mode 100644
index 0000000..2fbdbd3
--- /dev/null
+++ b/test_deliverable/testcases/test_SWITCH_driver.c
@@ -0,0 +1,6 @@
+int switch_(int, int);
+
+int main()
+{
+ return !( 9 == switch_(9, 4) );
+}