|
5 | 5 | #include "script-private.h" |
6 | 6 |
|
7 | 7 | #include <stddef.h> |
| 8 | +#include <stdarg.h> |
8 | 9 |
|
9 | 10 | #ifdef _WIN32 |
10 | 11 | #include <windows.h> |
@@ -34,6 +35,7 @@ MC_PICKLE_END_RECORD() |
34 | 35 | MC_PICKLE_BEGIN_RECORD(MCScriptHandlerType) |
35 | 36 | MC_PICKLE_ARRAY_OF_RECORD(MCScriptHandlerTypeParameter, parameters, parameter_count) |
36 | 37 | MC_PICKLE_UINDEX(return_type) |
| 38 | + MC_PICKLE_ARRAY_OF_NAMEREF(parameter_names, parameter_name_count) |
37 | 39 | MC_PICKLE_END_RECORD() |
38 | 40 |
|
39 | 41 | MC_PICKLE_BEGIN_RECORD(MCScriptRecordTypeField) |
@@ -884,3 +886,166 @@ MCNameRef MCScriptGetNameOfGlobalVariableInModule(MCScriptModuleRef self, uindex |
884 | 886 | } |
885 | 887 |
|
886 | 888 | //////////////////////////////////////////////////////////////////////////////// |
| 889 | + |
| 890 | +static int s_current_indent = 0; |
| 891 | + |
| 892 | +static void __write(MCStreamRef stream, int p_indent, bool p_newline, const char *p_format, va_list p_args) |
| 893 | +{ |
| 894 | + MCAutoStringRef t_formatted_string; |
| 895 | + MCStringFormatV(&t_formatted_string, p_format, p_args); |
| 896 | + MCAutoStringRef t_string; |
| 897 | + MCStringFormat(&t_string, "%.*s%@%s", p_indent * 2, " ", *t_formatted_string, p_newline ? "\n" : ""); |
| 898 | + MCAutoStringRefAsUTF8String t_utf8_string; |
| 899 | + t_utf8_string . Lock(*t_string); |
| 900 | + MCStreamWrite(stream, *t_utf8_string, t_utf8_string . Size()); |
| 901 | +} |
| 902 | + |
| 903 | +static void __enterln(MCStreamRef stream, const char *format, ...) |
| 904 | +{ |
| 905 | + va_list t_args; |
| 906 | + va_start(t_args, format); |
| 907 | + __write(stream, s_current_indent, true, format, t_args); |
| 908 | + va_end(t_args); |
| 909 | + s_current_indent += 1; |
| 910 | +} |
| 911 | + |
| 912 | +static void __leaveln(MCStreamRef stream, const char *format, ...) |
| 913 | +{ |
| 914 | + s_current_indent -= 1; |
| 915 | + va_list t_args; |
| 916 | + va_start(t_args, format); |
| 917 | + __write(stream, s_current_indent, true, format, t_args); |
| 918 | + va_end(t_args); |
| 919 | +} |
| 920 | + |
| 921 | +static void __writeln(MCStreamRef stream, const char *format, ...) |
| 922 | +{ |
| 923 | + va_list t_args; |
| 924 | + va_start(t_args, format); |
| 925 | + __write(stream, s_current_indent, true, format, t_args); |
| 926 | + va_end(t_args); |
| 927 | +} |
| 928 | + |
| 929 | +static void def_to_name(MCScriptModuleRef self, uindex_t p_index, MCStringRef& r_string) |
| 930 | +{ |
| 931 | + MCScriptDefinition *t_def; |
| 932 | + t_def = self -> definitions[p_index]; |
| 933 | + if (t_def -> kind == kMCScriptDefinitionKindExternal) |
| 934 | + { |
| 935 | + MCScriptExternalDefinition *t_ext_def; |
| 936 | + t_ext_def = static_cast<MCScriptExternalDefinition *>(t_def); |
| 937 | + |
| 938 | + MCStringFormat(r_string, "%@", /*self -> dependencies[self -> imported_definitions[t_ext_def -> index] . module] . name, */self -> imported_definitions[t_ext_def -> index] . name); |
| 939 | + } |
| 940 | + else |
| 941 | + MCStringFormat(r_string, "%@", self -> definition_names[p_index]); |
| 942 | +} |
| 943 | + |
| 944 | +static void type_to_string(MCScriptModuleRef self, uindex_t p_type, MCStringRef& r_string) |
| 945 | +{ |
| 946 | + MCScriptType *t_type; |
| 947 | + t_type = self -> types[p_type]; |
| 948 | + switch(t_type -> kind) |
| 949 | + { |
| 950 | + case kMCScriptTypeKindDefined: |
| 951 | + def_to_name(self, static_cast<MCScriptDefinedType *>(t_type) -> index, r_string); |
| 952 | + break; |
| 953 | + case kMCScriptTypeKindOptional: |
| 954 | + { |
| 955 | + MCAutoStringRef t_target_name; |
| 956 | + type_to_string(self, static_cast<MCScriptOptionalType *>(t_type) -> type, &t_target_name); |
| 957 | + MCStringFormat(r_string, "optional %@", *t_target_name); |
| 958 | + } |
| 959 | + break; |
| 960 | + case kMCScriptTypeKindHandler: |
| 961 | + { |
| 962 | + MCAutoStringRef t_sig; |
| 963 | + MCScriptHandlerType *t_htype; |
| 964 | + t_htype = static_cast<MCScriptHandlerType *>(t_type); |
| 965 | + MCStringCreateMutable(0, &t_sig); |
| 966 | + MCStringAppendChar(*t_sig, '('); |
| 967 | + for(uindex_t i = 0; i < t_htype -> parameter_count; i++) |
| 968 | + { |
| 969 | + if (i != 0) |
| 970 | + MCStringAppendNativeChars(*t_sig, (const char_t *)", ", 2); |
| 971 | + static const char *s_mode_strings[] = {"in", "out", "inout"}; |
| 972 | + MCAutoStringRef t_ptype; |
| 973 | + type_to_string(self, t_htype -> parameters[i] . type, &t_ptype); |
| 974 | + MCStringAppendFormat(*t_sig, "%s %@ as %@", s_mode_strings[t_htype -> parameters[i] . mode], t_htype -> parameter_names[i], *t_ptype); |
| 975 | + } |
| 976 | + MCAutoStringRef t_rtype; |
| 977 | + type_to_string(self, t_htype -> return_type, &t_rtype); |
| 978 | + MCStringAppendFormat(*t_sig, ") as %@", *t_rtype); |
| 979 | + MCStringCopy(*t_sig, r_string); |
| 980 | + } |
| 981 | + break; |
| 982 | + default: |
| 983 | + __MCScriptUnreachable__("inappropriate type found in definition"); |
| 984 | + break; |
| 985 | + } |
| 986 | +} |
| 987 | + |
| 988 | +bool MCScriptWriteInterfaceOfModule(MCScriptModuleRef self, MCStreamRef stream) |
| 989 | +{ |
| 990 | + __enterln(stream, "import module %@", self -> name); |
| 991 | + for(uindex_t i = 0; i < self -> dependency_count; i++) |
| 992 | + { |
| 993 | + if (MCNameIsEqualTo(self -> dependencies[i] . name, MCNAME("__builtin__"))) |
| 994 | + continue; |
| 995 | + |
| 996 | + MCStringRef t_string; |
| 997 | + t_string = MCNameGetString(self -> dependencies[i] . name); |
| 998 | + |
| 999 | + __writeln(stream, "use %@", self -> dependencies[i] . name); |
| 1000 | + } |
| 1001 | + for(uindex_t i = 0; i < self -> exported_definition_count; i++) |
| 1002 | + { |
| 1003 | + MCNameRef t_def_name; |
| 1004 | + MCScriptDefinition *t_def; |
| 1005 | + t_def_name = self -> exported_definitions[i] . name; |
| 1006 | + t_def = self -> definitions[self -> exported_definitions[i] . index]; |
| 1007 | + switch(t_def -> kind) |
| 1008 | + { |
| 1009 | + case kMCScriptDefinitionKindType: |
| 1010 | + { |
| 1011 | + MCScriptType *t_type; |
| 1012 | + t_type = self -> types[static_cast<MCScriptTypeDefinition *>(t_def) -> type]; |
| 1013 | + switch(t_type -> kind) |
| 1014 | + { |
| 1015 | + case kMCScriptTypeKindForeign: |
| 1016 | + __writeln(stream, "foreign type %@", t_def_name); |
| 1017 | + break; |
| 1018 | + } |
| 1019 | + } |
| 1020 | + break; |
| 1021 | + case kMCScriptDefinitionKindVariable: |
| 1022 | + { |
| 1023 | + MCAutoStringRef t_type_string; |
| 1024 | + type_to_string(self, static_cast<MCScriptVariableDefinition *>(t_def) -> type, &t_type_string); |
| 1025 | + __writeln(stream, "variable %@ as %@", t_def_name, *t_type_string); |
| 1026 | + } |
| 1027 | + break; |
| 1028 | + case kMCScriptDefinitionKindHandler: |
| 1029 | + { |
| 1030 | + MCAutoStringRef t_sig; |
| 1031 | + type_to_string(self, static_cast<MCScriptHandlerDefinition *>(t_def) -> type, &t_sig); |
| 1032 | + __writeln(stream, "handler %@%@", t_def_name, *t_sig); |
| 1033 | + } |
| 1034 | + break; |
| 1035 | + case kMCScriptDefinitionKindForeignHandler: |
| 1036 | + { |
| 1037 | + MCAutoStringRef t_sig; |
| 1038 | + type_to_string(self, static_cast<MCScriptForeignHandlerDefinition *>(t_def) -> type, &t_sig); |
| 1039 | + __writeln(stream, "foreign handler %@%@", t_def_name, *t_sig); |
| 1040 | + } |
| 1041 | + break; |
| 1042 | + default: |
| 1043 | + break; |
| 1044 | + } |
| 1045 | + } |
| 1046 | + __leaveln(stream, "end module"); |
| 1047 | + |
| 1048 | + return true; |
| 1049 | +} |
| 1050 | + |
| 1051 | +//////////////////////////////////////////////////////////////////////////////// |
0 commit comments