home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / utility / unittool / turbo5 / intrfac5 / objstuff.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-12-14  |  12.9 KB  |  482 lines

  1. unit objstuff;
  2. { These are the object oriented routines }
  3.  
  4. interface
  5.  
  6. uses
  7.   util,globals,hash;
  8.  
  9. procedure print_obj_list;
  10. procedure print_obj(obj:obj_ptr);
  11. procedure write_type_def(def:type_def_ptr);
  12. procedure write_type_info(var name:string; info:type_info_ptr);
  13. function find_type(unit_rec:unit_list_ptr;def_ofs:word):obj_ptr;
  14. procedure write_var_type(type_unit,type_def_ofs:word);
  15. procedure write_var_info(var name:string; info:var_info_ptr);
  16. procedure write_args(arg:arg_ptr; num_args:word);
  17. procedure write_func_info(var name:string; info:func_info_ptr);
  18. procedure write_proc_info(var name:string; info:func_info_ptr);
  19. procedure write_const_info(var name:string; info:const_info_ptr);
  20. procedure write_general(kind:byte; title,name,suffix:string);
  21.  
  22. implementation
  23.  
  24. const
  25.   semicrlf = ';'+^M+^J;
  26.   colontab = ':'+^I;
  27.  
  28. function obj_ofs(obj:pointer):word;
  29. begin
  30.   obj_ofs := ptr_diff(obj,buffer);
  31. end;
  32.  
  33. procedure write_type_def(def:type_def_ptr);
  34. var
  35.   i : integer;
  36.   l : longint;
  37.   save_kind : byte;
  38.   field_list : list_ptr;
  39.   current : list_ptr;
  40.   obj : obj_ptr;
  41. begin
  42.   with def^ do
  43.     case type_type of
  44.       0 : write('untyped');
  45.       1 : begin                  {Array}
  46.             write('array[');
  47.             write_var_type(index_unit,index_ofs);
  48.             write('] of ');
  49.             write_var_type(element_unit,element_ofs);
  50.           end;
  51.       2 : begin                  {Record}
  52.             save_kind := last_kind;
  53.             last_kind := record_id;
  54.             writeln ('Record ');
  55.  
  56.             build_list(field_list,buffer,@hash_table);
  57.  
  58.             current := field_list;
  59.             while current^.offset < $ffff do
  60.             begin
  61.               obj := add_offset(buffer,current^.offset);
  62.               write(^I);
  63.               print_obj(obj);
  64.               current := current^.next;
  65.             end;
  66.  
  67.             write(^I,'end');
  68.             last_kind := save_kind;
  69.           end;
  70.       3 : begin                  {File}
  71.             write('file');
  72.             if base_unit <> 0 then
  73.             begin
  74.               write(' of ');
  75.               write_var_type(base_unit,base_ofs);
  76.             end;
  77.           end;
  78.       4 : write('built-in text file');  {Text}
  79.       5 : begin                  {procedure}
  80.             write('procedure');
  81.             write_args(arg_ptr(add_offset(def,10)),num_args);
  82.           end;
  83.       6 : begin                  {function}
  84.             write('function');
  85.             write_args(arg_ptr(add_offset(def,10)),num_args);
  86.             write(':');
  87.             write_var_type(return_unit,return_ofs);
  88.           end;
  89.       7 : begin                  {Set}
  90.             write('set of ');
  91.             write_var_type(base_unit,base_ofs);
  92.           end;
  93.       8 : begin                  {Pointer}
  94.             write('^',target_name);
  95.           end;
  96.  
  97.       9 : begin                  {String}
  98.             write('string[',size-1,']');
  99.             {N.B. actually record is like array of char, but "string" with
  100.                   no length is different.}
  101.           end;
  102.      10 : write('built-in 8087 type');    {8087}
  103.      11 : write('built-in 6-byte real');
  104.      12 : begin                  {Range}
  105.             write(lower,'..',upper);
  106.           end;
  107.      13 : write('built-in boolean');
  108.      14 : write('built-in char');
  109.      15 : begin                  {Enumeration}
  110.             write('(');
  111.             {  Assume following records are constant declarations  }
  112.             obj := add_offset(def,16);
  113.             for l:=lower to upper-1 do
  114.             begin
  115.               write(obj^.name,',');
  116.               obj:=add_offset(obj,12+length(obj^.name));
  117.             end;
  118.             write(obj^.name,')');
  119.           end;
  120.      else
  121.           begin
  122.             writeln('Type definition of type ',type_type, 'otherbyte=',
  123.                     other_byte,'size=',size);
  124.             write(' junk=');
  125.             for i:=3 to 8 do
  126.               write(who_knows[i]:6);
  127.             writeln;
  128.           end;
  129.     end;
  130. end;
  131.  
  132. procedure write_type_info(var name:string; info:type_info_ptr);
  133. begin
  134.   if (last_kind <> record_id) and (last_kind <> type_id) then
  135.   begin
  136.     writeln('type');
  137.     last_kind := type_id;
  138.   end;
  139.   write(^I,name,'=',^I);
  140.   with info^,get_unit(info^.type_unit)^ do
  141.   begin
  142.     if buffer <> nil then
  143.       write_type_def(add_offset(buffer,type_def_ofs))
  144.     else
  145.       write(name,'.ofs',type_def_ofs);
  146.     writeln(';');
  147.   end;
  148. end;
  149.  
  150. function find_type(unit_rec:unit_list_ptr;def_ofs:word):obj_ptr;
  151. var
  152.   current:list_ptr;
  153.   obj : obj_ptr;
  154.   obj_info : type_info_ptr;
  155. begin
  156.   with unit_rec^ do
  157.   begin
  158.     if obj_list = nil then
  159.       build_list(obj_list,buffer,add_offset(buffer,header_ptr(buffer)^.ofs_hashtable));
  160.     current := obj_list;
  161.     while current^.offset < $ffff do
  162.     begin
  163.       obj := add_offset(buffer,current^.offset);
  164.       obj_info := add_offset(obj,3+length(obj^.name));
  165.       if     (obj_info^.id = type_id)
  166.          and (obj_info^.type_def_ofs = def_ofs)
  167.          and (obj_info^.type_unit = own_record) then
  168.       begin
  169.         find_type := obj;
  170.         exit;
  171.       end;
  172.       current := current^.next;
  173.     end;
  174.     find_type := nil;
  175.   end;
  176. end;
  177.  
  178. function find_name(unit_rec:unit_list_ptr;info_ofs:word):string;
  179. {  Unreliable way to get a name from a pointer to its info }
  180. var
  181.   i:word;
  182.   name:string;
  183. begin
  184.   with unit_rec^ do
  185.   begin
  186.     for i:=info_ofs-2 downto 0 do
  187.       if i+buffer^[i]+2 = info_ofs then
  188.       begin
  189.         move(buffer^[i],name[0],buffer^[i]+1);
  190.         find_name := name;
  191.         exit;
  192.       end;
  193.   end;
  194.   find_name := '';
  195. end;
  196.  
  197. procedure write_var_type(type_unit,type_def_ofs:word);
  198. var
  199.   type_obj : obj_ptr;
  200. begin
  201.   if type_unit > 0 then
  202.   begin
  203.     with get_unit(type_unit)^ do
  204.     begin
  205.       if buffer <> nil then
  206.       begin
  207.         type_obj := find_type(get_unit(type_unit),type_def_ofs);
  208.         if type_obj <> nil then
  209.           write(type_obj^.name)
  210.         else
  211.           write_type_def(add_offset(buffer,type_def_ofs));
  212.       end
  213.       else
  214.         write(name,'.ofs',type_def_ofs);
  215.     end;
  216.   end
  217.   else
  218.     write('type_unit not found');
  219. end;
  220.  
  221. procedure write_var_info(var name:string; info:var_info_ptr);
  222. var
  223.   orig_unit:unit_list_ptr;
  224. begin
  225.   with info^ do
  226.   begin
  227.     if last_kind <> record_id then
  228.       case c_or_v and $FFEF of
  229.         0 : write_general(var_id,'var',name,colontab);
  230.         1 : write_general(const_id,'const',name,colontab);
  231.         2 : write_general(local_id,'local var',name,colontab);
  232.         6 : write_general(referenced_id,'referenced var',name,colontab);
  233.         else write('C_or_V=',c_or_v,^I,name,colontab);
  234.       end
  235.     else
  236.       write(^I,name,colontab);
  237.  
  238.     write_var_type(type_unit,type_def_ofs);
  239.  
  240.     if (c_or_v and $10) <> 0 then
  241.     begin
  242.       write(' absolute ');
  243.       orig_unit := get_unit(in_unit);
  244.       if orig_unit <> nil then
  245.       begin
  246.         if orig_unit <> unit_list[1] then
  247.           write(orig_unit^.name,'.');
  248.         write(find_name(orig_unit,offset));
  249.         info := add_offset(orig_unit^.buffer,offset-1);
  250.       end
  251.       else
  252.         write('?????');
  253.     end;
  254.   end;
  255.   with info^ do
  256.   begin
  257.     if c_or_v = 1 then
  258.       write('=',^I,'?');
  259.     if in_function then
  260.       write(';',^I,'{BP ofs ',integer(offset))
  261.     else
  262.     begin
  263.       write(';',^I,'{ofs ',offset);
  264.       if (in_unit <> 0) and (last_kind <> record_id) then
  265.         writeln(' in unit ',get_unit(in_unit)^.name);
  266.     end;
  267.     writeln('}');
  268.   end;
  269. end;
  270.  
  271. procedure write_args(arg:arg_ptr;num_args:word);
  272. var
  273.   i:word;
  274. begin
  275.   writeln('(');
  276.   for i:=1 to num_args do
  277.   begin
  278.     with arg^ do
  279.     begin
  280.       write(^I);
  281.       case var_or_val of
  282.       2 : write('    ');
  283.       6 : write('var ');
  284.       else
  285.         writeln('var_or_val=',var_or_val,', not 2 or 6!');
  286.       end;
  287.       write(name,':',^I);
  288.       write_var_type(type_unit,type_def_ofs);
  289.       writeln(';');
  290.     end;
  291.     arg := add_offset(arg,6+length(arg^.name));
  292.   end;
  293.   write(^I,^I,')');
  294. end;
  295.  
  296. procedure write_locals(var name:string; info:func_info_ptr);
  297. var
  298.   save_list : list_ptr;
  299.   save_in_function : boolean;
  300. begin
  301.   if info^.local_hash = 0 then
  302.     exit;
  303.   save_list := obj_list;
  304.   save_in_function := in_function;
  305.   in_function := true;
  306.   build_list(obj_list,buffer,add_offset(buffer,info^.local_hash));
  307.   writeln('{ ',name,' locals begin...}');
  308.   print_obj_list;
  309.   writeln('{ ...',name,' locals end.}');
  310.   writeln;
  311.   obj_list := save_list;
  312.   in_function := save_in_function;
  313. end;
  314.  
  315. procedure write_func_info(var name:string; info:func_info_ptr);
  316. begin
  317.   write('function',^I,name);
  318.   if info^.num_args > 0 then
  319.     write_args(arg_ptr(add_offset(info,sizeof(func_info_rec))),
  320.                info^.num_args);
  321.   write(':',^I);
  322.   write_var_type(info^.type_unit,info^.type_def_ofs);
  323.   writeln(';');
  324.  
  325.   write_locals(name,info);
  326. end;
  327.  
  328. procedure write_proc_info(var name:string; info:func_info_ptr);
  329. begin
  330.   write('procedure',^I,name);
  331.   if info^.num_args > 0 then
  332.     write_args(arg_ptr(add_offset(info,sizeof(func_info_rec))),
  333.                info^.num_args);
  334.   writeln(';');
  335.  
  336.  
  337.   write_locals(name,info);
  338. end;
  339.  
  340. procedure write_const_info(var name:string; info:const_info_ptr);
  341. var
  342.   type_obj : obj_ptr;
  343. begin
  344.   if (last_kind <> record_id) and (last_kind <> const_id) then
  345.   begin
  346.     writeln('Const');
  347.     last_kind := const_id;
  348.   end;
  349.   write(^I,name,'=',^I);
  350.   with info^,get_unit(type_unit)^ do
  351.   begin
  352.     if buffer <> nil then
  353.     begin
  354.       type_obj := find_type(get_unit(type_unit),type_def_ofs);
  355.       if type_obj <> nil then
  356.       begin
  357.         with type_obj^ do
  358.         begin
  359.           if name = 'LONGINT' then
  360.             write(intval)
  361.           else if name = 'REAL' then
  362.             write(realval)
  363. {         else if name = 'EXTENDED' then  } {put this in only if compiled with}
  364. {           write(extendval)              } { N+ option }
  365.           else
  366.             write(name,' value ',intval); {Don't know correct way to print}
  367.         end;
  368.       end
  369.       else
  370.       begin
  371.         if (type_def_ofs = 134)   { Risky to fix this, but can't see any
  372.                                   other way to detect string constants }
  373.            and (get_unit(type_unit)^.name = 'SYSTEM') then
  374.            write('''',stringval,'''')
  375.         else
  376.           write('?');
  377.       end;
  378.     end
  379.     else
  380.       write('?');
  381.   end;
  382.   writeln(';');
  383. end;
  384.  
  385. procedure write_general(kind:byte; title,name,suffix:string);
  386. begin
  387.   if last_kind <> kind then
  388.   begin
  389.     writeln(title);
  390.     last_kind := kind;
  391.   end;
  392.   write(^I,name,suffix);
  393. end;
  394.  
  395. procedure print_obj(obj:obj_ptr);
  396. var
  397.   j:word;
  398.   obj_info : ^byte_array;
  399.   new_entry : list_ptr;
  400.   info_len,info_ofs : word;
  401. const
  402.   known_types : set of byte = [81..90];
  403.  
  404. begin
  405.   info_ofs := 3+length(obj^.name);
  406.   obj_info := add_offset(obj,info_ofs);
  407.  
  408.   if obj_info^[0] in known_types then
  409.   begin
  410.     if obj_info^[0] = unit_id then
  411.       add_unit(obj,unit_ptr(obj_info));
  412.  
  413.     case obj_info^[0] of
  414.        const_id : write_const_info(obj^.name,pointer(obj_info));
  415.        type_id : write_type_info(obj^.name,pointer(obj_info));
  416.  
  417.        var_id  : write_var_info(obj^.name,pointer(obj_info));
  418.  
  419.        proc_id : begin
  420.                    write_proc_info(obj^.name,pointer(obj_info));
  421.                    last_kind := proc_id;
  422.                  end;
  423.        func_id : begin
  424.                    write_func_info(obj^.name,pointer(obj_info));
  425.                    last_kind := func_id;
  426.                  end;
  427.  
  428.        sys_proc_id : write_general(sys_proc_id,'built-in procedure',obj^.name,semicrlf);
  429.  
  430.        sys_fn_id : write_general(sys_fn_id,'built-in function',obj^.name,semicrlf);
  431.  
  432.        sys_port_id : write_general(sys_port_id,'port array',obj^.name,semicrlf);
  433.  
  434.        sys_mem_id : write_general(sys_mem_id,'memory array',obj^.name,semicrlf);
  435.  
  436.        unit_id :   if obj_ofs(obj) = header^.ofs_this_unit then
  437.                    begin
  438.                      writeln('Unit',^I,obj^.name,';');
  439.                      last_kind := init_id;
  440.                    end
  441.                    else
  442.                    begin
  443.                      if last_kind = unit_id then
  444.                        writeln(^I,',',obj^.name)
  445.                      else
  446.                      begin
  447.                        writeln('Uses',^I,obj^.name);
  448.                        last_kind := unit_id;
  449.                      end;
  450.                    end;
  451.  
  452.     end; {case}
  453.   end
  454.   else
  455.   begin
  456.     writeln('Unknown kind ',obj_info^[0],^I,obj^.name,' with info at ',obj_ofs(obj_info));
  457.             ;
  458.     for j:=0 to 15 do
  459.       write(obj_info^[j]:5);
  460.     writeln;
  461.     last_kind := obj_info^[0];
  462.   end;
  463. end;
  464.  
  465. procedure print_obj_list;
  466. var
  467.   obj : obj_ptr;
  468.   current : list_ptr;
  469.   bytes : ^byte_array;
  470.   j : integer;
  471. begin
  472.   last_kind := init_id;
  473.   current := obj_list;
  474.   while current^.offset < $ffff do
  475.   begin
  476.     obj := add_offset(buffer,current^.offset);
  477.     print_obj(obj);
  478.     current := current^.next;
  479.   end;
  480. end;
  481.  
  482. end.