aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2017-03-22 14:17:29 +0000
committerYann Herklotz <ymherklotz@gmail.com>2017-03-22 14:17:29 +0000
commitf12ccd62ecf08774ce599a2e15d9042500d2760a (patch)
tree12012ae296025441c3329e23a7290732cf33c36c
parent190b7a0e5d45367230795ac0bdf6fc2f248ba9e1 (diff)
downloadCompiler-f12ccd62ecf08774ce599a2e15d9042500d2760a.tar.gz
Compiler-f12ccd62ecf08774ce599a2e15d9042500d2760a.zip
Adding test and break working
-rw-r--r--c_compiler/include/bindings.hpp13
-rw-r--r--c_compiler/include/declaration.hpp5
-rw-r--r--c_compiler/include/statement.hpp56
-rw-r--r--c_compiler/src/bindings.cpp28
-rw-r--r--c_compiler/src/c_lexer.flex4
-rw-r--r--c_compiler/src/c_parser.y24
-rw-r--r--c_compiler/src/compiler_main.cpp19
-rw-r--r--c_compiler/src/declaration.cpp21
-rw-r--r--c_compiler/src/function.cpp48
-rw-r--r--c_compiler/src/statement.cpp164
-rw-r--r--c_compiler/src/translation_unit.cpp6
-rw-r--r--c_compiler/src/type.cpp28
-rw-r--r--c_compiler/test/in/fib.c2
-rw-r--r--c_compiler/test/in/fib_recusive.c20
-rw-r--r--c_compiler/test/in/short.c9
-rwxr-xr-xrun_test_deliverable.sh19
-rw-r--r--test_deliverable/testcases/test_BREAK.c13
-rw-r--r--test_deliverable/testcases/test_BREAK_driver.c6
18 files changed, 345 insertions, 140 deletions
diff --git a/c_compiler/include/bindings.hpp b/c_compiler/include/bindings.hpp
index 0afb3e9..2559420 100644
--- a/c_compiler/include/bindings.hpp
+++ b/c_compiler/include/bindings.hpp
@@ -23,6 +23,8 @@ class VariableStackBindings
{
private:
std::map<std::string, DeclarationData> bindings_;
+ std::string break_label_;
+ std::string continue_label_;
int stack_counter_;
int expression_stack_;
@@ -33,13 +35,18 @@ public:
void increaseStackPosition();
void setStackPosition(int stack_counter);
void nextExpressionStackPosition();
- void setExpressionStackPosition(const int& stack_counter);
+ void setExpressionStackPosition(const int &stack_counter);
+
+ std::string breakLabel();
+ std::string breakLabel(const std::string &label);
+ std::string continueLabel();
+ std::string continueLabel(const std::string &label);
int currentStackPosition() const;
- int stackPosition(const std::string& id) const;
+ int stackPosition(const std::string &id) const;
int currentExpressionStackPosition() const;
- bool bindingExists(const std::string& id) const;
+ bool bindingExists(const std::string &id) const;
};
diff --git a/c_compiler/include/declaration.hpp b/c_compiler/include/declaration.hpp
index 76f0efc..f99c4a3 100644
--- a/c_compiler/include/declaration.hpp
+++ b/c_compiler/include/declaration.hpp
@@ -19,7 +19,7 @@ private:
ExpressionPtr initializer_;
DeclarationPtr next_declaration_;
DeclarationPtr next_list_declaration_;
- bool extern_declaration;
+ bool extern_declaration_;
public:
Declaration(const std::string& id = "", Expression* initializer = nullptr);
@@ -34,7 +34,8 @@ public:
void linkListDeclaration(Declaration* next_list_declaration);
void setType(Type* type);
- void setInitializer(Expression* initializer);
+ void setInitializer(Expression* initializer);
+ void setExternDeclaration(bool is_extern);
DeclarationPtr getNext() const;
DeclarationPtr getNextListItem() const;
diff --git a/c_compiler/include/statement.hpp b/c_compiler/include/statement.hpp
index 887ffc5..ba12911 100644
--- a/c_compiler/include/statement.hpp
+++ b/c_compiler/include/statement.hpp
@@ -53,14 +53,14 @@ public:
};
-class SelectionStatement : public Statement
+class IfElseStatement : public Statement
{
protected:
ExpressionPtr condition_;
StatementPtr if_;
StatementPtr else_;
public:
- SelectionStatement(Expression* condition, Statement* _if, Statement* _else = nullptr);
+ IfElseStatement(Expression* condition, Statement* _if, Statement* _else = nullptr);
virtual void print() const;
virtual void printXml() const;
@@ -91,20 +91,58 @@ public:
class JumpStatement : public Statement
{
-protected:
- ExpressionPtr expression_;
public:
- JumpStatement(Expression* expression = nullptr);
-
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const = 0;
+
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 ReturnStatement : public JumpStatement
+{
+private:
+ ExpressionPtr expression_;
+public:
+ 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;
};
+class BreakStatement : public JumpStatement
+{
+public:
+ BreakStatement();
+
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &) const;
+};
+
+class ContinueStatement : public JumpStatement
+{
+public:
+ ContinueStatement();
+
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &) const;
+};
+
+class GotoStatement : public JumpStatement
+{
+private:
+ std::string label_;
+public:
+ GotoStatement(const std::string &label);
+
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &) const;
+};
+
class IterationStatement : public Statement
{
@@ -125,8 +163,10 @@ public:
class WhileLoop : public IterationStatement
{
+private:
+ bool is_while_;
public:
- WhileLoop(Expression* condition, Statement* statement);
+ WhileLoop(Expression* condition, Statement* statement, const bool &is_while = true);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
};
diff --git a/c_compiler/src/bindings.cpp b/c_compiler/src/bindings.cpp
index a76429c..944ce56 100644
--- a/c_compiler/src/bindings.cpp
+++ b/c_compiler/src/bindings.cpp
@@ -1,12 +1,10 @@
#include "bindings.hpp"
-#include <iostream>
-
// VariableStackBindings definition
VariableStackBindings::VariableStackBindings()
- : stack_counter_(0), expression_stack_(16)
+ : break_label_(""), continue_label_(""), stack_counter_(0), expression_stack_(16)
{}
void VariableStackBindings::insertBinding(std::string id, TypePtr type, int stack_position)
@@ -33,11 +31,33 @@ void VariableStackBindings::nextExpressionStackPosition()
expression_stack_ += 4;
}
-void VariableStackBindings::setExpressionStackPosition(const int& stack_counter)
+void VariableStackBindings::setExpressionStackPosition(const int &stack_counter)
{
expression_stack_ = stack_counter;
}
+std::string VariableStackBindings::breakLabel()
+{
+ return break_label_;
+}
+
+std::string VariableStackBindings::breakLabel(const std::string &label)
+{
+ break_label_ = label;
+ return break_label_;
+}
+
+std::string VariableStackBindings::continueLabel()
+{
+ return continue_label_;
+}
+
+std::string VariableStackBindings::continueLabel(const std::string &label)
+{
+ continue_label_ = label;
+ return continue_label_;
+}
+
int VariableStackBindings::currentStackPosition() const
{
return stack_counter_;
diff --git a/c_compiler/src/c_lexer.flex b/c_compiler/src/c_lexer.flex
index 90790b5..4255880 100644
--- a/c_compiler/src/c_lexer.flex
+++ b/c_compiler/src/c_lexer.flex
@@ -47,6 +47,10 @@ ALL .
(const) { return T_CONST; }
(volatile) { return T_VOLATILE; }
+(continue) { return T_CONTINUE; }
+(break) { return T_BREAK; }
+(goto) { return T_GOTO; }
+
[;] { return T_SC; }
[,] { return T_CMA; }
[(] { return T_LRB; }
diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y
index 1fb2777..c58bc75 100644
--- a/c_compiler/src/c_parser.y
+++ b/c_compiler/src/c_parser.y
@@ -44,6 +44,8 @@ void yyerror(const char *);
T_TYPEDEF T_EXTERN T_STATIC T_AUTO T_REGISTER
T_CONST T_VOLATILE
+
+ T_GOTO T_BREAK T_CONTINUE
%nonassoc T_RRB
%nonassoc T_ELSE
@@ -107,12 +109,12 @@ FunctionDefinition:
;
ParameterList:
- %empty { $$ = new Declaration(); }
- | Parameter { $$ = $1; }
+ Parameter { $$ = $1; }
| ParameterList T_CMA Parameter { $3->linkDeclaration($$); $$ = $3; }
;
Parameter: DeclarationSpecifierList T_IDENTIFIER { $$ = new Declaration(*$2); delete $2; delete $1; }
+ | DeclarationSpecifierList {$$ = new Declaration(""); }
;
// Declaration
@@ -184,9 +186,9 @@ DirectDeclarator:
| T_LRB Declarator T_RRB { $$ = $2; }
| DirectDeclarator T_LSB ConditionalExpression T_RSB { $$ = $1; }
| DirectDeclarator T_LSB T_RSB { $$ = $1; }
- | DirectDeclarator T_LRB T_RRB { $$ = $1; }
- | DirectDeclarator T_LRB ParameterList T_RRB { $1->linkDeclaration($3); $$ = $1; }
- | DirectDeclarator T_LRB IdentifierList T_RRB { $$ = $1; }
+ | DirectDeclarator T_LRB T_RRB { $$ = $1; $$->setExternDeclaration(true); }
+ | DirectDeclarator T_LRB ParameterList T_RRB { $1->linkDeclaration($3); $$ = $1; $$->setExternDeclaration(true); }
+ | DirectDeclarator T_LRB IdentifierList T_RRB { $$ = $1; $$->setExternDeclaration(true); }
;
IdentifierList: T_IDENTIFIER { $$ = new Declaration(); }
@@ -218,8 +220,8 @@ CompoundStatement_2:
;
SelectionStatement:
- T_IF T_LRB Expression T_RRB Statement { $$ = new SelectionStatement($3, $5); }
- | T_IF T_LRB Expression T_RRB Statement T_ELSE Statement { $$ = new SelectionStatement($3, $5, $7); }
+ 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); }
;
ExpressionStatement:
@@ -227,12 +229,16 @@ ExpressionStatement:
| Expression T_SC { $$ = new ExpressionStatement($1); }
;
-JumpStatement: T_RETURN Expression T_SC { $$ = new JumpStatement($2); }
+JumpStatement: T_RETURN Expression T_SC { $$ = new ReturnStatement($2); }
+ | T_BREAK T_SC { $$ = new BreakStatement(); }
+ | T_CONTINUE T_SC { $$ = new ContinueStatement(); }
+ | T_GOTO T_IDENTIFIER { $$ = new GotoStatement(*$2); }
;
IterationStatement:
T_WHILE T_LRB Expression T_RRB Statement { $$ = new WhileLoop($3, $5); }
- | T_DO Statement T_WHILE T_LRB Expression T_RRB T_SC { $$ = $2; }
+ | T_DO Statement T_WHILE T_LRB Expression T_RRB T_SC
+ { $$ = new WhileLoop($5, $2, false); }
| T_FOR T_LRB Expression T_SC Expression T_SC Expression T_RRB Statement
{ $$ = new ForLoop($3, $5, $7, $9); }
;
diff --git a/c_compiler/src/compiler_main.cpp b/c_compiler/src/compiler_main.cpp
index dcc9e09..e9a12b9 100644
--- a/c_compiler/src/compiler_main.cpp
+++ b/c_compiler/src/compiler_main.cpp
@@ -6,20 +6,21 @@
Node* parseAST();
-int main(int argc, char *argv[])
+int main(int, char**)
{
- (void)argc, (void)argv;
-
- try {
+ try
+ {
std::unique_ptr<Node> ast(parseAST());
VariableStackBindings bindings;
unsigned label_count = 0;
- ast->printAsm(bindings, label_count);
-
- } catch(std::string error_msg) {
+ ast->printAsm(bindings, label_count);
+ }
+ catch(std::string error_msg)
+ {
fprintf(stderr, "%s\n", error_msg.c_str());
-
- } catch(...) {
+ }
+ catch(...)
+ {
fprintf(stderr, "Error : Exception thrown\n");
}
diff --git a/c_compiler/src/declaration.cpp b/c_compiler/src/declaration.cpp
index 417aa84..eb98480 100644
--- a/c_compiler/src/declaration.cpp
+++ b/c_compiler/src/declaration.cpp
@@ -9,7 +9,7 @@
// Declaration definition
Declaration::Declaration(const std::string& id, Expression* initializer)
- : id_(id), initializer_(initializer)
+ : id_(id), initializer_(initializer), extern_declaration_(false)
{}
void Declaration::print() const
@@ -36,13 +36,15 @@ void Declaration::printXml() const
VariableStackBindings Declaration::printAsm(VariableStackBindings bindings, unsigned& label_count) const
{
(void)label_count;
+ if(!extern_declaration_)
+ {
+ if(initializer_ == nullptr)
+ printf("\t.comm\t%s,4,4\n", id_.c_str());
+ else
+ printf("\t.data\n\t.globl\t%s\n%s:\n\t.word\t%d\n",
+ id_.c_str(), id_.c_str(), initializer_->constantFold());
+ }
- if(initializer_ == nullptr)
- printf("\t.comm\t%s,4,4\n", id_.c_str());
- else
- printf("\t.data\n\t.globl\t%s\n%s:\n\t.word\t%d\n",
- id_.c_str(), id_.c_str(), initializer_->constantFold());
-
bindings.insertBinding(id_, type_, -1);
return bindings;
}
@@ -95,6 +97,11 @@ void Declaration::setInitializer(Expression* initializer)
initializer_ = expression_ptr;
}
+void Declaration::setExternDeclaration(bool is_extern)
+{
+ extern_declaration_ = is_extern;
+}
+
DeclarationPtr Declaration::getNext() const
{
return next_declaration_;
diff --git a/c_compiler/src/function.cpp b/c_compiler/src/function.cpp
index c1f60cd..a44347e 100644
--- a/c_compiler/src/function.cpp
+++ b/c_compiler/src/function.cpp
@@ -1,6 +1,6 @@
#include "function.hpp"
-#include <iostream>
+#include <cstdio>
#include <vector>
@@ -12,7 +12,7 @@ Function::Function(const std::string& id, Statement* statement, DeclarationPtr p
void Function::print() const
{
- std::cout << id_ << std::endl;
+ printf("%s\n", id_.c_str());
if(parameter_list_ != nullptr)
parameter_list_->print();
@@ -23,26 +23,28 @@ void Function::print() const
void Function::printXml() const
{
- std::cout << "<Function id=\"" << id_ << "\">" << std::endl;
+ printf("<Function id=\"%s\">\n", id_.c_str());
DeclarationPtr parameter = parameter_list_;
std::vector<std::string> parameter_vec;
- while(parameter != nullptr) {
+ while(parameter != nullptr)
+ {
parameter_vec.push_back(parameter->getId());
parameter = parameter->getNext();
}
for(std::vector<std::string>::reverse_iterator itr = parameter_vec.rbegin();
- itr != parameter_vec.rend(); ++itr) {
-
- std::cout << "<Parameter id=\"" << *itr << "\" />" << std::endl;
+ itr != parameter_vec.rend(); ++itr)
+ {
+ printf("<Parameter id=\"%s\" />", (*itr).c_str());
}
+
if(statement_ != nullptr)
statement_->printXml();
- std::cout << "</Function>" << std::endl;
+ printf("</Function>\n");
}
VariableStackBindings Function::printAsm(VariableStackBindings bindings, unsigned& label_count) const
@@ -72,11 +74,10 @@ VariableStackBindings Function::printAsm(VariableStackBindings bindings, unsigne
// make frame double word aligned
if(memory_needed % 8 != 0)
memory_needed += 4;
-
- std::cout << "\t.text\n\t.globl\t" << id_ << "\n" << id_ << ":\n\taddiu\t$sp,$sp,-"
- << memory_needed << "\n\tsw\t$31," << memory_needed-4 << "($sp)\n" << "\tsw\t$fp,"
- << memory_needed-8 << "($sp)\n\tmove\t$fp,$sp\n";
-
+
+ printf("\t.text\n\t.globl\t%s\n%s:\n\taddiu\t$sp,$sp,-%d\n\tsw\t",
+ id_.c_str(), id_.c_str(), memory_needed);
+ printf("$31,%d($sp)\n\tsw\t$fp,%d($sp)\n\tmove\t$fp,$sp\n", memory_needed-4, memory_needed-8);
// set the stack counter to the right value
bindings.setStackPosition((max_argument_count+parameter_count)*4);
@@ -86,10 +87,9 @@ VariableStackBindings Function::printAsm(VariableStackBindings bindings, unsigne
// Prints the asm for the compound statement in the function
statement_->printAsm(bindings, label_count);
-
- std::cout << "0:\n\tmove\t$sp,$fp\n\tlw\t$31," << memory_needed-4 << "($sp)\n\tlw\t$fp,"
- << memory_needed-8 << "($sp)\n\taddiu\t$sp,$sp," << memory_needed
- << "\n\tjr\t$31\n\tnop\n";
+
+ printf("\tmove\t$2,$0\n0:\n\tmove\t$sp,$fp\n\tlw\t$31,%d($sp)\n\tlw\t$fp,%d", memory_needed-4, memory_needed-8);
+ printf("($sp)\n\taddiu\t$sp,$sp,%d\n\tjr\t$31\n\tnop\n", memory_needed);
return original_bindings;
}
@@ -100,19 +100,20 @@ void Function::printParameterAsm(VariableStackBindings& bindings, unsigned& stac
std::vector<DeclarationPtr> parameter_vector;
DeclarationPtr parameter_list = parameter_list_;
- while(parameter_list != nullptr) {
+ while(parameter_list != nullptr)
+ {
parameter_vector.push_back(parameter_list);
parameter_list = parameter_list->getNext();
}
- for(auto itr = parameter_vector.rbegin(); itr != parameter_vector.rend(); ++itr) {
+ for(auto itr = parameter_vector.rbegin(); itr != parameter_vector.rend(); ++itr)
+ {
unsigned i = itr-parameter_vector.rbegin();
bindings.insertBinding((*itr)->getId(), (*itr)->getType(), (i+stack_offset)*4);
if(i < 4)
- std::cout << "\tsw\t$" << 4+i << "," << (i+stack_offset)*4 << "($fp)\n";
+ printf("\tsw\t$%d,%d($fp)\n", 4+i, (i+stack_offset)*4);
else
- std::cout << "\tlw\t$2," << frame_offset + 4*i << "($fp)\n\tsw\t$2," << (i+stack_offset)*4
- << "($fp)\n";
+ printf("\tlw\t$2,%d($fp)\n\tsw\t$2,%d($fp)\n", frame_offset+4*i, (i+stack_offset)*4);
}
}
@@ -120,7 +121,8 @@ void Function::countParameters(unsigned& parameter_count) const
{
DeclarationPtr parameter_list = parameter_list_;
- while(parameter_list != nullptr) {
+ while(parameter_list != nullptr)
+ {
parameter_count++;
parameter_list = parameter_list->getNext();
}
diff --git a/c_compiler/src/statement.cpp b/c_compiler/src/statement.cpp
index 77d3854..5eb3687 100644
--- a/c_compiler/src/statement.cpp
+++ b/c_compiler/src/statement.cpp
@@ -1,6 +1,6 @@
#include "statement.hpp"
-#include <iostream>
+#include <cstdio>
// General base Statement definition
@@ -40,7 +40,7 @@ void CompoundStatement::printXml() const
if(next_statement_ != nullptr)
next_statement_->printXml();
- std::cout << "<Scope>" << std::endl;
+ printf("<Scope>\n");
if(declaration_ != nullptr)
declaration_->printXml();
@@ -48,7 +48,7 @@ void CompoundStatement::printXml() const
if(statement_ != nullptr)
statement_->printXml();
- std::cout << "</Scope>" << std::endl;
+ printf("</Scope>\n");
}
VariableStackBindings CompoundStatement::printAsm(VariableStackBindings bindings, unsigned& label_count) const
@@ -104,14 +104,16 @@ void CompoundStatement::countArguments(unsigned& argument_count) const
void CompoundStatement::countExpressionDepth(unsigned &depth_count) const
{
unsigned previous_depth_count = depth_count;
- if(next_statement_ != nullptr) {
+ 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;
}
- if(statement_ != nullptr) {
+ if(statement_ != nullptr)
+ {
statement_->countExpressionDepth(depth_count);
if(previous_depth_count > depth_count)
depth_count = previous_depth_count;
@@ -121,10 +123,10 @@ void CompoundStatement::countExpressionDepth(unsigned &depth_count) const
// Selection Statement definition
-SelectionStatement::SelectionStatement(Expression* condition, Statement* _if, Statement* _else)
+IfElseStatement::IfElseStatement(Expression* condition, Statement* _if, Statement* _else)
: Statement(), condition_(condition), if_(_if), else_(_else) {}
-void SelectionStatement::print() const
+void IfElseStatement::print() const
{
condition_->print();
if_->print();
@@ -132,7 +134,7 @@ void SelectionStatement::print() const
else_->print();
}
-void SelectionStatement::printXml() const
+void IfElseStatement::printXml() const
{
if(next_statement_ != nullptr)
next_statement_->printXml();
@@ -144,7 +146,7 @@ void SelectionStatement::printXml() const
else_->printXml();
}
-VariableStackBindings SelectionStatement::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);
@@ -152,21 +154,21 @@ VariableStackBindings SelectionStatement::printAsm(VariableStackBindings binding
unsigned if_label = label_count++;
condition_->printAsm(bindings, label_count);
- std::cout << "\tbeq\t$2,$0,$" << if_label << "_else\n\tnop\n";
+ printf("\tbeq\t$2,$0,$%d_else\n\tnop\n", if_label);
if_->printAsm(bindings, label_count);
- std::cout << "\tb\t$" << if_label << "_if_end\n\tnop\n$" << if_label << "_else:\n";
+ printf("\tb\t$%d_if_end\n\tnop\n$%d_else:\n", if_label, if_label);
if(else_ != nullptr)
else_->printAsm(bindings, label_count);
- std::cout << "$" << if_label << "_if_end:\n";
+ printf("$%d_if_end:\n", if_label);
return bindings;
}
-void SelectionStatement::countVariables(unsigned& var_count) const
+void IfElseStatement::countVariables(unsigned& var_count) const
{
if(next_statement_ != nullptr)
next_statement_->countVariables(var_count);
@@ -178,7 +180,7 @@ void SelectionStatement::countVariables(unsigned& var_count) const
else_->countVariables(var_count);
}
-void SelectionStatement::countArguments(unsigned& argument_count) const
+void IfElseStatement::countArguments(unsigned& argument_count) const
{
if(next_statement_ != nullptr)
next_statement_->countArguments(argument_count);
@@ -190,11 +192,12 @@ void SelectionStatement::countArguments(unsigned& argument_count) const
else_->countArguments(argument_count);
}
-void SelectionStatement::countExpressionDepth(unsigned& depth_count) const
+void IfElseStatement::countExpressionDepth(unsigned& depth_count) const
{
unsigned previous_depth_count = depth_count;
- if(next_statement_ != nullptr) {
+ if(next_statement_ != nullptr)
+ {
next_statement_->countExpressionDepth(depth_count);
if(previous_depth_count > depth_count)
depth_count = previous_depth_count;
@@ -212,7 +215,8 @@ void SelectionStatement::countExpressionDepth(unsigned& depth_count) const
depth_count = previous_depth_count;
previous_depth_count = depth_count;
- if(else_ != nullptr) {
+ if(else_ != nullptr)
+ {
else_->countExpressionDepth(depth_count);
if(previous_depth_count > depth_count)
depth_count = previous_depth_count;
@@ -266,14 +270,16 @@ void ExpressionStatement::countExpressionDepth(unsigned& depth_count) const
{
unsigned previous_depth_count = depth_count;
- if(next_statement_ != nullptr) {
+ 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;
}
- if(expression_ != nullptr) {
+ if(expression_ != nullptr)
+ {
depth_count = 1;
expression_->expressionDepth(depth_count);
if(previous_depth_count > depth_count)
@@ -284,10 +290,6 @@ void ExpressionStatement::countExpressionDepth(unsigned& depth_count) const
// Jump Statement definition
-JumpStatement::JumpStatement(Expression* expression)
- : expression_(expression)
-{}
-
void JumpStatement::print() const
{}
@@ -297,7 +299,32 @@ void JumpStatement::printXml() const
next_statement_->printXml();
}
-VariableStackBindings JumpStatement::printAsm(VariableStackBindings bindings, unsigned& label_count) const
+void JumpStatement::countVariables(unsigned &var_count) const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->countVariables(var_count);
+}
+
+void JumpStatement::countArguments(unsigned &argument_count) const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->countArguments(argument_count);
+}
+
+void JumpStatement::countExpressionDepth(unsigned &depth_count) const
+{
+ if(next_statement_ != nullptr)
+ next_statement_->countExpressionDepth(depth_count);
+}
+
+
+// Return statement definition
+
+ReturnStatement::ReturnStatement(Expression* expression)
+ : expression_(expression)
+{}
+
+VariableStackBindings ReturnStatement::printAsm(VariableStackBindings bindings, unsigned& label_count) const
{
if(next_statement_ != nullptr)
next_statement_->printAsm(bindings, label_count);
@@ -305,18 +332,18 @@ VariableStackBindings JumpStatement::printAsm(VariableStackBindings bindings, un
if(expression_ != nullptr)
expression_->printAsm(bindings, label_count);
- std::cout << "\tj\t0f\n\tnop\n";
+ printf("\tj\t0f\n\tnop\n");
return bindings;
}
-void JumpStatement::countVariables(unsigned& var_count) const
+void ReturnStatement::countVariables(unsigned& var_count) const
{
if(next_statement_ != nullptr)
next_statement_->countVariables(var_count);
}
-void JumpStatement::countArguments(unsigned& argument_count) const
+void ReturnStatement::countArguments(unsigned& argument_count) const
{
if(next_statement_ != nullptr)
next_statement_->countArguments(argument_count);
@@ -330,18 +357,20 @@ void JumpStatement::countArguments(unsigned& argument_count) const
argument_count = tmp_argument_count;
}
-void JumpStatement::countExpressionDepth(unsigned& depth_count) const
+void ReturnStatement::countExpressionDepth(unsigned& depth_count) const
{
unsigned previous_depth_count = depth_count;
- if(next_statement_ != nullptr) {
+ 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;
}
- if(expression_ != nullptr) {
+ if(expression_ != nullptr)
+ {
depth_count = 1;
expression_->expressionDepth(depth_count);
if(previous_depth_count > depth_count)
@@ -350,6 +379,43 @@ void JumpStatement::countExpressionDepth(unsigned& depth_count) const
}
+// Break statement definition
+
+BreakStatement::BreakStatement()
+{}
+
+VariableStackBindings BreakStatement::printAsm(VariableStackBindings bindings, unsigned &) const
+{
+ printf("\tb\t%s\n\tnop\n", bindings.breakLabel().c_str());
+ return bindings;
+}
+
+
+// Continue statement
+
+ContinueStatement::ContinueStatement()
+{}
+
+VariableStackBindings ContinueStatement::printAsm(VariableStackBindings bindings, unsigned &) const
+{
+ printf("\tb\t%s\n\tnop\n", bindings.continueLabel().c_str());
+ return bindings;
+}
+
+
+// Goto statement
+
+GotoStatement::GotoStatement(const std::string &label)
+ : label_(label)
+{}
+
+VariableStackBindings GotoStatement::printAsm(VariableStackBindings bindings, unsigned &) const
+{
+ printf("\tb\t%s\n\tnop\n", label_.c_str());
+ return bindings;
+}
+
+
// Iteration Statement definition
IterationStatement::IterationStatement(Expression* condition, Statement* statement)
@@ -390,7 +456,8 @@ void IterationStatement::countExpressionDepth(unsigned& depth_count) const
{
unsigned previous_depth_count = depth_count;
- if(next_statement_ != nullptr) {
+ if(next_statement_ != nullptr)
+ {
next_statement_->countExpressionDepth(depth_count);
if(previous_depth_count > depth_count)
depth_count = previous_depth_count;
@@ -411,8 +478,8 @@ void IterationStatement::countExpressionDepth(unsigned& depth_count) const
// While Loop definition
-WhileLoop::WhileLoop(Expression* condition, Statement* statement)
- : IterationStatement(condition, statement)
+WhileLoop::WhileLoop(Expression* condition, Statement* statement, const bool &is_while)
+ : IterationStatement(condition, statement), is_while_(is_while)
{}
VariableStackBindings WhileLoop::printAsm(VariableStackBindings bindings,
@@ -420,17 +487,23 @@ VariableStackBindings WhileLoop::printAsm(VariableStackBindings bindings,
{
if(next_statement_ != nullptr)
next_statement_->printAsm(bindings, label_count);
+
+ VariableStackBindings initial_bindings = bindings;
int while_label = label_count++;
-
- std::cout << "\tb\t$" << while_label << "_while_cond\n\tnop\n$" << while_label
- << "_while_body:\n";
+
+ bindings.continueLabel("$"+std::to_string(while_label)+"_while_cond");
+ bindings.breakLabel("$"+std::to_string(while_label)+"_while_break");
+
+ if(is_while_)
+ printf("\tb\t$%d_while_cond\n\tnop\n", while_label);
+ printf("$%d_while_body:\n", while_label);
statement_->printAsm(bindings, label_count);
- std::cout << "$" << while_label << "_while_cond:\n";
+ printf("$%d_while_cond:\n", while_label);
condition_->printAsm(bindings, label_count);
- std::cout << "\tbne\t$2,$0,$" << while_label << "_while_body\n\tnop\n";
+ printf("\tbne\t$2,$0,$%d_while_body\n\tnop\n$%d_while_break:\n", while_label, while_label);
- return bindings;
+ return initial_bindings;
}
ForLoop::ForLoop(Expression* initializer, Expression* condition,
@@ -442,16 +515,21 @@ VariableStackBindings ForLoop::printAsm(VariableStackBindings bindings, unsigned
{
if(next_statement_ != nullptr)
next_statement_->printAsm(bindings, label_count);
+
+ VariableStackBindings initial_bindings = bindings;
int for_label = label_count++;
+
+ bindings.continueLabel("$"+std::to_string(for_label)+"_for_cond");
+ bindings.breakLabel("$"+std::to_string(for_label)+"_for_break");
initializer_->printAsm(bindings, label_count);
- std::cout << "\tb\t$" << for_label << "_for_cond\n\tnop\n$" << for_label << "_for_body:\n";
+ printf("\tb\t$%d_for_cond\n\tnop\n$%d_for_body:\n", for_label, for_label);
statement_->printAsm(bindings, label_count);
incrementer_->printAsm(bindings, label_count);
- std::cout << "$" << for_label << "_for_cond:\n";
+ printf("$%d_for_cond:\n", for_label);
condition_->printAsm(bindings, label_count);
- std::cout << "\tbne\t$2,$0,$" << for_label << "_for_body\n\tnop\n";
+ printf("\tbne\t$2,$0,$%d_for_body\n\tnop\n$%d_for_break:\n", for_label, for_label);
- return bindings;
+ return initial_bindings;
}
diff --git a/c_compiler/src/translation_unit.cpp b/c_compiler/src/translation_unit.cpp
index 0c7815b..74847b6 100644
--- a/c_compiler/src/translation_unit.cpp
+++ b/c_compiler/src/translation_unit.cpp
@@ -1,6 +1,6 @@
#include "translation_unit.hpp"
-#include <iostream>
+#include <cstdio>
// Translation Unit definition
@@ -18,11 +18,11 @@ void TranslationUnit::print() const
void TranslationUnit::printXml() const
{
- std::cout << "<?xml version=\"1.0\"?>\n<Program>" << std::endl;
+ printf("<?xml version=\"1.0\"?>\n<Program>\n");
for(auto& node : translation_unit_) {
node->printXml();
}
- std::cout << "</Program>" << std::endl;
+ printf("</Program>\n");
}
VariableStackBindings TranslationUnit::printAsm(VariableStackBindings bindings, unsigned& label_count) const
diff --git a/c_compiler/src/type.cpp b/c_compiler/src/type.cpp
index a72807a..04bc245 100644
--- a/c_compiler/src/type.cpp
+++ b/c_compiler/src/type.cpp
@@ -1,22 +1,21 @@
#include "type.hpp"
+#include <cstdio>
#include <exception>
-#include <iostream>
// Type definition
void Type::print() const
{
- std::cout << getType() << " " << std::endl;
+ printf("%s\n", getType().c_str());
}
void Type::printXml() const
{}
-VariableStackBindings Type::printAsm(VariableStackBindings bindings, unsigned& label_count) const
+VariableStackBindings Type::printAsm(VariableStackBindings bindings, unsigned&) const
{
- (void)label_count;
return bindings;
}
@@ -25,45 +24,38 @@ TypePtr Type::type()
throw std::runtime_error("Error : does not have a type");
}
-TypePtr Type::type(Type* type_ptr)
+TypePtr Type::type(Type*)
{
- (void) type_ptr;
throw std::runtime_error("Error : cannot assign type");
}
-TypePtr Type::type(TypePtr type_ptr)
+TypePtr Type::type(TypePtr)
{
- (void)type_ptr;
throw std::runtime_error("Error : cannot assign type");
}
-void Type::setSigned(bool _signed)
+void Type::setSigned(bool)
{
- (void)_signed;
throw std::runtime_error("Error : cannot set sign");
}
-void Type::setExtern(bool _extern)
+void Type::setExtern(bool)
{
- (void)_extern;
throw std::runtime_error("Error : cannot set extern");
}
-void Type::setStatic(bool _static)
+void Type::setStatic(bool)
{
- (void)_static;
throw std::runtime_error("Error : cannot set static");
}
-void Type::setConst(bool _const)
+void Type::setConst(bool)
{
- (void)_const;
throw std::runtime_error("Error : cannot set const");
}
-void Type::setSize(int _size)
+void Type::setSize(int)
{
- (void)_size;
throw std::runtime_error("Error : cannot set size");
}
diff --git a/c_compiler/test/in/fib.c b/c_compiler/test/in/fib.c
index 17a3b41..62a9a07 100644
--- a/c_compiler/test/in/fib.c
+++ b/c_compiler/test/in/fib.c
@@ -1,6 +1,6 @@
int main()
{
- int n, first = 0, second = 1, next, c;
+ unsigned long int n, first = 0, second = 1, next, c;
n = 10;
diff --git a/c_compiler/test/in/fib_recusive.c b/c_compiler/test/in/fib_recusive.c
index 55abe06..1b7ceda 100644
--- a/c_compiler/test/in/fib_recusive.c
+++ b/c_compiler/test/in/fib_recusive.c
@@ -1,12 +1,4 @@
-int Fibonacci(int n)
-{
- if ( n == 0 )
- return 0;
- else if ( n == 1 )
- return 1;
- else
- return ( Fibonacci(n-1) + Fibonacci(n-2) );
-}
+int Fibonacci(int);
int main()
{
@@ -22,3 +14,13 @@ int main()
return res;
}
+
+int Fibonacci(int n)
+{
+ if ( n == 0 )
+ return 0;
+ else if ( n == 1 )
+ return 1;
+ else
+ return ( Fibonacci(n-1) + Fibonacci(n-2) );
+}
diff --git a/c_compiler/test/in/short.c b/c_compiler/test/in/short.c
new file mode 100644
index 0000000..2e0b96c
--- /dev/null
+++ b/c_compiler/test/in/short.c
@@ -0,0 +1,9 @@
+short f(short a)
+{
+ return a;
+}
+
+int main()
+{
+ return f(5);
+}
diff --git a/run_test_deliverable.sh b/run_test_deliverable.sh
index 35f6629..ae96054 100755
--- a/run_test_deliverable.sh
+++ b/run_test_deliverable.sh
@@ -3,12 +3,23 @@
if [[ -z "$1" ]]; then
COMPILER=bin/c_compiler
else
- COMPILER=$1
+ COMPILER=bin/c_compiler
+ make clean
+ make -B ${COMPILER}
fi
+echo ""
+echo "========================================"
+echo " Testing compiler"
+echo ""
+
+PASSED=0
+CHECKED=0
+
mkdir -p working
for DRIVER in test_deliverable/testcases/*_driver.c ; do
+ CHECKED=$(( CHECKED+1 ))
NAME=$(basename $DRIVER _driver.c)
TESTCODE=test_deliverable/testcases/$NAME.c
@@ -39,7 +50,13 @@ for DRIVER in test_deliverable/testcases/*_driver.c ; do
qemu-mips working/${NAME}.elf
if [[ $? -ne 0 ]]; then
>&2 echo "ERROR : Testcase returned $?, but expected 0."
+ continue
fi
echo "pass"
+ PASSED=$(( PASSED+1 ))
done
+
+echo "########################################"
+echo " Passed ${PASSED} out of ${CHECKED}"
+echo ""
diff --git a/test_deliverable/testcases/test_BREAK.c b/test_deliverable/testcases/test_BREAK.c
new file mode 100644
index 0000000..c63ced3
--- /dev/null
+++ b/test_deliverable/testcases/test_BREAK.c
@@ -0,0 +1,13 @@
+int iterate(int a, int b)
+{
+ while(a < b)
+ {
+ if(a == b / 2)
+ {
+ break;
+ }
+ ++a;
+ }
+
+ return a;
+}
diff --git a/test_deliverable/testcases/test_BREAK_driver.c b/test_deliverable/testcases/test_BREAK_driver.c
new file mode 100644
index 0000000..acabf07
--- /dev/null
+++ b/test_deliverable/testcases/test_BREAK_driver.c
@@ -0,0 +1,6 @@
+int iterate(int, int);
+
+int main()
+{
+ return !( 5 == iterate(1, 10) );
+}