comparison scripts/dgen.rb @ 16:19885b43130e

Huge update, the bridge actually works now
author Jacob Carlborg <doob@me.com>
date Sun, 03 Jan 2010 22:06:11 +0100
parents 7ff919f595d5
children
comparison
equal deleted inserted replaced
15:7ff919f595d5 16:19885b43130e
10 require "rubygems" 10 require "rubygems"
11 gem "xml-simple" 11 gem "xml-simple"
12 require "xmlsimple" 12 require "xmlsimple"
13 require "optparse" 13 require "optparse"
14 require "date" 14 require "date"
15 require "stringio"
15 16
16 # Extensions to String 17 # Extensions to String
17 class String 18 class String
18 19
19 # Passes each character to the supplied block 20 # Passes each character to the supplied block
321 file << header.typedefs 322 file << header.typedefs
322 file << header.cftypes 323 file << header.cftypes
323 file << header.function_pointers 324 file << header.function_pointers
324 file << header.c_constants 325 file << header.c_constants
325 file << header.d_constants 326 file << header.d_constants
327 file << header.d_constants_static_this unless header.d_constants_static_this.length == 0
326 file << header.enums_gnu if header.needs_type_encoding 328 file << header.enums_gnu if header.needs_type_encoding
327 file << header.enums 329 file << header.enums
328 file << header.structs 330 file << header.structs
329 331
330 unless header.d_constants_static_this.length == 0 332 # Put the templates/mixins before the classes just to make sure we don't get forward reference errors
331 file << "static this ()".nl(false) 333 templates = get_templates(header.name)
332 file << "{".nl(false) 334
333 file << header.d_constants_static_this 335 templates.each do |template, value|
334 file << "}".nl(false).nl(false) 336 file << value.code.nl(false)
337 @templates.delete(template)
335 end 338 end
336 339
337 classes = get_classes(header.name) 340 classes = get_classes(header.name)
338 341
339 classes.each do |clazz, value| 342 classes.each do |clazz, value|
346 interfaces.each do |interface, value| 349 interfaces.each do |interface, value|
347 file << value.code.nl(false) 350 file << value.code.nl(false)
348 @interfaces.delete(interface) 351 @interfaces.delete(interface)
349 end 352 end
350 353
351 templates = get_templates(header.name)
352
353 templates.each do |template, value|
354 file << value.code.nl(false)
355 @templates.delete(template)
356 end
357
358 file << header.function_wrappers 354 file << header.function_wrappers
359 file << header.c_functions 355 file << header.c_functions
360 end 356 end
361 357
362 File.open(bindings_file_path, "w") do |file| 358 File.open(bindings_file_path, "w") do |file|
359 file << copyright
363 file << "module " 360 file << "module "
364 file << mod 361 file << mod
365 file << "_bindings;" 362 file << "_bindings;"
366 file << header.imports.nl(false) 363 file << header.imports.nl(false)
367 file << header.constants 364 file << header.constants
388 file << header.typedefs 385 file << header.typedefs
389 file << header.cftypes 386 file << header.cftypes
390 file << header.function_pointers 387 file << header.function_pointers
391 file << header.c_constants 388 file << header.c_constants
392 file << header.d_constants 389 file << header.d_constants
390 file << header.d_constants_static_this unless header.d_constants_static_this.nil?
393 file << header.enums_gnu if header.needs_type_encoding 391 file << header.enums_gnu if header.needs_type_encoding
394 file << header.enums 392 file << header.enums
395 file << header.structs 393 file << header.structs
396 394
397 unless header.d_constants_static_this.nil? 395 # Put the templates/mixins before the classes just to make sure we don't get forward reference errors
398 file << "static this ()".nl(false) 396 templates = get_templates(header.name)
399 file << "{".nl(false) 397
400 file << header.d_constants_static_this 398 templates.each do |template, value|
401 file << "}".nl(false).nl(false) 399 file << value.code.nl(false)
400 @templates.delete(template)
402 end 401 end
403 402
404 classes = get_classes(header.name) 403 classes = get_classes(header.name)
405 404
406 classes.each do |clazz, value| 405 classes.each do |clazz, value|
411 interfaces = get_interfaces(header.name) 410 interfaces = get_interfaces(header.name)
412 411
413 interfaces.each do |interface, value| 412 interfaces.each do |interface, value|
414 file << value.code.nl(false) 413 file << value.code.nl(false)
415 @interfaces.delete(interface) 414 @interfaces.delete(interface)
416 end
417
418 templates = get_templates(header.name)
419
420 templates.each do |template, value|
421 file << value.code.nl(false)
422 @templates.delete(template)
423 end 415 end
424 416
425 file << header.function_wrappers 417 file << header.function_wrappers
426 file << header.c_functions 418 file << header.c_functions
427 end 419 end
546 538
547 str << "\n" 539 str << "\n"
548 end 540 end
549 541
550 str << "{".nl(false) 542 str << "{".nl(false)
551 str << "mixin ObjcWrap".indent.nl 543 str << "mixin (ObjcWrap)".indent.nl
552
553 templates_for_class(clazz.name).each do |template, value|
554 str << "mixin #{get_identifier("T" + template)}".indent.nl
555 end
556
557 str << "\n" 544 str << "\n"
558 545
559 str << methods(clazz.method, clazz.name) 546 str << methods(clazz.method, clazz.name)
560 str << "\n" if protocols.length > 0 547 str << "\n" if protocols.length > 0
561 548
565 552
566 unless interface.nil? 553 unless interface.nil?
567 str << methods(interface.method, interface.name) 554 str << methods(interface.method, interface.name)
568 str << "\n" unless i == protocols.length - 1 555 str << "\n" unless i == protocols.length - 1
569 end 556 end
570 end 557 end
558
559 # Put the mixins at the end of the class just to make sure we don't get any forward reference errors
560 templates_for_class(clazz.name).each do |template, value|
561 str << "mixin (#{get_identifier("T" + template)})".indent.nl
562 end
571 563
572 str << "}".nl(false) 564 str << "}".nl(false)
573 565
574 @classes[clazz.name] ||= {} 566 @classes[clazz.name] ||= {}
575 @classes[clazz.name].code = str.string 567 @classes[clazz.name].code = str.string
631 end 623 end
632 624
633 # Generates the D code for the templates 625 # Generates the D code for the templates
634 def templates (templates) 626 def templates (templates)
635 templates.each do |template| 627 templates.each do |template|
628 methods = methods(template.method, template.name, true) #unless template["class"] == "NSObject"
629 bindings = bindings(template)
630
636 str = StringIO.new 631 str = StringIO.new
637 632
638 str << "template " 633 str << "const "
639 str << get_identifier("T" + template.name) 634 str << get_identifier("T" + template.name)
640 str << " ()".nl(false) 635 str << " = `".nl(false)
641 str << "{".nl(false) 636 str << "".nl(false)
642 str << interface_methods(template.method, template.name) if template["class"] == "NSObject" 637 #str << interface_methods(template.method, template.name) if template["class"] == "NSObject"
643 str << methods(template.method, template.name) unless template["class"] == "NSObject" 638
644 str << "}".nl(false) 639 str << methods.nl(false)
640 str << bindings.nl(false)
641 str << "`".nl
645 642
646 @templates[template.name] ||= {} 643 @templates[template.name] ||= {}
647 @templates[template.name].code = str.string 644 @templates[template.name].code = str.string
648 framework = get_framework(template.file) 645 framework = get_framework(template.file)
649 @templates[template.name].framework = framework unless framework.nil? 646 @templates[template.name].framework = framework unless framework.nil?
650 @templates[template.name].file = get_identifier(template.file) 647 @templates[template.name].file = get_identifier(template.file)
651 @templates[template.name][:class] = get_identifier(template["class"]) 648 @templates[template.name][:class] = get_identifier(template["class"])
652 end 649 end
650 end
651
652 def bindings (template)
653 str = StringIO.new
654
655 template.method.each do |method|
656 static = method.classMethod == "true"
657
658 str << "mixin ObjcBindMethod!(".indent unless static
659 str << "mixin ObjcBindClassMethod!(".indent if static
660 str << get_method_name(method.selector)
661 str << ', "'
662 str << method.selector
663 str << '")'.nl
664 end
665
666 str.string
653 end 667 end
654 668
655 # Generates the D code for the constants/globals 669 # Generates the D code for the constants/globals
656 def constants (constants) 670 def constants (constants)
657 return "" if constants.length == 0 671 return "" if constants.length == 0
720 def d_constants 734 def d_constants
721 return "" if @d_constants.length == 0 735 return "" if @d_constants.length == 0
722 736
723 str = StringIO.new 737 str = StringIO.new
724 738
739 str << "private\n{\n"
740
725 @d_constants.each do |constant| 741 @d_constants.each do |constant|
726 # Deep copy constant 742 # Deep copy constant
727 c = constant.dup 743 c = constant.dup
728 c.name = c.name.dup 744 c.name = c.name.dup
729 c.type = c.type.dup 745 c.type = c.type.dup
730 746
731 str << "const " if constant.const 747 #str << "const " if constant.const
732 str << get_identifier(constant.type) 748 str << get_identifier(constant.type).indent
733 str << " " 749 str << " "
734 str << get_identifier(constant.name).nl 750 str << get_identifier(constant.name)
751 str << "_".nl
735 @d_constants_static_this << c 752 @d_constants_static_this << c
736 end 753 end
737 754
738 str << "\n" 755 str << "}\n\n"
739 @d_constants.clear 756 @d_constants.clear
740 str.string 757 str.string
741 end 758 end
742 759
743 # Generates the D code for the constants the has to be in a "static this" 760 # Generates the D code for the constants the has to be in a "static this"
745 return "" if @d_constants_static_this.length == 0 762 return "" if @d_constants_static_this.length == 0
746 763
747 str = StringIO.new 764 str = StringIO.new
748 765
749 @d_constants_static_this.each do |constant| 766 @d_constants_static_this.each do |constant|
750 str << constant.name.indent 767 # str << constant.name.indent
751 str << " = new " 768 # str << " = new "
752 str << get_identifier(constant.type) 769 # str << get_identifier(constant.type)
753 str << "(" 770 # str << "("
754 str << "bindings." 771 # str << "bindings."
755 str << get_identifier(constant.name) 772 # str << get_identifier(constant.name)
773 # str << ")".nl
774
775 str << constant.type
776 str << " "
777 str << constant.name
778 str << " ()".nl(false)
779 str << "{".nl(false)
780 str << "if (".indent
781 str << constant.name + "_"
782 str << ")".nl(false)
783 str << "return ".indent(2)
784 str << constant.name
785 str << "_".nl
786 str << "\n"
787 str << "return ".indent
788 str << constant.name
789 str << "_ = new "
790 str << constant.type
791 str << "(bindings."
792 str << constant.name
756 str << ")".nl 793 str << ")".nl
794 str << "}\n\n"
757 end 795 end
758 796
759 @d_constants_static_this.clear 797 @d_constants_static_this.clear
760 str.string 798 str.string
761 end 799 end
904 if !method && original_type == "@" 942 if !method && original_type == "@"
905 return_type = "id" 943 return_type = "id"
906 else 944 else
907 return_type = get_type(original_type, function.returnValue[0].type64, function.returnValue[0].declaredType) 945 return_type = get_type(original_type, function.returnValue[0].type64, function.returnValue[0].declaredType)
908 args(function.arg, variadic) unless function.arg.nil? 946 args(function.arg, variadic) unless function.arg.nil?
909 end 947 end
910 948
911 str << "static " if static 949 str << "static " if static
912 str << return_type 950 str << return_type
913 str << " " 951 str << " "
914 str << function["name"] 952 str << function["name"]
997 1035
998 # A helper function that generates the D code for the functions 1036 # A helper function that generates the D code for the functions
999 def functions_helper (function, wrapper_needed) 1037 def functions_helper (function, wrapper_needed)
1000 str = StringIO.new 1038 str = StringIO.new
1001 1039
1002 str << ("private " + build_function(function)).indent if wrapper_needed 1040 str << ("package " + build_function(function)).indent if wrapper_needed
1003 str << build_function(function).indent unless wrapper_needed 1041 str << build_function(function).indent unless wrapper_needed
1004 1042
1005 str.string 1043 str.string
1006 end 1044 end
1007 1045
1072 str << "import dstep.objc.bridge.TypeEncoding".nl if header.needs_type_encoding && !@needs_bridge 1110 str << "import dstep.objc.bridge.TypeEncoding".nl if header.needs_type_encoding && !@needs_bridge
1073 1111
1074 if @needs_bridge 1112 if @needs_bridge
1075 str << "import dstep.objc.bridge.Bridge".nl 1113 str << "import dstep.objc.bridge.Bridge".nl
1076 str << "import dstep.objc.bridge.TypeEncoding".nl if header.needs_type_encoding 1114 str << "import dstep.objc.bridge.TypeEncoding".nl if header.needs_type_encoding
1077 str << "import dstep.objc.objc : id".nl 1115 str << "import dstep.objc.objc".nl
1078 end 1116 end
1079 1117
1080 str << "\n\n" 1118 str << "\n\n"
1081 str = str.string.sort.to_s 1119 str = str.string.sort.to_s
1082 str << "\n" 1120 str << "\n"
1084 return "\n\npublic:" << str if filename == get_framework_name(framework_name) 1122 return "\n\npublic:" << str if filename == get_framework_name(framework_name)
1085 return str 1123 return str
1086 end 1124 end
1087 1125
1088 # Generates the D code for the methods 1126 # Generates the D code for the methods
1089 def methods (methods, class_name) 1127 def methods (methods, class_name, template = false)
1090 return "" if methods.length == 0 1128 return "" if methods.length == 0
1091 1129
1092 str = StringIO.new 1130 str = StringIO.new
1093 1131
1094 methods.each do |method| 1132 methods.each do |method|
1133 next if method.selector.length >= 5 && get_method_name(method.selector)[0 ... 5] == "alloc" # skip alloc
1134
1135 name = get_method_name(method.selector)
1095 return_type = get_type(method.returnValue[0].type, method.returnValue[0].type64, method.returnValue[0].declaredType) 1136 return_type = get_type(method.returnValue[0].type, method.returnValue[0].type64, method.returnValue[0].declaredType)
1137
1138 if name.length >= 4 && name[0 ... 4] == "init" && name != "initialize"
1139 if template
1140 return_type = "typeof(this)"
1141 else
1142 return_type = class_name
1143 end
1144
1145 method["returnValue"][0]["declaredType"] = return_type
1146 end
1147
1096 variadic = method.variadic == "true" 1148 variadic = method.variadic == "true"
1097 static = method.classMethod == "true" 1149 static = method.classMethod == "true"
1098 1150
1099 index = 0 1151 index = 0
1100 declaration = build_function(method, true, static)[0 ... -2].indent.nl(false) 1152 declaration = build_function(method, true, static)[0 ... -2].indent.nl(false)
1101 index = declaration.index_of(" ") if static 1153 index = declaration.index_of(" ") if static
1102 index = declaration.index_of(" ", index) 1154 index = declaration.index_of(" ", index)
1103 name = get_method_name(method.selector)
1104 1155
1105 str << (declaration[0 .. index] + name + declaration[index .. -1]).gsub(/ +/, " ") 1156 str << (declaration[0 .. index] + name + declaration[index .. -1]).gsub(/ +/, " ")
1106 str << "{".indent.nl(false) 1157 str << "{".indent.nl(false)
1107 1158
1159 has_ref = false
1160
1161 method.arg.each_with_index do |arg, i|
1162 if arg.declaredType =~ /NSError\*\*/ || arg.declaredType =~ /NSDictionary\*\*/
1163 has_ref = true
1164 str << "id __arg#{i};\n".indent(2)
1165 end
1166 end if method.arg
1167
1168 if has_ref
1169 str << "\n"
1170
1171 method.arg.each_with_index do |arg, i|
1172 if arg.declaredType =~ /NSError\*\*/ || arg.declaredType =~ /NSDictionary\*\*/
1173 str << "if (#{arg.name})\n".indent(2)
1174 str << "__arg#{i} = #{arg.name}.objcObject".indent(3).nl.nl(false)
1175 end
1176 end if method.arg
1177 end
1178
1108 if static 1179 if static
1109 str << "return invokeObjcSelfClass!(".indent(2) 1180 if has_ref
1110 str << return_type 1181 str << "#{return_type} result = ".indent(2) unless return_type == "void"
1182 str << "".indent(2) if return_type == "void"
1183 str << "invokeObjcSelf!("
1184 str << return_type
1185 else
1186 str << "return invokeObjcSelfClass!(".indent(2)
1187 str << return_type
1188 end
1111 else 1189 else
1112 if return_type == class_name 1190 if return_type == class_name
1113 str << "id result = invokeObjcSelf!(".indent(2) 1191 str << "id result = invokeObjcSelf!(".indent(2)
1114 str << "id" 1192 str << "id"
1193 elsif has_ref
1194 str << "#{return_type} result = ".indent(2) unless return_type == "void"
1195 str << "".indent(2) if return_type == "void"
1196 str << "invokeObjcSelf!("
1197 str << return_type
1115 else 1198 else
1116 str << "return invokeObjcSelf!(".indent(2) 1199 str << "return invokeObjcSelf!(".indent(2)
1117 str << return_type 1200 str << return_type
1118 end 1201 end
1119 end 1202 end
1122 str << method.selector 1205 str << method.selector
1123 str << '"' 1206 str << '"'
1124 1207
1125 method.arg.each do |arg| 1208 method.arg.each do |arg|
1126 str << ", " 1209 str << ", "
1127 str << get_type(arg.type, arg.type, arg.declaredType) 1210
1211 if arg.declaredType =~ /NSError\*\*/ || arg.declaredType =~ /NSDictionary\*\*/
1212 str << "id*"
1213 else
1214 str << get_type(arg.type, arg.type, arg.declaredType)
1215 end
1128 end unless method.arg.nil? 1216 end unless method.arg.nil?
1129 1217
1130 unless method.arg.nil? 1218 unless method.arg.nil?
1131 str << ")" 1219 str << ")"
1132 str << "(" 1220 str << "("
1133 end 1221 end
1134 1222
1135 method.arg.each_with_index do |arg, i| 1223 method.arg.each_with_index do |arg, i|
1136 str << get_identifier(arg.name) 1224 if arg.declaredType =~ /NSError\*\*/ || arg.declaredType =~ /NSDictionary\*\*/
1225 str << "&__arg#{i}"
1226 else
1227 str << get_identifier(arg.name)
1228 end
1229
1137 str << ", " unless i == method.arg.length - 1 1230 str << ", " unless i == method.arg.length - 1
1138 end unless method.arg.nil? 1231 end unless method.arg.nil?
1139 1232
1140 str << ")".nl 1233 str << ")".nl
1141 str << "return result is this.objcObject ? this : (result !is null ? new #{return_type}(result) : null)".indent(2).nl if return_type == class_name && !static 1234
1235 if has_ref
1236 str << "\n"
1237
1238 method.arg.each_with_index do |arg, i|
1239 if arg.declaredType =~ /NSError\*\*/ || arg.declaredType =~ /NSDictionary\*\*/
1240 str << "if (__arg#{i})\n".indent(2)
1241 argType = get_type(arg.type, arg.type64, arg.declaredType)
1242 argType = argType[4 .. -1] # cut off "ref "
1243 str << "#{arg.name} = new #{argType}(__arg#{i})".indent(3).nl
1244 end
1245 end
1246
1247 unless return_type == "void" || return_type == class_name || return_type == "typeof(this)"
1248 str << "\n"
1249 str << "return result".indent(2).nl
1250 end
1251 end
1252
1253 if (return_type == class_name || return_type == "typeof(this)") && !static
1254 str << "\n"
1255 str << "return result is this.objcObject ? this : (result !is null ? new #{return_type}(result) : null)".indent(2).nl
1256 end
1257
1142 str << "}".indent.nl(false).nl(false) 1258 str << "}".indent.nl(false).nl(false)
1143 1259
1144 if name.length >= 4 && name[0 ... 4] == "init" && name != "initialize" 1260 if name.length >= 4 && name[0 ... 4] == "init" && name != "initialize"
1145 str << ("this" + declaration[index .. -1]).gsub(/ +/, " ").indent 1261 str << ("this" + declaration[index .. -1]).gsub(/ +/, " ").indent
1146 str << "{".indent.nl(false) 1262 str << "{".indent.nl(false)
1147 str << 'objcObject = Bridge.invokeObjcClassMethod!(id, "alloc")(objcClass)'.indent(2).nl 1263 str << "super(".indent(2)
1148 str << 'id result = Bridge.invokeObjcMethod!(id, "'.indent(2) 1264 str << typeof(this) if template
1149 str << method.selector 1265 str << class_name unless template
1150 str << '"' 1266 str << ".alloc."
1151 1267 str << get_method_name(method.selector)
1152 method.arg.each do |arg| 1268
1153 str << ", " 1269 unless method.arg.nil?
1154 str << get_type(arg.type, arg.type, arg.declaredType) 1270 str << "("
1155 end unless method.arg.nil? 1271 args = StringIO.new
1156 1272
1157 str << ")(objcObject" 1273 method.arg.each do |arg|
1158 1274 args << get_identifier(arg.name)
1159 method.arg.each do |arg| 1275 args << ", "
1160 str << ", " 1276 end
1161 str << get_identifier(arg.name) 1277
1162 end unless method.arg.nil? 1278 str << args.string[0 ... -2]
1163 1279 str << ")"
1164 str << ")".nl.nl(false) 1280 end
1165 1281
1166 str << "if (result)".indent(2).nl(false) 1282 str << ".objcObject)".nl
1167 str << "objcObject = ret".indent(3).nl.nl(false)
1168 str << "dObject = this".indent(2).nl
1169 str << "}".indent.nl(false).nl(false) 1283 str << "}".indent.nl(false).nl(false)
1170 end 1284 end
1171 end 1285 end
1172 1286
1173 str.string[0 .. -2] 1287 str.string[0 .. -2]
1285 when "BOOL"; return "bool" 1399 when "BOOL"; return "bool"
1286 when "CGFloat"; return type 1400 when "CGFloat"; return type
1287 when "NSInteger"; return type 1401 when "NSInteger"; return type
1288 when "NSUInteger"; return type 1402 when "NSUInteger"; return type
1289 when "IMP"; return type; 1403 when "IMP"; return type;
1404 when "size_t"; return type;
1290 1405
1291 when "unichar*" 1406 when "unichar*"
1292 when "UniChar*"; return "wchar*" 1407 when "UniChar*"; return "wchar*"
1293 when "BOOL*"; return "bool*" 1408 when "BOOL*"; return "bool*"
1294 when "CGFloat*"; return type 1409 when "CGFloat*"; return type
1295 when "NSInteger*"; return type 1410 when "NSInteger*"; return type
1296 when "NSUInteger*"; return type 1411 when "NSUInteger*"; return type
1412 when "size_t*"; return type;
1297 1413
1298 when "unichar**" 1414 when "unichar**"
1299 when "UniChar**"; return "wchar**" 1415 when "UniChar**"; return "wchar**"
1300 when "BOOL**"; return "bool**" 1416 when "BOOL**"; return "bool**"
1301 when "CGFloat**"; return type 1417 when "CGFloat**"; return type
1302 when "NSInteger**"; return type 1418 when "NSInteger**"; return type
1303 when "NSUInteger**"; return type 1419 when "NSUInteger**"; return type
1304 else return nil; 1420 when "size_t**"; return type;
1421
1422 # special case, asume ref parameter
1423 when "NSError**"; return "ref NSError"
1424 when "NSDictionary**"; return "ref NSDictionary"
1425 when "typeof(this)"; return type
1426 else
1427 return nil;
1305 end 1428 end
1306 end 1429 end
1307 1430
1308 # Gets the method name from the supplied selector 1431 # Gets the method name from the supplied selector
1309 # selector:: the selector to get the method name from 1432 # selector:: the selector to get the method name from
1336 # === Example: 1459 # === Example:
1337 # get_type("I", "Q", "NSUInteger") #=> NSUInteger 1460 # get_type("I", "Q", "NSUInteger") #=> NSUInteger
1338 # get_type("I", "I", "unsigned int") #=> uint 1461 # get_type("I", "I", "unsigned int") #=> uint
1339 # 1462 #
1340 def get_type (type, type64, declared_type) 1463 def get_type (type, type64, declared_type)
1464 t = check_declared_type(declared_type)
1465 return t unless t.nil?
1466
1341 declared_type = "I" + $1 if declared_type =~ /\w+\s*<(.+)>/ 1467 declared_type = "I" + $1 if declared_type =~ /\w+\s*<(.+)>/
1342 declared_type.gsub!(/\(|\)/, "") 1468 declared_type.gsub!(/\(|\)/, "")
1343 1469
1344 return get_identifier(declared_type) if type.nil? && type64.nil? 1470 return get_identifier(declared_type) if type.nil? && type64.nil?
1345
1346 t = check_declared_type(declared_type)
1347 return t unless t.nil?
1348 1471
1349 unless type64 == "" || type64.nil? 1472 unless type64 == "" || type64.nil?
1350 return get_identifier(declared_type) if type != type64 1473 return get_identifier(declared_type) if type != type64
1351 end 1474 end
1352 1475
1422 i += 1 1545 i += 1
1423 end unless types.nil? 1546 end unless types.nil?
1424 1547
1425 get_identifier(resolved_types) 1548 get_identifier(resolved_types)
1426 when "^" 1549 when "^"
1427 t = type[1 .. -1] 1550 if type == "^@"
1428 t64 = type64.nil? ? t : type64[1 .. -1] 1551 t = type[1 .. -1]
1429 get_identifier(get_type(t, t64, declared_type).dup + "*") 1552 t64 = type64.nil? ? t : type64[1 .. -1]
1553 get_identifier(get_type(t, t64, "ref " + declared_type).dup)
1554
1555 elsif type == "^?"
1556 tmp = cfp_to_dfp(type)
1557 return get_identifier(tmp) unless tmp.nil?
1558 end
1559 # t = type[1 .. -1]
1560 # t64 = type64.nil? ? t : type64[1 .. -1]
1561 # get_identifier(get_type(t, t64, declared_type).dup + "*")
1562
1563
1564
1430 1565
1431 # if type == "^@" 1566 # if type == "^@"
1432 # return get_identifier(get_type(type[1 .. -1], type64[1 .. -1], declared_type).dup + "*") 1567 # return get_identifier(get_type(type[1 .. -1], type64[1 .. -1], declared_type).dup + "*")
1433 # elsif type.length > 2 && type[0 ... 2] == "^^" 1568 # elsif type.length > 2 && type[0 ... 2] == "^^"
1434 # return get_identifier(get_type(type[2 .. -1], type64[2 .. -1], declared_type).dup + "**") 1569 # return get_identifier(get_type(type[2 .. -1], type64[2 .. -1], declared_type).dup + "**")