aboutsummaryrefslogtreecommitdiffstats
path: root/c_compiler
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2017-03-21 17:03:38 +0000
committerYann Herklotz <ymherklotz@gmail.com>2017-03-21 17:03:38 +0000
commit190b7a0e5d45367230795ac0bdf6fc2f248ba9e1 (patch)
treedc9a605ced1784faf80d71f7f59e49b79d6bb2c7 /c_compiler
parentaf8b76d0a83813b3cebac7468db4bd64e534c235 (diff)
downloadCompiler-190b7a0e5d45367230795ac0bdf6fc2f248ba9e1.tar.gz
Compiler-190b7a0e5d45367230795ac0bdf6fc2f248ba9e1.zip
changed type layout to have all necessary information
Diffstat (limited to 'c_compiler')
-rw-r--r--c_compiler/include/declaration.hpp1
-rw-r--r--c_compiler/include/expression.hpp38
-rw-r--r--c_compiler/include/type.hpp86
-rw-r--r--c_compiler/src/c_lexer.flex31
-rw-r--r--c_compiler/src/c_parser.y130
-rw-r--r--c_compiler/src/declaration.cpp6
-rw-r--r--c_compiler/src/expression.cpp190
-rw-r--r--c_compiler/src/type.cpp136
-rw-r--r--c_compiler/test/in/fib.c20
-rw-r--r--c_compiler/test/in/fib_recusive.c24
-rw-r--r--c_compiler/test/in/for.c5
11 files changed, 486 insertions, 181 deletions
diff --git a/c_compiler/include/declaration.hpp b/c_compiler/include/declaration.hpp
index d09faec..76f0efc 100644
--- a/c_compiler/include/declaration.hpp
+++ b/c_compiler/include/declaration.hpp
@@ -19,6 +19,7 @@ private:
ExpressionPtr initializer_;
DeclarationPtr next_declaration_;
DeclarationPtr next_list_declaration_;
+ bool extern_declaration;
public:
Declaration(const std::string& id = "", Expression* initializer = nullptr);
diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp
index 1563211..21e5880 100644
--- a/c_compiler/include/expression.hpp
+++ b/c_compiler/include/expression.hpp
@@ -26,13 +26,11 @@ public:
virtual void print() const;
virtual void printXml() const;
virtual void countArguments(unsigned& argument_count) const;
- virtual void expressionDepth(unsigned& depth_count) const;
-
+ virtual void expressionDepth(unsigned& depth_count) const;
virtual int postfixStackPosition(VariableStackBindings bindings) const;
virtual void setPostfixExpression(Expression* postfix_expression);
-
virtual std::string id() const;
-
+
void linkExpression(Expression* next_expression);
ExpressionPtr nextExpression() const;
};
@@ -47,21 +45,14 @@ public:
OperationExpression(Expression* lhs, Expression* rhs);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const = 0;
+
virtual int constantFold() const;
virtual void expressionDepth(unsigned& depth_count) const;
+
void evaluateExpression(VariableStackBindings bindings, unsigned& label_count) const;
};
-class PostfixExpression : public Expression
-{
-public:
- PostfixExpression();
-
- virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
-};
-
-
class PostfixArrayElement : public Expression
{
public:
@@ -86,11 +77,28 @@ public:
void setPostfixExpression(Expression* postfix_expression);
};
+class PostfixPostIncDecExpression : public Expression
+{
+private:
+ std::string operator_;
+ ExpressionPtr postfix_expression_;
+
+public:
+ PostfixPostIncDecExpression(const std::string& _operator, Expression* postfix_expression);
+
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+
+};
+
-class UnaryExpression : public Expression
+class UnaryPreIncDecExpression : public Expression
{
+private:
+ std::string operator_;
+ ExpressionPtr unary_expression_;
+
public:
- UnaryExpression();
+ UnaryPreIncDecExpression(const std::string& _operator, Expression* unary_expression);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
};
diff --git a/c_compiler/include/type.hpp b/c_compiler/include/type.hpp
index 9b9bbba..bd9fd4b 100644
--- a/c_compiler/include/type.hpp
+++ b/c_compiler/include/type.hpp
@@ -8,71 +8,101 @@
#include <string>
class Type;
-
typedef std::shared_ptr<Type> TypePtr;
-
-class Type : public Node {
+class Type : public Node
+{
public:
virtual void print() const;
virtual void printXml() const;
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
virtual std::string getType() const = 0;
-};
+ virtual TypePtr type();
+ virtual TypePtr type(Type* type_ptr);
+ virtual TypePtr type(TypePtr type_ptr);
+ virtual void setSigned(bool _signed);
+ virtual void setExtern(bool _extern);
+ virtual void setStatic(bool _static);
+ virtual void setConst(bool _const);
+ virtual void setSize(int size);
+};
-class Specifier : public Type {
+class Array : public Type
+{
public:
- virtual std::string getType() const = 0;
+ Array();
+ virtual std::string getType() const;
};
-
-class Pointer : public Type {
-protected:
- TypePtr pointer_type_;
-
+class Pointer : public Type
+{
public:
- Pointer(Type* pointer_type);
-
+ Pointer();
virtual std::string getType() const;
};
-
-class Array : public Type {
+class TypeContainer : public Type
+{
protected:
- TypePtr array_type_;
- unsigned size_;
+ TypePtr type_;
+ int size_;
+ bool extern_;
+ bool static_;
+ bool const_;
+ bool signed_;
public:
- Array(Type* array_type, unsigned size = 0);
-
+ TypeContainer();
+
virtual std::string getType() const;
+ virtual TypePtr type();
+ virtual TypePtr type(Type* type_ptr);
+ virtual TypePtr type(TypePtr type_ptr);
+ virtual void setSigned(bool _signed);
+ virtual void setExtern(bool _extern);
+ virtual void setStatic(bool _static);
+ virtual void setConst(bool _const);
+ virtual void setSize(int size);
};
-
-class Void : public Specifier {
+class Specifier : public Type
+{
public:
- Void();
-
- virtual std::string getType() const;
+ virtual std::string getType() const = 0;
};
-
-class Int : public Specifier {
+class Int : public Specifier
+{
public:
Int();
virtual std::string getType() const;
};
+class Void : public Specifier
+{
+public:
+ Void();
+
+ virtual std::string getType() const;
+};
-class Char : public Specifier {
+class Char : public Specifier
+{
public:
Char();
- virtual std::string getType() const;
+ virtual std::string getType() const;
};
+class Float : public Specifier
+{
+public:
+ Float();
+
+ virtual std::string getType() const;
+};
#endif
diff --git a/c_compiler/src/c_lexer.flex b/c_compiler/src/c_lexer.flex
index a761343..90790b5 100644
--- a/c_compiler/src/c_lexer.flex
+++ b/c_compiler/src/c_lexer.flex
@@ -28,17 +28,24 @@ ALL .
%%
-(void) { return T_VOID; }
-(char) { return T_CHAR; }
-(signed[ ]char) { return T_SCHAR; }
-(unsigned[ ]char) { return T_UCHAR; }
-((short[ ]int)|(signed[ ]short[ ]int)|short|(signed[ ]short)) { return T_SSINT; }
-((unsigned[ ]short[ ]int)|(unsigned[ ]short)) { return T_USINT; }
-((signed[ ]long[ ]int)|(signed[ ]long)|(long[ ]int)|long) { return T_LINT; }
-((unsigned[ ]long[ ]int)|(unsigned[ ]long)) { return T_ULINT; }
-((unsigned[ ]int)|unsigned) { return T_UINT; }
-((signed[ ]int)|int|signed) { return T_SINT; }
-
+(void) { return T_VOID; }
+(char) { return T_CHAR; }
+(short) { return T_SHORT; }
+(int) { return T_INT; }
+(long) { return T_LONG; }
+(float) { return T_FLOAT; }
+(double) { return T_DOUBLE; }
+(signed) { return T_SIGNED; }
+(unsigned) { return T_UNSIGNED; }
+
+(typedef) { return T_TYPEDEF; }
+(extern) { return T_EXTERN; }
+(static) { return T_STATIC; }
+(auto) { return T_AUTO; }
+(register) { return T_REGISTER; }
+
+(const) { return T_CONST; }
+(volatile) { return T_VOLATILE; }
[;] { return T_SC; }
[,] { return T_CMA; }
@@ -66,7 +73,7 @@ ALL .
[!] { return T_NOT; }
[.] { return T_DOT; }
[-][>] { return T_ARROW; }
-[+-][+-] { return T_INCDEC; }
+[+-][+-] { yylval.string = new std::string(yytext); return T_INCDEC; }
[+-] { yylval.string = new std::string(yytext); return T_ADDSUB_OP; }
[=] { yylval.string = new std::string(yytext); return T_EQ; }
diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y
index 6375053..1fb2777 100644
--- a/c_compiler/src/c_parser.y
+++ b/c_compiler/src/c_parser.y
@@ -10,6 +10,7 @@
extern Node* g_root; // A way of getting the AST out
+void setTypeInformation(Type* type_ptr, std::string type_str);
//! This is to fix problems when generating C++
// We are declaring the functions provided by Flex, so
@@ -38,7 +39,11 @@ void yyerror(const char *);
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_VOID T_CHAR T_SCHAR T_UCHAR T_SSINT T_USINT T_LINT T_ULINT T_UINT T_SINT
+ 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
%nonassoc T_RRB
%nonassoc T_ELSE
@@ -66,11 +71,13 @@ void yyerror(const char *);
PostfixExpression PostfixExpression2 ArgumentExpressionList PrimaryExpression
Constant
+%type <type> DeclarationSpecifierList
+
%type <number> T_INT_CONST
%type <string> T_IDENTIFIER ASSIGN_OPER T_ASSIGN_OPER T_EQ T_AND T_ADDSUB_OP T_TILDE T_NOT
- T_MULT T_DIV T_REM T_EQUALITY_OP T_REL_OP T_SHIFT_OP MultDivRemOP UnaryOperator
- DeclarationSpec
+ T_MULT T_DIV T_REM T_EQUALITY_OP T_REL_OP T_SHIFT_OP T_INCDEC MultDivRemOP
+ UnaryOperator DeclarationSpecifier
%start ROOT
@@ -95,7 +102,7 @@ ExternalDeclaration:
// FUNCTION DEFINITION
FunctionDefinition:
- DeclarationSpec Declarator CompoundStatement
+ DeclarationSpecifierList Declarator CompoundStatement
{ $$ = new Function($2->getId(), $3, $2->getNext()); delete $1; }
;
@@ -105,7 +112,7 @@ ParameterList:
| ParameterList T_CMA Parameter { $3->linkDeclaration($$); $$ = $3; }
;
-Parameter: DeclarationSpec T_IDENTIFIER { $$ = new Declaration(*$2); delete $2; delete $1; }
+Parameter: DeclarationSpecifierList T_IDENTIFIER { $$ = new Declaration(*$2); delete $2; delete $1; }
;
// Declaration
@@ -115,36 +122,48 @@ DeclarationList:
| DeclarationList Declaration { $2->linkDeclaration($$); $$ = $2; }
;
-Declaration: DeclarationSpec InitDeclaratorList T_SC
+Declaration: DeclarationSpecifierList InitDeclaratorList T_SC
{
$$ = $2;
Declaration* tmp_decl = $2;
+ Type* tmp_type = new TypeContainer();
while(tmp_decl != nullptr) {
- if(*$1 == "void") {
- tmp_decl->setType(new Void);
- } else if(*$1 == "char") {
- tmp_decl->setType(new Char);
- } else {
- tmp_decl->setType(new Int);
- }
+ tmp_type->type($1->type());
tmp_decl = tmp_decl->getNextListItem().get();
}
delete $1;
};
-DeclarationSpec:
+DeclarationSpecifierList:
+ DeclarationSpecifier
+ {
+ $$ = new TypeContainer();
+ setTypeInformation($$, *$1);
+ delete $1;
+ }
+ | DeclarationSpecifierList DeclarationSpecifier
+ { setTypeInformation($$, *$2); delete $2; }
+ ;
+
+DeclarationSpecifier:
T_VOID { $$ = new std::string("void"); }
| T_CHAR { $$ = new std::string("char"); }
- | T_SCHAR { $$ = new std::string("char"); }
- | T_UCHAR { $$ = new std::string("char"); }
- | T_SSINT { $$ = new std::string("int"); }
- | T_USINT { $$ = new std::string("int"); }
- | T_LINT { $$ = new std::string("int"); }
- | T_ULINT { $$ = new std::string("int"); }
- | T_UINT { $$ = new std::string("int"); }
- | T_SINT { $$ = new std::string("int"); }
+ | T_SHORT { $$ = new std::string("short"); }
+ | T_INT { $$ = new std::string("int"); }
+ | T_LONG { $$ = new std::string("long"); }
+ | T_FLOAT { $$ = new std::string("float"); }
+ | T_DOUBLE { $$ = new std::string("double"); }
+ | T_SIGNED { $$ = new std::string("signed"); }
+ | T_UNSIGNED { $$ = new std::string("unsigned"); }
+ | T_TYPEDEF { $$ = new std::string("typedef"); }
+ | T_EXTERN { $$ = new std::string("extern"); }
+ | T_STATIC { $$ = new std::string("static"); }
+ | T_AUTO { $$ = new std::string("auto"); }
+ | T_REGISTER { $$ = new std::string("register"); }
+ | T_CONST { $$ = new std::string("const"); }
+ | T_VOLATILE { $$ = new std::string("volatile"); }
;
InitDeclaratorList:
@@ -298,26 +317,16 @@ MultDivRemOP: T_MULT { $$ = $1; }
;
CastExpression: UnaryExpression { $$ = $1; }
- | T_LRB DeclarationSpec T_RRB CastExpression
- {
- if(*$2 == "int") {
- $$ = new CastExpression(new Int, $4);
- } else if(*$2 == "char") {
- $$ = new CastExpression(new Char, $4);
- } else {
- $$ = new CastExpression(new Void, $4);
- }
-
- delete $2;
- }
+ | T_LRB DeclarationSpecifierList T_RRB CastExpression
+ { new CastExpression($2, $4); delete $2; }
;
UnaryExpression:
PostfixExpression { $$ = $1; }
- | T_INCDEC UnaryExpression { $$ = $2; }
+ | T_INCDEC UnaryExpression { $$ = new UnaryPreIncDecExpression(*$1, $2); delete $1; }
| UnaryOperator CastExpression { $$ = $2; }
| T_SIZEOF UnaryExpression { $$ = $2; }
- | T_SIZEOF T_LRB DeclarationSpec T_RRB { $$ = new Constant(0); delete $3; }
+ | T_SIZEOF T_LRB DeclarationSpecifierList T_RRB { $$ = new Constant(0); delete $3; }
;
UnaryOperator: T_AND { $$ = $1; }
@@ -333,7 +342,8 @@ PostfixExpression:
| PostfixExpression T_LRB PostfixExpression2 { $$ = $3; $$->setPostfixExpression($1); }
| PostfixExpression T_DOT T_IDENTIFIER { $$ = $1; }
| PostfixExpression T_ARROW T_IDENTIFIER { $$ = $1; }
- | PostfixExpression T_INCDEC { $$ = $1; }
+ | PostfixExpression T_INCDEC
+ { $$ = new PostfixPostIncDecExpression(*$2, $1); delete $2; }
;
PostfixExpression2:
@@ -359,8 +369,52 @@ Constant: T_INT_CONST { $$ = new Constant($1); }
Node* g_root; // Definition of variable (to match declaration earlier)
-Node* parseAST() {
+Node* parseAST()
+{
g_root = 0;
yyparse();
return g_root;
}
+
+void setTypeInformation(Type* type_ptr, std::string type_str)
+{
+ if(type_str == "void") {
+ type_ptr->type(new Void());
+ } else if(type_str == "char") {
+ type_ptr->type(new Char());
+ type_ptr->setSize(8);
+ } else if(type_str == "short") {
+ type_ptr->type(new Int());
+ type_ptr->setSize(16);
+ } else if(type_str == "int") {
+ type_ptr->type(new Int());
+ } else if(type_str == "long") {
+ type_ptr->type(new Int());
+ } else if(type_str == "float") {
+ type_ptr->type(new Float());
+ } else if(type_str == "double") {
+ type_ptr->type(new Float());
+ } else if(type_str == "signed") {
+ type_ptr->type(new Int());
+ type_ptr->setSigned(true);
+ } else if(type_str == "unsigned") {
+ type_ptr->type(new Int());
+ type_ptr->setSigned(false);
+ } else if(type_str == "typedef") {
+ // TODO do typedef
+ } else if(type_str == "extern") {
+ type_ptr->setExtern(true);
+ } else if(type_str == "static") {
+ type_ptr->setStatic(true);
+ } else if(type_str == "auto") {
+ // TODO do auto
+ } else if(type_str == "register") {
+ // TODO do register
+ } else if(type_str == "const") {
+ type_ptr->setConst(true);
+ } else if(type_str == "volatile") {
+ // TODO do volatile
+ } else {
+
+ }
+}
diff --git a/c_compiler/src/declaration.cpp b/c_compiler/src/declaration.cpp
index 9aa647a..417aa84 100644
--- a/c_compiler/src/declaration.cpp
+++ b/c_compiler/src/declaration.cpp
@@ -26,9 +26,8 @@ void Declaration::printXml() const
if(next_declaration_ != nullptr)
next_declaration_->printXml();
- if(next_list_declaration_ != nullptr) {
+ if(next_list_declaration_ != nullptr)
next_list_declaration_->printXml();
- }
if(id_ != "")
printf("<Variable id=\"%s\" />", id_.c_str());
@@ -56,7 +55,8 @@ VariableStackBindings Declaration::localAsm(VariableStackBindings bindings, unsi
if(next_list_declaration_ != nullptr)
bindings = next_list_declaration_->localAsm(bindings, label_count);
- if(id_ != "") {
+ if(id_ != "")
+ {
if(initializer_ != nullptr)
initializer_->printAsm(bindings, label_count);
else
diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp
index bd64325..cdf7d0a 100644
--- a/c_compiler/src/expression.cpp
+++ b/c_compiler/src/expression.cpp
@@ -2,7 +2,6 @@
#include <cstdio>
#include <exception>
-#include <iostream>
#include <vector>
// Expression definition
@@ -102,18 +101,6 @@ void OperationExpression::evaluateExpression(VariableStackBindings bindings, uns
lhs_stack_position, bindings.currentExpressionStackPosition());
}
-
-// PostfixExpression definition
-
-PostfixExpression::PostfixExpression()
-{}
-
-VariableStackBindings PostfixExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const
-{
- return bindings;
-}
-
-
// PostfixArrayElement
PostfixArrayElement::PostfixArrayElement()
@@ -137,12 +124,14 @@ VariableStackBindings PostfixFunctionCall::printAsm(VariableStackBindings bindin
ExpressionPtr current_argument = argument_expression_list_;
unsigned argument_counter = 0;
- while(current_argument != nullptr) {
+ while(current_argument != nullptr)
+ {
argument_vector.push_back(current_argument);
current_argument = current_argument->nextExpression();
}
- for(auto itr = argument_vector.rbegin(); itr != argument_vector.rend(); ++itr) {
+ for(auto itr = argument_vector.rbegin(); itr != argument_vector.rend(); ++itr)
+ {
(*itr)->printAsm(bindings, label_count);
if(argument_counter < 4)
@@ -164,7 +153,8 @@ void PostfixFunctionCall::countArguments(unsigned int &argument_count) const
argument_count = 0;
- while(current_argument != nullptr) {
+ while(current_argument != nullptr)
+ {
argument_count++;
current_argument = current_argument->nextExpression();
}
@@ -177,13 +167,46 @@ void PostfixFunctionCall::setPostfixExpression(Expression* postfix_expression)
}
-// UnaryExpression definition
+// Post increment and decrement definition
-UnaryExpression::UnaryExpression()
+PostfixPostIncDecExpression::PostfixPostIncDecExpression(const std::string& _operator, Expression* postfix_expression)
+ : operator_(_operator), postfix_expression_(postfix_expression)
{}
-VariableStackBindings UnaryExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const
+VariableStackBindings PostfixPostIncDecExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const
{
+ postfix_expression_->printAsm(bindings, label_count);
+ if(operator_ == "++")
+ printf("\taddi\t$3,$2,1\n");
+ else if(operator_ == "--")
+ printf("\tsubi\t$3,$2,1\n");
+ else
+ throw std::runtime_error("Error : '"+operator_+"' not recognized");
+
+ printf("\tsw\t$2,%d($fp)\n\tsw\t$3,%d($fp)\n", bindings.currentExpressionStackPosition(),
+ postfix_expression_->postfixStackPosition(bindings));
+ return bindings;
+}
+
+
+// Pre increment and decrement implementation
+
+UnaryPreIncDecExpression::UnaryPreIncDecExpression(const std::string& _operator, Expression* unary_expression)
+ : operator_(_operator), unary_expression_(unary_expression)
+{}
+
+VariableStackBindings UnaryPreIncDecExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const
+{
+ unary_expression_->printAsm(bindings, label_count);
+ if(operator_ == "++")
+ printf("\taddi\t$2,$2,1\n");
+ else if(operator_ == "--")
+ printf("\tsubi\t$2,$2,1\n");
+ else
+ throw std::runtime_error("Error : '"+operator_+"' not recognized");
+
+ printf("\tsw\t$2,%d($fp)\n\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition(),
+ unary_expression_->postfixStackPosition(bindings));
return bindings;
}
@@ -245,17 +268,20 @@ VariableStackBindings MultiplicativeExpression::printAsm(VariableStackBindings b
evaluateExpression(bindings, label_count);
// then perform the right operation
- if(operator_ == "*") {
- printf("\tmul\t$2,$2,$3\n");
-
- } else if(operator_ == "/" || operator_ == "%") {
+ if(operator_ == "*")
+ {
+ printf("\tmul\t$2,$2,$3\n");
+ }
+ else if(operator_ == "/" || operator_ == "%")
+ {
printf("\tdiv\t$2,$3\n");
if(operator_ == "/")
printf("\tmflo\t$2\n");
else
- printf("\tmfhi\t$2\n");
-
- } else {
+ printf("\tmfhi\t$2\n");
+ }
+ else
+ {
throw std::runtime_error("Error : '"+operator_+"' not recognized");
}
@@ -286,15 +312,20 @@ VariableStackBindings ShiftExpression::printAsm(VariableStackBindings bindings,
{
evaluateExpression(bindings, label_count);
- if(operator_ == "<<") {
- std::cout << "\tsll\t$2,$2,$3\n";
- } else if(operator_ == ">>") {
- std::cout << "\tsra\t$2,$2,$3\n";
- } else {
- std::cerr << "Error : don't recognize symbol '" << operator_ << "'\n";
+ if(operator_ == "<<")
+ {
+ printf("\tsll\t$2,$2,$3\n");
+ }
+ else if(operator_ == ">>")
+ {
+ printf("\tsra\t$2,$2,$3\n");
+ }
+ else
+ {
+ throw std::runtime_error("Error : '"+operator_+"' not recognized");
}
- std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n";
+ printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition());
return bindings;
}
@@ -317,34 +348,47 @@ VariableStackBindings RelationalExpression::printAsm(VariableStackBindings bindi
{
evaluateExpression(bindings, label_count);
- if(operator_ == "<") {
- std::cout << "\tslt\t$2,$2,$3\n";
- } else if(operator_ == ">") {
- std::cout << "\tslt\t$2,$3,$2\n";
- } else if(operator_ == "<=") {
- std::cout << "\tslt\t$2,$3,$2\n\txori\t$2,$2,0x1\n";
- } else if(operator_ == ">=") {
- std::cout << "\tslt\t$2,$2,$3\n\txori\t$2,$2,0x1\n";
- } else {
- std::cerr << "Error : don't recognize symbol '" << operator_ << "'\n";
+ if(operator_ == "<")
+ {
+ printf("\tslt\t$2,$2,$3\n");
+ }
+ else if(operator_ == ">")
+ {
+ printf("\tslt\t$2,$3,$2\n");
+ }
+ else if(operator_ == "<=")
+ {
+ printf("\tslt\t$2,$3,$2\n\txori\t$2,$2,0x1\n");
+ }
+ else if(operator_ == ">=")
+ {
+ printf("\tslt\t$2,$2,$3\n\txori\t$2,$2,0x1\n");
+ }
+ else
+ {
+ throw std::runtime_error("Error : '"+operator_+"' not recognized");
}
// TODO might get rid of this
- std::cout << "\tandi\t$2,$2,0x00ff\n";
-
- std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n";
-
+ printf("\tandi\t$2,$2,0x00ff\n\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition());
return bindings;
}
int RelationalExpression::constantFold() const
{
if(operator_ == "<")
+ {
return lhs_->constantFold()<rhs_->constantFold();
+ }
else if(operator_ == ">")
+ {
return lhs_->constantFold()>rhs_->constantFold();
+ }
else if(operator_ == "<=")
+ {
return lhs_->constantFold()<=rhs_->constantFold();
+ }
+
return lhs_->constantFold()>=rhs_->constantFold();
}
@@ -358,22 +402,23 @@ EqualityExpression::EqualityExpression(Expression* lhs, const std::string& _oper
VariableStackBindings EqualityExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const
{
evaluateExpression(bindings, label_count);
+ printf("\txor\t$2,$2,$3\n");
- std::cout << "\txor\t$2,$2,$3\n";
-
- if(operator_ == "==") {
- std::cout << "\tsltiu\t$2,$2,1\n";
- } else if(operator_ == "!="){
- std::cout << "\tsltu\t$2,$0,$2\n";
- } else {
- std::cerr << "Error : no instruction found for operator '" << operator_ << "'\n";
+ if(operator_ == "==")
+ {
+ printf("\tsltiu\t$2,$2,1\n");
+ }
+ else if(operator_ == "!=")
+ {
+ printf("\tsltu\t$2,$0,$2\n");
+ }
+ else
+ {
+ throw std::runtime_error("Error : '"+operator_+"' not recognized");
}
// TODO Work out why it is necessary to remove bytes 3 and 2.
- std::cout << "\tandi\t$2,$2,0x00ff\n";
-
- std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n";
-
+ printf("\tandi\t$2,$2,0x00ff\n\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition());
return bindings;
}
@@ -394,11 +439,7 @@ AndExpression::AndExpression(Expression* lhs, Expression* rhs)
VariableStackBindings AndExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const
{
evaluateExpression(bindings, label_count);
-
- std::cout << "\tand\t$2,$2,$3\n";
-
- std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n";
-
+ printf("\tand\t$2,$2,$3\n\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition());
return bindings;
}
@@ -534,16 +575,20 @@ VariableStackBindings Identifier::printAsm(VariableStackBindings bindings, unsig
{
(void)label_count;
- if(bindings.bindingExists(id_)) {
- if(bindings.stackPosition(id_) == -1) {
+ if(bindings.bindingExists(id_))
+ {
+ if(bindings.stackPosition(id_) == -1)
+ {
// it's a global variable
- printf("\tlui\t$2,%%hi(%s)\n\tlw\t$2,%%lo(%s)($2)\n", id_.c_str(), id_.c_str());
-
- } else {
+ printf("\tlui\t$2,%%hi(%s)\n\tlw\t$2,%%lo(%s)($2)\n", id_.c_str(), id_.c_str());
+ }
+ else
+ {
printf("\tlw\t$2,%d($fp)\n", bindings.stackPosition(id_));
}
-
- } else{
+ }
+ else
+ {
throw std::runtime_error("Error : Can't find '"+id_+"' in current scope binding");
}
@@ -553,7 +598,8 @@ VariableStackBindings Identifier::printAsm(VariableStackBindings bindings, unsig
int Identifier::postfixStackPosition(VariableStackBindings bindings) const
{
- if(bindings.bindingExists(id_)) {
+ if(bindings.bindingExists(id_))
+ {
return bindings.stackPosition(id_);
}
diff --git a/c_compiler/src/type.cpp b/c_compiler/src/type.cpp
index 44c4ddb..a72807a 100644
--- a/c_compiler/src/type.cpp
+++ b/c_compiler/src/type.cpp
@@ -1,5 +1,6 @@
#include "type.hpp"
+#include <exception>
#include <iostream>
@@ -15,45 +16,138 @@ void Type::printXml() const
VariableStackBindings Type::printAsm(VariableStackBindings bindings, unsigned& label_count) const
{
+ (void)label_count;
return bindings;
}
+TypePtr Type::type()
+{
+ throw std::runtime_error("Error : does not have a type");
+}
+
+TypePtr Type::type(Type* type_ptr)
+{
+ (void) type_ptr;
+ throw std::runtime_error("Error : cannot assign type");
+}
+
+TypePtr Type::type(TypePtr type_ptr)
+{
+ (void)type_ptr;
+ throw std::runtime_error("Error : cannot assign type");
+}
+
+void Type::setSigned(bool _signed)
+{
+ (void)_signed;
+ throw std::runtime_error("Error : cannot set sign");
+}
+
+void Type::setExtern(bool _extern)
+{
+ (void)_extern;
+ throw std::runtime_error("Error : cannot set extern");
+}
+
+void Type::setStatic(bool _static)
+{
+ (void)_static;
+ throw std::runtime_error("Error : cannot set static");
+}
+
+void Type::setConst(bool _const)
+{
+ (void)_const;
+ throw std::runtime_error("Error : cannot set const");
+}
+
+void Type::setSize(int _size)
+{
+ (void)_size;
+ throw std::runtime_error("Error : cannot set size");
+}
+
// Pointer definition
-Pointer::Pointer(Type* pointer_type) : pointer_type_(pointer_type)
+Pointer::Pointer()
{}
std::string Pointer::getType() const
{
- return "pointer " + pointer_type_->getType();
+ return "pointer";
}
// Array definition
-Array::Array(Type* array_type, unsigned size)
- : array_type_(array_type), size_(size)
+Array::Array()
{}
std::string Array::getType() const
{
- return "array " + array_type_->getType();
+ return "array";
}
-// Void definition
+// TypeContainer definition
-Void::Void()
+TypeContainer::TypeContainer()
+ : type_(nullptr), size_(32), extern_(false), static_(false), const_(false), signed_(true)
{}
-std::string Void::getType() const
+std::string TypeContainer::getType() const
{
- return "void";
+ return type_->getType();
}
+TypePtr TypeContainer::type()
+{
+ return type_;
+}
+
+TypePtr TypeContainer::type(Type* type_ptr)
+{
+ TypePtr new_type_ptr(type_ptr);
+ type_ = new_type_ptr;
-// Int defintion
+ return type_;
+}
+
+TypePtr TypeContainer::type(TypePtr type_ptr)
+{
+ type_ = type_ptr;
+
+ return type_;
+}
+
+void TypeContainer::setSigned(bool _signed)
+{
+ signed_ = _signed;
+}
+
+void TypeContainer::setExtern(bool _extern)
+{
+ extern_ = _extern;
+}
+
+void TypeContainer::setStatic(bool _static)
+{
+ static_ = _static;
+}
+
+void TypeContainer::setConst(bool _const)
+{
+ const_ = _const;
+}
+
+void TypeContainer::setSize(int size)
+{
+ size_ = size;
+}
+
+
+// Int definition
Int::Int()
{}
@@ -64,6 +158,17 @@ std::string Int::getType() const
}
+// Void definition
+
+Void::Void()
+{}
+
+std::string Void::getType() const
+{
+ return "void";
+}
+
+
// Char definition
Char::Char()
@@ -73,3 +178,14 @@ std::string Char::getType() const
{
return "char";
}
+
+
+// Float definition
+
+Float::Float()
+{}
+
+std::string Float::getType() const
+{
+ return "float";
+}
diff --git a/c_compiler/test/in/fib.c b/c_compiler/test/in/fib.c
new file mode 100644
index 0000000..17a3b41
--- /dev/null
+++ b/c_compiler/test/in/fib.c
@@ -0,0 +1,20 @@
+int main()
+{
+ int n, first = 0, second = 1, next, c;
+
+ n = 10;
+
+ for ( c = 0 ; c < n ; c++ )
+ {
+ if ( c <= 1 )
+ next = c;
+ else
+ {
+ next = first + second;
+ first = second;
+ second = next;
+ }
+ }
+
+ return next;
+}
diff --git a/c_compiler/test/in/fib_recusive.c b/c_compiler/test/in/fib_recusive.c
new file mode 100644
index 0000000..55abe06
--- /dev/null
+++ b/c_compiler/test/in/fib_recusive.c
@@ -0,0 +1,24 @@
+int Fibonacci(int n)
+{
+ if ( n == 0 )
+ return 0;
+ else if ( n == 1 )
+ return 1;
+ else
+ return ( Fibonacci(n-1) + Fibonacci(n-2) );
+}
+
+int main()
+{
+ int n, i = 0, c, res = 0;
+
+ n = 10;
+
+ for ( c = 1 ; c <= n ; c++ )
+ {
+ res = Fibonacci(i);
+ i++;
+ }
+
+ return res;
+}
diff --git a/c_compiler/test/in/for.c b/c_compiler/test/in/for.c
index 5163ba5..1f6d104 100644
--- a/c_compiler/test/in/for.c
+++ b/c_compiler/test/in/for.c
@@ -3,11 +3,10 @@ int main()
int x, y, z;
y = 0;
- for(x = 0; x < 50; x = x+1) {
+ for(x = 0; x < 50; x++) {
y = y + 1;
}
- z = y + x - 5;
-
+ z = y + x - 6;
return z;
}