home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sa104os2.zip / SATHR104.ZIP / SATHER / COMPILER / CALL.SA < prev    next >
Text File  |  1995-02-13  |  10KB  |  263 lines

  1. -- Copyright (C) International Computer Science Institute, 1994.  COPYRIGHT  --
  2. -- NOTICE: This code is provided "AS IS" WITHOUT ANY WARRANTY and is subject --
  3. -- to the terms of the SATHER LIBRARY GENERAL PUBLIC LICENSE contained in    --
  4. -- the file "Doc/License" of the Sather distribution.  The license is also   --
  5. -- available from ICSI, 1947 Center St., Suite 600, Berkeley CA 94704, USA.  --
  6. --------> Please email comments to "sather-bugs@icsi.berkeley.edu". <----------
  7.  
  8. -- call5.sa: Representation of routine and iter calls.
  9. -------------------------------------------------------------------
  10. -- $CALL_TP: Supertype of argument types in a call.
  11. -- CALL_TP_VOID: The type of a "void" expression.
  12. -- CALL_TP_CREATE: The type of an untyped creation expression.
  13. -- CALL_TP_ARRAY: The type of an array creation expression.
  14. -- CALL_TP_UNDERSCORE: The type of a bound underscore argument.
  15. -- CALL_SIG: The type signature of a routine or iter call.
  16. -------------------------------------------------------------------
  17. type $CALL_TP is
  18.    -- Supertype of the possible types of an argument in a call.
  19.    -- This is either an actual type under $TP or CALL_TP_VOID for a 
  20.    -- "void" argument, CALL_TP_CREATE for a creation expression without
  21.    -- a type, CALL_TP_ARRAY for an array creation expression,
  22.    -- or CALL_TP_UNDERSCORE for an underscore argument in a bound
  23.    -- routine or iter.
  24.  
  25.    str:STR;            -- The string representation of self.
  26.    
  27.    is_subtype(t:$TP):BOOL;    -- True if self might be a legal
  28.       -- argument type for an argument whose declared type is `t'.
  29.    
  30. end; -- type $CALL_TP
  31.  
  32. -------------------------------------------------------------------
  33. class CALL_TP_VOID < $CALL_TP is
  34.    -- The type of the argument "void".
  35.    
  36.    shared cache:SAME;   
  37.    
  38.    create:SAME is
  39.       -- The representative object.
  40.       if void(cache) then cache:=new end; return cache end;
  41.    
  42.    str:STR is
  43.       -- The string: "void".
  44.       return "void-expression" end;
  45.  
  46.    is_subtype(t:$TP):BOOL 
  47.       -- True.
  48.       pre ~void(t) is
  49.       return true end;
  50.    
  51. end; -- class CALL_TP_VOID
  52.  
  53. -------------------------------------------------------------------
  54. class CALL_TP_CREATE < $CALL_TP is
  55.    -- The type of an untyped creation expression.
  56.    
  57.    shared cache:SAME;
  58.    
  59.    create:SAME is
  60.       -- The representative object.
  61.       if void(cache) then cache:=new end; 
  62.       return cache end;
  63.  
  64.    str:STR is
  65.       -- The string: "create".
  66.       return "create-expression" end;
  67.  
  68.    is_subtype(t:$TP):BOOL 
  69.       -- True if `t' is a reference or value type.
  70.       pre ~void(t) is
  71.       case t.kind
  72.       when TP_KIND::val_tp then return true
  73.       when TP_KIND::ref_tp then return true
  74.       when TP_KIND::abs_tp then return false
  75.       when TP_KIND::ext_tp then return false
  76.       when TP_KIND::rout_tp then return false
  77. --    when TP_KIND::iter_tp then return false end end;                          -- NLP
  78.       when TP_KIND::iter_tp then return false end; return false; end;           -- NLP
  79.  
  80. end; -- class CALL_TP_CREATE
  81.  
  82. -------------------------------------------------------------------
  83. class CALL_TP_ARRAY < $CALL_TP is
  84.    -- The type of an array creation expression.
  85.    
  86.    shared cache:SAME;
  87.    
  88.    create:SAME is
  89.       -- The representative object.
  90.       if void(cache) then cache:=new end; 
  91.       return cache end;
  92.    
  93.    str:STR is
  94.       -- The string: "array".
  95.       return "array-expression" end;
  96.  
  97.    is_subtype(t:$TP):BOOL is
  98.       -- True if `t' is ARRAY{T} for some T.
  99.       typecase t
  100.       when TP_CLASS then
  101.      return t.name=t.prog.ident_for("ARRAY")
  102. --    else return false end end;                                                -- NLP
  103.       else; end; return false; end;                                             -- NLP
  104.    
  105. end; -- class CALL_TP_ARRAY
  106.  
  107. -------------------------------------------------------------------
  108. class CALL_TP_UNDERSCORE < $CALL_TP is
  109.    -- The type of an underscore argument in a bound routine or iter 
  110.    -- call and doesn't have a type specified.
  111.    
  112.    attr tp:$TP;            -- The type if one is specified. 
  113.  
  114.    create:SAME is
  115.       -- A new object.
  116.       return new end;
  117.    
  118.    str:STR is
  119.       -- The string: "underscore" followed by ":TYPE" if a type is 
  120.       -- present. 
  121.       if void(tp) then return "underscore-expression" else
  122. --       return "underscore-expression:" + tp.str end end;                      -- NLP
  123.          end; return "underscore-expression:" + tp.str; end;                    -- NLP
  124.    
  125.    is_subtype(t:$TP):BOOL 
  126.       -- True if self may represent `t'.
  127.       pre ~void(t) is
  128.       if void(tp) then return true else 
  129. --       return tp.is_subtype(t) end end;                                       -- NLP
  130.          end; return tp.is_subtype(t); end;                                     -- NLP
  131.    
  132. end; -- class CALL_TP_UNDERSCORE
  133.  
  134. -------------------------------------------------------------------
  135. class CALL_SIG is
  136.    -- The type signature of a routine or iter *call*. There are special
  137.    -- type objects for arguments which are void, untyped creation 
  138.    -- expressions, array creation expressions, integer literals, or
  139.    -- floating point literals.
  140.  
  141.    attr tp:$TP;            -- The type on which the call is made.
  142.    attr name:IDENT;        -- The name of the call.
  143.    attr args:ARRAY{$CALL_TP};    -- The argument types, if any. 
  144.    attr has_ret:BOOL;        -- True if the return value is used. 
  145.    attr unknown_ret:BOOL;    -- True if this is a bound routine
  146.       -- or iter call signature and we don't know whether there
  147.       -- is a return value or not.    
  148.  
  149.    prog:PROG is
  150.       -- The program in which this call appears.
  151.       return tp.prog end;
  152.  
  153.    create:SAME is
  154.       -- An uninitialized call sig.
  155.       return new end;
  156.  
  157.    str:STR is
  158.       -- The string representation of self. Uses no whitespace. Use
  159.       -- an underbar "_" for the return type if there is one, and 
  160.       -- the special strings "void", "create", "array", and 
  161.       -- "underscore" for call arguments whose type is inferred: 
  162.       -- "FOO::foo!(A,void,C,array):_". 
  163.       -- If self is void, returns "void".
  164.       if void(self) then return "void" end;
  165.       s::=#FSTR + tp.str + "::" + name.str;
  166.       if ~void(args) then
  167.      s:=s + '(';
  168.      loop s:=s + ",".separate!(args.elt!.str) end;
  169.      s:=s + ')' end;
  170.       if unknown_ret then s:=s + ":?" 
  171.       elsif has_ret then s:=s + ":_" end;
  172.       return s.str end;
  173.  
  174.    conforms_to(s:SIG):BOOL is
  175.       -- True if a call with signature self could be made on the routine
  176.       -- or iter described by `s'. They must:
  177.       -- 1) have the same name, 
  178.       -- 2) have the same number of arguments, 
  179.       -- 3) each call argument must conform to the corresponding 
  180.       --    declared argument,
  181.       -- 4) both must have or not have a return value.
  182.       -- 5) Appear in the same type.
  183.       if void(self) or void(s) then return false end;
  184.       if tp/=s.tp then return false end;
  185.       if name/=s.name then return false end;
  186.       if ~unknown_ret then
  187.      if has_ret then if void(s.ret) then return false end
  188.      elsif ~void(s.ret) then return false end end;
  189.       if args.size/=s.args.size then return false end;
  190.       loop ca::=args.elt!; sa::=s.args.elt!;
  191.      if ~ca.is_subtype(sa) then return false end end; 
  192.       return true end;
  193.  
  194.    lookup(in_class:BOOL):SIG is
  195.       -- Lookup self and return the corresponding signature if there
  196.       -- is one. Print an error message if it is ambiguous or absent and
  197.       -- return void. Callers should set the err_loc. If `in_class' 
  198.       -- is true, then consider both public and private routines, 
  199.       -- otherwise just public ones.
  200.       st::=tp;            -- The type the call is made on.
  201.       typecase st
  202.       when TP_CLASS then
  203.      if in_class then
  204.         return prog.impl_tbl.impl_of(tp).sig_for_internal_call(self);
  205.      else return prog.ifc_tbl.ifc_of(tp).sig_for_call(self) end;
  206.       when TP_ROUT then
  207.      if name/=prog.ident_builtin.call_ident then
  208.         prog.err("Only `call' may be applied to a bound routine.");
  209.         return void end;
  210.      if ~unknown_ret then
  211.         if has_ret and void(st.ret) then
  212.            prog.err("The bound routine " + st.str +
  213.               " has no return value, but one is needed."); 
  214.            return void
  215.         elsif ~has_ret and ~void(st.ret) then
  216.            prog.err("The bound routine " + st.str +
  217.            " has a return value, but it isn't used."); 
  218.            return void end end;
  219.      if st.args.size/=args.size then
  220.         prog.err("The call " + str +
  221.            " has the wrong number of args for " + st.str + ".");
  222.         return void end;
  223.      loop at::=args.elt!; brat::=st.args.elt!;
  224.         if ~at.is_subtype(brat) then
  225.            prog.err("The argument type " + at.str + " in the call " +
  226.               str + " doesn't conform to " + brat.str + 
  227.               " in the bound routine " + st.str + "."); 
  228.            return void end end;
  229.      return SIG::bound_routine_call(st)
  230.       when TP_ITER then
  231.      if name/=prog.ident_builtin.call_bang_ident then
  232.         prog.err("Only `call!' may be applied to a bound iter.");
  233.         return void end;
  234.      if ~unknown_ret then
  235.         if has_ret and void(st.ret) then
  236.            prog.err("The bound iter " + st.str +
  237.            " has no return value, but one is needed."); return void
  238.         elsif ~has_ret and ~void(st.ret) then
  239.            prog.err("The bound iter " + st.str +
  240.            " has a return value, but it isn't used."); 
  241.            return void end end;
  242.      if st.args.size/=args.size then
  243.         prog.err("The call " + str + 
  244.            " has the wrong number of args for " + st.str +".");
  245.         return void end;
  246.      loop at::=args.elt!; brat::=st.args.elt!;
  247.         if ~at.is_subtype(brat) then
  248.            prog.err("The argument type " + at.str + " in the call " +
  249.               str + " doesn't conform to " + brat.str + 
  250.               " in the bound routine " + st.str + "."); 
  251.            return void end end;
  252. --       return SIG::bound_iter_call(st) end end;                               -- NLP
  253.          return SIG::bound_iter_call(st) end; return void; end;                 -- NLP
  254.    
  255. end; -- class CALL_SIG
  256.  
  257. -------------------------------------------------------------------
  258.  
  259.  
  260.  
  261.  
  262.  
  263.