aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2017-03-20 13:11:19 +0000
committerYann Herklotz <ymherklotz@gmail.com>2017-03-20 13:11:19 +0000
commitaf8b76d0a83813b3cebac7468db4bd64e534c235 (patch)
treee387cec775526f4b0eaea5ab333baf0ae5afdb0b
parentb0caad48b1a2c90a03f5d130a50f3fdee1c097a5 (diff)
downloadCompiler-af8b76d0a83813b3cebac7468db4bd64e534c235.tar.gz
Compiler-af8b76d0a83813b3cebac7468db4bd64e534c235.zip
global vars work and changing to printf
-rw-r--r--Notes.org14
-rw-r--r--c_compiler/include/declaration.hpp2
-rw-r--r--c_compiler/include/expression.hpp14
-rw-r--r--c_compiler/src/compiler_main.cpp22
-rw-r--r--c_compiler/src/declaration.cpp40
-rw-r--r--c_compiler/src/expression.cpp172
-rw-r--r--c_compiler/src/function.cpp3
-rw-r--r--c_compiler/src/statement.cpp2
-rw-r--r--c_compiler/src/translation_unit.cpp2
-rw-r--r--c_compiler/test/in/global.c6
10 files changed, 200 insertions, 77 deletions
diff --git a/Notes.org b/Notes.org
index 509d913..a5e33b7 100644
--- a/Notes.org
+++ b/Notes.org
@@ -142,8 +142,18 @@
CLOCK: [2017-03-17 Fri 15:44]--[2017-03-17 Fri 16:00] => 0:16
Have to fix type assigment for declaration lists, need to make new pointers of the right type.
-**** TODO Load more that 4 bytes into a variable.
-**** TODO Fix expressions and temporary variables
+**** DONE Load more that 4 bytes into a variable.
+**** DONE Fix expressions and temporary variables
I have to store the temporary expression in normal registers.
+**** TODO Convert cout to printf
+
+ convert all cout to printf
+
+**** TODO Add global variables
+
+ Change code so that it also prints global variables. This should be done with
+ the globalAsm function.
+
+ I might have to change the print Asm and the global Asm function in the declarations.
diff --git a/c_compiler/include/declaration.hpp b/c_compiler/include/declaration.hpp
index ce4faa7..d09faec 100644
--- a/c_compiler/include/declaration.hpp
+++ b/c_compiler/include/declaration.hpp
@@ -27,6 +27,8 @@ public:
virtual void printXml() const;
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ VariableStackBindings localAsm(VariableStackBindings bindings, unsigned& label_count) const;
+
void linkDeclaration(Declaration* next_declaration);
void linkListDeclaration(Declaration* next_list_declaration);
diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp
index 313d678..1563211 100644
--- a/c_compiler/include/expression.hpp
+++ b/c_compiler/include/expression.hpp
@@ -22,6 +22,7 @@ private:
public:
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const = 0;
+ virtual int constantFold() const;
virtual void print() const;
virtual void printXml() const;
virtual void countArguments(unsigned& argument_count) const;
@@ -46,7 +47,7 @@ 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;
};
@@ -117,6 +118,7 @@ public:
AdditiveExpression(Expression* lhs, const std::string& _operator, Expression* rhs);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual int constantFold() const;
};
@@ -129,6 +131,7 @@ public:
MultiplicativeExpression(Expression* lhs, const std::string& _operator, Expression* rhs);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual int constantFold() const;
};
@@ -140,6 +143,7 @@ public:
ShiftExpression(Expression* lhs, const std::string& _operator, Expression* rhs);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual int constantFold() const;
};
@@ -151,6 +155,7 @@ public:
RelationalExpression(Expression* lhs, const std::string& _operator, Expression* rhs);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual int constantFold() const;
};
@@ -162,6 +167,7 @@ public:
EqualityExpression(Expression* lhs, const std::string& _operator, Expression* rhs);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual int constantFold() const;
};
@@ -171,6 +177,7 @@ public:
AndExpression(Expression* lhs, Expression* rhs);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual int constantFold() const;
};
@@ -180,6 +187,7 @@ public:
ExclusiveOrExpression(Expression* lhs, Expression* rhs);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual int constantFold() const;
};
@@ -189,6 +197,7 @@ public:
InclusiveOrExpression(Expression* lhs, Expression* rhs);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual int constantFold() const;
};
@@ -198,6 +207,7 @@ public:
LogicalAndExpression(Expression* lhs, Expression* rhs);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual int constantFold() const;
};
@@ -207,6 +217,7 @@ public:
LogicalOrExpression(Expression* lhs, Expression* rhs);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual int constantFold() const;
};
@@ -255,6 +266,7 @@ public:
Constant(const int32_t& constant);
virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const;
+ virtual int constantFold() const;
};
diff --git a/c_compiler/src/compiler_main.cpp b/c_compiler/src/compiler_main.cpp
index 15276dd..dcc9e09 100644
--- a/c_compiler/src/compiler_main.cpp
+++ b/c_compiler/src/compiler_main.cpp
@@ -1,19 +1,27 @@
#include "node.hpp"
#include "bindings.hpp"
-#include <iostream>
+#include <cstdio>
+#include <string>
Node* parseAST();
int main(int argc, char *argv[])
{
(void)argc, (void)argv;
- std::unique_ptr<Node> ast(parseAST());
-
- VariableStackBindings bindings;
- unsigned label_count = 0;
-
- ast->printAsm(bindings, label_count);
+
+ try {
+ std::unique_ptr<Node> ast(parseAST());
+ VariableStackBindings bindings;
+ unsigned label_count = 0;
+ ast->printAsm(bindings, label_count);
+
+ } catch(std::string error_msg) {
+ fprintf(stderr, "%s\n", error_msg.c_str());
+
+ } catch(...) {
+ fprintf(stderr, "Error : Exception thrown\n");
+ }
return 0;
}
diff --git a/c_compiler/src/declaration.cpp b/c_compiler/src/declaration.cpp
index b25ece4..9aa647a 100644
--- a/c_compiler/src/declaration.cpp
+++ b/c_compiler/src/declaration.cpp
@@ -3,7 +3,7 @@
#include "type.hpp"
#include "expression.hpp"
-#include <iostream>
+#include <cstdio>
// Declaration definition
@@ -18,7 +18,7 @@ void Declaration::print() const
next_declaration_->print();
if(id_ != "")
- std::cout << id_ << std::endl;
+ printf("%s\n", id_.c_str());
}
void Declaration::printXml() const
@@ -31,41 +31,43 @@ void Declaration::printXml() const
}
if(id_ != "")
- std::cout << "<Variable id=\""<< id_ << "\" />" << std::endl;
+ printf("<Variable id=\"%s\" />", id_.c_str());
}
VariableStackBindings Declaration::printAsm(VariableStackBindings bindings, unsigned& label_count) const
{
- // if(init == nullptr)
- // std::cout << "\t.comm\t" << id << ",4,4" << std::endl;
- // else {
- // std::cout << "\t.data\n\t.globl\t" << id << std::endl;
- // std::cout << id << ":\n\t.word\t" << std::endl;
- // }
+ (void)label_count;
+
+ 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());
- // return bindings;
+ bindings.insertBinding(id_, type_, -1);
+ return bindings;
+}
+VariableStackBindings Declaration::localAsm(VariableStackBindings bindings, unsigned& label_count) const
+{
if(next_declaration_ != nullptr)
- bindings = next_declaration_->printAsm(bindings, label_count);
+ bindings = next_declaration_->localAsm(bindings, label_count);
if(next_list_declaration_ != nullptr)
- bindings = next_list_declaration_->printAsm(bindings, label_count);
+ bindings = next_list_declaration_->localAsm(bindings, label_count);
if(id_ != "") {
if(initializer_ != nullptr)
initializer_->printAsm(bindings, label_count);
else
- std::cout << "\tmove\t$2,$0" << std::endl;
-
- int32_t stack_position = bindings.currentStackPosition();
-
- std::cout << "\tsw\t$2," << stack_position << "($fp)" << std::endl;
+ printf("\tmove\t$2,$0\n");
+ int stack_position = bindings.currentStackPosition();
+ printf("\tsw\t$2,%d($fp)\n", stack_position);
bindings.insertBinding(id_, type_, stack_position);
-
bindings.increaseStackPosition();
}
-
+
return bindings;
}
diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp
index 98ca018..bd64325 100644
--- a/c_compiler/src/expression.cpp
+++ b/c_compiler/src/expression.cpp
@@ -1,10 +1,17 @@
#include "expression.hpp"
+#include <cstdio>
+#include <exception>
#include <iostream>
#include <vector>
// Expression definition
+int Expression::constantFold() const
+{
+ throw std::runtime_error("Error : Cannot constant fold this expression");
+}
+
void Expression::print() const
{}
@@ -24,11 +31,8 @@ void Expression::expressionDepth(unsigned& depth_count) const
int Expression::postfixStackPosition(VariableStackBindings bindings) const
{
- // call this if the expression is not a postfix expression
- std::cerr << "Error : Can't call 'getPostfixStackPosition(VariableStackBindings " <<
- "bindings)' on this type of expression" << std::endl;
(void)bindings;
- return -1;
+ throw std::runtime_error("Error : Can't call postfixStackExpression() on this type");
}
void Expression::setPostfixExpression(Expression *postfix_expression)
@@ -61,6 +65,11 @@ OperationExpression::OperationExpression(Expression* lhs, Expression* rhs)
: lhs_(lhs), rhs_(rhs)
{}
+int OperationExpression::constantFold() const
+{
+ throw std::runtime_error("Error : Cannot constant fold expression\n");
+}
+
void OperationExpression::expressionDepth(unsigned& depth_count) const
{
unsigned lhs_depth_count = depth_count;
@@ -89,9 +98,8 @@ void OperationExpression::evaluateExpression(VariableStackBindings bindings, uns
// now I have them evaluated at two positions in the stack and can load both into registers
// $2 and $3
-
- std::cout << "\tlw\t$2," << lhs_stack_position << "($fp)" << std::endl;
- std::cout << "\tlw\t$3," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl;
+ printf("\tlw\t$2,%d($fp)\n\tlw\t$3,%d($fp)\n",
+ lhs_stack_position, bindings.currentExpressionStackPosition());
}
@@ -138,16 +146,15 @@ VariableStackBindings PostfixFunctionCall::printAsm(VariableStackBindings bindin
(*itr)->printAsm(bindings, label_count);
if(argument_counter < 4)
- std::cout << "\tmove\t$" << 4+argument_counter << ",$2\n";
+ printf("\tmove\t$%d,$2\n", 4+argument_counter);
else
- std::cout << "\tsw\t$2," << 4*argument_counter << "($fp)\n";
+ printf("\tsw\t$2,%d($fp)\n", 4*argument_counter);
argument_counter++;
}
- std::cout << "\tjal\t" << postfix_expression_->id() << "\n\tnop\n";
- std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n";
-
+ printf("\tjal\t%s\n\tnop\n\tsw\t$2,%d($fp)\n",
+ postfix_expression_->id().c_str(), bindings.currentExpressionStackPosition());
return bindings;
}
@@ -206,18 +213,25 @@ 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_ == "+")
- std::cout << "\tadd\t$2,$2,$3" << std::endl;
+ printf("\tadd\t$2,$2,$3\n");
else if(operator_ == "-")
- std::cout << "\tsub\t$2,$2,$3" << std::endl;
+ printf("\tsub\t$2,$2,$3\n");
else
- std::cerr << "Don't recognize symbol: '" << operator_ << "'" << std::endl;
+ throw std::runtime_error("Error : '"+operator_+"' not recognized");
// now I have to store it back into the original stack position
- std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl;
+ printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition());
return bindings;
}
+int AdditiveExpression::constantFold() const
+{
+ if(operator_ == "+")
+ return lhs_->constantFold()+rhs_->constantFold();
+ return lhs_->constantFold()-rhs_->constantFold();
+}
+
// Multiplicative Expression definition
@@ -231,23 +245,36 @@ VariableStackBindings MultiplicativeExpression::printAsm(VariableStackBindings b
evaluateExpression(bindings, label_count);
// then perform the right operation
- if(operator_ == "*")
- std::cout << "\tmul\t$2,$2,$3" << std::endl;
- else if(operator_ == "/" || operator_ == "%") {
- std::cout << "\tdiv\t$2,$3" << std::endl;
+ if(operator_ == "*") {
+ printf("\tmul\t$2,$2,$3\n");
+
+ } else if(operator_ == "/" || operator_ == "%") {
+ printf("\tdiv\t$2,$3\n");
if(operator_ == "/")
- std::cout << "\tmflo\t$2" << std::endl;
+ printf("\tmflo\t$2\n");
else
- std::cout << "\tmfhi\t$2" << std::endl;
- } else
- std::cerr << "Error : don't recognize symbol '" << operator_ << "'\n";
+ printf("\tmfhi\t$2\n");
+
+ } else {
+ throw std::runtime_error("Error : '"+operator_+"' not recognized");
+ }
+
// finally store result back into the stack position
- std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n";
+ printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition());
return bindings;
}
+int MultiplicativeExpression::constantFold() const
+{
+ if(operator_ == "*")
+ return lhs_->constantFold()*rhs_->constantFold();
+ else if(operator_ == "/")
+ return lhs_->constantFold()/rhs_->constantFold();
+ return lhs_->constantFold()%rhs_->constantFold();
+}
+
// ShiftExpression definition
@@ -272,6 +299,13 @@ VariableStackBindings ShiftExpression::printAsm(VariableStackBindings bindings,
return bindings;
}
+int ShiftExpression::constantFold() const
+{
+ if(operator_ == "<<")
+ return lhs_->constantFold()<<rhs_->constantFold();
+ return lhs_->constantFold()>>rhs_->constantFold();
+}
+
// RelationalExpression definition
@@ -303,6 +337,17 @@ VariableStackBindings RelationalExpression::printAsm(VariableStackBindings bindi
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();
+}
+
// EqualityExpression definition
@@ -332,6 +377,13 @@ VariableStackBindings EqualityExpression::printAsm(VariableStackBindings binding
return bindings;
}
+int EqualityExpression::constantFold() const
+{
+ if(operator_ == "==")
+ return lhs_->constantFold()==rhs_->constantFold();
+ return lhs_->constantFold()!=rhs_->constantFold();
+}
+
// AndExpression definition
@@ -350,6 +402,11 @@ VariableStackBindings AndExpression::printAsm(VariableStackBindings bindings, un
return bindings;
}
+int AndExpression::constantFold() const
+{
+ return lhs_->constantFold()&rhs_->constantFold();
+}
+
// ExclusiveOrExpression definition
@@ -360,14 +417,15 @@ ExclusiveOrExpression::ExclusiveOrExpression(Expression* lhs, Expression* rhs)
VariableStackBindings ExclusiveOrExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const
{
evaluateExpression(bindings, label_count);
-
- std::cout << "\txor\t$2,$2,$3\n";
-
- std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n";
-
+ printf("\txor\t$2,$2,$3\n\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition());
return bindings;
}
+int ExclusiveOrExpression::constantFold() const
+{
+ return lhs_->constantFold()^rhs_->constantFold();
+}
+
// InclusiveOrExpression definition
@@ -378,14 +436,15 @@ InclusiveOrExpression::InclusiveOrExpression(Expression* lhs, Expression* rhs)
VariableStackBindings InclusiveOrExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const
{
evaluateExpression(bindings, label_count);
-
- std::cout << "\tor\t$2,$2,$3\n";
-
- std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n";
-
+ printf("\tor\t$2,$2,$3\n\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition());
return bindings;
}
+int InclusiveOrExpression::constantFold() const
+{
+ return lhs_->constantFold()|rhs_->constantFold();
+}
+
// LogicalAndExpression definition
@@ -398,6 +457,11 @@ VariableStackBindings LogicalAndExpression::printAsm(VariableStackBindings bindi
return bindings;
}
+int LogicalAndExpression::constantFold() const
+{
+ return lhs_->constantFold()&&rhs_->constantFold();
+}
+
// LogicalOrExpression definition
@@ -410,6 +474,11 @@ VariableStackBindings LogicalOrExpression::printAsm(VariableStackBindings bindin
return bindings;
}
+int LogicalOrExpression::constantFold() const
+{
+ return lhs_->constantFold()&&rhs_->constantFold();
+}
+
// ConditionalExpression definition
@@ -447,10 +516,10 @@ VariableStackBindings AssignmentExpression::printAsm(VariableStackBindings bindi
rhs_->printAsm(bindings, label_count);
// now the result of the rhs will be in that stack position, so we can load it into $2
- std::cout << "\tlw\t$2," << expression_stack_position << "($fp)" << std::endl;
+ 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
- std::cout << "\tsw\t$2," << store_stack_position << "($fp)" << std::endl;
+ printf("\tsw\t$2,%d($fp)\n", store_stack_position);
return bindings;
}
@@ -464,13 +533,21 @@ Identifier::Identifier(const std::string& id)
VariableStackBindings Identifier::printAsm(VariableStackBindings bindings, unsigned& label_count) const
{
(void)label_count;
+
if(bindings.bindingExists(id_)) {
- std::cout << "\tlw\t$2," << bindings.stackPosition(id_) << "($fp)" << std::endl;
- } else
- std::cerr << "Can't find identifier '" << id_ << "' in current scope binding" << std::endl;
-
- std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl;
+ 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("\tlw\t$2,%d($fp)\n", bindings.stackPosition(id_));
+ }
+ } else{
+ throw std::runtime_error("Error : Can't find '"+id_+"' in current scope binding");
+ }
+
+ printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition());
return bindings;
}
@@ -480,7 +557,7 @@ int Identifier::postfixStackPosition(VariableStackBindings bindings) const
return bindings.stackPosition(id_);
}
- return -1;
+ throw std::runtime_error("Error : Variable '"+id_+"' not yet declared");
}
std::string Identifier::id() const
@@ -499,7 +576,12 @@ VariableStackBindings Constant::printAsm(VariableStackBindings bindings, unsigne
{
(void)label_count;
// constant only has to load to $2 because the other expression will take care of the rest
- std::cout << "\tli\t$2," << constant_ << std::endl;
- std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl;
+ printf("\tli\t$2,%d\n", constant_);
+ printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition());
return bindings;
}
+
+int Constant::constantFold() const
+{
+ return constant_;
+}
diff --git a/c_compiler/src/function.cpp b/c_compiler/src/function.cpp
index 35e02f4..c1f60cd 100644
--- a/c_compiler/src/function.cpp
+++ b/c_compiler/src/function.cpp
@@ -47,6 +47,7 @@ void Function::printXml() const
VariableStackBindings Function::printAsm(VariableStackBindings bindings, unsigned& label_count) const
{
+ VariableStackBindings original_bindings = bindings;
// Counting all the variables being declared in the function
unsigned variable_count = 0;
if(statement_ != nullptr)
@@ -90,7 +91,7 @@ VariableStackBindings Function::printAsm(VariableStackBindings bindings, unsigne
<< memory_needed-8 << "($sp)\n\taddiu\t$sp,$sp," << memory_needed
<< "\n\tjr\t$31\n\tnop\n";
- return bindings;
+ return original_bindings;
}
void Function::printParameterAsm(VariableStackBindings& bindings, unsigned& stack_offset,
diff --git a/c_compiler/src/statement.cpp b/c_compiler/src/statement.cpp
index 13e779f..77d3854 100644
--- a/c_compiler/src/statement.cpp
+++ b/c_compiler/src/statement.cpp
@@ -59,7 +59,7 @@ VariableStackBindings CompoundStatement::printAsm(VariableStackBindings bindings
next_statement_->printAsm(bindings, label_count);
if(declaration_ != nullptr)
- bindings = declaration_->printAsm(bindings, label_count);
+ bindings = declaration_->localAsm(bindings, label_count);
if(statement_ != nullptr)
statement_->printAsm(bindings, label_count);
diff --git a/c_compiler/src/translation_unit.cpp b/c_compiler/src/translation_unit.cpp
index cb581d3..0c7815b 100644
--- a/c_compiler/src/translation_unit.cpp
+++ b/c_compiler/src/translation_unit.cpp
@@ -28,7 +28,7 @@ void TranslationUnit::printXml() const
VariableStackBindings TranslationUnit::printAsm(VariableStackBindings bindings, unsigned& label_count) const
{
for(auto& node : translation_unit_) {
- node->printAsm(bindings, label_count);
+ bindings = node->printAsm(bindings, label_count);
}
return bindings;
diff --git a/c_compiler/test/in/global.c b/c_compiler/test/in/global.c
new file mode 100644
index 0000000..da59c9f
--- /dev/null
+++ b/c_compiler/test/in/global.c
@@ -0,0 +1,6 @@
+int x = 3 + 4;
+
+int main()
+{
+ return x;
+}