diff options
-rw-r--r-- | c_compiler/include/ast.hpp | 3 | ||||
-rw-r--r-- | c_compiler/include/declaration.hpp | 2 | ||||
-rw-r--r-- | c_compiler/include/expression.hpp | 24 | ||||
-rw-r--r-- | c_compiler/include/initializer.hpp | 29 | ||||
-rw-r--r-- | c_compiler/src/c_parser.y | 28 | ||||
-rw-r--r-- | c_compiler/src/compiler_main.cpp | 2 | ||||
-rw-r--r-- | c_compiler/src/expression.cpp | 24 | ||||
-rw-r--r-- | c_compiler/src/function.cpp | 16 | ||||
-rw-r--r-- | c_compiler/src/initializer.cpp | 28 | ||||
-rw-r--r-- | c_compiler/src/statement.cpp | 15 | ||||
-rw-r--r-- | c_compiler/test/.gitignore | 2 | ||||
-rw-r--r-- | c_compiler/test/in/02.c | 4 | ||||
-rw-r--r-- | c_compiler/test/in/03.c | 5 | ||||
-rw-r--r-- | c_compiler/test/in/04.c | 9 | ||||
-rw-r--r-- | c_compiler/test/out/01.diff.txt | 0 | ||||
-rw-r--r-- | c_compiler/test/out/01.pretty.xml | 1 | ||||
-rw-r--r-- | c_compiler/test/out/01.stderr.txt | 1 | ||||
-rw-r--r-- | c_compiler/test/out/01.stdout.s | 0 | ||||
-rw-r--r-- | c_compiler/test/out/01.stdout.xml | 0 | ||||
-rwxr-xr-x | c_compiler/test/ref/01 | bin | 2929088 -> 0 bytes | |||
-rw-r--r-- | c_compiler/test/ref/01.s | 38 | ||||
-rw-r--r-- | makefile | 2 | ||||
-rwxr-xr-x | test_compiler.sh | 30 |
23 files changed, 124 insertions, 139 deletions
diff --git a/c_compiler/include/ast.hpp b/c_compiler/include/ast.hpp index cea7e82..4bcd523 100644 --- a/c_compiler/include/ast.hpp +++ b/c_compiler/include/ast.hpp @@ -12,9 +12,8 @@ struct VarLocation; typedef std::map<std::string, VarLocation> VariableStack; #include "node.hpp" -#include "expression.hpp" #include "type.hpp" -#include "initializer.hpp" +#include "expression.hpp" #include "declaration.hpp" #include "statement.hpp" #include "function.hpp" diff --git a/c_compiler/include/declaration.hpp b/c_compiler/include/declaration.hpp index c46aca2..7f862a5 100644 --- a/c_compiler/include/declaration.hpp +++ b/c_compiler/include/declaration.hpp @@ -9,7 +9,7 @@ class Declaration : public Node { protected: Type* type; std::string id; - Initializer* init; + Expression* init; Declaration* next_decl; Declaration* list_next_decl; diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp index 9e57fd4..71d993f 100644 --- a/c_compiler/include/expression.hpp +++ b/c_compiler/include/expression.hpp @@ -5,11 +5,31 @@ class Expression : public Node { public: - Expression(const Node* expr = nullptr); - + virtual void printasm() const = 0; + virtual void print() const; virtual void printxml() const; +}; + + +class Identifier : public Expression { +private: + std::string m_id; +public: + Identifier(const std::string& id); + virtual void printasm() const; }; + +class Constant : public Expression { +private: + int32_t m_constant; +public: + Constant(const int32_t& constant); + + virtual void printasm() const; +}; + + #endif diff --git a/c_compiler/include/initializer.hpp b/c_compiler/include/initializer.hpp deleted file mode 100644 index f7c0dab..0000000 --- a/c_compiler/include/initializer.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef INITIALIZER_HPP -#define INITIALIZER_HPP - -#include "ast.hpp" - - -class Initializer : public Node { -public: - Initializer(); - - virtual void print() const; - virtual void printxml() const; - virtual void printasm() const; -}; - - -class Integer : public Initializer { -public: - Integer(); -}; - - -class StringLiteral : public Initializer { -public: - StringLiteral(); -}; - - -#endif diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y index c643f10..5866c57 100644 --- a/c_compiler/src/c_parser.y +++ b/c_compiler/src/c_parser.y @@ -22,7 +22,6 @@ void yyerror(const char *); Declaration* declaration; Expression* expression; Type* type; - Initializer* initializer; double number; std::string* string; } @@ -57,13 +56,12 @@ void yyerror(const char *); AndExpression EqualityExpression RelationalExpression ShiftExpression AdditiveExpression MultiplicativeExpression CastExpression UnaryExpression PostfixExpression PostfixExpression2 ArgumentExpressionList PrimaryExpression + Constant %type <type> DeclarationSpec %type <string> Declarator DirectDeclarator -%type <initializer> Constant - %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 @@ -202,7 +200,7 @@ ExpressionStatement: ; JumpStatement: - T_RETURN ExpressionStatement { $$ = new JumpStatement(); } + T_RETURN Expression T_SC { $$ = new JumpStatement($2); } ; IterationStatement: @@ -298,7 +296,7 @@ UnaryExpression: | T_INCDEC UnaryExpression { $$ = $2; } | UnaryOperator CastExpression { $$ = $2; } | T_SIZEOF UnaryExpression { $$ = $2; } - | T_SIZEOF T_LRB DeclarationSpec T_RRB { $$ = new Expression(); } + | T_SIZEOF T_LRB DeclarationSpec T_RRB { $$ = new Constant(0); } ; UnaryOperator: @@ -313,29 +311,29 @@ PostfixExpression: PrimaryExpression { $$ = $1; } | PostfixExpression T_LSB Expression T_RSB { $$ = $3; } | PostfixExpression T_LRB PostfixExpression2 { $$ = $3; } - | PostfixExpression T_DOT T_IDENTIFIER { $$ = new Expression(); } - | PostfixExpression T_ARROW T_IDENTIFIER { $$ = new Expression(); } - | PostfixExpression T_INCDEC { $$ = new Expression(); } + | PostfixExpression T_DOT T_IDENTIFIER { $$ = $1; } + | PostfixExpression T_ARROW T_IDENTIFIER { $$ = $1; } + | PostfixExpression T_INCDEC { $$ = $1; } ; PostfixExpression2: - T_RRB { $$ = new Expression(); } - | ArgumentExpressionList T_RRB { $$ = new Expression; } + T_RRB { $$ = new Constant(0); } + | ArgumentExpressionList T_RRB { $$ = new Constant(0); } ; ArgumentExpressionList: - AssignmentExpression { $$ = new Expression; } - | ArgumentExpressionList T_CMA AssignmentExpression { $$ = new Expression; } + AssignmentExpression { $$ = $1; } + | ArgumentExpressionList T_CMA AssignmentExpression { $$ = $1; } ; PrimaryExpression: - T_IDENTIFIER { $$ = new Expression(); } - | Constant { $$ = new Expression($1); } + T_IDENTIFIER { $$ = new Identifier(*$1); } + | Constant { $$ = $1; } | T_LRB Expression T_RRB { $$ = $2; } ; Constant: - T_INT_CONST { $$ = new Initializer(); } + T_INT_CONST { $$ = new Constant($1); } ; %% diff --git a/c_compiler/src/compiler_main.cpp b/c_compiler/src/compiler_main.cpp index b550eba..e0222a3 100644 --- a/c_compiler/src/compiler_main.cpp +++ b/c_compiler/src/compiler_main.cpp @@ -6,8 +6,6 @@ int main(int argc, char *argv[]) { Node* ast = parseAST(); - ast->printxml(); - ast->printasm(); return 0; diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp index 4b09581..76a6c43 100644 --- a/c_compiler/src/expression.cpp +++ b/c_compiler/src/expression.cpp @@ -3,14 +3,30 @@ // Expression definition -Expression::Expression(const Node* expr) -{} - void Expression::print() const {} void Expression::printxml() const {} -void Expression::printasm() const + +// Identifier definition + +Identifier::Identifier(const std::string& id) + : m_id(id) +{} + +void Identifier::printasm() const {} + + +// Constant definition + +Constant::Constant(const int32_t& constant) + : m_constant(constant) +{} + +void Constant::printasm() const +{ + std::cout << "\tli\t$2," << m_constant << std::endl; +} diff --git a/c_compiler/src/function.cpp b/c_compiler/src/function.cpp index acd5547..5475ec9 100644 --- a/c_compiler/src/function.cpp +++ b/c_compiler/src/function.cpp @@ -45,9 +45,23 @@ void Function::printxml() const void Function::printasm() const { + // Counting all the variables being declared in the function int32_t count = 0; if(statement != nullptr) statement->count_variables(count); - std::cout << id << ": " << count << " variables defined" << std::endl; + // 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(); + + 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/initializer.cpp b/c_compiler/src/initializer.cpp deleted file mode 100644 index 580d81f..0000000 --- a/c_compiler/src/initializer.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "ast.hpp" - - -// Initializer definition - -Initializer::Initializer() -{} - -void Initializer::print() const -{} - -void Initializer::printxml() const -{} - -void Initializer::printasm() const -{} - - -// Integer definition - -Integer::Integer() : Initializer() -{} - - -// String Literal definition - -StringLiteral::StringLiteral() : Initializer() -{} diff --git a/c_compiler/src/statement.cpp b/c_compiler/src/statement.cpp index dcd2271..99b2879 100644 --- a/c_compiler/src/statement.cpp +++ b/c_compiler/src/statement.cpp @@ -49,7 +49,15 @@ void CompoundStatement::printxml() const } void CompoundStatement::printasm() const -{} +{ + if(next_statement != nullptr) + next_statement->printasm(); + + // TODO printasm for the declaration + + if(m_statement != nullptr) + m_statement->printasm(); +} void CompoundStatement::count_variables(int32_t& var_count) const { @@ -67,13 +75,9 @@ void CompoundStatement::count_variables(int32_t& var_count) const while(declaration_list != nullptr) { var_count++; - std::cout << declaration_list->getType() << std::endl; - declaration_list = declaration_list->getNextListItem(); } - std::cout << declaration->getType() << std::endl; - var_count++; declaration = declaration->getNext(); @@ -158,7 +162,6 @@ void JumpStatement::printxml() const void JumpStatement::printasm() const { m_expr->printasm(); - std::cout << "\tlw\t$2,8($fp)" << std::endl; } void JumpStatement::count_variables(int32_t& var_count) const diff --git a/c_compiler/test/.gitignore b/c_compiler/test/.gitignore new file mode 100644 index 0000000..9ff5da3 --- /dev/null +++ b/c_compiler/test/.gitignore @@ -0,0 +1,2 @@ +out/ +ref/ diff --git a/c_compiler/test/in/02.c b/c_compiler/test/in/02.c new file mode 100644 index 0000000..95c954c --- /dev/null +++ b/c_compiler/test/in/02.c @@ -0,0 +1,4 @@ +int main() { + int x = 26; + return x; +} diff --git a/c_compiler/test/in/03.c b/c_compiler/test/in/03.c new file mode 100644 index 0000000..911f7e2 --- /dev/null +++ b/c_compiler/test/in/03.c @@ -0,0 +1,5 @@ +int main() { + int x; + x = 15; + return x; +} diff --git a/c_compiler/test/in/04.c b/c_compiler/test/in/04.c new file mode 100644 index 0000000..57cf697 --- /dev/null +++ b/c_compiler/test/in/04.c @@ -0,0 +1,9 @@ +int main() { + int a = 3; + int b = 5; + return a + b; +} + +int f(int a, int v) { + return a + v; +} diff --git a/c_compiler/test/out/01.diff.txt b/c_compiler/test/out/01.diff.txt deleted file mode 100644 index e69de29..0000000 --- a/c_compiler/test/out/01.diff.txt +++ /dev/null diff --git a/c_compiler/test/out/01.pretty.xml b/c_compiler/test/out/01.pretty.xml deleted file mode 100644 index 8b13789..0000000 --- a/c_compiler/test/out/01.pretty.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/c_compiler/test/out/01.stderr.txt b/c_compiler/test/out/01.stderr.txt deleted file mode 100644 index 37006dc..0000000 --- a/c_compiler/test/out/01.stderr.txt +++ /dev/null @@ -1 +0,0 @@ -./test_compiler.sh: line 28: ./bin/c_compiler: No such file or directory diff --git a/c_compiler/test/out/01.stdout.s b/c_compiler/test/out/01.stdout.s deleted file mode 100644 index e69de29..0000000 --- a/c_compiler/test/out/01.stdout.s +++ /dev/null diff --git a/c_compiler/test/out/01.stdout.xml b/c_compiler/test/out/01.stdout.xml deleted file mode 100644 index e69de29..0000000 --- a/c_compiler/test/out/01.stdout.xml +++ /dev/null diff --git a/c_compiler/test/ref/01 b/c_compiler/test/ref/01 Binary files differdeleted file mode 100755 index 9655601..0000000 --- a/c_compiler/test/ref/01 +++ /dev/null diff --git a/c_compiler/test/ref/01.s b/c_compiler/test/ref/01.s deleted file mode 100644 index db5d0b4..0000000 --- a/c_compiler/test/ref/01.s +++ /dev/null @@ -1,38 +0,0 @@ - .file 1 "01.c" - .section .mdebug.abi32 - .previous - .nan legacy - .module fp=xx - .module nooddspreg - .abicalls - .option pic0 - .text - .align 2 - .globl main - .set nomips16 - .set nomicromips - .ent main - .type main, @function -main: - .frame $fp,24,$31 # vars= 8, regs= 1/0, args= 0, gp= 8 - .mask 0x40000000,-4 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - addiu $sp,$sp,-24 - sw $fp,20($sp) - move $fp,$sp - li $2,13 # 0xd - sw $2,8($fp) - lw $2,8($fp) - move $sp,$fp - lw $fp,20($sp) - addiu $sp,$sp,24 - jr $31 - nop - - .set macro - .set reorder - .end main - .size main, .-main - .ident "GCC: (Codescape GNU Tools 2016.05-03 for MIPS MTI Linux) 4.9.2" @@ -69,7 +69,7 @@ $(PARSRCDIR)/c_parser.tab.cpp $(PARSRCDIR)/c_parser.tab.hpp : $(PARSRCDIR)/c_par # Make the c_parser bin/c_compiler: $(COMPBUILDDIR)/compiler_main.o $(COMPBUILDDIR)/statement.o \ $(COMPBUILDDIR)/function.o $(COMPBUILDDIR)/expression.o \ - $(COMPBUILDDIR)/initializer.o $(COMPBUILDDIR)/translation_unit.o \ + $(COMPBUILDDIR)/translation_unit.o \ $(COMPBUILDDIR)/declaration.o $(COMPBUILDDIR)/type.o \ $(COMPBUILDDIR)/c_parser.tab.o $(COMPBUILDDIR)/c_lexer.yy.o @echo "Linking..." diff --git a/test_compiler.sh b/test_compiler.sh index 3f64457..700afe5 100755 --- a/test_compiler.sh +++ b/test_compiler.sh @@ -20,22 +20,36 @@ echo " Testing compiler" PASSED=0 CHECKED=0 +mkdir -p c_compiler/test/out +mkdir -p c_compiler/test/ref + for i in c_compiler/test/in/*.c; do echo "===========================" echo "" echo "Input file : ${i}" BASENAME=$(basename $i .c); - cat $i | ./bin/c_compiler > c_compiler/test/out/$BASENAME.stdout.s 2> c_compiler/test/out/$BASENAME.stderr.txt + cat $i | ./bin/c_compiler > c_compiler/test/out/$BASENAME.s 2> c_compiler/test/out/$BASENAME.stderr.txt - diff <(cat c_compiler/test/ref/$BASENAME.stdout.s) <(cat c_compiler/test/out/$BASENAME.stdout.s) > c_compiler/test/out/$BASENAME.diff.txt + mips-linux-gnu-gcc -S -c c_compiler/test/in/$BASENAME.c -o c_compiler/test/ref/$BASENAME.s + mips-linux-gnu-gcc -static c_compiler/test/ref/$BASENAME.s -o c_compiler/test/ref/$BASENAME - if [[ "$?" -ne "0" ]]; then - echo -e "\nERROR" - else - PASSED=$(( ${PASSED}+1 )); - fi + mips-linux-gnu-gcc -static c_compiler/test/out/$BASENAME.s -o c_compiler/test/out/$BASENAME + + qemu-mips c_compiler/test/ref/$BASENAME + REFOUTPUT=$? - CHECKED=$(( ${CHECKED}+1 )); + qemu-mips c_compiler/test/out/$BASENAME + TESTOUTPUT=$? + + if [ "$TESTOUTPUT" = "$REFOUTPUT" ]; then + PASSED=$(( PASSED+1 )) + else + echo -e "\nERROR" + fi + + echo -e "output: $TESTOUTPUT\n" + + CHECKED=$(( CHECKED+1 )) done echo "########################################" |