67 lines
1.4 KiB
Elixir
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)
|