[visitors] ported llvm asm generator
[ozulis.git] / src / ozulis / compiler.cc
blob4a37d482aaf46aebfd47ff2a59d777295b8db08f
1 #include <iostream>
2 #include <fstream>
3 #include <algorithm>
4 #include <boost/foreach.hpp>
6 #include <ozulis/core/assert.hh>
7 #include <ozulis/core/string.hh>
8 #include <ozulis/core/process.hh>
9 #include <ozulis/ast/ast.hh>
10 #include <ozulis/parser-factory.hh>
11 #include <ozulis/compiler.hh>
12 #include <ozulis/task.hh>
13 #include <ozulis/parse-task.hh>
14 #include <ozulis/plugin-manager.hh>
15 #include <ozulis/target-data-factory.hh>
16 #include <ozulis/visitors/scope-builder.hh>
17 #include <ozulis/visitors/browser.hh>
18 #include <ozulis/visitors/type-checker.hh>
19 #include <ozulis/visitors/ascii-printer.hh>
20 #include <ozulis/visitors/simplify.hh>
21 #include <ozulis/visitors/llvm-asm-generator.hh>
23 template class ozulis::core::Singleton<ozulis::Compiler>;
25 namespace ozulis
27 /**
28 * @class Compiler
29 * @todo get the targetData from options. The default option is native.
31 Compiler::Compiler()
32 : core::Singleton<Compiler>(),
33 tasks_(),
34 astDumpParse_(false),
35 astDumpTypeCheck_(false),
36 astDumpSimplify_(false),
37 targetData_(TargetDataFactory::native())
39 visitors::Browser<visitors::ScopeBuilder>::Base::instance();
40 PluginManager::instance().addPluginPath(OZULIS_PLUGINDIR);
43 Compiler::~Compiler()
47 void
48 Compiler::addTask(Task * task)
50 assert(task);
51 std::vector<Task *> * deps = task->dependancies();
52 if (deps)
54 BOOST_FOREACH(Task * dep, *deps)
55 addTask(dep);
56 delete deps;
58 tasks_.push_back(task);
61 void
62 Compiler::compile()
64 std::sort(tasks_.begin(), tasks_.end());
65 std::unique(tasks_.begin(), tasks_.end());
66 BOOST_FOREACH(Task * task, tasks_)
68 assert(task);
69 task->accept(*this);
73 void
74 Compiler::work(Task & /*task*/)
76 assert(false);
79 void
80 Compiler::work(ParseTask & task)
82 ast::File * file = lang::ParserFactory::parseFile(task.filename);
83 file->path = task.filename;
84 if (astDumpParse_) {
85 std::cout << "Parsed AST" << std::endl;
86 visitors::AsciiPrinter v;
87 visitors::AsciiPrinter::visit(*file, v);
90 visitors::ScopeBuilder sb;
91 visitors::ScopeBuilder::visit(*file, sb);
93 visitors::TypeChecker tc;
94 visitors::TypeChecker::visit(*file, tc);
95 if (astDumpTypeCheck_) {
96 std::cout << "TypeChecked AST" << std::endl;
97 visitors::AsciiPrinter v;
98 visitors::AsciiPrinter::visit(*file, v);
101 visitors::Simplify sv;
102 visitors::Simplify::visit(*file, sv);
103 if (astDumpSimplify_) {
104 std::cout << "Simplified AST" << std::endl;
105 visitors::AsciiPrinter v;
106 visitors::AsciiPrinter::visit(*file, v);
109 std::string asm_filename(task.filename);
110 core::replace_extension(asm_filename, "ll");
111 std::ofstream asm_stream(asm_filename.c_str(),
112 std::ios_base::out | std::ios_base::trunc);
113 visitors::LLVMAsmGenerator lag(asm_stream);
114 visitors::LLVMAsmGenerator::visit(*file, lag);
115 asm_stream.close();
117 core::Process llvm_as;
118 llvm_as.setBinary("llvm-as");
119 llvm_as.addArg("-f");
120 llvm_as.addArg(asm_filename);
121 llvm_as.run();
122 assert(!llvm_as.wait());
124 std::string bc_filename(asm_filename);
125 core::replace_extension(bc_filename, "bc");
126 std::string bin_filename(asm_filename);
127 core::replace_extension(bin_filename, "");
128 core::Process llvm_ld;
129 llvm_ld.setBinary("llvm-ld");
130 llvm_ld.addArg("-native");
131 llvm_ld.addArg("-o");
132 llvm_ld.addArg(bin_filename);
133 llvm_ld.addArg(bc_filename);
134 llvm_ld.run();
135 assert(!llvm_ld.wait());