diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..14d6358 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +library diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..715cee1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "densaku_lib"] + path = densaku_lib + url = git@gitlab.anubis-language.com:totoro/densaku_lib.git diff --git a/densaku.aproj b/densaku.aproj new file mode 100644 index 0000000..51e6f59 --- /dev/null +++ b/densaku.aproj @@ -0,0 +1,595 @@ + + + {48AEB6F3-398C-4A63-AA74-6F17C6C11D27} + Debug + AnyCPU + Exe + takaden + takaden + src\main.anubis + False + False + False + C:\Program Files %28x86%29\Anubis\1.14\ + ./%3b./src + + + bin\Debug\ + True + Full + False + + + bin\Release\ + False + None + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/densaku.ide b/densaku.ide new file mode 100644 index 0000000..0bfef3b --- /dev/null +++ b/densaku.ide @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +# SharpDevelop 1.0.12.108 +Project("{B6712916-30DE-4a3e-A54C-2A79AC984AEE}") = "densaku", "densaku.aproj", "D41E2417-E9CD-451B-8823-F48BABAACC4A" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {48AEB6F3-398C-4A63-AA74-6F17C6C11D27}.Debug|Any CPU.Build.0 = Debug|Any CPU + {48AEB6F3-398C-4A63-AA74-6F17C6C11D27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {48AEB6F3-398C-4A63-AA74-6F17C6C11D27}.Release|Any CPU.Build.0 = Release|Any CPU + {48AEB6F3-398C-4A63-AA74-6F17C6C11D27}.Release|Any CPU.ActiveCfg = Release|Any CPU + D41E2417-E9CD-451B-8823-F48BABAACC4A.Debug|Any CPU.Build.0 = Debug|Any CPU + D41E2417-E9CD-451B-8823-F48BABAACC4A.Debug|Any CPU.ActiveCfg = Debug|Any CPU + D41E2417-E9CD-451B-8823-F48BABAACC4A.Release|Any CPU.Build.0 = Release|Any CPU + D41E2417-E9CD-451B-8823-F48BABAACC4A.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/densaku_lib b/densaku_lib new file mode 160000 index 0000000..7e96578 --- /dev/null +++ b/densaku_lib @@ -0,0 +1 @@ +Subproject commit 7e96578325b591652558fe6bdc0364f830f186e3 diff --git a/name.txt b/name.txt new file mode 100644 index 0000000..f0c5529 --- /dev/null +++ b/name.txt @@ -0,0 +1,12 @@ +高速伝言 +Kōsoku dengon +un message haut débit +高伝 +takaden + +伝言作成 +Dengon Sakusei +Message creation + +伝作 +DenSaku diff --git a/src/generation/files.anubis b/src/generation/files.anubis new file mode 100644 index 0000000..15f86c4 --- /dev/null +++ b/src/generation/files.anubis @@ -0,0 +1,39 @@ +/* + * Created by PyramIDE. + * User: フランスのトトロ aka (David RENÉ) + * Date: 15/01/2017 + * Time: 23:40 + * © David RENÉ + */ + +read densaku_lib/types/densaku.anubis +read densaku_lib/ds_generator.anubis +read tools/basis.anubis +read types_checking.anubis +read generation/types.anubis + +public define Maybe(One) + generate_message_files + ( + List(DS_Type) types, //Types description +// DS_Messages messages, + String destination_dir + )= + + if check_types(types) is + { + failure then failure, + success(_) then + //since _types is hk_database(name, apps), + println("Generating types and message files"); + make_all_types(types, destination_dir); + //make_vtm(apps, destination_dir); + //if generate_create_table(apps, destination_dir) is failure then println("failure");failure else + //println("Generating message collection"); + //if generate_menus(apps, destination_dir) is failure then println("failure");failure else + success(unique) + }. + +global define DS_Generator_API + ds_gen = + ds_api(generate_message_files). diff --git a/src/generation/types.anubis b/src/generation/types.anubis new file mode 100644 index 0000000..a6cd9f7 --- /dev/null +++ b/src/generation/types.anubis @@ -0,0 +1,68 @@ +/* + * Created by PyramIDE. + * User: フランスのトトロ aka (David RENÉ) + * Date: 21/01/2017 + * Time: 01:33 + * © Calexium + */ + +read generation/types_header.anubis +read generation/types_messages.anubis + +read system/files.anubis +read system/string.anubis +read tools/streams.anubis +read tools/basis.anubis +read densaku_lib/types/ds_types.anubis + +define Maybe(One) + generate_type + ( + Stream stream, + DS_Type ds_type + )= + if write_string(stream, dump_DS_Type(ds_type)) is failure then failure else + + success(unique) +. + +define Maybe(One) + make_type_file + ( + DS_Type ds_type, //type description + String dest_dir + ) + = + since ds_type is ds_type(name, alternatives), + println("Generating file for type ["+name+"]"); + with file_name = dest_dir+"types/generated/"+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 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)}}}}} + } +. + +public define One + make_all_types + ( + 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) +. + diff --git a/src/generation/types_header.anubis b/src/generation/types_header.anubis new file mode 100644 index 0000000..4951d0f --- /dev/null +++ b/src/generation/types_header.anubis @@ -0,0 +1,47 @@ +/* + * Created by PyramIDE. + * User: フランスのトトロ aka (David RENÉ) + * Date: 21/01/2017 + * Time: 01:44 + * © Calexium + */ + +read tools/basis.anubis +read tools/streams.anubis +read tools/ISO-8601.anubis +read system/string.anubis +read densaku_lib/types/ds_types.anubis + + +public define String + insert_read_foreign_type + ( +// Stream stream, + DS_Type sd_type //type description + )= + with foreign_type_list = get_all_extern_type(sd_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) + generate_type_header + ( + Stream stream, + DS_Type sd_type //type description + )= + write_string(stream, +"/* + * Created by 伝作 (Densaku). + * User: Automat + * Date: "+_Int_to_ISO_8601_date(now)+" + * Time: "+_Int_to_ISO_8601_time(now)+" + * + */ + +transmit system/muscle.anubis +" + + insert_read_foreign_type(sd_type)+ +"\n" + ) + . + diff --git a/src/generation/types_messages.anubis b/src/generation/types_messages.anubis new file mode 100644 index 0000000..4d51ec1 --- /dev/null +++ b/src/generation/types_messages.anubis @@ -0,0 +1,352 @@ +/* + * Created by PyramIDE. + * User: フランスのトトロ aka (David RENÉ) + * Date: 21/01/2017 + * Time: 15:57 + * © Calexium + */ + +read tools/basis.anubis +read tools/streams.anubis +read tools/ISO-8601.anubis +read system/string.anubis +read densaku_lib/types/ds_types.anubis + + +public define String + insert_read_foreign_type + ( +// Stream stream, + DS_Type ds_type //type description + )= + with foreign_type_list = get_all_extern_type(ds_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) + generate_type_message_description + ( + 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" + ) + . + +define String + anb_type_to_message + ( + String type_msg, + DS_Anubis_Type anb_type, + String name + )= + if anb_type is + { + one then + "add_string("+type_msg+", \""+name+"\", _"+name+")", + bool then + "add_bool("+type_msg+", \""+name+"\", _"+name+")", + int then + "add_string("+type_msg+", \""+name+"\", to_String(_"+name+"))", + string then + "add_string("+type_msg+", \""+name+"\", _"+name+")", + float then + "add_float("+type_msg+", \""+name+"\", _"+name+")", + ds_type(type_name) then + "add_message("+type_msg+", \""+name+"\", to_Message(_"+name+"))", + extern_type(type_name, _) then //external type. No need to check + "add_message("+type_msg+", \""+name+"\", to_Message(_"+name+"))", + } +. + +define String + generate_component_to_message + ( + String prefix, + String type_msg, + String alt_name, + List(DS_Component) components + )= + if components is + { + [] then ",\n", + [h . t] then + since h is component(b_list, anb_type, name, comment), + ";\n"+ + prefix +"// [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 + prefix +"map_forget(("+dump(anb_type)+ " _"+name+") |-> "+anb_type_to_message(type_msg, anb_type, name)+", __"+name+")" + else + prefix +"forget("+anb_type_to_message(type_msg, anb_type, name)+")") + + + generate_component_to_message(prefix, type_msg, alt_name, t) + } +. + +define String + generate_arguments_list + ( + List(DS_Component) components + )= + join(", ", map((DS_Component compo) |-> since compo is component(b_list, _, name, _), (if b_list is list then "__"else "_")+name, components)). +. + +define String + generate_one_alternative_to_message + ( + String type_msg, + DS_Alternative ds_alternative + )= + with prefix = " ", + if ds_alternative is + { + //generate the enum alternative + enum(alt_name, comment) then + prefix + "//Alternative "+alt_name+" (NO TYPE)\n"+ + prefix + alt_name + " then \n"+ + prefix + " forget(add_string("+type_msg+", \"__TYPE_ALT__\", \""+alt_name+"\")),\n\n", + + //generate the alternative with components + alternative(alt_name, components_list) then + prefix + "//Alternative "+alt_name+"\n"+ + prefix + alt_name + "("+ generate_arguments_list(components_list) +")"+ " then \n"+ + prefix + " forget(add_string("+type_msg+", \"__TYPE_ALT__\", \""+alt_name+"\"))"+ + generate_component_to_message(prefix+" ", type_msg, alt_name, components_list)+ + "\n" + } +. + +define String + generate_type_alternatives_to_message + ( + String type_msg, + List(DS_Alternative) ds_alts + )= + if ds_alts is + { + [] then "", + [h . t] then + generate_one_alternative_to_message(type_msg, h) + + generate_type_alternatives_to_message(type_msg, t) + } +. + +public define Maybe(One) + 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"+ +" "+type_name+" "+lower_type_name+"\n"+ +" )=\n"+ +" with "+type_msg+" = message((Word32)0), //\n"+ +" forget(add_string("+type_msg+", \"__TYPE__\", \""+type_name+"\"));\n"+ +" if "+lower_type_name+" is\n"+ +" {\n"+ generate_type_alternatives_to_message(type_msg, alternatives)+ +" };\n"+ +" "+type_msg+"\n"+ +".\n\n" + ) +. + +/****************************** FROM MESSAGE ***********************************/ + +define String +/* anb_type_list_from_message + * Generate the function which get the list of the target type ie. Bool, complex type, etc. + * To do so, we get in the given Message, all fields with the name and encoded type of expected type. + * Encoded type is not the final type. For example for Anubis Int, there is not exists any equilavent + * in C, C++ etc... So, the Int is stored Message as String. + * The process to send and received an Anubis real integer follow these steps: + * SEND Int -> String -> Message + * RECEIVE Message -> String -> Maybe(Int) -> Int + * Here we are in RECEIVE process for list + */ + anb_type_list_from_message + ( + String indent, + String type_msg, + DS_Anubis_Type anb_type, + String name, + Var(Int) brace_counter + )= + if anb_type is + { + //empty then indent + "with " + name + " = map_escape(( String str ) |-> (Maybe(String)) from_Message(msg), find_strings("+type_msg+", \""+name+"\")),\n", + one then indent + "with " + name + " = map_escape((Message msg) |-> (Maybe("+dump(anb_type)+ ")) from_Message(msg), find_messages("+type_msg+", \""+name+"\")),\n", + bool then indent + "with " + name + " = find_bool_list("+type_msg+", \""+name+"\"),\n", + int then indent + "with " + name + " = map_escape((String int_str) |-> decimal_scan(int_str), find_string_list("+type_msg+", \""+name+"\")),\n", + string then indent + "with " + name + " = find_string_list("+type_msg+", \""+name+"\"),\n", + float then indent + "with " + name + " = find_float_list("+type_msg+", \""+name+"\"),\n", + ds_type(type_name) then + brace_counter <- *brace_counter + 1; + indent +"with _"+name+" = map_escape(( Message msg ) |-> (Maybe("+dump(anb_type)+ ")) from_Message(msg), find_message_list("+type_msg+", \""+name+"\")),\n"+ + indent +" if _"+name+" is {failure then failure, success("+name+") then\n", + extern_type(type_name, _) then + brace_counter <- *brace_counter + 1; + indent +"with _"+name+" = map_escape(( Message msg ) |-> (Maybe("+dump(anb_type)+ ")) from_Message(msg), find_message_list("+type_msg+", \""+name+"\")),\n"+ + indent +" if _"+name+" is {failure then failure, success("+name+") then\n" + } +. + +define String + anb_type_from_message + ( + String indent, + String type_msg, + DS_Anubis_Type anb_type, + String name, + Var(Int) brace_counter + )= + if anb_type is + { + one then + brace_counter <- (*brace_counter + 1); + indent + "if find_string("+type_msg+", \""+name+"\")"+" is {failure then failure, success(_) then with "+name+" = unique,\n", + bool then + brace_counter <- (*brace_counter + 1); + indent + "if find_bool("+type_msg+", \""+name+"\")"+" is {failure then failure, success("+name+") then\n", + int then + brace_counter <- (*brace_counter + 2); + indent + "if find_string("+type_msg+", \""+name+"\")"+" is {failure then failure, success(_"+name+") then\n"+ + indent + " if decimal_scan(_"+name+") is { failure then failure, success("+name+") then\n", + string then + brace_counter <- (*brace_counter + 1); + indent + "if find_string("+type_msg+", \""+name+"\")"+" is {failure then failure, success("+name+") then\n", + float then + brace_counter <- (*brace_counter + 1); + indent + "if find_float("+type_msg+", \""+name+"\)"+" is {failure then failure, success("+name+") then\n", + ds_type(type_name) then + brace_counter <- (*brace_counter + 2); + indent + "if find_message("+type_msg+", \""+name+"\")"+" is {failure then failure, success("+name+"_msg) then\n"+ + indent + " if (Maybe("+type_name+"))from_Message("+name+"_msg)"+" is {failure then failure, success("+name+") then\n", + extern_type(type_name, _) then //external type. No need to check + brace_counter <- (*brace_counter + 2); + indent + "if find_message("+type_msg+", \""+name+"\")"+" is {failure then failure, success("+name+"_msg) then\n"+ + indent + " if (Maybe("+type_name+"))from_Message("+name+"_msg)"+" is {failure then failure, success("+name+") then\n", + } +. + +define String + generate_arguments_list_from + ( + List(DS_Component) components + )= + join(", ", map((DS_Component compo) |-> since compo is component(b_list, _, name, _), name, components)). +. + +define String + generate_component_from_message + ( + String indent, + String type_msg, + String alt_name, + List(DS_Component) components, + Var(Int) brace_counter + )= + if components is + { + [] then "\n", + [h . t] then + 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, brace_counter) + else + anb_type_from_message(indent, type_msg, anb_type, name, brace_counter)) + + + generate_component_from_message(indent, type_msg, alt_name, t, brace_counter) + + } +. + +define String + generate_one_alternative_from_message + ( + String indent, + String type_msg, + DS_Alternative ds_alternative + )= + with brace_counter = (Var(Int))var(0), + if ds_alternative is + { + //generate the enum alternative + enum(alt_name, comment) then + "//Alternative "+alt_name+" (NO TYPE)\n"+ + indent + "if __type_alt__ = \""+alt_name+"\" then\n"+ + indent + " success("+alt_name+")\n"+ + indent + "else " + + //generate the alternative with components + alternative(alt_name, components_list) then + with begin = + "//Alternative "+alt_name+"\n"+ + indent + "if __type_alt__ = \""+alt_name+"\" then //Alternative "+alt_name+"\n"+ + //prefix + alt_name + "("+ generate_arguments_list(components_list) +")"+ " then \n"+ + //prefix + " forget(add_string("+type_msg+", \"__TYPE_ALT__\", \""+alt_name+"\"))"+ + generate_component_from_message(indent+" ", type_msg, alt_name, components_list, brace_counter)+ + indent + " success("+alt_name+"("+generate_arguments_list_from(components_list)+"))\n", + + begin + + //indent + "brace counter ["+*brace_counter+"]"+ + indent + fill(*brace_counter, '}') +"\n"+ + indent + "else " + } +. + +define String + generate_type_alternative_from_message + ( + String indent, + String type_msg, + List(DS_Alternative) ds_alts + )= + if ds_alts is + { + [] then "", + [h . t] then + generate_one_alternative_from_message(indent, type_msg, h)+ + generate_type_alternative_from_message(indent, type_msg, t) + } +. + +public define Maybe(One) + 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"+ +" Message "+type_msg+"\n"+ +" )=\n"+ +" if find_string("+type_msg+", \"__TYPE__\") is {failure then failure, success(__type__) then\n"+ +" if find_string("+type_msg+", \"__TYPE_ALT__\") is {failure then failure, success(__type_alt__) then\n"+ +" if __type__ = \""+type_name+"\" then \n"+ +" "+generate_type_alternative_from_message(" ",type_msg, alternatives)+"\n"+ +" failure //No valid Alternative found !\n"+ +" else\n"+ +" failure //Type not found in message !\n"+ +" }}\n"+ +".\n\n" + ) +. diff --git a/src/main.anubis b/src/main.anubis new file mode 100644 index 0000000..d104a88 --- /dev/null +++ b/src/main.anubis @@ -0,0 +1,92 @@ +/************************************************** + * Project* The Takaden (高伝) project + * + * *Title* Generating type and Muscle message with Anubis + * + * *Copyright* Copyright © David RENÉ 2017. + * + * + * *Overview* + * + * + */ + +/* + * + * Created by PyramIDE. + * User: フランスのトトロ aka (David RENÉ) + * Date: 15/01/2017 + * Time: 23:30 + * © Calexium + */ + +read densaku_lib/types/densaku.anubis +read generation/files.anubis + +public define List(DS_Type) the_types_list = + [ + 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_Entry", "calexium_lib/database.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_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")]) + ]), + ]. + + global define One + takaden + ( + List(String) args + ) = + if load_tk_generator is + { + failure then println("Takaden generator can't be load"), + success(hk_gen) then forget(tk_gen.generate_type_msg_files(the_type_msg_description, "")) + }. + +global define One + densaku + ( + List(String) args + )= + //print(dump_TK_Type_list(the_types_list)). + forget(generate_message_files(the_types_list, "")). + diff --git a/src/types_checking.anubis b/src/types_checking.anubis new file mode 100644 index 0000000..9633b4c --- /dev/null +++ b/src/types_checking.anubis @@ -0,0 +1,62 @@ +/* + * Created by PyramIDE. + * User: フランスのトトロ aka (David RENÉ) + * Date: 21/01/2017 + * Time: 00:36 + * © Calexium + */ + +read densaku_lib/types/ds_types.anubis +read system/string.anubis +read tools/basis.anubis + +define Bool + is_upper_case_start + ( + String name + )= + if nth(0, name) is + { + failure then println("Can't get the first character of "+name);false, + success(char) then + if (char +=< 90) & (64 +< char) then + true + else + println("Type name ["+name+"] doesn't start with upper case");false + } +. + +define Maybe(One) +/* Check if the type name start with upper case and if that type doesn't already exists + */ + check_name + ( + List(DS_Type) types, //types description + List(String) so_far, + Maybe(One) return + )= + if types is + { + [] then return, + [h . t] then + since h is ds_type(type_name, tk_alts), + if is_upper_case_start(type_name) then + check_name(t, [], return) + else + check_name(t, [], failure) + } +. + +public define Maybe(One) + check_types + ( + List(DS_Type) types //types description + )= + //check if name start with upper case + if check_name(types, [], success(unique)) is + { + failure then println("Error(s) in type checking "); failure + success(_) then + success(unique) + } +. -- libgit2 0.21.4