aboutsummaryrefslogtreecommitdiffstats
path: root/c_compiler/src
diff options
context:
space:
mode:
Diffstat (limited to 'c_compiler/src')
-rw-r--r--c_compiler/src/c_lexer.flex96
-rw-r--r--c_compiler/src/c_parser.y354
-rw-r--r--c_compiler/src/compiler_main.cpp15
-rw-r--r--c_compiler/src/declaration.cpp75
-rw-r--r--c_compiler/src/expression.cpp34
-rw-r--r--c_compiler/src/function.cpp72
-rw-r--r--c_compiler/src/statement.cpp205
-rw-r--r--c_compiler/src/translation_unit.cpp37
-rw-r--r--c_compiler/src/type.cpp70
9 files changed, 958 insertions, 0 deletions
diff --git a/c_compiler/src/c_lexer.flex b/c_compiler/src/c_lexer.flex
new file mode 100644
index 0000000..b225522
--- /dev/null
+++ b/c_compiler/src/c_lexer.flex
@@ -0,0 +1,96 @@
+%option noyywrap
+
+%{
+
+#include "c_parser.tab.hpp"
+
+%}
+
+IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
+
+ASSIGNMENT_OPERATOR (([<>][<>]|[*\/%+\-&^|])[=]|[=])
+
+INTEGERSUFFIX ([uU][lL]|[lL][uU]|[uUlL])
+
+DECIMALCONSTANT ([1-9][0-9]*)
+OCTALCONSTANT ([0][0-7]*)
+HEXCONSTANT ([0][xX][0-9A-Fa-f]+)
+
+CHARCONSTANT ('(([\\]['])|([^']))+')
+
+STRINGLITERAL ["](([\\]["])|([^"]))*["]
+
+WHITESPACE [ \t\r\n]+
+
+PREPROC [#][ ][0-9]+[ ]{STRINGLITERAL}[ 0-9]*
+
+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; }
+
+
+[;] { return T_SC; }
+[,] { return T_CMA; }
+[(] { return T_LRB; }
+[)] { return T_RRB; }
+[{] { return T_LCB; }
+[}] { return T_RCB; }
+[[] { return T_LSB; }
+[]] { return T_RSB; }
+[?] { return T_QU; }
+[:] { return T_COL; }
+[|][|] { return T_LOG_OR; }
+[&][&] { return T_LOG_AND; }
+[|] { return T_OR; }
+[\^] { return T_XOR; }
+[&] { return T_AND; }
+[=][=] { return T_EQUALITY_OP; }
+[!][=] { return T_EQUALITY_OP; }
+([<>][=])|[<>] { return T_REL_OP; }
+[<>][<>] { return T_SHIFT_OP; }
+[*] { return T_MULT; }
+[\/] { return T_DIV; }
+[%] { return T_REM; }
+[~] { return T_TILDE; }
+[!] { return T_NOT; }
+[.] { return T_DOT; }
+[-][>] { return T_ARROW; }
+[+-][+-] { return T_INCDEC; }
+[+-] { return T_ADDSUB_OP; }
+[=] { yylval.string = new std::string(yytext); return T_EQ; }
+
+{ASSIGNMENT_OPERATOR} { yylval.string = new std::string(yytext); return T_ASSIGN_OPER; }
+
+if { return T_IF; }
+else { return T_ELSE; }
+return { return T_RETURN; }
+while { return T_WHILE; }
+do { return T_DO; }
+for { return T_FOR; }
+sizeof { return T_SIZEOF; }
+
+{IDENTIFIER} { yylval.string = new std::string(yytext); return T_IDENTIFIER; }
+
+({HEXCONSTANT}|{OCTALCONSTANT}|{DECIMALCONSTANT}){INTEGERSUFFIX}? { yylval.number = strtol(yytext, NULL, 0); return T_INT_CONST; }
+
+{WHITESPACE} { ; }
+
+. { fprintf(stderr, "Invalid token\n"); exit(1); }
+
+%%
+
+void yyerror(char const *s) {
+ fprintf (stderr, "Parse error : %s\n", s);
+ exit(1);
+}
diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y
new file mode 100644
index 0000000..a42463c
--- /dev/null
+++ b/c_compiler/src/c_parser.y
@@ -0,0 +1,354 @@
+%code requires{
+
+#include "node.hpp"
+#include "translation_unit.hpp"
+#include "function.hpp"
+#include "declaration.hpp"
+#include "statement.hpp"
+#include "expression.hpp"
+#include "type.hpp"
+
+
+extern Node* g_root; // A way of getting the AST out
+
+//! This is to fix problems when generating C++
+// We are declaring the functions provided by Flex, so
+// that Bison generated code can call them.
+int yylex(void);
+void yyerror(const char *);
+
+}
+
+// Represents the value associated with any kind of
+// AST node.
+%union{
+ Node* node;
+ TranslationUnit* trans_unit;
+ Function* function;
+ Statement* statement;
+ Declaration* declaration;
+ Expression* expression;
+ Type* type;
+ double number;
+ std::string* string;
+}
+
+%token T_IDENTIFIER T_SC T_CMA T_LRB T_LCB T_RCB T_LSB T_RSB T_QU T_COL T_LOG_OR
+ T_LOG_AND T_OR T_XOR T_AND T_EQUALITY_OP T_REL_OP T_SHIFT_OP T_MULT T_DIV
+ T_REM T_TILDE T_NOT T_DOT T_ARROW T_INCDEC T_ADDSUB_OP T_ASSIGN_OPER T_EQ
+ T_SIZEOF T_INT_CONST T_IF T_WHILE T_DO T_FOR T_RETURN
+
+ T_VOID T_CHAR T_SCHAR T_UCHAR T_SSINT T_USINT T_LINT T_ULINT T_UINT T_SINT
+
+%nonassoc T_RRB
+%nonassoc T_ELSE
+
+
+%type <node> ExternalDeclaration
+
+%type <trans_unit> TranslationUnit
+
+%type <function> FunctionDefinition
+
+%type <statement> StatementList Statement CompoundStatement CompoundStatement_2
+ SelectionStatement
+ ExpressionStatement JumpStatement IterationStatement
+
+%type <declaration> ParameterList Parameter DeclarationList Declaration InitDeclaratorList
+ InitDeclarator
+ IdentifierList
+
+%type <expression> Expression AssignmentExpression ConditionalExpression LogicalOrExpression
+ LogicalAndExpression InclusiveOrExpression ExclusiveOrExpression
+ AndExpression EqualityExpression RelationalExpression ShiftExpression
+ AdditiveExpression MultiplicativeExpression CastExpression UnaryExpression
+ PostfixExpression PostfixExpression2 ArgumentExpressionList PrimaryExpression
+ Constant
+
+%type <type> DeclarationSpec
+
+%type <string> Declarator DirectDeclarator
+
+%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 MultDivRemOP UnaryOperator
+
+%start ROOT
+
+%%
+
+ROOT:
+ TranslationUnit { g_root = $1; }
+ ;
+
+// EXTERNAL DEFINITION
+
+TranslationUnit:
+ ExternalDeclaration { $$ = new TranslationUnit($1); }
+ | TranslationUnit ExternalDeclaration { $$->push($2); }
+ ;
+
+ExternalDeclaration:
+ Declaration { $$ = $1; }
+ | FunctionDefinition { $$ = $1; }
+ ;
+
+// FUNCTION DEFINITION
+
+FunctionDefinition:
+ DeclarationSpec T_IDENTIFIER T_LRB ParameterList T_RRB CompoundStatement { $$ = new Function(*$2, $4, $6); }
+ ;
+
+ParameterList:
+ %empty { $$ = new Declaration(); }
+ | Parameter { $$ = $1; }
+ | ParameterList T_CMA Parameter { $3->addDeclaration($$); $$ = $3;}
+ ;
+
+Parameter:
+ DeclarationSpec T_IDENTIFIER { $$ = new Declaration(*$2); }
+ ;
+
+// Declaration
+
+DeclarationList:
+ Declaration { $$ = $1; }
+ | DeclarationList Declaration { $2->addDeclaration($$); $$ = $2; }
+ ;
+
+Declaration:
+ DeclarationSpec InitDeclaratorList T_SC {
+ $$ = $2;
+ Declaration* tmp_decl = $2;
+
+ while(tmp_decl != nullptr) {
+ tmp_decl->setType($1);
+ tmp_decl = tmp_decl->getNextListItem();
+ }
+ }
+ ;
+
+DeclarationSpec:
+ T_VOID { $$ = new Void; }
+ | T_CHAR { $$ = new Char; }
+ | T_SCHAR { $$ = new Char; }
+ | T_UCHAR { $$ = new Char; }
+ | T_SSINT { $$ = new Int; }
+ | T_USINT { $$ = new Int; }
+ | T_LINT { $$ = new Int; }
+ | T_ULINT { $$ = new Int; }
+ | T_UINT { $$ = new Int; }
+ | T_SINT { $$ = new Int; }
+ ;
+
+InitDeclaratorList:
+ InitDeclarator { $$ = new Declaration(*$1); }
+ | InitDeclaratorList T_CMA InitDeclarator { $3->addList($$); $$ = $3; }
+ ;
+
+InitDeclarator:
+ Declarator { $$ = new Declaration(*$1); }
+ | Declarator T_EQ AssignmentExpression { $$ = new Declaration(*$1); }
+ ;
+
+Declarator:
+ DirectDeclarator { $$ = $1; }
+ | T_MULT DirectDeclarator { $$ = $2; }
+ ;
+
+DirectDeclarator:
+ T_IDENTIFIER { $$ = $1; }
+ | T_LRB Declarator T_RRB { $$ = $2; }
+ | DirectDeclarator T_LSB ConditionalExpression T_RSB { $$ = $1; }
+ | DirectDeclarator T_LSB T_RSB { $$ = $1; }
+ | DirectDeclarator T_LRB ParameterList T_RRB { $$ = $1; }
+ | DirectDeclarator T_LRB IdentifierList T_RRB { $$ = $1; }
+ ;
+
+IdentifierList:
+ T_IDENTIFIER { $$ = new Declaration(); }
+ | IdentifierList T_CMA T_IDENTIFIER { $$ = new Declaration(); }
+
+// Statement
+
+StatementList:
+ Statement { $$ = $1; }
+ | StatementList Statement { $2->addStatement($$); $$ = $2; }
+ ;
+
+Statement:
+ CompoundStatement { $$ = $1; }
+ | SelectionStatement { $$ = $1; }
+ | ExpressionStatement { $$ = $1; }
+ | JumpStatement { $$ = $1; }
+ | IterationStatement { $$ = $1; }
+ ;
+
+CompoundStatement:
+ T_LCB CompoundStatement_2 { $$ = $2; }
+ ;
+
+CompoundStatement_2:
+ T_RCB { $$ = new CompoundStatement; }
+ | DeclarationList T_RCB { $$ = new CompoundStatement($1); }
+ | DeclarationList StatementList T_RCB { $$ = new CompoundStatement($1, $2); }
+ | StatementList T_RCB { $$ = new CompoundStatement($1); }
+ ;
+
+SelectionStatement:
+ T_IF T_LRB Expression T_RRB Statement { $$ = new SelectionStatement($5); }
+ | T_IF T_LRB Expression T_RRB Statement T_ELSE Statement { $$ = new SelectionStatement($5, $7); }
+ ;
+
+ExpressionStatement:
+ T_SC { $$ = new ExpressionStatement(); }
+| Expression T_SC { $$ = new ExpressionStatement(); }
+ ;
+
+JumpStatement:
+ T_RETURN Expression T_SC { $$ = new JumpStatement($2); }
+ ;
+
+IterationStatement:
+ T_WHILE T_LRB Expression T_RRB Statement { $$ = $5; }
+ | T_DO Statement T_WHILE T_LRB Expression T_RRB T_SC { $$ = $2; }
+ | T_FOR T_LRB Expression T_SC Expression T_SC Expression T_RRB Statement { $$ = $9; }
+ ;
+
+// Expressions
+
+Expression:
+ AssignmentExpression { $$ = $1; }
+ ;
+
+AssignmentExpression:
+ ConditionalExpression { $$ = $1; }
+ | UnaryExpression ASSIGN_OPER AssignmentExpression { $$ = $1; }
+ ;
+
+ASSIGN_OPER:
+ T_ASSIGN_OPER { ; }
+ | T_EQ { ; }
+ ;
+
+ConditionalExpression:
+ LogicalOrExpression { $$ = $1; }
+ | LogicalOrExpression T_QU Expression T_COL ConditionalExpression { $$ = $1; }
+ ;
+
+LogicalOrExpression:
+ LogicalAndExpression { $$ = $1; }
+ | LogicalOrExpression T_LOG_OR LogicalAndExpression { $$ = $3; }
+ ;
+
+LogicalAndExpression:
+ InclusiveOrExpression { $$ = $1; }
+ | LogicalAndExpression T_LOG_AND InclusiveOrExpression { $$ = $3; }
+ ;
+
+InclusiveOrExpression:
+ ExclusiveOrExpression { $$ = $1; }
+ | InclusiveOrExpression T_OR ExclusiveOrExpression { $$ = $3; }
+ ;
+
+ExclusiveOrExpression:
+ AndExpression { $$ = $1; }
+ | ExclusiveOrExpression T_XOR AndExpression { $$ = $3; }
+ ;
+
+AndExpression:
+ EqualityExpression { $$ = $1; }
+ | AndExpression T_AND EqualityExpression { $$ = $3; }
+ ;
+
+EqualityExpression:
+ RelationalExpression { $$ = $1; }
+ | EqualityExpression T_EQUALITY_OP RelationalExpression { $$ = $3; }
+ ;
+
+RelationalExpression:
+ ShiftExpression { $$ = $1; }
+ | RelationalExpression T_REL_OP ShiftExpression { $$ = $3; }
+ ;
+
+ShiftExpression:
+ AdditiveExpression { $$ = $1; }
+ | ShiftExpression T_SHIFT_OP AdditiveExpression { $$ = $3; }
+ ;
+
+AdditiveExpression:
+ MultiplicativeExpression { $$ = $1; }
+ | AdditiveExpression T_ADDSUB_OP MultiplicativeExpression { $$ = $3; }
+ ;
+
+MultiplicativeExpression:
+ CastExpression { $$ = $1; }
+ | MultiplicativeExpression MultDivRemOP CastExpression { $$ = $3; }
+ ;
+
+MultDivRemOP:
+ T_MULT { $$ = $1; }
+ | T_DIV { $$ = $1; }
+ | T_REM { $$ = $1; }
+ ;
+
+CastExpression:
+ UnaryExpression { $$ = $1; }
+ | T_LRB DeclarationSpec T_RRB CastExpression { $$ = $4; }
+ ;
+
+UnaryExpression:
+ PostfixExpression { $$ = $1; }
+ | T_INCDEC UnaryExpression { $$ = $2; }
+ | UnaryOperator CastExpression { $$ = $2; }
+ | T_SIZEOF UnaryExpression { $$ = $2; }
+ | T_SIZEOF T_LRB DeclarationSpec T_RRB { $$ = new Constant(0); }
+ ;
+
+UnaryOperator:
+ T_AND { $$ = $1; }
+ | T_ADDSUB_OP { $$ = $1; }
+ | T_MULT { $$ = $1; }
+ | T_TILDE { $$ = $1; }
+ | T_NOT { $$ = $1; }
+ ;
+
+PostfixExpression:
+ PrimaryExpression { $$ = $1; }
+ | PostfixExpression T_LSB Expression T_RSB { $$ = $3; }
+ | PostfixExpression T_LRB PostfixExpression2 { $$ = $3; }
+ | PostfixExpression T_DOT T_IDENTIFIER { $$ = $1; }
+ | PostfixExpression T_ARROW T_IDENTIFIER { $$ = $1; }
+ | PostfixExpression T_INCDEC { $$ = $1; }
+ ;
+
+PostfixExpression2:
+ T_RRB { $$ = new Constant(0); }
+ | ArgumentExpressionList T_RRB { $$ = new Constant(0); }
+ ;
+
+ArgumentExpressionList:
+ AssignmentExpression { $$ = $1; }
+ | ArgumentExpressionList T_CMA AssignmentExpression { $$ = $1; }
+ ;
+
+PrimaryExpression:
+ T_IDENTIFIER { $$ = new Identifier(*$1); }
+ | Constant { $$ = $1; }
+ | T_LRB Expression T_RRB { $$ = $2; }
+ ;
+
+Constant:
+ T_INT_CONST { $$ = new Constant($1); }
+ ;
+
+%%
+
+Node* g_root; // Definition of variable (to match declaration earlier)
+
+Node* parseAST() {
+ g_root = 0;
+ yyparse();
+ return g_root;
+}
diff --git a/c_compiler/src/compiler_main.cpp b/c_compiler/src/compiler_main.cpp
new file mode 100644
index 0000000..a7d7eb3
--- /dev/null
+++ b/c_compiler/src/compiler_main.cpp
@@ -0,0 +1,15 @@
+#include "ast.hpp"
+
+#include <iostream>
+
+int main(int argc, char *argv[])
+{
+ Node* ast = parseAST();
+
+ VariableStackBindings bindings;
+ int32_t var_count;
+
+ ast->printasm(bindings, var_count);
+
+ return 0;
+}
diff --git a/c_compiler/src/declaration.cpp b/c_compiler/src/declaration.cpp
new file mode 100644
index 0000000..0f125b0
--- /dev/null
+++ b/c_compiler/src/declaration.cpp
@@ -0,0 +1,75 @@
+#include "ast.hpp"
+
+
+// Declaration definition
+
+Declaration::Declaration(const std::string& _id)
+ : id(_id)
+{}
+
+void Declaration::print() const
+{
+ if(next_decl != nullptr)
+ next_decl->print();
+
+ if(id != "")
+ std::cout << id << std::endl;
+}
+
+void Declaration::printxml() const
+{
+ if(next_decl != nullptr)
+ next_decl->printxml();
+
+ if(list_next_decl != nullptr) {
+ list_next_decl->printxml();
+ }
+
+ if(id != "")
+ std::cout << "<Variable id=\""<< id << "\" />" << std::endl;
+}
+
+void Declaration::printasm(VariableStackBindings bindings, int32_t& var_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 Declaration::addDeclaration(Declaration* _next_decl)
+{
+ next_decl = _next_decl;
+}
+
+void Declaration::addList(Declaration* _next_decl)
+{
+ list_next_decl = _next_decl;
+}
+
+void Declaration::setType(Type* _type)
+{
+ type = _type;
+}
+
+Declaration* Declaration::getNext() const
+{
+ return next_decl;
+}
+
+Declaration* Declaration::getNextListItem() const
+{
+ return list_next_decl;
+}
+
+std::string Declaration::getId() const
+{
+ return id;
+}
+
+std::string Declaration::getType() const
+{
+ return type->getType();
+}
diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp
new file mode 100644
index 0000000..11fa66e
--- /dev/null
+++ b/c_compiler/src/expression.cpp
@@ -0,0 +1,34 @@
+#include "expression.hpp"
+
+#include <iostream>
+
+// Expression definition
+
+void Expression::print() const
+{}
+
+void Expression::printxml() const
+{}
+
+
+// Identifier definition
+
+Identifier::Identifier(const std::string& id)
+ : m_id(id)
+{}
+
+void Identifier::printasm(VariableStackBindings bindings) const
+{}
+
+
+// Constant definition
+
+Constant::Constant(const int32_t& constant)
+ : m_constant(constant)
+{}
+
+void Constant::printasm(VariableStackBindings bindings) const
+{
+ std::cout << "\tli\t$2," << m_constant << std::endl;
+}
+
diff --git a/c_compiler/src/function.cpp b/c_compiler/src/function.cpp
new file mode 100644
index 0000000..090e070
--- /dev/null
+++ b/c_compiler/src/function.cpp
@@ -0,0 +1,72 @@
+#include "function.hpp"
+#include "statement.hpp"
+#include "declaration.hpp"
+
+#include <iostream>
+#include <vector>
+
+
+// Function definition
+
+Function::Function(const std::string& _id, Declaration* _parameter_list, Statement* _statement)
+ : id(_id), parameter_list(_parameter_list), statement(_statement)
+{}
+
+void Function::print() const
+{
+ std::cout << id << std::endl;
+
+ if(parameter_list != nullptr)
+ parameter_list->print();
+
+ if(statement != nullptr)
+ statement->print();
+}
+
+void Function::printxml() const
+{
+ std::cout << "<Function id=\"" << id << "\">" << std::endl;
+
+ Declaration* parameter = parameter_list;
+ std::vector<std::string> parameter_vec;
+
+ while(parameter != nullptr) {
+ if(parameter->getId() != "")
+ 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;
+ }
+
+ if(statement != nullptr)
+ statement->printxml();
+
+ std::cout << "</Function>" << std::endl;
+}
+
+VariableStackBindings Function::printasm(VariableStackBindings bindings) const
+{
+ // Counting all the variables being declared in the function
+ int32_t count = 0;
+ if(statement != nullptr)
+ statement->count_variables(count);
+
+ // This includes the space for the old frame counter and (return address)?
+ int32_t memory_needed = 4*count+8;
+
+ std::cout << "\t.text\n\t.globl\t" << id << std::endl << id << ":\n\taddiu\t$sp,$sp,-"
+ << memory_needed << "\n\tsw\t$fp," << memory_needed-4 << "($sp)\n\tmove\t$fp,$sp"
+ << std::endl;
+
+ // TODO print asm for parameters
+
+ // Prints the asm for the compound statement in the function
+ statement->printasm(bindings);
+
+ std::cout << "\tmove\t$sp,$fp\n\tlw\t$fp," << memory_needed-4 << "($sp)\n\taddiu\t$sp,$sp,"
+ << memory_needed << "\n\tjr\t$31\n\tnop" << std::endl;
+}
diff --git a/c_compiler/src/statement.cpp b/c_compiler/src/statement.cpp
new file mode 100644
index 0000000..7b98631
--- /dev/null
+++ b/c_compiler/src/statement.cpp
@@ -0,0 +1,205 @@
+#include "statement.hpp"
+#include "declaration.hpp"
+#include "expression.hpp"
+
+#include <iostream>
+
+
+// General base Statement definition
+
+Statement::Statement(Statement* statement)
+ : next_statement(statement)
+{}
+
+void Statement::addStatement(Statement* _next)
+{
+ next_statement = _next;
+}
+
+
+// Compound Statement definition
+
+CompoundStatement::CompoundStatement(Declaration* decl, Statement* statement)
+ : Statement(), m_decl(decl), m_statement(statement)
+{}
+
+CompoundStatement::CompoundStatement(Statement* statement)
+ : m_statement(statement)
+{}
+
+void CompoundStatement::print() const
+{
+ if(m_decl != nullptr)
+ m_decl->print();
+
+ if(m_statement != nullptr)
+ m_statement->print();
+}
+
+void CompoundStatement::printxml() const
+{
+ if(next_statement != nullptr)
+ next_statement->printxml();
+
+ std::cout << "<Scope>" << std::endl;
+
+ if(m_decl != nullptr)
+ m_decl->printxml();
+
+ if(m_statement != nullptr)
+ m_statement->printxml();
+
+ std::cout << "</Scope>" << std::endl;
+}
+
+VariableStackBindings CompoundStatement::printasm(VariableStackBindings bindings, int32_t& var_count) const
+{
+ if(next_statement != nullptr)
+ next_statement->printasm(bindings, var_count);
+
+ // TODO printasm for the declaration
+
+ if(m_statement != nullptr)
+ m_statement->printasm(bindings, var_count);
+}
+
+void CompoundStatement::count_variables(int32_t& var_count) const
+{
+ Declaration* declaration = m_decl;
+
+ if(next_statement != nullptr)
+ next_statement->count_variables(var_count);
+
+ if(m_statement != nullptr)
+ m_statement->count_variables(var_count);
+
+ while(declaration != nullptr) {
+ Declaration* declaration_list = declaration->getNextListItem();
+
+ while(declaration_list != nullptr) {
+ var_count++;
+
+ declaration_list = declaration_list->getNextListItem();
+ }
+
+ var_count++;
+
+ declaration = declaration->getNext();
+ }
+}
+
+
+// Selection Statement definition
+
+SelectionStatement::SelectionStatement(Statement* _if, Statement* _else)
+ : Statement(), m_if(_if), m_else(_else) {}
+
+void SelectionStatement::print() const
+{
+ m_if->print();
+ m_else->print();
+}
+
+void SelectionStatement::printxml() const
+{
+ if(next_statement != nullptr)
+ next_statement->printxml();
+ if(m_if != nullptr)
+ m_if->printxml();
+ if(m_else != nullptr)
+ m_else->printxml();
+}
+
+VariableStackBindings SelectionStatement::printasm(VariableStackBindings bindings, int32_t& var_count) const
+{}
+
+void SelectionStatement::count_variables(int32_t& var_count) const
+{
+ if(next_statement != nullptr)
+ next_statement->count_variables(var_count);
+
+ if(m_if != nullptr)
+ m_if->count_variables(var_count);
+
+ if(m_else != nullptr)
+ m_else->count_variables(var_count);
+}
+
+
+// Expression Statement definition
+
+ExpressionStatement::ExpressionStatement(Expression* expr)
+ : Statement(), m_expr(expr)
+{}
+
+void ExpressionStatement::print() const
+{}
+
+void ExpressionStatement::printxml() const
+{}
+
+VariableStackBindings ExpressionStatement::printasm(VariableStackBindings bindings, int32_t& var_count) const
+{}
+
+void ExpressionStatement::count_variables(int32_t& var_count) const
+{
+ if(next_statement != nullptr)
+ next_statement->count_variables(var_count);
+}
+
+
+// Jump Statement definition
+
+JumpStatement::JumpStatement(Expression* expr)
+ : m_expr(expr)
+{}
+
+void JumpStatement::print() const
+{}
+
+void JumpStatement::printxml() const
+{
+ if(next_statement != nullptr)
+ next_statement->printxml();
+}
+
+VariableStackBindings JumpStatement::printasm(VariableStackBindings bindings, int32_t& var_count) const
+{
+ m_expr->printasm(bindings, var_count);
+}
+
+void JumpStatement::count_variables(int32_t& var_count) const
+{
+ if(next_statement != nullptr)
+ next_statement->count_variables(var_count);
+}
+
+
+// Iteration Statement definition
+
+IterationStatement::IterationStatement(Statement* statement)
+ : m_statement(statement)
+{}
+
+void IterationStatement::print() const
+{}
+
+void IterationStatement::printxml() const
+{
+ if(next_statement != nullptr)
+ next_statement->printxml();
+ if(m_statement != nullptr)
+ m_statement->printxml();
+}
+
+VariableStackBindings IterationStatement::printasm(VariableStackBindings bindings, int32_t& var_count) const
+{}
+
+void IterationStatement::count_variables(int32_t& var_count) const
+{
+ if(next_statement != nullptr)
+ next_statement->count_variables(var_count);
+
+ if(m_statement != nullptr)
+ m_statement->count_variables(var_count);
+}
diff --git a/c_compiler/src/translation_unit.cpp b/c_compiler/src/translation_unit.cpp
new file mode 100644
index 0000000..e85237b
--- /dev/null
+++ b/c_compiler/src/translation_unit.cpp
@@ -0,0 +1,37 @@
+#include "ast.hpp"
+
+
+// Translation Unit definition
+
+TranslationUnit::TranslationUnit(Node* decl)
+{
+ push(decl);
+}
+
+void TranslationUnit::print() const
+{
+ for(auto& node : translation_unit) {
+ node->print();
+ }
+}
+
+void TranslationUnit::printxml() const
+{
+ std::cout << "<?xml version=\"1.0\"?>\n<Program>" << std::endl;
+ for(auto& node : translation_unit) {
+ node->printxml();
+ }
+ std::cout << "</Program>" << std::endl;
+}
+
+void TranslationUnit::printasm(VariableStackBindings bindings, int32_t& var_count) const
+{
+ for(auto& node : translation_unit) {
+ node->printasm(bindings, var_count);
+ }
+}
+
+void TranslationUnit::push(Node* decl)
+{
+ translation_unit.push_back(decl);
+}
diff --git a/c_compiler/src/type.cpp b/c_compiler/src/type.cpp
new file mode 100644
index 0000000..13496e9
--- /dev/null
+++ b/c_compiler/src/type.cpp
@@ -0,0 +1,70 @@
+#include "ast.hpp"
+
+
+// Type definition
+
+void Type::print() const
+{
+ std::cout << getType() << " " << std::endl;
+}
+
+void Type::printxml() const
+{}
+
+void Type::printasm(VariableStackBindings bindings, int32_t& var_count) const
+{}
+
+
+// Pointer definition
+
+Pointer::Pointer(Type* _pointer_type) : pointer_type(_pointer_type)
+{}
+
+std::string Pointer::getType() const
+{
+ return "pointer " + pointer_type->getType();
+}
+
+
+// Array definition
+
+Array::Array(Type* _array_type, int32_t _size) : size(_size), array_type(_array_type)
+{}
+
+std::string Array::getType() const
+{
+ return "array " + array_type->getType();
+}
+
+
+// Void definition
+
+Void::Void()
+{}
+
+std::string Void::getType() const
+{
+ return "void";
+}
+
+
+// Int defintion
+
+Int::Int()
+{}
+
+std::string Int::getType() const
+{
+ return "int";
+}
+
+
+// Char definition
+
+Char::Char()
+{}
+
+std::string Char::getType() const
+{
+ return "char";
+}