elipl/tpl_json.exs
2026-05-09 01:47:31 +02:00

67 lines
1.4 KiB
Elixir

Code.require_file("tpl.exs")
defmodule TplJson do
# --- JSON Transpiler ---
# transforms sexps into lists
# braces into objects
# tokens and strings into strings
def to_json(ast) do
ast
|> Enum.map(&to_json_item/1)
|> IO.inspect(label: "AST for JSON")
# if the top level is a single elem, we output that directly
|> case do
[[single]] -> single
[single] -> single
multiple -> multiple
end
|> Jason.encode!(pretty: true)
end
defp to_json_item(%{t: :sexp, list: list}) do
list |> Enum.map(&to_json_item/1)
end
defp to_json_item(%{t: :brace, list: list}) do
list
|> Enum.map(fn
%{t: :sexp, list: [key_item | value_list]} ->
key = to_json_item(key_item)
value =
case value_list do
[ex] -> to_json_item(ex)
_ -> value_list |> Enum.map(&to_json_item/1)
end
{key, value}
end)
|> Enum.into(%{})
end
defp to_json_item(%{t: :token, str: str}), do: str
defp to_json_item(%{t: :string, chunks: chunks, values: values}) do
# For simplicity, concatenate chunks and ignore interpolations
Enum.join(chunks)
end
end
json_output =
"""
{
asd "something else "
nested {
a ( b c asd asd asd)
d e f
inner {
x y z
}
}
"""
|> Tpl.to_ast()
|> TplJson.to_json()
IO.puts("\n--- Generated JSON Output ---")
IO.puts(json_output)