From c3836245ff0b16fffcb221345bd4c31d5b1ca272 Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Thu, 29 Jan 2009 03:18:03 +0100 Subject: [PATCH] Generates llvm assembly code for additions :-) --- src/ast/CMakeLists.txt | 2 + src/ast/generator-data.cc | 18 ++++++++ src/ast/llvm-generator-visitor.cc | 89 +++++++++++++++++++++++++++++++++++++++ src/ast/llvm-generator-visitor.hh | 42 ++++++++++++++++++ src/ast/simplify-visitor.cc | 34 +++++++++++---- src/ast/simplify-visitor.hh | 1 + src/ast/type-checker-visitor.cc | 13 ++++++ src/ast/type-checker-visitor.hh | 21 +++++++++ src/compiler.cc | 10 +++++ tests/lang/mugiwara/input/add.mgw | 13 ++++++ 10 files changed, 234 insertions(+), 9 deletions(-) create mode 100644 src/ast/llvm-generator-visitor.cc create mode 100644 src/ast/llvm-generator-visitor.hh create mode 100644 src/ast/type-checker-visitor.cc create mode 100644 src/ast/type-checker-visitor.hh create mode 100644 tests/lang/mugiwara/input/add.mgw diff --git a/src/ast/CMakeLists.txt b/src/ast/CMakeLists.txt index 112fa46..43506af 100644 --- a/src/ast/CMakeLists.txt +++ b/src/ast/CMakeLists.txt @@ -30,6 +30,8 @@ ADD_LIBRARY(ast ast.cc browse-visitor.cc default-visitor.cc + llvm-generator-visitor.cc + type-checker-visitor.cc simplify-visitor.cc scope.cc scope-builder-visitor.cc diff --git a/src/ast/generator-data.cc b/src/ast/generator-data.cc index 1a08bdd..8a23e84 100644 --- a/src/ast/generator-data.cc +++ b/src/ast/generator-data.cc @@ -163,5 +163,23 @@ const ag::Node ag::nodes[] = { } }, + /* 3 address decomposition */ + {"TmpResultExp", "Exp", "A temporary result, used for 3 address", { + {"std::string", "name"} + } + }, + + {"LoadVar", "Node", "A temporary result, used for 3 address", { + {"std::string", "name"}, + {"std::string", "to"} + } + }, + + {"StoreVar", "Node", "A temporary result, used for 3 address", { + {"std::string", "name"}, + {"Exp *", "value"}, // must be TmpResultExp or NumberExp + } + }, + {"", "", "", {{"", ""}}} }; diff --git a/src/ast/llvm-generator-visitor.cc b/src/ast/llvm-generator-visitor.cc new file mode 100644 index 0000000..46f30e9 --- /dev/null +++ b/src/ast/llvm-generator-visitor.cc @@ -0,0 +1,89 @@ +#include +#include + +#include "llvm-generator-visitor.hh" + +namespace ast +{ + LLVMGeneratorVisitor::LLVMGeneratorVisitor(std::ostream & out) + : super_t(), + out_(out) + { + assert_msg(out.good(), "The output for llvm assembly is not valid."); + } + + LLVMGeneratorVisitor::~LLVMGeneratorVisitor() + { + } + + void + LLVMGeneratorVisitor::visit(const Function & node) + { + out_ << "define void @" << node.name << "() {" << std::endl; + super_t::visit(node); + out_ << " ret void" << std::endl + << "}" << std::endl; + } + + void + LLVMGeneratorVisitor::visit(const VarDecl & node) + { + out_ << " %" << node.name << " = alloca i32" << std::endl; + } + + void + LLVMGeneratorVisitor::visit(const LoadVar & node) + { + out_ << " %" << node.to << " = load i32 * %" << node.name << std::endl; + } + + void + LLVMGeneratorVisitor::visit(const StoreVar & node) + { + out_ << " store i32 "; + node.value->accept(*this); + out_ << ", i32 * %" << node.name << std::endl; + } + + void + LLVMGeneratorVisitor::visit(const AssignExp & node) + { + out_ << " %" << node.name << " = "; + if (typeid (*node.value) == typeid (NumberExp) || + typeid (*node.value) == typeid (IdExp)) + { + out_ << "add i32 0, "; + node.value->accept(*this); + } + else + node.value->accept(*this); + out_ << std::endl; + } + + void + LLVMGeneratorVisitor::visit(const AddExp & node) + { + out_ << "add i32 "; + node.left->accept(*this); + out_ << ", "; + node.right->accept(*this); + } + + void + LLVMGeneratorVisitor::visit(const IdExp & node) + { + out_ << "%" << node.name; + } + + void + LLVMGeneratorVisitor::visit(const TmpResultExp & node) + { + out_ << "%" << node.name; + } + + void + LLVMGeneratorVisitor::visit(const NumberExp & node) + { + out_ << node.number; + } +} diff --git a/src/ast/llvm-generator-visitor.hh b/src/ast/llvm-generator-visitor.hh new file mode 100644 index 0000000..aca2b9a --- /dev/null +++ b/src/ast/llvm-generator-visitor.hh @@ -0,0 +1,42 @@ +#ifndef AST_LLVM_GENERATOR_VISITOR_HH +# define AST_LLVM_GENERATOR_VISITOR_HH + +# include + +# include + +namespace ast +{ + /// @defgroup Visitors + /** + * @brief Generates LLVM assembly + * @ingroup Visitors + */ + class LLVMGeneratorVisitor : public ConstBrowseVisitor + { + public: + typedef ConstBrowseVisitor super_t; + + LLVMGeneratorVisitor(std::ostream & out); + virtual ~LLVMGeneratorVisitor(); + + virtual void visit(const Function & node); + + virtual void visit(const VarDecl & node); + + virtual void visit(const LoadVar & node); + virtual void visit(const StoreVar & node); + + virtual void visit(const IdExp & node); + virtual void visit(const NumberExp & node); + virtual void visit(const TmpResultExp & node); + + virtual void visit(const AssignExp & node); + virtual void visit(const AddExp & node); + + protected: + std::ostream & out_; + }; +} + +#endif /* !AST_LLVM_GENERATOR_VISITOR_HH */ diff --git a/src/ast/simplify-visitor.cc b/src/ast/simplify-visitor.cc index ec99205..44c3cf1 100644 --- a/src/ast/simplify-visitor.cc +++ b/src/ast/simplify-visitor.cc @@ -37,6 +37,14 @@ namespace ast return ss.str(); } + std::string + SimplifyVisitor::currentId() const + { + std::stringstream ss; + ss << "r" << nextId_; + return ss.str(); + } + void SimplifyVisitor::visit(Block & block) { @@ -76,9 +84,9 @@ namespace ast \ std::string name = nextId(); \ \ - IdExp * id = new IdExp(); \ - id->name = name; \ - replacement_ = id; \ + TmpResultExp * tmpRes = new TmpResultExp(); \ + tmpRes->name = name; \ + replacement_ = tmpRes; \ \ AssignExp * assign = new AssignExp(); \ assign->name = name; \ @@ -105,12 +113,12 @@ namespace ast node.value->accept(*this); node.value = replacement_; - std::string name = nextId(); + StoreVar * sv = new StoreVar(); + sv->name = node.name; + sv->value = replacement_; + simplifications_.push_back(sv); - IdExp * id = new IdExp(); - id->name = name; - replacement_ = id; - simplifications_.push_back(&node); + delete &node; } void @@ -122,6 +130,14 @@ namespace ast void SimplifyVisitor::visit(IdExp & node) { - replacement_ = &node; + LoadVar * lv = new LoadVar(); + lv->name = node.name; + lv->to = nextId(); + simplifications_.push_back(lv); + + TmpResultExp * tre = new TmpResultExp(); + tre->name = lv->to; + replacement_ = tre; + delete &node; } } diff --git a/src/ast/simplify-visitor.hh b/src/ast/simplify-visitor.hh index 2ee8af4..e72cd0d 100644 --- a/src/ast/simplify-visitor.hh +++ b/src/ast/simplify-visitor.hh @@ -49,6 +49,7 @@ namespace ast //virtual void visit(Function & node); protected: + std::string currentId() const; std::string nextId(); std::vector simplifications_; diff --git a/src/ast/type-checker-visitor.cc b/src/ast/type-checker-visitor.cc new file mode 100644 index 0000000..e8ad232 --- /dev/null +++ b/src/ast/type-checker-visitor.cc @@ -0,0 +1,13 @@ +#include "type-checker-visitor.hh" + +namespace ast +{ + TypeCheckerVisitor::TypeCheckerVisitor() + : BrowseVisitor() + { + } + + TypeCheckerVisitor::~TypeCheckerVisitor() + { + } +} diff --git a/src/ast/type-checker-visitor.hh b/src/ast/type-checker-visitor.hh new file mode 100644 index 0000000..9399dbe --- /dev/null +++ b/src/ast/type-checker-visitor.hh @@ -0,0 +1,21 @@ +#ifndef AST_TYPE_CHECKER_VISITOR_HH +# define AST_TYPE_CHECKER_VISITOR_HH + +# include + +namespace ast +{ + /// @defgroup Visitors + /** + * @brief Check that all expressions are correct (type) + * @ingroup Visitors + */ + class TypeCheckerVisitor : public BrowseVisitor + { + public: + TypeCheckerVisitor(); + virtual ~TypeCheckerVisitor(); + }; +} + +#endif /* !AST_TYPE_CHECKER_VISITOR_HH */ diff --git a/src/compiler.cc b/src/compiler.cc index 27c6e22..aabd477 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -1,9 +1,12 @@ +#include #include #include #include #include #include +#include +#include #include #include #include @@ -54,13 +57,20 @@ Compiler::work(ParseTask & task) ast::AsciiVisitor v; file->accept(v); } + ast::ScopeBuilderVisitor sbv; file->accept(sbv); + ast::TypeCheckerVisitor tcv; + file->accept(tcv); + ast::SimplifyVisitor sv; file->accept(sv); if (astDump_) { ast::AsciiVisitor v; file->accept(v); } + + ast::LLVMGeneratorVisitor lgv(std::cout); + file->accept(lgv); } diff --git a/tests/lang/mugiwara/input/add.mgw b/tests/lang/mugiwara/input/add.mgw new file mode 100644 index 0000000..eb686c5 --- /dev/null +++ b/tests/lang/mugiwara/input/add.mgw @@ -0,0 +1,13 @@ +int main() +{ + int toto; + int tutu; + int tata; + + toto = 1; + tutu = 2; + tata = 3; + + toto = 3 + 4 + 6 + 7; + tata = tutu + toto + tata + 35; +} -- 2.11.4.GIT