language: Erlang (erl-5.7.3)
date: 1062 days 11 hours ago
link:
visibility: public
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
#! /usr/bin/env escript
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% erlasm
% A script to take erlang code from the command line and display the generated
% BEAM assembler.  The passed-in code must consist of one or more complete
% functions.
%
main (Strings) ->
  Asm = lists:flatten(
          lists:map(fun (A) ->
                      compile("-module(null). -compile(export_all). " ++ A)
                    end,
                    Strings)),
  io:format("~p~n", [Asm]).
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% compile/1
% Take a string and return the BEAM "assembler" that results from compiling it.
% Since the module is a bogus wrapper, strip any module-related information
% first.
%
compile (String) ->
  {ok, null, BinRet} = compile:forms(parse(forms(tokens(String))), ['S']),
  {_, _, _, Asm, _} = BinRet,
  lists:filter(fun (A) ->
                 case A of
                   {function, module_info, _, _, _} -> false;
                   _                                -> true
                 end
               end,
               Asm).
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% tokens/1
% Take a string and return a list of tokens made from it.
%
tokens (String) ->
  {ok, Tokens, _} = erl_scan:string(String),
  Tokens.
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% forms/1
% Take a list of tokens (from erl_scan:*) and return a list of abstract forms.
%
forms (List)      -> forms(List, []).
 
%%%%%%%%%%%%%%%%%%%
% forms/2
% Worker function for forms/1 which accumulates a list of forms for later use
% with erl_parse:parse_form/2.
%
forms ([], Acc)   -> Acc;
forms (List, Acc) -> 
  {Form, [_|Rest]} = lists:splitwith(fun(A) -> 
                                       A /= {dot, 1} 
                                     end, 
                                     List),
  forms(Rest, Acc ++ [Form ++ [{dot, 1}]]).
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% parse/1
% Take a list of lists of tokens, one list per form, and generate a list of
% corresponding abstract forms.
%
parse (List) ->
  lists:map(fun(A) -> 
              {ok, AbsForm} = erl_parse:parse_form(A),
              AbsForm
            end, 
            List).