A Gleam codegen library in Gleam
at main 2.3 kB view raw
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}