aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2017-03-24 17:32:19 +0000
committerYann Herklotz <ymherklotz@gmail.com>2017-03-24 17:32:19 +0000
commite539805d39de73e25eeaa48a48730255c4ae695f (patch)
tree9a15bcc1f5c03214085ebf90d51e999456174074
parent3a8cbbd0c0b9b8bc80d4346d98a305671f0869a9 (diff)
downloadCompiler-e539805d39de73e25eeaa48a48730255c4ae695f.tar.gz
Compiler-e539805d39de73e25eeaa48a48730255c4ae695f.zip
Pointers working
-rw-r--r--c_compiler/include/expression.hpp48
-rw-r--r--c_compiler/src/c_parser.y34
-rw-r--r--c_compiler/src/compiler_main.cpp4
-rw-r--r--c_compiler/src/expression.cpp86
-rw-r--r--qemu_test_POINTER0.elf_20170324-163137_8747.corebin0 -> 8556544 bytes
-rw-r--r--test_deliverable/testcases/test_NESTEQU.c7
-rw-r--r--test_deliverable/testcases/test_NESTEQU_driver.c6
-rw-r--r--test_deliverable/testcases/test_POINTER0.c5
-rw-r--r--test_deliverable/testcases/test_POINTER0_driver.c6
-rw-r--r--test_deliverable/testcases/test_POINTER1.c7
-rw-r--r--test_deliverable/testcases/test_POINTER1_driver.c6
-rw-r--r--test_deliverable/testcases/test_POINTER2.c4
-rw-r--r--test_deliverable/testcases/test_POINTER2_driver.c8
13 files changed, 145 insertions, 76 deletions
diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp
index 57c24ef..244b2a8 100644
--- a/c_compiler/include/expression.hpp
+++ b/c_compiler/include/expression.hpp
@@ -10,10 +10,8 @@
#include <string>
class Expression;
-
typedef std::shared_ptr<Expression> ExpressionPtr;
-
class Expression : public Node
{
private:
@@ -26,16 +24,13 @@ public:
virtual void print() const;
virtual void printXml() const;
virtual void countArguments(unsigned &argument_count) const;
- virtual void expressionDepth(unsigned &depth_count) const;
- virtual int postfixStackPosition(VariableStackBindings bindings) const;
- virtual void setPostfixExpression(Expression *postfix_expression);
+ virtual void expressionDepth(unsigned &depth_count) const;
virtual std::string id() const;
void linkExpression(Expression* next_expression);
ExpressionPtr nextExpression() const;
};
-
class OperationExpression : public Expression
{
protected:
@@ -56,8 +51,15 @@ public:
void evaluateExpression(VariableStackBindings bindings, unsigned &label_count) const;
};
+class UnaryExpression : public Expression
+{
+public:
+ virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const = 0;
-class PostfixArrayElement : public Expression
+ virtual void stackPosition(VariableStackBindings bindings) const;
+};
+
+class PostfixArrayElement : public UnaryExpression
{
public:
PostfixArrayElement();
@@ -65,8 +67,7 @@ public:
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
};
-
-class PostfixFunctionCall : public Expression
+class PostfixFunctionCall : public UnaryExpression
{
private:
ExpressionPtr postfix_expression_;
@@ -81,7 +82,7 @@ public:
void setPostfixExpression(Expression *postfix_expression);
};
-class PostfixPostIncDecExpression : public Expression
+class PostfixPostIncDecExpression : public UnaryExpression
{
private:
std::string operator_;
@@ -94,8 +95,7 @@ public:
};
-
-class UnaryPreIncDecExpression : public Expression
+class UnaryPreIncDecExpression : public UnaryExpression
{
private:
std::string operator_;
@@ -107,7 +107,7 @@ public:
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
};
-class OperatorUnaryExpression : public Expression
+class OperatorUnaryExpression : public UnaryExpression
{
private:
std::string operator_;
@@ -117,6 +117,7 @@ public:
OperatorUnaryExpression(const std::string &_operator, Expression *cast_expression);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
+ virtual void stackPosition(VariableStackBindings bindings) const;
};
@@ -132,7 +133,6 @@ public:
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
};
-
class AdditiveExpression : public OperationExpression
{
private:
@@ -145,7 +145,6 @@ public:
virtual int constantFold() const;
};
-
class MultiplicativeExpression : public OperationExpression
{
private:
@@ -158,7 +157,6 @@ public:
virtual int constantFold() const;
};
-
class ShiftExpression : public OperationExpression
{
private:
@@ -170,7 +168,6 @@ public:
virtual int constantFold() const;
};
-
class RelationalExpression : public OperationExpression
{
private:
@@ -182,7 +179,6 @@ public:
virtual int constantFold() const;
};
-
class EqualityExpression : public OperationExpression
{
private:
@@ -194,7 +190,6 @@ public:
virtual int constantFold() const;
};
-
class AndExpression : public OperationExpression
{
public:
@@ -204,7 +199,6 @@ public:
virtual int constantFold() const;
};
-
class ExclusiveOrExpression : public OperationExpression
{
public:
@@ -214,7 +208,6 @@ public:
virtual int constantFold() const;
};
-
class InclusiveOrExpression : public OperationExpression
{
public:
@@ -224,7 +217,6 @@ public:
virtual int constantFold() const;
};
-
class LogicalAndExpression : public OperationExpression
{
public:
@@ -234,7 +226,6 @@ public:
virtual int constantFold() const;
};
-
class LogicalOrExpression : public OperationExpression
{
public:
@@ -244,7 +235,6 @@ public:
virtual int constantFold() const;
};
-
class ConditionalExpression : public Expression
{
private:
@@ -259,7 +249,6 @@ public:
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
};
-
class AssignmentExpression : public OperationExpression
{
public:
@@ -269,8 +258,7 @@ public:
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
};
-
-class Identifier : public Expression
+class Identifier : public UnaryExpression
{
private:
std::string id_;
@@ -278,12 +266,11 @@ public:
Identifier(const std::string &id);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const;
- virtual int postfixStackPosition(VariableStackBindings bindings) const;
+ virtual void stackPosition(VariableStackBindings bindings) const;
virtual std::string id() const;
};
-
-class Constant : public Expression
+class Constant : public UnaryExpression
{
private:
int32_t constant_;
@@ -294,5 +281,4 @@ public:
virtual int constantFold() const;
};
-
#endif
diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y
index 1bdfe12..c56b4b6 100644
--- a/c_compiler/src/c_parser.y
+++ b/c_compiler/src/c_parser.y
@@ -109,8 +109,8 @@ ParameterList:
| ParameterList T_CMA Parameter { $3->linkDeclaration($$); $$ = $3; }
;
-Parameter: DeclarationSpecifierList T_IDENTIFIER { $$ = new Declaration(*$2); delete $2; delete $1; }
- | DeclarationSpecifierList {$$ = new Declaration(""); }
+Parameter: DeclarationSpecifierList Declarator { $$ = new Declaration($2->getId()); delete $1; }
+ | DeclarationSpecifierList {$$ = new Declaration(""); }
;
// Declaration
@@ -179,24 +179,24 @@ InitDeclarator: Declarator { $$ = $1; }
;
Declarator: DirectDeclarator { $$ = $1; }
-| Pointer DirectDeclarator { $$ = $2; std::shared_ptr<Type> tmp($1); $$->setType(tmp); }
+ | Pointer DirectDeclarator { $$ = $2; std::shared_ptr<Type> tmp($1); $$->setType(tmp); }
;
Pointer:
-T_MULT { $$ = new Pointer(); delete $1; }
-| T_MULT Pointer { $$ = $2; delete $1; }
-| T_MULT TypeQualifierList Pointer { $$ = $3; delete $1; delete $2; }
-;
+ T_MULT { $$ = new Pointer(); delete $1; }
+ | T_MULT Pointer { $$ = $2; delete $1; }
+ | T_MULT TypeQualifierList Pointer { $$ = $3; delete $1; delete $2; }
+ ;
TypeQualifierList:
-TypeQualifier { $$ = $1; }
-| TypeQualifierList TypeQualifier { $$ = $2; delete $1; }
-;
+ TypeQualifier { $$ = $1; }
+ | TypeQualifierList TypeQualifier { $$ = $2; delete $1; }
+ ;
TypeQualifier:
-T_CONST { $$ = new std::string("const"); }
-| T_VOLATILE { $$ = new std::string("volatile"); }
-;
+ T_CONST { $$ = new std::string("const"); }
+ | T_VOLATILE { $$ = new std::string("volatile"); }
+ ;
DirectDeclarator:
T_IDENTIFIER { $$ = new Declaration(*$1); delete $1; }
@@ -417,7 +417,13 @@ UnaryOperator: T_AND { $$ = $1; }
PostfixExpression:
PrimaryExpression { $$ = $1; }
| PostfixExpression T_LSB Expression T_RSB { $$ = new PostfixArrayElement(); }
- | PostfixExpression T_LRB PostfixExpression2 { $$ = $3; $$->setPostfixExpression($1); }
+ | PostfixExpression T_LRB PostfixExpression2
+ {
+ $$ = $3;
+ PostfixFunctionCall *tmp = dynamic_cast<PostfixFunctionCall *>($$);
+ if(tmp != nullptr)
+ tmp->setPostfixExpression($1);
+ }
| PostfixExpression T_DOT T_IDENTIFIER { $$ = $1; }
| PostfixExpression T_ARROW T_IDENTIFIER { $$ = $1; }
| PostfixExpression T_INCDEC
diff --git a/c_compiler/src/compiler_main.cpp b/c_compiler/src/compiler_main.cpp
index e9a12b9..4ac641c 100644
--- a/c_compiler/src/compiler_main.cpp
+++ b/c_compiler/src/compiler_main.cpp
@@ -15,9 +15,9 @@ int main(int, char**)
unsigned label_count = 0;
ast->printAsm(bindings, label_count);
}
- catch(std::string error_msg)
+ catch(const std::exception& e)
{
- fprintf(stderr, "%s\n", error_msg.c_str());
+ fprintf(stderr, "%s\n", e.what());
}
catch(...)
{
diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp
index b07a31e..af2687d 100644
--- a/c_compiler/src/expression.cpp
+++ b/c_compiler/src/expression.cpp
@@ -12,7 +12,12 @@ int Expression::constantFold() const
}
void Expression::print() const
-{}
+{
+ if(next_expression_ != nullptr)
+ next_expression_->print();
+
+ printf("Expression\n");
+}
void Expression::printXml() const
{}
@@ -26,18 +31,6 @@ void Expression::countArguments(unsigned &argument_count) const
void Expression::expressionDepth(unsigned &) const
{}
-int Expression::postfixStackPosition(VariableStackBindings bindings) const
-{
- (void)bindings;
- throw std::runtime_error("Error : Can't call postfixStackExpression() on this type");
-}
-
-void Expression::setPostfixExpression(Expression *postfix_expression)
-{
- // do nothing if expression isn't a postfix expression
- (void)postfix_expression;
-}
-
std::string Expression::id() const
{
// by default return empty id, which cannot be valid.
@@ -68,7 +61,7 @@ OperationExpression::OperationExpression(ExpressionPtr lhs, Expression *rhs)
int OperationExpression::constantFold() const
{
- throw std::runtime_error("Error : Cannot constant fold expression\n");
+ throw std::runtime_error("Error : Cannot constant fold expression");
}
void OperationExpression::expressionDepth(unsigned &depth_count) const
@@ -113,6 +106,15 @@ void OperationExpression::evaluateExpression(VariableStackBindings bindings, uns
lhs_stack_position, bindings.currentExpressionStackPosition());
}
+
+// Unary expression definition
+
+void UnaryExpression::stackPosition(VariableStackBindings) const
+{
+ throw std::runtime_error("Error : Cannot get stack position of expression");
+}
+
+
// PostfixArrayElement
PostfixArrayElement::PostfixArrayElement()
@@ -189,14 +191,19 @@ VariableStackBindings PostfixPostIncDecExpression::printAsm(VariableStackBinding
{
postfix_expression_->printAsm(bindings, label_count);
if(operator_ == "++")
- printf("\taddi\t$3,$2,1\n");
+ printf("\taddiu\t$3,$2,1\n");
else if(operator_ == "--")
- printf("\tsubi\t$3,$2,1\n");
+ printf("\tsubiu\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));
+ std::shared_ptr<UnaryExpression> unary_expression;
+ unary_expression = std::static_pointer_cast<UnaryExpression>(postfix_expression_);
+
+ printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition());
+ unary_expression->stackPosition(bindings);
+ printf("\tsw\t$3,0($t0)\n");
+
return bindings;
}
@@ -216,9 +223,13 @@ VariableStackBindings UnaryPreIncDecExpression::printAsm(VariableStackBindings b
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));
+
+ std::shared_ptr<UnaryExpression> unary_expression;
+ unary_expression = std::static_pointer_cast<UnaryExpression>(unary_expression_);
+
+ printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition());
+ unary_expression->stackPosition(bindings);
+ printf("\tsw\t$2,0($t0)\n");
return bindings;
}
@@ -242,7 +253,10 @@ VariableStackBindings OperatorUnaryExpression::printAsm(VariableStackBindings bi
}
else if(operator_ == "&")
{
- printf("\taddiu\t$2,$fp,%d\n", cast_expression_->postfixStackPosition(bindings));
+ std::shared_ptr<UnaryExpression> unary_expression;
+ unary_expression = std::static_pointer_cast<UnaryExpression>(cast_expression_);
+ unary_expression->stackPosition(bindings);
+ printf("\tmove\t$2,$t0\n");
}
else if(operator_ == "-")
{
@@ -258,6 +272,17 @@ VariableStackBindings OperatorUnaryExpression::printAsm(VariableStackBindings bi
return bindings;
}
+void OperatorUnaryExpression::stackPosition(VariableStackBindings bindings) const
+{
+ if(operator_ == "*")
+ {
+ std::shared_ptr<UnaryExpression> unary_expression;
+ unary_expression = std::static_pointer_cast<UnaryExpression>(cast_expression_);
+ unary_expression->stackPosition(bindings);
+ printf("\tlw\t$t0,0($t0)\n");
+ }
+}
+
// CastExpression definition
@@ -284,9 +309,9 @@ VariableStackBindings AdditiveExpression::printAsm(VariableStackBindings binding
// TODO currently using signed and sub because I only have signed numbers implemented
// must update this as I add more types
if(operator_ == "+")
- printf("\tadd\t$2,$2,$3\n");
+ printf("\taddu\t$2,$2,$3\n");
else if(operator_ == "-")
- printf("\tsub\t$2,$2,$3\n");
+ printf("\tsubu\t$2,$2,$3\n");
else
throw std::runtime_error("Error : '"+operator_+"' not recognized");
@@ -615,7 +640,8 @@ VariableStackBindings AssignmentExpression::printAsm(VariableStackBindings bindi
// TODO add stack and store results in there, also for addition and multiplication.
// get the current location of lhs in the stack so that I can store result there
- int store_stack_position = lhs_->postfixStackPosition(bindings);
+ std::shared_ptr<UnaryExpression> lhs_postfix;
+ lhs_postfix = std::static_pointer_cast<UnaryExpression>(lhs_);
// get the current available stack position
int expression_stack_position = bindings.currentExpressionStackPosition();
@@ -628,7 +654,8 @@ VariableStackBindings AssignmentExpression::printAsm(VariableStackBindings bindi
printf("\tlw\t$2,%d($fp)\n", expression_stack_position);
// we are assigning so we don't have to evaluate the lhs as it will be overwritten anyways
- printf("\tsw\t$2,%d($fp)\n", store_stack_position);
+ lhs_postfix->stackPosition(bindings);
+ printf("\tsw\t$2,0($t0)\n");
return bindings;
}
@@ -664,14 +691,15 @@ VariableStackBindings Identifier::printAsm(VariableStackBindings bindings, unsig
return bindings;
}
-int Identifier::postfixStackPosition(VariableStackBindings bindings) const
+void Identifier::stackPosition(VariableStackBindings bindings) const
{
if(bindings.bindingExists(id_))
{
- return bindings.stackPosition(id_);
+ printf("\taddiu\t$t0,$fp,%d\n", bindings.stackPosition(id_));
+ return;
}
- throw std::runtime_error("Error : Variable '"+id_+"' not yet declared");
+ throw std::runtime_error("Error : '"+id_+"' not yet declared");
}
std::string Identifier::id() const
diff --git a/qemu_test_POINTER0.elf_20170324-163137_8747.core b/qemu_test_POINTER0.elf_20170324-163137_8747.core
new file mode 100644
index 0000000..8e2096d
--- /dev/null
+++ b/qemu_test_POINTER0.elf_20170324-163137_8747.core
Binary files differ
diff --git a/test_deliverable/testcases/test_NESTEQU.c b/test_deliverable/testcases/test_NESTEQU.c
new file mode 100644
index 0000000..698784f
--- /dev/null
+++ b/test_deliverable/testcases/test_NESTEQU.c
@@ -0,0 +1,7 @@
+int nestequ(int a)
+{
+ int b = 4;
+ int c;
+ c = b = a;
+ return b;
+}
diff --git a/test_deliverable/testcases/test_NESTEQU_driver.c b/test_deliverable/testcases/test_NESTEQU_driver.c
new file mode 100644
index 0000000..02f31a5
--- /dev/null
+++ b/test_deliverable/testcases/test_NESTEQU_driver.c
@@ -0,0 +1,6 @@
+int nestequ(int);
+
+int main()
+{
+ return !( 3091 == nestequ(3091) );
+}
diff --git a/test_deliverable/testcases/test_POINTER0.c b/test_deliverable/testcases/test_POINTER0.c
new file mode 100644
index 0000000..d0110e3
--- /dev/null
+++ b/test_deliverable/testcases/test_POINTER0.c
@@ -0,0 +1,5 @@
+int *pointer(int a)
+{
+ int *b = &a;
+ return b;
+}
diff --git a/test_deliverable/testcases/test_POINTER0_driver.c b/test_deliverable/testcases/test_POINTER0_driver.c
new file mode 100644
index 0000000..3d7c7aa
--- /dev/null
+++ b/test_deliverable/testcases/test_POINTER0_driver.c
@@ -0,0 +1,6 @@
+int *pointer(int);
+
+int main()
+{
+ return !( 67 == *pointer(67) );
+}
diff --git a/test_deliverable/testcases/test_POINTER1.c b/test_deliverable/testcases/test_POINTER1.c
new file mode 100644
index 0000000..88d6df2
--- /dev/null
+++ b/test_deliverable/testcases/test_POINTER1.c
@@ -0,0 +1,7 @@
+int pointer1(int a)
+{
+ int *b = &a;
+
+ a += *b;
+ return a;
+}
diff --git a/test_deliverable/testcases/test_POINTER1_driver.c b/test_deliverable/testcases/test_POINTER1_driver.c
new file mode 100644
index 0000000..a66a63e
--- /dev/null
+++ b/test_deliverable/testcases/test_POINTER1_driver.c
@@ -0,0 +1,6 @@
+int pointer1(int);
+
+int main()
+{
+ return !( 392 == pointer1(392/2) );
+}
diff --git a/test_deliverable/testcases/test_POINTER2.c b/test_deliverable/testcases/test_POINTER2.c
new file mode 100644
index 0000000..a22d524
--- /dev/null
+++ b/test_deliverable/testcases/test_POINTER2.c
@@ -0,0 +1,4 @@
+void pointer2(int *a)
+{
+ *a = 238;
+}
diff --git a/test_deliverable/testcases/test_POINTER2_driver.c b/test_deliverable/testcases/test_POINTER2_driver.c
new file mode 100644
index 0000000..81e298a
--- /dev/null
+++ b/test_deliverable/testcases/test_POINTER2_driver.c
@@ -0,0 +1,8 @@
+void pointer2(int *);
+
+int main()
+{
+ int a = 83;
+ pointer2(&a);
+ return !( 238 == a );
+}