Skip to content

Instantly share code, notes, and snippets.

@RumataEstor
Created December 12, 2010 00:59
Show Gist options
  • Save RumataEstor/737760 to your computer and use it in GitHub Desktop.
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.
#! /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