Skip to content

Commit 3585006

Browse files
committed
reversed skeleton of minimal emitter from llvm backend
1 parent 8408bd5 commit 3585006

File tree

4 files changed

+127
-2
lines changed

4 files changed

+127
-2
lines changed

dialects/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ add_thorin_dialect(backend
121121
backend/backend.h
122122
backend/be/ocaml_emit.h
123123
backend/be/ocaml_emit.cpp
124+
backend/be/ocaml_emitter.cpp
124125
backend/be/haskell_emit.h
125126
backend/be/haskell_emit.cpp
126127
backend/be/rust_emit.h

dialects/backend/backend.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ extern "C" THORIN_EXPORT DialectInfo thorin_get_dialect_info() {
1717
register_phase<backend::ocaml_phase, backend::OCamlEmitter>(passes); //, std::cout);
1818
},
1919
[](Backends& backends) {
20-
backends["ml"] = &backend::ocaml::emit;
20+
// backends["ml"] = &backend::ocaml::emit;
21+
backends["ml"] = &backend::ocaml::emit2;
2122
backends["hs"] = &backend::haskell::emit;
2223
backends["rs"] = &backend::rust::emit;
2324
},

dialects/backend/be/ocaml_emit.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ namespace backend {
1212

1313
namespace ocaml {
1414
void emit(World&, std::ostream&);
15-
}
15+
void emit2(World&, std::ostream&);
16+
} // namespace ocaml
1617

1718
class OCamlEmitter : public Phase {
1819
public:

dialects/backend/be/ocaml_emitter.cpp

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#include <deque>
2+
#include <fstream>
3+
#include <iomanip>
4+
#include <iostream>
5+
#include <limits>
6+
#include <ranges>
7+
#include <string_view>
8+
9+
#include "thorin/axiom.h"
10+
#include "thorin/def.h"
11+
#include "thorin/tuple.h"
12+
13+
#include "thorin/analyses/cfg.h"
14+
#include "thorin/analyses/deptree.h"
15+
#include "thorin/be/emitter.h"
16+
#include "thorin/fe/tok.h"
17+
#include "thorin/util/assert.h"
18+
#include "thorin/util/print.h"
19+
#include "thorin/util/sys.h"
20+
21+
#include "absl/container/flat_hash_map.h"
22+
#include "dialects/backend/be/ocaml_emit.h"
23+
#include "dialects/core/autogen.h"
24+
#include "dialects/core/core.h"
25+
#include "dialects/math/math.h"
26+
#include "dialects/mem/autogen.h"
27+
#include "dialects/mem/mem.h"
28+
29+
using namespace std::string_literals;
30+
31+
namespace thorin::backend::ocaml {
32+
33+
const char* PREFACE_CODE = R"(
34+
let bool2bit x = if x then 1 else 0
35+
(* handle uninitialized values *)
36+
(* let rec magic () : 'a = magic () *)
37+
let unpack m = match m with
38+
| Some x -> x
39+
| None -> failwith "expected Some, got None"
40+
let get_0_of_2 (x, _) = x (* fst *)
41+
let get_1_of_2 (_, x) = x (* snd *)
42+
let get_0_of_3 (x, _, _) = x
43+
let get_1_of_3 (_, x, _) = x
44+
let get_2_of_3 (_, _, x) = x
45+
[@@@warning "-partial-match"]
46+
47+
)";
48+
49+
// test via:
50+
// ./build/bin/thorin -d backend --backend ml --output - lit/backend/pow.thorin
51+
52+
struct unit {};
53+
54+
class Emitter : public thorin::Emitter<std::string, std::string, unit, Emitter> {
55+
public:
56+
using Super = thorin::Emitter<std::string, std::string, unit, Emitter>;
57+
58+
Emitter(World& world, std::ostream& ostream)
59+
: Super(world, "ocaml_emitter", ostream) {}
60+
61+
bool is_valid(std::string_view s) { return !s.empty(); }
62+
void start() override;
63+
void emit_imported(Lam*);
64+
void emit_epilogue(Lam*);
65+
std::string emit_bb(unit&, const Def*);
66+
std::string prepare(const Scope&);
67+
void prepare(Lam*, std::string_view);
68+
void finalize(const Scope&);
69+
70+
template<class... Args>
71+
void declare(const char* s, Args&&... args) {
72+
std::ostringstream decl;
73+
print(decl << "declare ", s, std::forward<Args&&>(args)...);
74+
decls_.emplace(decl.str());
75+
}
76+
77+
private:
78+
std::string id(const Def*, bool force_bb = false) const;
79+
std::string convert(const Def*);
80+
std::string convert_ret_pi(const Pi*);
81+
82+
absl::btree_set<std::string> decls_;
83+
std::ostringstream type_decls_;
84+
std::ostringstream vars_decls_;
85+
std::ostringstream func_decls_;
86+
std::ostringstream func_impls_;
87+
};
88+
89+
void emit2(World& world, std::ostream& ostream) { Emitter(world, ostream).run(); }
90+
91+
std::string Emitter::id(const Def* def, bool force_bb /*= false*/) const {
92+
return "id";
93+
// std::string s("id");
94+
// return s;
95+
// return "";
96+
// std::ostringstream s;
97+
// s << "id";
98+
// return s.str();
99+
}
100+
101+
std::string Emitter::convert(const Def* type) { return "convert_placeholder"; }
102+
103+
void Emitter::start() {
104+
Super::start();
105+
ostream() << type_decls_.str() << '\n';
106+
for (auto&& decl : decls_) ostream() << decl << '\n';
107+
ostream() << func_decls_.str() << '\n';
108+
ostream() << vars_decls_.str() << '\n';
109+
ostream() << func_impls_.str() << '\n';
110+
}
111+
112+
void Emitter::emit_imported(Lam* lam) {}
113+
114+
std::string Emitter::prepare(const Scope& scope) { return "prepare_placeholder"; }
115+
116+
void Emitter::finalize(const Scope& scope) {}
117+
118+
void Emitter::emit_epilogue(Lam* lam) {}
119+
120+
std::string Emitter::emit_bb(unit& bb, const Def* def) { return "bb_placeholder"; }
121+
122+
} // namespace thorin::backend::ocaml

0 commit comments

Comments
 (0)