diff options
author | ymherklotz <ymherklotz@gmail.com> | 2017-03-10 15:23:46 +0000 |
---|---|---|
committer | ymherklotz <ymherklotz@gmail.com> | 2017-03-10 15:23:46 +0000 |
commit | b751d9ade81f47d75a5dc16f40890f30a6a1d1c5 (patch) | |
tree | d2ff52856eff330ad2b9df60d88884c2a73569e1 | |
parent | 21c873789eda041f7004d12637be3f3ed6f4cebc (diff) | |
download | Compiler-b751d9ade81f47d75a5dc16f40890f30a6a1d1c5.tar.gz Compiler-b751d9ade81f47d75a5dc16f40890f30a6a1d1c5.zip |
Got variables and bindings kind of working
43 files changed, 246 insertions, 93 deletions
@@ -12,3 +12,4 @@ c_compiler/build/ *.log .vagrant test/ +*~ @@ -71,7 +71,6 @@ specified in the lab. The AST was already built for us and the language was already parsed using C++ instead of bison. - ** TODO Coursework (c compiler) DEADLINE: <2017-03-28 Tue> @@ -92,9 +91,20 @@ - sw :: Store Word *** TODOs -**** Expression +**** TODO Current + +***** DONE VariableStackBindings class + + The class will contain map of strings containing the variable name as the _key_ and the stack + position as the stack position and type as the attributes, which will be combined using a struct. + +***** TODO Work on statements and declaration -***** void evaluate(VariableStackBindings binding) + Implement the adding to the bindings part that has to be added in the statements and declarations. + +**** TODO Expression + +***** printasm(VSB binding) Statements evaluate the expression by writing it out and printing the resulting asm onto the command line. I will also have to pass the bindings to the evaluate function @@ -107,14 +117,16 @@ Have to be careful because of the way the expressions are parsed. Constant expressions will just output li $2, 6 for example -**** Function class +**** TODO Function class -**** Statement class +**** TODO Statement class - Need function that prints declaration bits and expression bits, as well as connected statements -**** Definition class + - need to add labels so that it jumps to the exit of the function once it gets a return + +**** TODO Definition class - need function that will print the code for declaration. Basic code should be: @@ -127,6 +139,6 @@ That is if we want a 6 stored in the variable. - The declaration class should only be in charge of storing it in the right location in - the stack. + the stack and adding that to the bindings. diff --git a/c_compiler/GPATH b/c_compiler/GPATH Binary files differindex 1af534b..26679f3 100644 --- a/c_compiler/GPATH +++ b/c_compiler/GPATH diff --git a/c_compiler/GRTAGS b/c_compiler/GRTAGS Binary files differindex c1933dc..13d7d20 100644 --- a/c_compiler/GRTAGS +++ b/c_compiler/GRTAGS diff --git a/c_compiler/GTAGS b/c_compiler/GTAGS Binary files differindex 4128c61..5418332 100644 --- a/c_compiler/GTAGS +++ b/c_compiler/GTAGS diff --git a/c_compiler/include/ast.hpp b/c_compiler/include/ast.hpp deleted file mode 100644 index 88ef36b..0000000 --- a/c_compiler/include/ast.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef AST_HPP -#define AST_HPP - -#include <vector> -#include <string> -#include <iostream> -#include <map> -#include <cstdint> - -struct VarLocation; - -typedef std::map<std::string, VarLocation> VariableStackBindings; - -#include "node.hpp" -#include "type.hpp" -#include "expression.hpp" -#include "declaration.hpp" -#include "statement.hpp" -#include "function.hpp" -#include "translation_unit.hpp" - -Node* parseAST(); - -#endif diff --git a/c_compiler/include/bindings.hpp b/c_compiler/include/bindings.hpp new file mode 100644 index 0000000..9ca862f --- /dev/null +++ b/c_compiler/include/bindings.hpp @@ -0,0 +1,39 @@ +#ifndef BINDINGS_HPP +#define BINDINGS_HPP + +#include <cstdint> +#include <map> +#include <string> + +class Type; + + +// struct containing information on the variable declaration +struct DeclarationData +{ + Type* type; + int32_t stack_position; +}; + + +// stores bindings for the current scope and where they are in the stack +class VariableStackBindings +{ +private: + std::map<std::string, DeclarationData> bindings; + int32_t stack_counter; + +public: + VariableStackBindings(); + + void insertBinding(std::string id, Type* type, int32_t stack_position); + void increaseStackPosition(); + + int32_t getCurrentStackPosition() const; + int32_t getStackPosition(const std::string& id) const; + + bool bindingExists(const std::string& id) const; +}; + + +#endif diff --git a/c_compiler/include/declaration.hpp b/c_compiler/include/declaration.hpp index 8226090..5780bd9 100644 --- a/c_compiler/include/declaration.hpp +++ b/c_compiler/include/declaration.hpp @@ -15,7 +15,7 @@ private: Declaration* list_next_decl; public: - Declaration(const std::string& _id = ""); + Declaration(const std::string& _id = "", Expression* _init = nullptr); virtual void print() const; virtual void printxml() const; diff --git a/c_compiler/include/node.hpp b/c_compiler/include/node.hpp index 584ed32..e14a711 100644 --- a/c_compiler/include/node.hpp +++ b/c_compiler/include/node.hpp @@ -5,19 +5,13 @@ #include <map> #include <string> -struct VarLocation; class Type; +class VariableStackBindings; -typedef std::map<std::string, VarLocation> VariableStackBindings; - -struct VarLocation { - Type* type; - int32_t stack_position; -}; - - -class Node { +// base node class +class Node +{ public: virtual ~Node() {} diff --git a/c_compiler/include/translation_unit.hpp b/c_compiler/include/translation_unit.hpp index c290163..5c20855 100644 --- a/c_compiler/include/translation_unit.hpp +++ b/c_compiler/include/translation_unit.hpp @@ -5,7 +5,6 @@ #include <vector> - class TranslationUnit : public Node { protected: std::vector<Node* > translation_unit; diff --git a/c_compiler/src/bindings.cpp b/c_compiler/src/bindings.cpp new file mode 100644 index 0000000..e920783 --- /dev/null +++ b/c_compiler/src/bindings.cpp @@ -0,0 +1,48 @@ +#include "bindings.hpp" + + +// VariableStackBindings definition + +VariableStackBindings::VariableStackBindings() + : stack_counter(4) +{} + +void VariableStackBindings::insertBinding(std::string id, Type* type, int32_t stack_position) +{ + DeclarationData decl_data; + decl_data.type = type; + decl_data.stack_position = stack_position; + + bindings.insert(std::pair<std::string, DeclarationData>(id, decl_data)); +} + +void VariableStackBindings::increaseStackPosition() +{ + stack_counter += 4; +} + +int32_t VariableStackBindings::getCurrentStackPosition() const +{ + return stack_counter; +} + +int32_t VariableStackBindings::getStackPosition(const std::string &id) const +{ + auto binding = bindings.find(id); + + if(binding != bindings.end()) + return (*binding).second.stack_position; + + else return 0; +} + +bool VariableStackBindings::bindingExists(const std::string &id) const +{ + auto binding = bindings.find(id); + + if(binding == bindings.end()) + return false; + + else + return true; +} diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y index a42463c..b3430ee 100644 --- a/c_compiler/src/c_parser.y +++ b/c_compiler/src/c_parser.y @@ -126,8 +126,7 @@ Declaration: tmp_decl->setType($1); tmp_decl = tmp_decl->getNextListItem(); } - } - ; + }; DeclarationSpec: T_VOID { $$ = new Void; } @@ -149,7 +148,7 @@ InitDeclaratorList: InitDeclarator: Declarator { $$ = new Declaration(*$1); } - | Declarator T_EQ AssignmentExpression { $$ = new Declaration(*$1); } +| Declarator T_EQ AssignmentExpression { $$ = new Declaration(*$1, $3); } ; Declarator: diff --git a/c_compiler/src/compiler_main.cpp b/c_compiler/src/compiler_main.cpp index a7d7eb3..69504c9 100644 --- a/c_compiler/src/compiler_main.cpp +++ b/c_compiler/src/compiler_main.cpp @@ -1,15 +1,17 @@ -#include "ast.hpp" +#include "node.hpp" +#include "bindings.hpp" #include <iostream> +Node* parseAST(); + int main(int argc, char *argv[]) { Node* ast = parseAST(); VariableStackBindings bindings; - int32_t var_count; - - ast->printasm(bindings, var_count); + + ast->printasm(bindings); return 0; } diff --git a/c_compiler/src/declaration.cpp b/c_compiler/src/declaration.cpp index 0f125b0..9eff776 100644 --- a/c_compiler/src/declaration.cpp +++ b/c_compiler/src/declaration.cpp @@ -1,10 +1,15 @@ -#include "ast.hpp" +#include "declaration.hpp" +#include "bindings.hpp" +#include "type.hpp" +#include "expression.hpp" + +#include <iostream> // Declaration definition -Declaration::Declaration(const std::string& _id) - : id(_id) +Declaration::Declaration(const std::string& _id, Expression* _init) + : id(_id), init(_init) {} void Declaration::print() const @@ -29,14 +34,39 @@ void Declaration::printxml() const std::cout << "<Variable id=\""<< id << "\" />" << std::endl; } -void Declaration::printasm(VariableStackBindings bindings, int32_t& var_count) const +VariableStackBindings Declaration::printasm(VariableStackBindings bindings) 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; + // 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; + // } + + // return bindings; + + if(next_decl != nullptr) + bindings = next_decl->printasm(bindings); + + if(list_next_decl != nullptr) + bindings = list_next_decl->printasm(bindings); + + if(id != "") { + if(init != nullptr) + init->printasm(bindings); + else + std::cout << "\tmove\t$2,$0" << std::endl; + + int32_t stack_position = bindings.getCurrentStackPosition(); + + std::cout << "\tsw\t$2," << stack_position << "($fp)" << std::endl; + + bindings.insertBinding(id, type, stack_position); + + bindings.increaseStackPosition(); } + + return bindings; } void Declaration::addDeclaration(Declaration* _next_decl) diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp index 11fa66e..d9a366b 100644 --- a/c_compiler/src/expression.cpp +++ b/c_compiler/src/expression.cpp @@ -1,4 +1,5 @@ #include "expression.hpp" +#include "bindings.hpp" #include <iostream> @@ -17,8 +18,17 @@ Identifier::Identifier(const std::string& id) : m_id(id) {} -void Identifier::printasm(VariableStackBindings bindings) const -{} +VariableStackBindings Identifier::printasm(VariableStackBindings bindings) const +{ + if(bindings.bindingExists(m_id)) { + int32_t stack_position = bindings.getStackPosition(m_id); + + std::cout << "\tlw\t$2," << stack_position << "($fp)" << std::endl; + } else + std::cerr << "Can't find identifier '" << m_id << "' in current scope binding" << std::endl; + + return bindings; +} // Constant definition @@ -27,8 +37,10 @@ Constant::Constant(const int32_t& constant) : m_constant(constant) {} -void Constant::printasm(VariableStackBindings bindings) const +VariableStackBindings Constant::printasm(VariableStackBindings bindings) const { std::cout << "\tli\t$2," << m_constant << std::endl; + + return bindings; } diff --git a/c_compiler/src/function.cpp b/c_compiler/src/function.cpp index 090e070..6c41c7a 100644 --- a/c_compiler/src/function.cpp +++ b/c_compiler/src/function.cpp @@ -1,6 +1,7 @@ #include "function.hpp" #include "statement.hpp" #include "declaration.hpp" +#include "bindings.hpp" #include <iostream> #include <vector> @@ -69,4 +70,6 @@ VariableStackBindings Function::printasm(VariableStackBindings bindings) const 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; + + return bindings; } diff --git a/c_compiler/src/statement.cpp b/c_compiler/src/statement.cpp index 7b98631..af382dc 100644 --- a/c_compiler/src/statement.cpp +++ b/c_compiler/src/statement.cpp @@ -1,6 +1,7 @@ #include "statement.hpp" #include "declaration.hpp" #include "expression.hpp" +#include "bindings.hpp" #include <iostream> @@ -52,15 +53,20 @@ void CompoundStatement::printxml() const std::cout << "</Scope>" << std::endl; } -VariableStackBindings CompoundStatement::printasm(VariableStackBindings bindings, int32_t& var_count) const +VariableStackBindings CompoundStatement::printasm(VariableStackBindings bindings) const { + VariableStackBindings outer_scope_bindings = bindings; + if(next_statement != nullptr) - next_statement->printasm(bindings, var_count); + next_statement->printasm(bindings); - // TODO printasm for the declaration + if(m_decl != nullptr) + bindings = m_decl->printasm(bindings); if(m_statement != nullptr) - m_statement->printasm(bindings, var_count); + m_statement->printasm(bindings); + + return outer_scope_bindings; } void CompoundStatement::count_variables(int32_t& var_count) const @@ -110,8 +116,10 @@ void SelectionStatement::printxml() const m_else->printxml(); } -VariableStackBindings SelectionStatement::printasm(VariableStackBindings bindings, int32_t& var_count) const -{} +VariableStackBindings SelectionStatement::printasm(VariableStackBindings bindings) const +{ + return bindings; +} void SelectionStatement::count_variables(int32_t& var_count) const { @@ -138,8 +146,18 @@ void ExpressionStatement::print() const void ExpressionStatement::printxml() const {} -VariableStackBindings ExpressionStatement::printasm(VariableStackBindings bindings, int32_t& var_count) const -{} +VariableStackBindings ExpressionStatement::printasm(VariableStackBindings bindings) const +{ + if(next_statement != nullptr) + next_statement->printasm(bindings); + + if(m_expr != nullptr) { + std::cout << "SHould print" << std::endl; + m_expr->printasm(bindings); + } + + return bindings; +} void ExpressionStatement::count_variables(int32_t& var_count) const { @@ -163,9 +181,15 @@ void JumpStatement::printxml() const next_statement->printxml(); } -VariableStackBindings JumpStatement::printasm(VariableStackBindings bindings, int32_t& var_count) const +VariableStackBindings JumpStatement::printasm(VariableStackBindings bindings) const { - m_expr->printasm(bindings, var_count); + if(next_statement != nullptr) + next_statement->printasm(bindings); + + if(m_expr != nullptr) + m_expr->printasm(bindings); + + return bindings; } void JumpStatement::count_variables(int32_t& var_count) const @@ -192,8 +216,10 @@ void IterationStatement::printxml() const m_statement->printxml(); } -VariableStackBindings IterationStatement::printasm(VariableStackBindings bindings, int32_t& var_count) const -{} +VariableStackBindings IterationStatement::printasm(VariableStackBindings bindings) const +{ + return bindings; +} void IterationStatement::count_variables(int32_t& var_count) const { diff --git a/c_compiler/src/translation_unit.cpp b/c_compiler/src/translation_unit.cpp index e85237b..4bddac2 100644 --- a/c_compiler/src/translation_unit.cpp +++ b/c_compiler/src/translation_unit.cpp @@ -1,4 +1,7 @@ -#include "ast.hpp" +#include "translation_unit.hpp" +#include "bindings.hpp" + +#include <iostream> // Translation Unit definition @@ -24,11 +27,13 @@ void TranslationUnit::printxml() const std::cout << "</Program>" << std::endl; } -void TranslationUnit::printasm(VariableStackBindings bindings, int32_t& var_count) const +VariableStackBindings TranslationUnit::printasm(VariableStackBindings bindings) const { for(auto& node : translation_unit) { - node->printasm(bindings, var_count); + node->printasm(bindings); } + + return bindings; } void TranslationUnit::push(Node* decl) diff --git a/c_compiler/src/type.cpp b/c_compiler/src/type.cpp index 13496e9..6a89e2a 100644 --- a/c_compiler/src/type.cpp +++ b/c_compiler/src/type.cpp @@ -1,4 +1,7 @@ -#include "ast.hpp" +#include "type.hpp" +#include "bindings.hpp" + +#include <iostream> // Type definition @@ -11,8 +14,10 @@ void Type::print() const void Type::printxml() const {} -void Type::printasm(VariableStackBindings bindings, int32_t& var_count) const -{} +VariableStackBindings Type::printasm(VariableStackBindings bindings) const +{ + return bindings; +} // Pointer definition diff --git a/c_compiler/test/in/01.c b/c_compiler/test/in/01.c deleted file mode 100644 index c362948..0000000 --- a/c_compiler/test/in/01.c +++ /dev/null @@ -1,3 +0,0 @@ -int main() { - return 13; -} diff --git a/c_compiler/test/in/02.c b/c_compiler/test/in/02.c deleted file mode 100644 index 95c954c..0000000 --- a/c_compiler/test/in/02.c +++ /dev/null @@ -1,4 +0,0 @@ -int main() { - int x = 26; - return x; -} diff --git a/c_compiler/test/in/03.c b/c_compiler/test/in/03.c deleted file mode 100644 index 911f7e2..0000000 --- a/c_compiler/test/in/03.c +++ /dev/null @@ -1,5 +0,0 @@ -int main() { - int x; - x = 15; - return x; -} diff --git a/c_compiler/test/out/03 b/c_compiler/test/out/03 Binary files differindex a020bfc..9a997cd 100755 --- a/c_compiler/test/out/03 +++ b/c_compiler/test/out/03 diff --git a/c_compiler/test/out/03.s b/c_compiler/test/out/03.s index eae78d0..b1071cb 100644 --- a/c_compiler/test/out/03.s +++ b/c_compiler/test/out/03.s @@ -4,6 +4,9 @@ main: addiu $sp,$sp,-12 sw $fp,8($sp) move $fp,$sp + move $2,$0 + sw $2,4($fp) + lw $2,4($fp) move $sp,$fp lw $fp,8($sp) addiu $sp,$sp,12 diff --git a/c_compiler/test/out/04 b/c_compiler/test/out/04 Binary files differindex a23dad4..e50b1ae 100755 --- a/c_compiler/test/out/04 +++ b/c_compiler/test/out/04 diff --git a/c_compiler/test/out/04.s b/c_compiler/test/out/04.s index 992f12a..a91af30 100644 --- a/c_compiler/test/out/04.s +++ b/c_compiler/test/out/04.s @@ -4,6 +4,11 @@ main: addiu $sp,$sp,-16 sw $fp,12($sp) move $fp,$sp + li $2,3 + sw $2,4($fp) + li $2,5 + sw $2,8($fp) + lw $2,8($fp) move $sp,$fp lw $fp,12($sp) addiu $sp,$sp,16 diff --git a/c_compiler/test/out/04.stderr.txt b/c_compiler/test/out/04.stderr.txt index e69de29..e585698 100644 --- a/c_compiler/test/out/04.stderr.txt +++ b/c_compiler/test/out/04.stderr.txt @@ -0,0 +1 @@ +Can't find identifier 'v' in current scope binding @@ -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)/translation_unit.o \ + $(COMPBUILDDIR)/translation_unit.o $(COMPBUILDDIR)/bindings.o \ $(COMPBUILDDIR)/declaration.o $(COMPBUILDDIR)/type.o \ $(COMPBUILDDIR)/c_parser.tab.o $(COMPBUILDDIR)/c_lexer.yy.o @echo "Linking..." diff --git a/working/test_ADD0.compile.stderr b/working/test_ADD0.compile.stderr new file mode 100644 index 0000000..2a88882 --- /dev/null +++ b/working/test_ADD0.compile.stderr @@ -0,0 +1 @@ +./run_test_deliverable.sh: line 25: bin/c_compiler: No such file or directory diff --git a/working/test_ADD0.s b/working/test_ADD0.s new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/working/test_ADD0.s diff --git a/working/test_ADD0_driver.compile.stderr b/working/test_ADD0_driver.compile.stderr new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/working/test_ADD0_driver.compile.stderr diff --git a/working/test_ADD1.compile.stderr b/working/test_ADD1.compile.stderr new file mode 100644 index 0000000..2a88882 --- /dev/null +++ b/working/test_ADD1.compile.stderr @@ -0,0 +1 @@ +./run_test_deliverable.sh: line 25: bin/c_compiler: No such file or directory diff --git a/working/test_ADD1.s b/working/test_ADD1.s new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/working/test_ADD1.s diff --git a/working/test_ADD1_driver.compile.stderr b/working/test_ADD1_driver.compile.stderr new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/working/test_ADD1_driver.compile.stderr diff --git a/working/test_CALL.compile.stderr b/working/test_CALL.compile.stderr new file mode 100644 index 0000000..2a88882 --- /dev/null +++ b/working/test_CALL.compile.stderr @@ -0,0 +1 @@ +./run_test_deliverable.sh: line 25: bin/c_compiler: No such file or directory diff --git a/working/test_CALL.s b/working/test_CALL.s new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/working/test_CALL.s diff --git a/working/test_CALL_driver.compile.stderr b/working/test_CALL_driver.compile.stderr new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/working/test_CALL_driver.compile.stderr diff --git a/working/test_LOCAL.compile.stderr b/working/test_LOCAL.compile.stderr new file mode 100644 index 0000000..2a88882 --- /dev/null +++ b/working/test_LOCAL.compile.stderr @@ -0,0 +1 @@ +./run_test_deliverable.sh: line 25: bin/c_compiler: No such file or directory diff --git a/working/test_LOCAL.s b/working/test_LOCAL.s new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/working/test_LOCAL.s diff --git a/working/test_LOCAL_driver.compile.stderr b/working/test_LOCAL_driver.compile.stderr new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/working/test_LOCAL_driver.compile.stderr diff --git a/working/test_RETURN.compile.stderr b/working/test_RETURN.compile.stderr new file mode 100644 index 0000000..2a88882 --- /dev/null +++ b/working/test_RETURN.compile.stderr @@ -0,0 +1 @@ +./run_test_deliverable.sh: line 25: bin/c_compiler: No such file or directory diff --git a/working/test_RETURN.s b/working/test_RETURN.s new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/working/test_RETURN.s diff --git a/working/test_RETURN_driver.compile.stderr b/working/test_RETURN_driver.compile.stderr new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/working/test_RETURN_driver.compile.stderr |