MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
driver.h
Go to the documentation of this file.
1#pragma once
2
3#include <list>
4#include <utility>
5
6#include <absl/container/node_hash_map.h>
7
8#include "mim/flags.h"
9#include "mim/ast/tok.h"
10#include "mim/plugin.h"
11#include "mim/world.h"
12
13#include "mim/util/log.h"
14
15namespace mim {
16
17/// Some "global" variables needed all over the place.
18/// Well, there are not really global - that's the point of this class.
19class Driver : public fe::SymPool {
20public:
21 Driver();
22
23 /// @name Getters
24 ///@{
25 Flags& flags() { return flags_; }
26 const Flags& flags() const { return flags_; }
27 Log& log() const { return log_; }
28 World& world() { return world_; }
29 ///@}
30
31 /// @name Manage Search Paths
32 /// Search paths for plugins are in the following order:
33 /// 1. The empty path. Used as prefix to look into current working directory without resorting to an absolute path.
34 /// 2. All further user-specified paths via Driver::add_search_path; paths added first will also be searched first.
35 /// 3. All paths specified in the environment variable `MIM_PLUGIN_PATH`.
36 /// 4. `path/to/mim.exe/../../lib/mim`
37 /// 5. `CMAKE_INSTALL_PREFIX/lib/mim`
38 ///@{
39 const auto& search_paths() const { return search_paths_; }
40 void add_search_path(fs::path path) {
41 if (fs::exists(path) && fs::is_directory(path)) search_paths_.insert(insert_, std::move(path));
42 }
43 ///@}
44
45 /// @name Manage Imports
46 /// This tracks:
47 /// 1. The distinct files that have already been parsed to avoid reparsing them,
48 /// 2. The distinct import or plugin directives that should be emitted again later.
49 ///@{
50 class Imports {
51 public:
52 struct Entry {
53 fs::path path;
54 Sym sym;
56 };
57
58 Imports(Driver& driver)
59 : driver_(driver) {}
60
61 /// @name Get imports
62 ///@{
63 const auto& entries() const { return entries_; }
64 ///@}
65
66 /// @name Iterators
67 ///@{
68 auto begin() const { return entries_.cbegin(); }
69 auto end() const { return entries_.cend(); }
70 ///@}
71
72 /// Remembers an import or plugin directive and reports whether the resolved file is new.
73 std::pair<const fs::path*, bool> add(fs::path, Sym, ast::Tok::Tag);
74
75 private:
76 Driver& driver_;
77 std::deque<Entry> entries_;
78 std::deque<fs::path> parsed_paths_;
79 };
80
81 const Imports& imports() const { return imports_; }
82 Imports& imports() { return imports_; }
83 ///@}
84
85 /// @name Load Plugin
86 /// Finds and loads a shared object file that implements the MimIR Plugin @p name.
87 /// If \a name is an absolute path to a `.so`/`.dll` file, this is used.
88 /// Otherwise, "name", "libmim_name.so" (Linux, Mac), "mim_name.dll" (Win)
89 /// are searched for in Driver::search_paths().
90 ///@{
91 void load(Sym name);
92 void load(const std::string& name) { return load(sym(name)); }
93 bool is_loaded(Sym sym) const { return lookup(plugins_, sym); }
94 void* get_fun_ptr(Sym plugin, const char* name);
95
96 template<class F>
97 auto get_fun_ptr(Sym plugin, const char* name) {
98 return reinterpret_cast<F*>(get_fun_ptr(plugin, name));
99 }
100
101 template<class F>
102 auto get_fun_ptr(const char* plugin, const char* name) {
103 return get_fun_ptr<F>(sym(plugin), name);
104 }
105 ///@}
106
107 /// @name Manage Plugins
108 /// All these lookups yield `nullptr` if the key has not been found.
109 ///@{
110 auto stage(flags_t flags) { return lookup(stages_, flags); }
111 const auto& stages() const { return stages_; }
112 auto normalizer(flags_t flags) const { return lookup(normalizers_, flags); }
113 auto normalizer(plugin_t d, tag_t t, sub_t s) const { return normalizer(d | flags_t(t << 8u) | s); }
114 auto backend(std::string_view name) { return lookup(backends_, name); }
115 ///@}
116
117private:
118 // This must go *first* so plugins will be unloaded *last* in the d'tor; otherwise funny things might happen ...
119 absl::node_hash_map<Sym, Plugin::Handle> plugins_;
120 Flags flags_;
121 mutable Log log_;
122 World world_;
123 std::list<fs::path> search_paths_;
124 std::list<fs::path>::iterator insert_ = search_paths_.end();
125 Backends backends_;
126 Flags2Stages stages_;
127 Normalizers normalizers_;
128 Imports imports_;
129};
130
131#define GET_FUN_PTR(plugin, f) get_fun_ptr<decltype(f)>(plugin, #f)
132
133} // namespace mim
auto end() const
Definition driver.h:69
Imports(Driver &driver)
Definition driver.h:58
auto begin() const
Definition driver.h:68
const auto & entries() const
Definition driver.h:63
std::pair< const fs::path *, bool > add(fs::path, Sym, ast::Tok::Tag)
Remembers an import or plugin directive and reports whether the resolved file is new.
Definition driver.cpp:10
const auto & stages() const
Definition driver.h:111
void load(Sym name)
Definition driver.cpp:71
const Imports & imports() const
Definition driver.h:81
void add_search_path(fs::path path)
Definition driver.h:40
auto backend(std::string_view name)
Definition driver.h:114
auto normalizer(plugin_t d, tag_t t, sub_t s) const
Definition driver.h:113
World & world()
Definition driver.h:28
Log & log() const
Definition driver.h:27
const Flags & flags() const
Definition driver.h:26
bool is_loaded(Sym sym) const
Definition driver.h:93
void * get_fun_ptr(Sym plugin, const char *name)
Definition driver.cpp:109
auto normalizer(flags_t flags) const
Definition driver.h:112
Imports & imports()
Definition driver.h:82
void load(const std::string &name)
Definition driver.h:92
Flags & flags()
Definition driver.h:25
auto get_fun_ptr(Sym plugin, const char *name)
Definition driver.h:97
auto get_fun_ptr(const char *plugin, const char *name)
Definition driver.h:102
auto stage(flags_t flags)
Definition driver.h:110
const auto & search_paths() const
Definition driver.h:39
Facility to log what you are doing.
Definition log.h:17
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:34
Definition ast.h:14
u8 sub_t
Definition types.h:49
u64 flags_t
Definition types.h:46
auto lookup(const C &container, const K &key)
Yields pointer to element (or the element itself if it is already a pointer), if found and nullptr ot...
Definition util.h:100
absl::btree_map< std::string, void(*)(World &, std::ostream &)> Backends
Definition plugin.h:24
absl::flat_hash_map< flags_t, std::function< std::unique_ptr< Stage >(World &)> > Flags2Stages
Maps an an axiom of a Stage to a function that creates one.
Definition plugin.h:22
absl::flat_hash_map< flags_t, NormalizeFn > Normalizers
Definition plugin.h:19
u64 plugin_t
Definition types.h:47
u8 tag_t
Definition types.h:48
Compiler switches that must be saved and looked up in later phases of compilation.
Definition flags.h:11