Created
December 12, 2010 00:59
-
-
Save RumataEstor/737760 to your computer and use it in GitHub Desktop.
A script to take erlang code from the command line and display the generated BEAM assembler.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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) -> | |
case A of | |
{dot, _} -> false; | |
_ -> true | |
end | |
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). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment