lytlang/lib/lytlang.ex

84 lines
1.8 KiB
Elixir

defmodule Lytlang do
def eval(string) do
{value, _} =
string
|> from_lytlang()
|> IO.inspect()
|> Code.eval_quoted()
|> IO.inspect()
value
end
def from_lytlang(string, binding \\ [], opts \\ []) do
string |> String.to_charlist() |> tokenize() |> parse() |> transform(binding, opts)
end
def tokenize(string) do
{:ok, tokens, _} =
:lytlang_lexer.string(string)
|> IO.inspect()
tokens
end
def parse(tokens) do
{:ok, tree} =
:lytlang_parser.parse(tokens)
|> IO.inspect()
tree
end
def transform(ast, binding \\ [], opts \\ [])
def transform([] = _expr_list, _binding, _opts), do: []
def transform([expr | rest] = _expr_list, binding, opts) do
[transform(expr, binding, opts) | transform(rest, binding, opts)]
end
def transform({:binary_op, _line, op, left, right}, binding, _) do
{op, binding, [transform(left), transform(right)]}
end
def transform({:unary_op, line, op, left}, _, _) do
{:op, line, op, transform(left)}
end
def transform({:integer, _, n} = _expr, _, _), do: n
end
"""
-module(elixir).
-export([eval/1, from_elixir/1, from_erlang/1]).
eval(String) ->
{value, Value, _} = erl_eval:expr(from_elixir(String), []),
Value.
% Temporary to aid debugging
from_elixir(String) ->
transform(parse(String)).
% Temporary to aid debugging
from_erlang(String) ->
{ok, Tokens, _} = erl_scan:string(String),
{ok, [Form]} = erl_parse:parse_exprs(Tokens),
Form.
parse(String) ->
{ok, Tokens, _} = elixir_lexer:string(String),
{ok, ParseTree} = elixir_parser:parse(Tokens),
ParseTree.
transform({ binary_op, Line, Op, Left, Right }) ->
{op, Line, Op, transform(Left), transform(Right)};
transform({ unary_op, Line, Op, Right }) ->
{op, Line, Op, transform(Right)};
transform({ integer, _, _ } = Expr) -> Expr.
"""