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). |
IyEgL3Vzci9iaW4vZW52IGVzY3JpcHQKCiUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUKJSBlcmxhc20KJSBBIHNjcmlwdCB0byB0YWtlIGVybGFuZyBjb2RlIGZyb20gdGhlIGNvbW1hbmQgbGluZSBhbmQgZGlzcGxheSB0aGUgZ2VuZXJhdGVkCiUgQkVBTSBhc3NlbWJsZXIuICBUaGUgcGFzc2VkLWluIGNvZGUgbXVzdCBjb25zaXN0IG9mIG9uZSBvciBtb3JlIGNvbXBsZXRlCiUgZnVuY3Rpb25zLgolCm1haW4gKFN0cmluZ3MpIC0+CiAgQXNtID0gbGlzdHM6ZmxhdHRlbigKICAgICAgICAgIGxpc3RzOm1hcChmdW4gKEEpIC0+CiAgICAgICAgICAgICAgICAgICAgICBjb21waWxlKCItbW9kdWxlKG51bGwpLiAtY29tcGlsZShleHBvcnRfYWxsKS4gIiArKyBBKQogICAgICAgICAgICAgICAgICAgIGVuZCwKICAgICAgICAgICAgICAgICAgICBTdHJpbmdzKSksCiAgaW86Zm9ybWF0KCJ+cH5uIiwgW0FzbV0pLgoKJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlCiUgY29tcGlsZS8xCiUgVGFrZSBhIHN0cmluZyBhbmQgcmV0dXJuIHRoZSBCRUFNICJhc3NlbWJsZXIiIHRoYXQgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBpdC4KJSBTaW5jZSB0aGUgbW9kdWxlIGlzIGEgYm9ndXMgd3JhcHBlciwgc3RyaXAgYW55IG1vZHVsZS1yZWxhdGVkIGluZm9ybWF0aW9uCiUgZmlyc3QuCiUKY29tcGlsZSAoU3RyaW5nKSAtPgogIHtvaywgbnVsbCwgQmluUmV0fSA9IGNvbXBpbGU6Zm9ybXMocGFyc2UoZm9ybXModG9rZW5zKFN0cmluZykpKSwgWydTJ10pLAogIHtfLCBfLCBfLCBBc20sIF99ID0gQmluUmV0LAogIGxpc3RzOmZpbHRlcihmdW4gKEEpIC0+CiAgICAgICAgICAgICAgICAgY2FzZSBBIG9mCgkgICAgICAgICAgIHtmdW5jdGlvbiwgbW9kdWxlX2luZm8sIF8sIF8sIF99IC0+IGZhbHNlOwogICAgICAgICAgICAgICAgICAgXyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLT4gdHJ1ZQogICAgICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgICBlbmQsCiAgICAgICAgICAgICAgIEFzbSkuCgolJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUKJSB0b2tlbnMvMQolIFRha2UgYSBzdHJpbmcgYW5kIHJldHVybiBhIGxpc3Qgb2YgdG9rZW5zIG1hZGUgZnJvbSBpdC4KJQp0b2tlbnMgKFN0cmluZykgLT4KICB7b2ssIFRva2VucywgX30gPSBlcmxfc2NhbjpzdHJpbmcoU3RyaW5nKSwKICBUb2tlbnMuCgolJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUKJSBmb3Jtcy8xCiUgVGFrZSBhIGxpc3Qgb2YgdG9rZW5zIChmcm9tIGVybF9zY2FuOiopIGFuZCByZXR1cm4gYSBsaXN0IG9mIGFic3RyYWN0IGZvcm1zLgolCmZvcm1zIChMaXN0KSAgICAgIC0+IGZvcm1zKExpc3QsIFtdKS4KCiUlJSUlJSUlJSUlJSUlJSUlJSUKJSBmb3Jtcy8yCiUgV29ya2VyIGZ1bmN0aW9uIGZvciBmb3Jtcy8xIHdoaWNoIGFjY3VtdWxhdGVzIGEgbGlzdCBvZiBmb3JtcyBmb3IgbGF0ZXIgdXNlCiUgd2l0aCBlcmxfcGFyc2U6cGFyc2VfZm9ybS8yLgolCmZvcm1zIChbXSwgQWNjKSAgIC0+IEFjYzsKZm9ybXMgKExpc3QsIEFjYykgLT4gCiAge0Zvcm0sIFtffFJlc3RdfSA9IGxpc3RzOnNwbGl0d2l0aChmdW4oQSkgLT4gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEEgLz0ge2RvdCwgMX0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdCksCiAgZm9ybXMoUmVzdCwgQWNjICsrIFtGb3JtICsrIFt7ZG90LCAxfV1dKS4KCiUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJQolIHBhcnNlLzEKJSBUYWtlIGEgbGlzdCBvZiBsaXN0cyBvZiB0b2tlbnMsIG9uZSBsaXN0IHBlciBmb3JtLCBhbmQgZ2VuZXJhdGUgYSBsaXN0IG9mCiUgY29ycmVzcG9uZGluZyBhYnN0cmFjdCBmb3Jtcy4KJQpwYXJzZSAoTGlzdCkgLT4KICBsaXN0czptYXAoZnVuKEEpIC0+IAogICAgICAgICAgICAgIHtvaywgQWJzRm9ybX0gPSBlcmxfcGFyc2U6cGFyc2VfZm9ybShBKSwKICAgICAgICAgICAgICBBYnNGb3JtCiAgICAgICAgICAgIGVuZCwgCiAgICAgICAgICAgIExpc3QpLgo=


