A Gleam codegen library in Gleam
1import gleam/list
2import gleam/result
3import gleam/string_tree
4import shellout
5import simplifile
6import stare/function
7import stare/import_
8import stare/internal/statement
9import stare/value
10
11@internal
12pub opaque type Module(a, b) {
13 Module(
14 imports: List(import_.Import),
15 functions: List(function.Function(a, b)),
16 )
17}
18
19pub fn module(
20 imports imports: List(import_.Import),
21 functions functions: List(function.Function(a, b)),
22) -> Module(a, b) {
23 Module(imports:, functions:)
24}
25
26pub fn add_ints(left left: Int, right right: Int) -> statement.Statement(a, b) {
27 statement.AddInts(value.int(left), value.int(right))
28}
29
30pub fn add_floats(
31 left left: Float,
32 right right: Float,
33) -> statement.Statement(a, b) {
34 statement.AddFloats(value.float(left), value.float(right))
35}
36
37pub fn value(value value: value.Value(a, b)) -> statement.Statement(a, b) {
38 statement.Raw(value)
39}
40
41pub fn local_variable(name name: String) -> statement.Statement(a, b) {
42 statement.LocalVariable(name)
43}
44
45pub fn generate(module: Module(a, b)) -> String {
46 let imports =
47 module.imports
48 |> list.fold(string_tree.new(), fn(acc, import_) {
49 string_tree.append(acc, import_.generate_import(import_:) <> "\n")
50 })
51
52 let functions =
53 module.functions
54 |> list.fold(string_tree.new(), fn(acc, function) {
55 string_tree.append(acc, function.generate_function(function:) <> "\n")
56 })
57
58 string_tree.new()
59 |> string_tree.append_tree(imports)
60 |> string_tree.append("\n")
61 |> string_tree.append_tree(functions)
62 |> string_tree.to_string()
63}
64
65pub fn format(code code: String) -> Result(String, Nil) {
66 use _ <- result.try(
67 simplifile.create_directory_all("./build/tmp/")
68 |> result.replace_error(Nil),
69 )
70 use _ <- result.try(
71 simplifile.write(to: "./build/tmp/format.gleam", contents: code)
72 |> result.replace_error(Nil),
73 )
74 use _ <- result.try(
75 shellout.command(
76 run: "gleam",
77 with: ["format", "./build/tmp/format.gleam"],
78 in: ".",
79 opt: [],
80 )
81 |> result.replace_error(Nil),
82 )
83 use code <- result.try(
84 simplifile.read(from: "./build/tmp/format.gleam")
85 |> result.replace_error(Nil),
86 )
87 use _ <- result.try(
88 simplifile.delete("./build/tmp/format.gleam")
89 |> result.replace_error(Nil),
90 )
91 Ok(code)
92}