From c480c7a869fab251dffe7673b57765ed3c80e926 Mon Sep 17 00:00:00 2001 From: totoro Date: Wed, 12 Apr 2017 21:29:55 +0200 Subject: [PATCH] Add support of DS_Type_File --- densaku.aproj | 1 + densaku_lib | 2 +- src/generation/files.anubis | 57 +++++++++++++++++++++++++++++++++------------------------ src/generation/intermediate_type.anubis | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/generation/message_messages.anubis | 4 ++-- src/generation/types.anubis | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- src/generation/types_header.anubis | 38 +++++++++++++++++++++++++------------- src/generation/types_messages.anubis | 31 +++++++++++++------------------ src/main.anubis | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------- 9 files changed, 486 insertions(+), 153 deletions(-) create mode 100644 src/generation/intermediate_type.anubis diff --git a/densaku.aproj b/densaku.aproj index ba84aec..ae45584 100644 --- a/densaku.aproj +++ b/densaku.aproj @@ -566,6 +566,7 @@ + diff --git a/densaku_lib b/densaku_lib index aaa5024..e19a5e6 160000 --- a/densaku_lib +++ b/densaku_lib @@ -1 +1 @@ -Subproject commit aaa50241ac140b5441e8cfb34bd4e884a4828af7 +Subproject commit e19a5e659e24d4bf9c97e5a4f313f80a86414f5e diff --git a/src/generation/files.anubis b/src/generation/files.anubis index 3c4f501..46daf21 100644 --- a/src/generation/files.anubis +++ b/src/generation/files.anubis @@ -18,9 +18,9 @@ read generation/graphviz/graphviz_main.anubis public define Maybe(One) generate_message_files ( - List(DS_Type) types, //Types description - List(DS_Message) messages, - String destination_dir + List(DS_Type_File) type_files, //Types description + List(DS_Message) messages, + String destination_dir )= //before processing the generation we check if we need to do it, by checking the SHA1 generated with the //previous generation. If SHA1 is same, this means the database is exactly same and we have nothing to do. @@ -28,14 +28,14 @@ public define Maybe(One) //process. We serialize the types and messages model and make SHA1 of the result. This result is stored in file densaku.ini //in root of destination_dir - with current_types_SHA1 = to_ascii(sha1(serialize(types))), + with current_types_SHA1 = to_ascii(sha1(serialize(type_files))), with current_messages_SHA1 = to_ascii(sha1(serialize(messages))), println("\nDensaku Generator"); println("Destination dir: "+destination_dir); with ini = loadIniFile(destination_dir+"/densaku.ini"), - with types_SHA1 = readString(ini, "TYPES", "SHA1", "N/A"), + with types_SHA1 = "::", //readString(ini, "TYPES", "SHA1", "N/A"), with messages_SHA1 = readString(ini, "MESSAGES", "SHA1", "N/A"), println("Saved Types SHA1 = "+types_SHA1); @@ -48,25 +48,34 @@ public define Maybe(One) if types_SHA1 = current_types_SHA1 & messages_SHA1 = current_messages_SHA1 then success(println("Types and messages already generated, nothing to do")) else - if check_types(types) is - { - failure then failure, - success(_) then - - println("Generating types and message files"); - make_all_types(types, destination_dir); - - println("Generating messages collection"); - make_all_messages(messages, destination_dir); - - println("Generating graphviz"); - forget(make_graphviz_types(types, destination_dir)); - - writeString(ini, "TYPES", "SHA1", current_types_SHA1); - writeString(ini, "MESSAGES", "SHA1", current_messages_SHA1); - writeIniInfo(ini); - success(unique) - }. + if map_escape((DS_Type_File file) + |-> + since file is ds_type_file(output_dir, file_name, types), + if check_types(types) is + { + failure then failure, + success(_) then + + println("Generating types and message files"); + make_all_types(output_dir, file_name, types, destination_dir); + + println("Generating messages collection"); + make_all_messages(messages, destination_dir); + + println("Generating graphviz"); + forget(make_graphviz_types(types, destination_dir)); + + writeString(ini, "TYPES", "SHA1", current_types_SHA1); + writeString(ini, "MESSAGES", "SHA1", current_messages_SHA1); + writeIniInfo(ini); + success(unique) + }, + type_files) is + { + failure then failure, + success(_) then success(unique) + } +. global define DS_Generator_API ds_gen = diff --git a/src/generation/intermediate_type.anubis b/src/generation/intermediate_type.anubis new file mode 100644 index 0000000..be1979c --- /dev/null +++ b/src/generation/intermediate_type.anubis @@ -0,0 +1,132 @@ +/* + * Created by PyramIDE. + * User: フランスのトトロ aka (David RENÉ) + * Date: 12/04/2017 + * Time: 05:42 + * © Calexium + */ + +read tools/basis.anubis +read densaku_lib/types/ds_types.anubis +read system/lists.anubis + +define Bool + is_higher_level + ( + Int level, + String search_type, + List(DS_Type) beside_type, + Int beside_level + )= + if beside_type is + { + [] then false, + [h . t] then + since h is ds_type(name, _, _), + if search_type = name then + if beside_level > level then + true + else + false + else + is_higher_level(level, search_type, t, beside_level +1) + } +. + +define Bool + is_higher_level + ( + Int level, + String search_type, + List(DS_Type) beside_type + )= + is_higher_level(level, search_type, beside_type, 0) +. + +define List(String) + extract_intermediate_type + ( + Int level, //level of main type where belonging the component + List(DS_Component) components, + List(String) so_far, + List(DS_Type) beside_type + )= + if components is + { + [] then so_far, + [h . t] then + since h is component(_b_list, _anb_type, _name, _comment), + if _anb_type is ds_type(_type_name) then + if is_higher_level(level, _type_name, beside_type) then + extract_intermediate_type(level, t, append_once(so_far, _type_name), beside_type) + else + extract_intermediate_type(level, t, so_far, beside_type) + else if _anb_type is extern_type(_type_name, read_file) then + extract_intermediate_type(level, t, so_far, beside_type) + else + extract_intermediate_type(level, t, so_far, beside_type) + } +. + +define List(String) +/* look into each alternative + */ + extract_intermediate_type + ( + Int level, + List(DS_Alternative) alt, + List(String) so_far, + List(DS_Type) beside_type + )= + if alt is + { + [] then so_far, + [h . t] then + if h is + { + enum(_ , _) then extract_intermediate_type(level, t, so_far, beside_type) + alternative(_, _, components) then + extract_intermediate_type(level, t, extract_intermediate_type(level, components, so_far, beside_type), beside_type) + } + } +. + +public define List(String) + get_all_intermediate_type + ( + DS_Type ds_type, //Type from which we want to extract the extern types + Int level, + List(DS_Type) beside_type //all known type in same file + )= + since ds_type is ds_type(_, _, ds_alternatives), + extract_intermediate_type(level, ds_alternatives, [], beside_type) +. + +public define List(String) + get_all_intermediate_type + ( + List(DS_Type) beside_type, //all known type in same file + List(DS_Type) scrut, + Int level, + List(String) so_far + )= + if scrut is + { + [] then so_far, + [h . t] then + get_all_intermediate_type(beside_type, t, level+1, so_far + get_all_intermediate_type(h, level, beside_type)) + } +. + +public define List(String) + get_all_intermediate_type + ( + List(DS_Type) beside_type //all known type in same file + )= + get_all_intermediate_type(beside_type, beside_type, 0, []) +. + + if beside_type + since ds_type is ds_type(_, _, ds_alternatives), + extract_intermediate_type(level, ds_alternatives, [], beside_type) +. diff --git a/src/generation/message_messages.anubis b/src/generation/message_messages.anubis index 936e7b5..a86452a 100644 --- a/src/generation/message_messages.anubis +++ b/src/generation/message_messages.anubis @@ -144,9 +144,9 @@ define String with name = "_"+to_lower(field_name), indent + "// [Field's type = "+(if b_list is list then "List(" else "")+dump(anb_type)+(if b_list is list then ")" else "")+"] Field's name '"+field_name+"'\n"+ (if b_list is list then - anb_type_list_from_message(indent, type_msg, anb_type, field_name, name, brace_counter) + anb_type_list_from_message(indent, type_msg, anb_type, field_name, "_"+name+"_", brace_counter) else - anb_type_from_message(indent, type_msg, anb_type, field_name, name, brace_counter)) + anb_type_from_message(indent, type_msg, anb_type, field_name, "_"+name+"_", brace_counter)) + generate_fields_from_message(indent, type_msg, t, brace_counter) diff --git a/src/generation/types.anubis b/src/generation/types.anubis index 36423cb..d2d5c88 100644 --- a/src/generation/types.anubis +++ b/src/generation/types.anubis @@ -12,62 +12,214 @@ read generation/graphviz/graphviz_main.anubis read system/files.anubis read system/string.anubis +read system/lists.anubis read tools/streams.anubis read tools/basis.anubis read densaku_lib/types/ds_types.anubis +read generation/intermediate_type.anubis -define Maybe(One) - generate_type +type Type_File_Parts: + type_file_part( + String transmit, + List(String) intermediate, + String declaration, + String message_str + ) +. + +define String + concat_transmit ( - Stream stream, - DS_Type ds_type + List(Type_File_Parts) _parts )= - if write_string(stream, dump_DS_Type(ds_type)) is failure then failure else + join("", + map((Type_File_Parts part) + |-> + since part is type_file_part(transmit_str, _, _, _), + transmit_str + , + _parts + ) + ) +. - success(unique) +define List(String) + unique_intermediate + ( + List(String) intermediate_types, + List(String) so_far + )= + if intermediate_types is + { + [] then so_far, + [h . t ] then unique_intermediate(t, append_once(so_far, h)) + } . -define Maybe(One) - make_type_file +define List(String) + unique_intermediate ( - DS_Type ds_type, //type description - String dest_dir + List(Type_File_Parts) _parts, + List(String) so_far + )= + if _parts is + { + [] then so_far, + [h . t] then + since h is type_file_part(_, intermediate, _, _), + unique_intermediate(intermediate, so_far) + } +. + + + +define String + concat_intermediate + ( + List(Type_File_Parts) _parts + )= + with final_list = unique_intermediate(_parts, []), + join("\n", + map((String intermediate) + |-> + "public type "+intermediate+":..." + , + final_list + ) + )+"\n" +. + +define String + concat_declaration + ( + List(Type_File_Parts) _parts + )= + join("\n\n", + map((Type_File_Parts part) + |-> + since part is type_file_part(_, _, declaration_str, _), + declaration_str + , + _parts + ) ) - = - since ds_type is ds_type(name, generation, alternatives), - println("Generating file for type ["+name+"]"); - with file_name = dest_dir+"types/generated/"+to_lower(name)+".anubis", +. + +define String + concat_message + ( + List(Type_File_Parts) _parts + )= + join("\n\n", + map((Type_File_Parts part) + |-> + since part is type_file_part(_, _, _, message_str), + message_str + , + _parts + ) + ) +. +define Maybe(One) + write_type_file + ( + String file_name, + String header, + List(Type_File_Parts) file_parts + )= + + //with file_name = dest_dir+to_lower(name)+".anubis", //create all necessary directories if doesn't exist. make_directories(file_name); - if file(file_name, new) is { failure then println("can't create file "+file_name);failure, success(fd) then with strm = make_stream(fd), - if generate_type_header(strm, ds_type) is { failure then failure, success(_) then - if generate_type(strm, ds_type) is { failure then failure, success(_) then - if generation is - { - no_message then success(unique), - message then - if generate_type_message_description(strm, ds_type) is { failure then failure, success(_) then - if generate_type_to_message(strm, ds_type) is { failure then failure, success(_) then - if generate_type_from_message(strm, ds_type) is { failure then failure, success(_) then - success(unique)}}} - }}} + write_string(strm, + header + + concat_transmit(file_parts) + "\n" + + concat_intermediate(file_parts) + "\n" + + concat_declaration(file_parts) + + concat_message(file_parts) + ) } . + +define Type_File_Parts + make_type_file + ( + DS_Type ds_type, //type description + String dest_dir, + List(DS_Type) same_file_types + ) + = + since ds_type is ds_type(name, generation, alternatives), + println("Generating file for type ["+name+"]"); + with transmit_foreign = generate_transmit_foreign_type(ds_type, same_file_types), + with intermediate_type= get_all_intermediate_type(same_file_types), + with type_declaration = dump_DS_Type(ds_type), + with message_str = + if generation is + { + no_message then "", + message then + generate_type_message_description(ds_type) + + generate_type_to_message(ds_type) + + generate_type_from_message(ds_type) + }, + type_file_part(transmit_foreign, intermediate_type, type_declaration, message_str) +. public define One make_all_types ( - List(DS_Type) types, - String destination_dir + DS_Type_File_Output_Dir out_dir, + DS_Type_File_Output_Name output_file_name, + List(DS_Type) types, + String destination_dir )= - map_forget((DS_Type type) |-> since type is ds_type(type_name, _, ds_alts), - println("generating type file for Type ["+type_name+"]"); - make_type_file(type, destination_dir), types) + with final_destination_dir = + if out_dir is + { + auto then destination_dir + "types/generated/", + relative_path(path) then destination_dir + path + "/", + absolute_path(path) then path + }, + + if output_file_name is + { + auto then + map_forget((DS_Type type) + |-> + since type is ds_type(type_name, _, ds_alts), + + with file_name = final_destination_dir+to_lower(type_name)+".anubis", + println("generating type file for Type ["+type_name+"] to "+file_name); + + with header = generate_header, + with file_parts = make_type_file(type, final_destination_dir, []), + + write_type_file(file_name, header, [file_parts]) + , + types) + + name(_file_name) then + with file_name = final_destination_dir+_file_name+".anubis", + + with header = generate_header, + with file_parts = + map((DS_Type type) + |-> + since type is ds_type(type_name, _, ds_alts), + println("generating type file for Type ["+type_name+"] to "+file_name); + make_type_file(type, final_destination_dir, types) + , + types), + + forget(write_type_file(file_name, header, file_parts)) + + } + . - diff --git a/src/generation/types_header.anubis b/src/generation/types_header.anubis index b84d28d..ce572fe 100644 --- a/src/generation/types_header.anubis +++ b/src/generation/types_header.anubis @@ -11,24 +11,32 @@ read tools/streams.anubis read tools/ISO-8601.anubis read system/string.anubis read densaku_lib/types/ds_types.anubis - +read generation/intermediate_type.anubis public define String - insert_read_foreign_type + generate_transmit_foreign_type ( - DS_Type sd_type //type description + DS_Type ds_t, //type description, + List(DS_Type) beside_type //type belonging of that file )= - with foreign_type_list = get_all_extern_type(sd_type), + with foreign_type_list = get_all_extern_type(ds_t, beside_type), join("", map((Extern_type ext_type) |-> since ext_type is extern(_, read_file), "transmit "+read_file+"\n", foreign_type_list)) . - -public define Maybe(One) - generate_type_header + + public define List(String) + generate_intermediate_type ( - Stream stream, - DS_Type sd_type //type description - )= - write_string(stream, + DS_Type ds_t, //type description, + List(DS_Type) beside_type //type belonging of that file + )= + with intermediate_list = get_all_intermediate_type(beside_type), + + //join("", map((String intermediate_type) |-> intermediate_type, intermediate_list)) +. + +public define String + generate_header + = "/* * Created by 伝作 (Densaku). * Types & Messages generator written by フランスのトトロ aka (David RENÉ) @@ -41,9 +49,13 @@ transmit system/muscle.anubis transmit system/convert.anubis transmit tools/basis.anubis -" + +" +. + + insert_read_foreign_type(sd_type)+ "\n" ) - . +. + + diff --git a/src/generation/types_messages.anubis b/src/generation/types_messages.anubis index 7a48a11..367573b 100644 --- a/src/generation/types_messages.anubis +++ b/src/generation/types_messages.anubis @@ -16,29 +16,28 @@ read densaku_lib/types/ds_types.anubis public define String insert_read_foreign_type ( -// Stream stream, - DS_Type ds_type //type description + DS_Type ds_type, //type description + List(DS_Type) beside_type )= - with foreign_type_list = get_all_extern_type(ds_type), + with foreign_type_list = get_all_extern_type(ds_type, beside_type), join("", map((Extern_type ext_type) |-> since ext_type is extern(_, read_file), "read "+read_file+"\n", foreign_type_list)) . -public define Maybe(One) +public define String generate_type_message_description ( - Stream stream, + //Stream stream, DS_Type ds_type //type description )= since ds_type is ds_type(type_name, _, alternatives), with title = type_name+" message format", - write_string(stream, + "\n"+ " "+title+"\n"+ " "+fill(length(title), '=')+"\n\n"+ // insert_type_message_description(ds_type)+ "\n" - ) - . +. public define String anb_type_to_message @@ -153,16 +152,15 @@ define String } . -public define Maybe(One) +public define String generate_type_to_message ( - Stream stream, DS_Type ds_type //type description - )= + )= since ds_type is ds_type(type_name, _, alternatives), with lower_type_name = "_"+to_lower(type_name), type_msg = lower_type_name+"_message", - write_string(stream, + "public define Message\n"+ " to_Message\n"+ " (\n"+ @@ -175,7 +173,6 @@ public define Maybe(One) " };\n"+ " "+type_msg+"\n"+ ".\n\n" - ) . /****************************** FROM MESSAGE ***********************************/ @@ -308,7 +305,7 @@ define String since h is component(b_list, anb_type, name, comment), indent + "// [type = "+(if b_list is list then "List(" else "")+dump(anb_type)+(if b_list is list then ")" else "")+"] "+alt_name+"."+name+"\n"+ (if b_list is list then - anb_type_list_from_message(indent, type_msg, anb_type, name, name, brace_counter) + anb_type_list_from_message(indent, type_msg, anb_type, name, "_"+name+"_", brace_counter) else anb_type_from_message(indent, type_msg, anb_type, name, "_"+name+"_", brace_counter)) + @@ -371,16 +368,15 @@ define String } . -public define Maybe(One) +public define String generate_type_from_message ( - Stream stream, DS_Type ds_type //type description )= since ds_type is ds_type(type_name, _, alternatives), with lower_type_name = "_"+to_lower(type_name), type_msg = lower_type_name+"_message", - write_string(stream, + "public define Maybe("+type_name+")\n"+ " from_Message\n"+ " (\n"+ @@ -395,5 +391,4 @@ public define Maybe(One) " failure //Type not found in message !\n"+ " }}\n"+ ".\n\n" - ) . diff --git a/src/main.anubis b/src/main.anubis index ac23cce..da40cbd 100644 --- a/src/main.anubis +++ b/src/main.anubis @@ -32,74 +32,106 @@ public define List(DS_Message) the_messages_list = ]) ]. -public define List(DS_Type) the_types_list = +public define List(DS_Type_File) the_types_list = [ - ds_type("User_Account", [ - alternative("account", [ - component(string, "first_name"), - component(string, "last_name"), - component(int, "extension") + ds_type_file( auto, auto, + [ + ds_type("User_Account", [ + alternative("account", [ + component(string, "first_name"), + component(string, "last_name"), + component(int, "extension") + ]), + alternative("account_ext", [ + component(string, "first_name"), + component(string, "last_name"), + component(list, int, "extension_list") + ]), + alternative("account_super_extended", [ + component(string, "first_name"), + component(string, "last_name"), + component(list, int, "extension_list"), + component(extern_type("DB_id", "calexium_lib/model/db_types.anubis"), "db_id") + ]) ]), - alternative("account_ext", [ - component(string, "first_name"), - component(string, "last_name"), - component(list, int, "extension_list") - ]), - alternative("account_super_extended", [ - component(string, "first_name"), - component(string, "last_name"), - component(list, int, "extension_list"), - component(extern_type("DB_id", "calexium_lib/model/db_types.anubis"), "db_id") - ]) - ]), - - ds_type("Trunk_SIP", [ - alternative("account", [ - component(string, "login"), - component(string, "password"), - component(string, "host") - ]) - ]), - - ds_type("HK_App", [ - alternative("hk_app", [ - component(string, "app_name", comment("Name of the application")), - component(ds_type("HK_Icon"), "icon", comment("Icon description")), - component(ds_type("HK_Help_Text"), "help"), - component(list, ds_type("HK_Table"),"hk_tables") - ]) - ]), - ds_type("HK_Database", [ - alternative("hk_database", [ - component(string, "name", comment("name of the database")), - component(list, ds_type("HK_App"), "apps", comment("list of applications")) - ]) - ]), - - ds_type("HK_Help_Text", [ - enum("no_help_text", comment("no help text available")), - alternative("help_text_TAG", [component(string, "tag_name", comment("TAG use with Anubis translation tool /locale/L3.anubis"))]), - alternative("help_text", [component(string, "help_text", comment("pure text to show"))]) - ]), - ds_type("HK_Icon", [ - enum("no_icon"), - alternative("icon16", [component(string, "name")]) + + ds_type("Trunk_SIP", [ + alternative("account", [ + component(string, "login"), + component(string, "password"), + component(string, "host") + ]) + ]), + + ds_type("HK_App", [ + alternative("hk_app", [ + component(string, "app_name", comment("Name of the application")), + component(ds_type("HK_Icon"), "icon", comment("Icon description")), + component(ds_type("HK_Help_Text"), "help"), + component(list, ds_type("HK_Table"),"hk_tables") + ]) + ]), + ds_type("HK_Database", [ + alternative("hk_database", [ + component(string, "name", comment("name of the database")), + component(list, ds_type("HK_App"), "apps", comment("list of applications")) + ]) + ]), + + ds_type("HK_Help_Text", [ + enum("no_help_text", comment("no help text available")), + alternative("help_text_TAG", [component(string, "tag_name", comment("TAG use with Anubis translation tool /locale/L3.anubis"))]), + alternative("help_text", [component(string, "help_text", comment("pure text to show"))]) + ]), + ds_type("HK_Icon", [ + enum("no_icon"), + alternative("icon16", [component(string, "name")]) + ]), + + ds_type("HK_Form", no_message, [ + alternative("hk_form_in_list", [ + component(string, "table_name", comment("database table name which belonging this form")), + component(string, "view_name", comment("name of the view")), + component(list, extern_type("HK_Form_Entry", "hk_form_entry.anubis"), "list"), + component(list, extern_type("HK_Form_Tab", "hk_form_tab.anubis"), "tabs") + ]), + alternative("hk_form_in_table", [ + component(string, "table_name", comment("database table name which belonging this form")), + component(string, "view_name", comment("name of the view")), + component(extern_type("HK_Form_Table", "hk_form_table.anubis"), "form_in_table") + ]) + ]) ]), - ds_type("HK_Form", no_message, [ - alternative("hk_form_in_list", [ - component(string, "table_name", comment("database table name which belonging this form")), - component(string, "view_name", comment("name of the view")), - component(list, extern_type("HK_Form_Entry", "hk_form_entry.anubis"), "list"), - component(list, extern_type("HK_Form_Tab", "hk_form_tab.anubis"), "tabs") + ds_type_file( relative_path("hayamiki_lib/view/types/"), name("HK_Editor_Table"), + [ + ds_type("HK_Editor_Table_Cell", [ + enum("empty"), + alternative("column", [ + component(string, "column_name") + ]), + alternative("label", [ + component(string, "label"), + ]), + alternative("table", [ + component(list, ds_type("HK_Editor_Table_Line"), "lines") + ]) ]), - alternative("hk_form_in_table", [ - component(string, "table_name", comment("database table name which belonging this form")), - component(string, "view_name", comment("name of the view")), - component(extern_type("HK_Form_Table", "hk_form_table.anubis"), "form_in_table") - ]) - ]) - ]. + + ds_type("HK_Editor_Table_Line", [ + alternative("line", [ + component(list, ds_type("HK_Editor_Table_Cell"), "cells") + ]) + ]), + + ds_type("HK_Editor_Table", [ + alternative("table", [ + component(list, ds_type("HK_Editor_Table_Line"), "lines") + ]) + ]), + ]) + ] +. -- libgit2 0.21.4