From 7b9c1b856be74b87deef83b1b847adce11a789b0 Mon Sep 17 00:00:00 2001 From: radrow Date: Tue, 8 Jun 2021 11:26:18 +0200 Subject: [PATCH] Upgrade doc generation --- src/aeb_fate_generate_docs.erl | 109 +++++++++++++++++++++++++++++++++ src/aeb_fate_generate_ops.erl | 50 +-------------- 2 files changed, 110 insertions(+), 49 deletions(-) create mode 100644 src/aeb_fate_generate_docs.erl diff --git a/src/aeb_fate_generate_docs.erl b/src/aeb_fate_generate_docs.erl new file mode 100644 index 0000000..e69a77c --- /dev/null +++ b/src/aeb_fate_generate_docs.erl @@ -0,0 +1,109 @@ +-module(aeb_fate_generate_docs). + +-export([generate_documentation/2, generate_documentation/3]). + +-export( + [ gen_protocol_opcodes_flags_and_gas/1 + , gen_protocol_description_of_operations/1 + ]). + +generate_documentation(Filename, Fields) -> + generate_documentation(Filename, Fields, fun(_) -> true end). +generate_documentation(Filename, Fields, Filter) when is_function(Filter, 1) -> + {ok, File} = file:open(Filename, [write]), + Instructions = + lists:flatten( + [gen_doc_for_op(Op, [F || F <- Fields]) + ++ "\n" || Op <- aeb_fate_generate_ops:get_ops(), Filter(Op)]), + Header = + lists:flatten( + "|" ++ [" " ++ header_name(F) ++ " |" || F <- Fields] ++ "\n" + ), + Separator = + lists:flatten( + "|" ++ [" " ++ ["-" || _ <- header_name(F)] ++ " |" || F <- Fields] ++ "\n" + ), + io:format(File, "~s~s~s\n", [Header, Separator, Instructions]), + file:close(File). + +header_name(opname) -> + "Name"; +header_name(opcode) -> + "Opcode"; +header_name(arity) -> + "Arity"; +header_name(end_bb) -> + "Ends basic block"; +header_name(in_auth) -> + "Allowed in auth"; +header_name(offchain) -> + "Allowed offchain"; +header_name(format) -> + "Args"; +header_name(doc) -> + "Description"; +header_name(gas) -> + "Gas cost"; +header_name(arg_types) -> + "Arg types"; +header_name(res_type) -> + "Res type". + +gen_doc_for_op(#{ opname := OpName + , opcode := OpCode + , arity := Arity + , end_bb := EndBB + , in_auth := InAuth + , offchain := AllowedOffchain + , format := FateFormat + , doc := Doc + , gas := Gas + , arg_types := ArgTypes + , res_type := ResType + }, Fields) -> + "| " ++ + string:join( + [ case Field of + opname -> io_lib:format("`~s`", [OpName]); + opcode -> io_lib:format("0x~.16b", [OpCode]); + arity -> io_lib:format("~p", [Arity]); + end_bb -> io_lib:format("~p", [EndBB]); + in_auth -> io_lib:format("~p", [InAuth]); + offchain -> io_lib:format("~p", [AllowedOffchain]); + format -> + case FateFormat of + [] -> ""; + _ -> lists:join( + " ", + [format_arg_doc(A) || + A <- + lists:zip(FateFormat, + lists:seq(0,length(FateFormat)-1))]) + end; + doc -> Doc; + gas -> io_lib:format("~p", [Gas]); + arg_types -> io_lib:format("~p", [ArgTypes]); + res_type -> io_lib:format("~p", [ResType]) + end + || Field <- Fields + ], + " | ") ++ " |". + +format_arg_doc({a, N}) -> io_lib:format("Arg~w", [N]); +format_arg_doc({is,_N}) -> "Identifier"; +format_arg_doc({ii,_N}) -> "Integer"; +format_arg_doc({li,_N}) -> "[Integers]"; +format_arg_doc({t,_N}) -> "Type". + + +%% --- protocol documentation --- + +gen_protocol_description_of_operations(Filename) -> + generate_documentation( + Filename, [opname, format, doc, arg_types, res_type] + ). + +gen_protocol_opcodes_flags_and_gas(Filename) -> + generate_documentation( + Filename, [opcode, opname, end_bb, in_auth, offchain, gas] + ). diff --git a/src/aeb_fate_generate_ops.erl b/src/aeb_fate_generate_ops.erl index 35e012e..b107ecc 100644 --- a/src/aeb_fate_generate_ops.erl +++ b/src/aeb_fate_generate_ops.erl @@ -2,7 +2,6 @@ -export([ gen_and_halt/1 , generate/0 - , generate_documentation/1 , get_ops/0 , test_asm_generator/1 ]). @@ -46,7 +45,7 @@ check_numbering(_, []) -> true. -define(GAS_IRIS(A, B), [{?IRIS_PROTOCOL_VSN, B}, {?LIMA_PROTOCOL_VSN, A}]). ops_defs() -> - %% Opname, Opcode, end_bb, in_auth offchain, gas, format, Constructor, ArgType, ResType, Documentation + %% Opname, Opcode, end_bb, in_auth,offchain, gas, format, Constructor, ArgType, ResType, Documentation [ { 'RETURN', 16#00, true, true, true, ?GAS(10), [], return, {}, any, "Return from function call, top of stack is return value . The type of the retun value has to match the return type of the function."} , { 'RETURNR', 16#01, true, true, true, ?GAS(10), [a], returnr, {any}, any, "Push Arg0 and return from function. The type of the retun value has to match the return type of the function."} , { 'CALL', 16#02, true, true, true, ?GAS(10), [a], call, {string}, any, "Call the function Arg0 with args on stack. The types of the arguments has to match the argument typs of the function."} @@ -778,50 +777,3 @@ gen_variant() -> 3 -> "(| 2 | 0 | ( " ++ imm_arg() ++ ", " ++ imm_arg() ++ " ) |)" end. - -%% TODO: add gas cost and end_bb/in_auth? -generate_documentation(Filename) -> - {ok, File} = file:open(Filename, [write]), - Instructions = lists:flatten([gen_doc(Op)++"\n" || Op <- get_ops()]), - io:format(File, - "### Operations\n\n" - "| OpCode | Name | Args | Description |\n" - "| --- | --- | --- | --- |\n" - "~s" - , [Instructions]), - io:format(File, "\n", []), - file:close(File). - -gen_doc(#{ opname := Name - , opcode := OpCode - , arity := _Arity - , end_bb := _EndBB - , format := FateFormat - , macro := _Macro - , type_name := _TypeName - , doc := Doc - , gas := _Gas - , type := _Type - , constructor := _Constructor - , constructor_type := _ConstructorType - }) -> - Arguments = - case FateFormat of - [] -> ""; - _ -> lists:join(" ", - [format_arg_doc(A) || - A <- - lists:zip(FateFormat, - lists:seq(0,length(FateFormat)-1))]) - end, - io_lib:format("| 0x~.16b | ~w | ~s | ~s |\n", - [ OpCode - , Name - , Arguments - , Doc]). - -format_arg_doc({a, N}) -> io_lib:format("Arg~w", [N]); -format_arg_doc({is,_N}) -> "Identifier"; -format_arg_doc({ii,_N}) -> "Integer"; -format_arg_doc({li,_N}) -> "[Integers]"; -format_arg_doc({t,_N}) -> "Type".