Merge branch 'master' of git://repo.or.cz/ozulis
[ozulis.git] / src / compiler.cc
blob4f7851302117161d747ea228ef53abb974f3fab6
1 #include <iostream>
2 #include <fstream>
3 #include <algorithm>
4 #include <boost/foreach.hpp>
6 #include <core/assert.hh>
7 #include <core/string.hh>
8 #include <core/process.hh>
9 #include <ast/ast.hh>
10 #include <ast/ascii-visitor.hh>
11 #include <ast/llvm-generator-visitor.hh>
12 #include <ast/type-checker-visitor.hh>
13 #include <ast/simplify-visitor.hh>
14 #include <ast/scope-builder-visitor.hh>
15 #include <lang/parser-factory.hh>
16 #include <compiler.hh>
17 #include <task.hh>
18 #include <parse-task.hh>
19 #include <target-data-factory.hh>
21 template class core::Singleton<Compiler>;
23 /**
24 * @class Compiler
25 * @todo get the targetData from options. The default option is native.
27 Compiler::Compiler()
28 : core::Singleton<Compiler>(),
29 tasks_(),
30 astDumpParse_(false),
31 astDumpTypeCheck_(false),
32 astDumpSimplify_(false),
33 targetData_(TargetDataFactory::native())
37 Compiler::~Compiler()
41 void
42 Compiler::addTask(Task * task)
44 assert(task);
45 std::vector<Task *> * deps = task->dependancies();
46 if (deps)
48 BOOST_FOREACH(Task * dep, *deps)
49 addTask(dep);
50 delete deps;
52 tasks_.push_back(task);
55 void
56 Compiler::compile()
58 std::sort(tasks_.begin(), tasks_.end());
59 std::unique(tasks_.begin(), tasks_.end());
60 BOOST_FOREACH(Task * task, tasks_)
62 assert(task);
63 task->accept(*this);
67 void
68 Compiler::work(Task & /*task*/)
70 assert(false);
73 void
74 Compiler::work(ParseTask & task)
76 ast::File * file = lang::ParserFactory::parseFile(task.filename);
77 file->path = task.filename;
78 if (astDumpParse_) {
79 std::cout << "Parsed AST" << std::endl;
80 ast::AsciiVisitor v;
81 file->accept(v);
84 ast::ScopeBuilderVisitor sbv;
85 file->accept(sbv);
87 ast::TypeCheckerVisitor tcv;
88 file->accept(tcv);
89 if (astDumpTypeCheck_) {
90 std::cout << "TypeChecked AST" << std::endl;
91 ast::AsciiVisitor v;
92 file->accept(v);
95 ast::SimplifyVisitor sv;
96 file->accept(sv);
97 if (astDumpSimplify_) {
98 std::cout << "Simplified AST" << std::endl;
99 ast::AsciiVisitor v;
100 file->accept(v);
103 std::string asm_filename(task.filename);
104 core::replace_extention(asm_filename, "ll");
105 std::ofstream asm_stream(asm_filename.c_str(),
106 std::ios_base::out | std::ios_base::trunc);
107 ast::LLVMGeneratorVisitor lgv(asm_stream);
108 file->accept(lgv);
109 asm_stream.close();
111 core::Process llvm_as;
112 llvm_as.setBinary("llvm-as");
113 llvm_as.addArg("-f");
114 llvm_as.addArg(asm_filename);
115 llvm_as.run();
116 assert(!llvm_as.wait());
118 std::string bc_filename(asm_filename);
119 core::replace_extention(bc_filename, "bc");
120 std::string bin_filename(asm_filename);
121 core::replace_extention(bin_filename, "");
122 core::Process llvm_ld;
123 llvm_ld.setBinary("llvm-ld");
124 llvm_ld.addArg("-native");
125 llvm_ld.addArg("-o");
126 llvm_ld.addArg(bin_filename);
127 llvm_ld.addArg(bc_filename);
128 llvm_ld.run();
129 assert(!llvm_ld.wait());