johnbender / unraverl

An erlang module built to provide language features and other operations through manipulation of the abstract form.

This URL has Read+Write access

johnbender (author)
Sat Aug 08 18:38:57 -0700 2009
commit  cc8310fab4538cefd035502f95327bf894130292
tree    6c650a303b615b99e0220b92d9bc8459be6dbc10
parent  f66c0ed3801b3aa8aa34eaaefee06f06086f0744
unraverl / util.erl
100644 84 lines (56 sloc) 2.468 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
-module(util).
 
-export([find_function/2,
replace/3,
replace/2,
find_attribute/2,
args_list_form/3,
to_string/1]).
 
 
find_function(Form, Name) ->
    [Result] = [{SType, LineNum, SName, Arity, Clauses} || {SType, LineNum, SName, Arity, Clauses} <- Form, Name == SName],
    Result.
    
 
%If the fun can handle both matching and replacement
replace(Form, ReplaceFun) when is_tuple(Form) ->
    map_tuple(ReplaceFun(Form), ?MODULE, replace, [ReplaceFun]);
 
replace(Form, ReplaceFun) when is_list(Form) ->
    [replace(X, ReplaceFun) || X <- ReplaceFun(Form)];
 
replace(Form, ReplaceFun) ->
    ReplaceFun(Form).
 
 
 
%If the third argument is not a replacement fun but a data structure
replace(Form, CompareFun, Replacement) when is_function(Replacement) == false ->
    replace(Form, CompareFun, fun(_) -> Replacement end);
 
%If the matching and replacement funs are separated
replace(Form, CompareFun, ReplaceFun) when is_tuple(Form) ->
    case CompareFun(Form) of
true -> ReplaceFun(Form);
_ -> map_tuple(Form, ?MODULE, replace, [CompareFun, ReplaceFun])
    end;
 
replace(Form, CompareFun, ReplaceFun) when is_list(Form) ->
    case CompareFun(Form) of
true -> ReplaceFun(Form);
_ -> [replace(X, CompareFun, ReplaceFun) || X <- Form]
    end;
 
replace(Form, CompareFun, ReplaceFun) ->
    case CompareFun(Form) of
true -> ReplaceFun(Form);
_ -> Form
    end.
 
 
map_tuple(Tuple, Module, Function, Args) when is_tuple(Tuple) ->
    map_tuple(tuple_to_list(Tuple), Module, Function, Args);
 
map_tuple([Head|T], Module, Function, Args) ->
    map_tuple(T, Module, Function, Args, { apply(Module, Function, [Head|Args]) }).
 
map_tuple([Head|T], Module, Function, Args, Acc) ->
    Tuple = erlang:append_element(Acc, apply(Module, Function, [Head|Args])),
    map_tuple(T, Module, Function, Args, Tuple);
 
map_tuple([], _, _, _, Acc) -> Acc.
 
 
find_attribute(Form, Name) ->
    [{SType, LineNum, SName, Value} || {SType, LineNum, SName, Value} <- Form, Name == SName].
 
 
args_list_form(Count, LineNum, NameSeed) when is_list(NameSeed) ->
    [{var, LineNum, list_to_atom(NameSeed ++ to_string(Num))} || Num <- lists:reverse(lists:seq(1, Count))].
 
 
to_string(Object) when is_number(Object) ->
    lists:flatten(io_lib:format("~w" , [Object]));
 
to_string(Object) when is_atom(Object) ->
    atom_to_list(Object);
 
to_string(Object) when is_binary(Object) ->
    binary_to_list(Object);
 
to_string(Object) when is_list(Object) ->
    Object.