Current section
Files
Jump to
Current section
Files
lib/elixir_script/translator/rewriter.ex
defmodule ElixirScript.Translator.Rewriter do
# :erlang, :lists, :maps, :beam_lib, :binary, :calendar, :digraph,
# :epp, :erl_lint, :erl_internal, :erl_expand_records, :erl_eval,
# :ets, :filename, :gen_event, :gen_server, :io, :io_lib, :math,
# :ordsets, :proc_lib, :rand, :re, :sets, :supervisor,:sys, :timer,
# :unicode, :os, :application, :code, :gen_tcp, :error_logger, :gen,
# :file
# http://erlang.org/doc/applications.html
def rewrite({{:., _, [:erlang, :abs]}, _, [number]}) do
quote do: Math.abs(unquote(number))
end
def rewrite({{:., _, [:erlang, :apply]}, _, [fun, args]}) do
quote do: unquote(fun).apply(nil, unquote(args))
end
def rewrite({{:., _, [:erlang, :apply]}, _, [module, fun, args]}) do
quote do: unquote(module).unquote(fun).apply(nil, unquote(args))
end
def rewrite({{:., _, [:erlang, :binary_part]}, _, [binary, start, length]})do
quote do: unquote(binary).substring(unquote(start), unquote(length))
end
def rewrite({{:., _, [:erlang, :bit_size]}, _, [bitstring]})do
quote do: unquote(bitstring).bit_size
end
def rewrite({{:., _, [:erlang, :byte_size]}, _, [bitstring]})do
quote do: unquote(bitstring).byte_size
end
def rewrite({{:., _, [:erlang, :div]}, _, [left, right]}) do
quote do: unquote(left) / unquote(right)
end
def rewrite({{:., _, [:erlang, :exit]}, _, [reason]}) do
# TODO: implement exit
quote do: nil
end
def rewrite({{:., _, [:erlang, :hd]}, _, [list]}) do
quote do: unquote(list)[0]
end
def rewrite({{:., _, [:erlang, :is_atom]}, _, [term]}) do
quote do: JS.typeof(unquote(term)) === "symbol"
end
def rewrite({{:., _, [:erlang, :is_binary]}, _, [term]}) do
quote do: JS.typeof(unquote(term)) === "string"
end
def rewrite({{:., _, [:erlang, :is_bitstring]}, _, [term]}) do
quote do: is_binary(unquote(term)) || JS.instanceof(unquote(term), Elixir.Core.BitString)
end
def rewrite({{:., _, [:erlang, :is_boolean]}, _, [term]}) do
quote do: JS.typeof(unquote(term)) === "boolean" || JS.instanceof(unquote(term), Boolean)
end
def rewrite({{:., _, [:erlang, :is_float]}, _, [term]}) do
quote do: (JS.typeof(unquote(term)) === "number" || JS.instanceof(unquote(term), Number)) && !Number.isInteger(unquote(term))
end
def rewrite({{:., _, [:erlang, :is_function]}, _, [term]}) do
quote do: JS.typeof(unquote(term)) === "function" || JS.instanceof(unquote(term), Function)
end
def rewrite({{:., _, [:erlang, :is_function]}, _, [term, _]}) do
quote do: JS.typeof(unquote(term)) === "function" || JS.instanceof(unquote(term), Function)
end
def rewrite({{:., _, [:erlang, :is_integer]}, _, [term]}) do
quote do: Number.isInteger(unquote(term))
end
def rewrite({{:., _, [:erlang, :is_list]}, _, [term]}) do
quote do: Array.isArray(unquote(term))
end
def rewrite({{:., _, [:erlang, :is_number]}, _, [term]}) do
quote do: JS.typeof(unquote(term)) === "number" || JS.instanceof(unquote(term), Number)
end
def rewrite({{:., _, [:erlang, :is_pid]}, _, [term]}) do
quote do: JS.instanceof(unquote(term), Elixir.Core.PID)
end
def rewrite({{:., _, [:erlang, :is_port]}, _, [_term]}) do
#TODO implement is_port
quote do: false
end
def rewrite({{:., _, [:erlang, :is_reference]}, _, [_term]}) do
#TODO implement is_reference
quote do: false
end
def rewrite({{:., _, [:erlang, :is_tuple]}, _, [term]}) do
quote do: JS.instanceof(unquote(term), Elixir.Core.Tuple)
end
def rewrite({{:., _, [:erlang, :is_map]}, _, [term]}) do
quote do: JS.typeof(unquote(term)) === "object" || JS.instanceof(unquote(term), Object)
end
def rewrite({{:., _, [:erlang, :length]}, _, [list]}) do
quote do: unquote(list).length
end
def rewrite({{:., _, [:erlang, :make_ref]}, _, []}) do
#TODO: implement make_ref
quote do: nil
end
def rewrite({{:., _, [:erlang, :map_size]}, _, [map]}) do
quote do: Object.keys(unquote(map)).length
end
def rewrite({{:., _, [:erlang, :max]}, _, [first, second]}) do
quote do: Math.max(unquote(first), unquote(second))
end
def rewrite({{:., _, [:erlang, :min]}, _, [first, second]}) do
quote do: Math.min(unquote(first), unquote(second))
end
def rewrite({{:., _, [:erlang, :node]}, _, []}) do
quote do: :nonode@nohost
end
def rewrite({{:., _, [:erlang, :node]}, _, [_]}) do
quote do: :nonode@nohost
end
def rewrite({{:., _, [:erlang, :rem]}, _, [first, second]}) do
{:%, [], [first, second]}
end
def rewrite({{:., _, [:erlang, :round]}, _, [number]}) do
quote do: Math.round(unquote(number))
end
def rewrite({{:., _, [:erlang, :send]}, _, [dest, msg]}) do
#TODO implement send
quote do: unquote(msg)
end
def rewrite({{:., _, [:erlang, :self]}, _, []}) do
#TODO: implement self
quote do: nil
end
def rewrite({{:., _, [:erlang, :spawn]}, _, [_fun]}) do
#TODO: implement spawn
quote do: nil
end
def rewrite({{:., _, [:erlang, :spawn]}, _, [_module, _fun, _args]}) do
#TODO: implement spawn
quote do: nil
end
def rewrite({{:., _, [:erlang, :spawn_link]}, _, [_fun]}) do
#TODO: implement spawn_link
quote do: nil
end
def rewrite({{:., _, [:erlang, :spawn_link]}, _, [_module, _fun, _args]}) do
#TODO: implement spawn_link
quote do: nil
end
def rewrite({{:., _, [:erlang, :spawn_monitor]}, _, [_fun]}) do
#TODO: implement spawn_monitor
quote do: nil
end
def rewrite({{:., _, [:erlang, :spawn_monitor]}, _, [_module, _fun, _args]}) do
#TODO: implement spawn_monitor
quote do: nil
end
def rewrite({{:., _, [:erlang, :throw]}, _, [term]}) do
quote do: JS.throw(unquote(term))
end
def rewrite({{:., _, [:erlang, :tl]}, _, [list]}) do
quote do: unquote(list).splice(1)
end
def rewrite({{:., _, [:erlang, :trunc]}, _, [number]}) do
quote do: Math.floor(unquote(number))
end
def rewrite({{:., _, [:erlang, :tuple_size]}, _, [tuple]}) do
quote do: unquote(tuple).length
end
def rewrite({{:., _, [:erlang, operator]}, _, [left, right]}) when operator in [:+, :-, :*, :/, :<, :>, :>=, :==] do
{operator, [], [left, right]}
end
def rewrite({{:., _, [:erlang, operator]}, _, [value]}) when operator in [:+, :-] do
{operator, [], [value]}
end
def rewrite({{:., _, [:erlang, :++]}, _, [left, right]}) do
quote do: unquote(left).concat(unquote(right))
end
def rewrite({{:., _, [:erlang, :--]}, _, [list, element]}) do
quote do: unquote(list).slice(unquote(list).indexOf(unquote(element)) + 1)
end
def rewrite({{:., _, [:erlang, :not]}, _, [value]}) do
{:!, [], [value]}
end
def rewrite({{:., _, [:erlang, :"=<"]}, _, [left, right]}) do
{:<=, [], [left, right]}
end
def rewrite({{:., _, [:erlang, :"/="]}, _, [left, right]}) do
{:!=, [], [left, right]}
end
def rewrite({{:., _, [:erlang, :"=:="]}, _, [left, right]}) do
{:===, [], [left, right]}
end
def rewrite({{:., _, [:erlang, :"=/="]}, _, [left, right]}) do
{:!==, [], [left, right]}
end
def rewrite({{:., _, [:erlang, :element]}, _, [index, tuple]}) do
quote do: unquote(tuple).get(unquote(index) - 1)
end
def rewrite({{:., _, [:erlang, :setelement]}, _, [index, tuple, value]}) do
quote do: unquote(tuple).put_elem(unquote(index) - 1, unquote(value))
end
def rewrite({{:., _, [:erlang, :orelse]}, _, [left, right]}) do
{:||, [], [left, right]}
end
def rewrite({{:., _, [:erlang, :or]}, _, [left, right]}) do
{:||, [], [left, right]}
end
def rewrite({{:., _, [:erlang, :andalso]}, _, [left, right]}) do
{:&&, [], [left, right]}
end
def rewrite({{:., _, [:erlang, :error]}, _, [error]}) do
quote do: JS.throw(unquote(error))
end
def rewrite({{:., _, [:erlang, :raise]}, _, [_class, reason, _stacktrace]}) do
quote do: JS.throw(unquote(reason))
end
def rewrite({{:., _, [:erlang, :atom_to_binary]}, _, [atom, _]}) do
quote do: Symbol.keyFor(unquote(atom))
end
def rewrite({{:., _, [:erlang, :atom_to_list]}, _, [atom]}) do
quote do: to_string(unquote(atom)).split("")
end
def rewrite({{:., _, [:erlang, :bnot]}, _, [expr]}) do
{:"~", [], [expr]}
end
def rewrite({{:., _, [:erlang, :band]}, _, [left, right]}) do
{:&, [], [left, right]}
end
def rewrite({{:., _, [:erlang, :bor]}, _, [left, right]}) do
{:|, [], [left, right]}
end
def rewrite({{:., _, [:erlang, :bxor]}, _, [left, right]}) do
{:^, [], [left, right]}
end
def rewrite({{:., _, [:erlang, :bsl]}, _, [left, right]}) do
{:"<<", [], [left, right]}
end
def rewrite({{:., _, [:erlang, :bsr]}, _, [left, right]}) do
{:">>", [], [left, right]}
end
def rewrite({{:., _, [:erlang, :function_exported]}, _, [_, _, _]}) do
quote do: true
end
def rewrite({{:., _, [:erlang, :make_tuple]}, _, [size, data]}) do
quote do: JS.new(Elixir.Core.Tuple, List.duplicate(unquote(size), unquote(data)))
end
def rewrite({{:., _, [:erlang, :insert_element]}, _, [index, tuple, term]}) do
quote do: unquote(tuple).put_elem(unquote(index) - 1, unquote(term))
end
def rewrite({{:., _, [:erlang, :tuple_to_list]}, _, [tuple]}) do
quote do: unquote(tuple).values
end
def rewrite({{:., _, [:erlang, :append_element]}, _, [tuple, value]}) do
quote do: unquote(tuple).put_elem(unquote(tuple).length, unquote(value))
end
def rewrite({{:., _, [:erlang, :delete_element]}, _, [index, tuple]}) do
quote do: unquote(tuple).remove_elem(unquote(index))
end
def rewrite({{:., _, [:lists, :map]}, _, [fun, list]}) do
quote do: unquote(list).map(unquote(fun))
end
def rewrite({{:., _, [:lists, :member]}, _, [elem, list]}) do
quote do: unquote(list).indexOf(unquote(elem)) > -1
end
def rewrite({{:., _, [:lists, :foldl]}, _, [fun, acc, list]}) do
quote do: Elixir.Core.Functions.foldl(unquote(fun), unquote(acc), unquote(list))
end
def rewrite({{:., _, [:lists, :foldr]}, _, [fun, acc, list]}) do
quote do: Elixir.Core.Functions.foldr(unquote(fun), unquote(acc), unquote(list))
end
def rewrite({{:., _, [:lists, :keymember]}, _, [key, n, list]}) do
quote do: Elixir.Core.Functions.keymember(unquote(key), unquote(n), unquote(list))
end
def rewrite({{:., _, [:lists, :keydelete]}, _, [key, n, list]}) do
quote do: Elixir.Core.Functions.keydelete(unquote(key), unquote(n), unquote(list))
end
def rewrite({{:., _, [:lists, :keystore]}, _, [key, n, list, newtuple]}) do
quote do: Elixir.Core.Functions.keystore(unquote(key), unquote(n), unquote(list), unquote(newtuple))
end
def rewrite({{:., _, [:lists, :keytake]}, _, [key, n, list]}) do
quote do: Elixir.Core.Functions.keystore(unquote(key), unquote(n), unquote(list))
end
def rewrite({{:., _, [:lists, :keyfind]}, _, [key, n, list]}) do
quote do: Elixir.Core.Functions.keyfind(unquote(key), unquote(n), unquote(list))
end
def rewrite({{:., _, [:lists, :keyreplace]}, _, [key, n, list, newtuple]}) do
quote do: Elixir.Core.Functions.keyreplace(unquote(key), unquote(n), unquote(list), unquote(newtuple))
end
def rewrite({{:., _, [:lists, :keysort]}, _, [n, tuplelist]}) do
#TODO: implement keysort
quote do: unquote(tuplelist)
end
def rewrite({{:., _, [:lists, :reverse]}, _, [list]}) do
quote do: Elixir.Core.Functions.reverse(unquote(list))
end
def rewrite({{:., _, [:lists, :reverse]}, _, [list, tail]}) do
quote do: Elixir.Core.Functions.reverse(unquote(list)) ++ unquote(tail)
end
def rewrite({{:., _, [:lists, :flatten]}, _, [list]}) do
quote do: Elixir.Core.Functions.flatten(unquote(list))
end
def rewrite({{:., _, [:lists, :flatten]}, _, [list, tail]}) do
quote do: Elixir.Core.Functions.flatten(unquote(list), unquote(tail))
end
def rewrite({{:., _, [:lists, :delete]}, _, [elem, list]}) do
quote do: Elixir.Core.Functions.remove_from_list(unquote(list), unquote(elem))
end
def rewrite({{:., _, [:lists, :duplicate]}, _, [n, elem]}) do
quote do: Elixir.Core.Functions.duplicate(unquote(n), unquote(elem))
end
def rewrite({{:., _, [:lists, :mapfoldl]}, _, [fun, acc, list]}) do
quote do: Elixir.Core.Functions.mapfoldl(unquote(fun), unquote(acc), unquote(list))
end
def rewrite({{:., _, [:lists, :sort]}, _, [list]}) do
quote do: unquote(list).sort()
end
#TODO: Implement sort
def rewrite({{:., _, [:lists, :sort]}, _, [_fun, list]}) do
quote do: unquote(list)
end
def rewrite({{:., _, [:lists, :filter]}, _, [pred, list]}) do
quote do: unquote(list).filter(unquote(pred))
end
def rewrite({{:., _, [:lists, :filtermap]}, _, [fun, list]}) do
quote do: Elixir.Core.Functions.filtermap(unquote(fun), unquote(list))
end
def rewrite({{:., _, [:lists, :concat]}, _, [things]}) do
quote do: unquote(things).join("")
end
def rewrite({{:., _, [:erlang, :binary_to_atom]}, _, [binary, _]}) do
quote do: Symbol.for(unquote(binary))
end
def rewrite({{:., _, [:erlang, :binary_to_existing_atom]}, _, [binary, _]}) do
quote do: Symbol.for(unquote(binary))
end
def rewrite({{:., _, [:erlang, :list_to_atom]}, _, [char_list]}) do
quote do: Symbol.for(unquote(char_list))
end
def rewrite({{:., _, [:erlang, :list_to_existing_atom]}, _, [char_list]}) do
quote do: Symbol.for(unquote(char_list))
end
def rewrite({{:., _, [:erlang, :list_to_tuple]}, _, [list]}) do
quote do: JS.new(Elixir.Core.Tuple, unquote(list))
end
def rewrite({{:., _, [:erlang, :list_to_float]}, _, [list]}) do
quote do: parseFloat(unquote(list))
end
def rewrite({{:., _, [:erlang, :list_to_integer]}, _, [list]}) do
quote do: parseInt(unquote(list))
end
def rewrite({{:., _, [:erlang, :list_to_integer]}, _, [list, base]}) do
quote do: parseInt(unquote(list), unquote(base))
end
def rewrite({{:., _, [:erlang, :integer_to_binary]}, _, [integer]}) do
quote do: unquote(integer).toString()
end
def rewrite({{:., _, [:erlang, :integer_to_binary]}, _, [integer, base]}) do
quote do: unquote(integer).toString(unquote(base))
end
def rewrite({{:., _, [:erlang, :integer_to_list]}, _, [integer]}) do
quote do: unquote(integer).toString()
end
def rewrite({{:., _, [:erlang, :integer_to_list]}, _, [integer, base]}) do
quote do: unquote(integer).toString(unquote(base))
end
def rewrite({{:., _, [:erlang, :float_to_binary]}, _, [float]}) do
quote do: unquote(float).toString()
end
def rewrite({{:., _, [:erlang, :float_to_binary]}, _, [float, base]}) do
quote do: unquote(float).toString(unquote(base))
end
def rewrite({{:., _, [:erlang, :float_to_list]}, _, [float]}) do
quote do: unquote(float).toString()
end
def rewrite({{:., _, [:erlang, :float_to_list]}, _, [float, base]}) do
quote do: unquote(float).toString(unquote(base))
end
def rewrite({{:., _, [:erlang, :binary_to_float]}, _, [binary]}) do
quote do: parseFloat(unquote(binary))
end
def rewrite({{:., _, [:erlang, :binary_to_integer]}, _, [binary]}) do
quote do: parseInt(unquote(binary))
end
def rewrite({{:., _, [:erlang, :binary_to_integer]}, _, [binary, base]}) do
quote do: parseInt(unquote(binary), unquote(base))
end
def rewrite({{:., _, [:maps, :is_key]}, _, [key, map]}) do
quote do: unquote(key) in Elixir.Core.Functions.get_object_keys(unquote(map))
end
def rewrite({{:., _, [:maps, :put]}, _, [key, value, map]}) do
quote do: Elixir.Core.Functions.add_property_to_map(unquote(map), unquote(key), unquote(value))
end
def rewrite({{:., _, [:maps, :update]}, _, [key, value, map]}) do
quote do: Elixir.Core.Functions.update_map(unquote(map), unquote(key), unquote(value))
end
def rewrite({{:., _, [:maps, :find]}, _, [key, map]}) do
quote do: Elixir.Core.Functions.maps_find(unquote(key), unquote(map))
end
def rewrite({{:., _, [:maps, :remove]}, _, [key, map]}) do
quote do: Elixir.Core.Functions.delete_property_from_map(unquote(map), unquote(key))
end
def rewrite({{:., _, [:maps, :fold]}, _, [fun, init, map]}) do
quote do: Elixir.Core.Functions.maps_fold(unquote(fun), unquote(init), unquote(map))
end
def rewrite({{:., _, [:maps, :from_list]}, _, [list]}) do
quote do: Elixir.Core.Functions.maps_fold(unquote(list))
end
end