Browse Source

+ parsing of disp variant invokes

git-svn-id: trunk@5162 -
florian 19 years ago
parent
commit
be2b715d3c
6 changed files with 138 additions and 24 deletions
  1. 1 1
      compiler/defutil.pas
  2. 23 0
      compiler/ncal.pas
  3. 1 0
      compiler/parser.pas
  4. 8 2
      compiler/pbase.pas
  5. 101 17
      compiler/pexpr.pas
  6. 4 4
      compiler/pinline.pas

+ 1 - 1
compiler/defutil.pas

@@ -1003,7 +1003,7 @@ implementation
           floatdef:
             result:=tfloatdef(p).typ in [s64currency,s64real,s32real];
           stringdef:
-            result:=tstringdef(p).string_typ in [st_shortstring,st_ansistring];
+            result:=tstringdef(p).string_typ in [st_ansistring,st_widestring];
           variantdef:
             result:=true;
         end;

+ 23 - 0
compiler/ncal.pas

@@ -145,6 +145,7 @@ interface
 
        tcallparanode = class(tbinarynode)
        public
+          named : tnode;
           callparaflags : tcallparaflags;
           parasym       : tparavarsym;
           used_by_callnode : boolean;
@@ -167,6 +168,7 @@ interface
        tcallparanodeclass = class of tcallparanode;
 
     function reverseparameters(p: tcallparanode): tcallparanode;
+    function translate_vardisp_call(p1,p2 : tnode) : tnode;
 
     var
       ccallnode : tcallnodeclass;
@@ -218,6 +220,27 @@ type
       end;
 
 
+    function translate_vardisp_call(p1,p2 : tnode) : tnode;
+      var
+        statements : tstatementnode;
+        result_data : ttempcreatenode;
+      begin
+        result:=internalstatements(statements);
+
+        { get temp for the result }
+        result_data:=ctempcreatenode.create(colevarianttype,colevarianttype.size,tt_persistent,true);
+        addstatement(statements,result_data);
+
+        { build parameters }
+
+        { first, count parameters }
+
+        { clean up }
+        addstatement(statements,ctempdeletenode.create_normal_temp(result_data));
+        addstatement(statements,ctemprefnode.create(result_data));
+      end;
+
+
     procedure maybe_load_para_in_temp(var p:tnode);
 
         function is_simple_node(hp:tnode):boolean;

+ 1 - 0
compiler/parser.pas

@@ -320,6 +320,7 @@ implementation
          important for the IDE }
          afterassignment:=false;
          in_args:=false;
+         named_args_allowed:=false;
          got_addrn:=false;
          getprocvardef:=nil;
 

+ 8 - 2
compiler/pbase.pas

@@ -41,6 +41,9 @@ interface
 
        { true, if we are parsing arguments }
        in_args : boolean = false;
+       
+       { true, if we are parsing arguments allowing named parameters }
+       named_args_allowed : boolean = false;
 
        { true, if we got an @ to get the address }
        got_addrn  : boolean = false;
@@ -57,6 +60,9 @@ interface
 
        { true, if we should ignore an equal in const x : 1..2=2 }
        ignore_equal : boolean;
+       
+       { true, if we found a name for a named arg }
+       found_arg_name : boolean;
 
 
     procedure identifier_not_found(const s:string);
@@ -175,8 +181,8 @@ implementation
     { check if a symbol contains the hint directive, and if so gives out a hint
       if required.
 
-      If this code is changed, it's like that consume_sym_orgid must be changed
-      as well (FK)
+      If this code is changed, it's likly that consume_sym_orgid and factor_read_id
+      must be changed as well (FK)
     }
     function consume_sym(var srsym:tsym;var srsymtable:tsymtable):boolean;
       begin

+ 101 - 17
compiler/pexpr.pas

@@ -45,7 +45,7 @@ interface
 
     function node_to_propaccesslist(p1:tnode):tpropaccesslist;
 
-    function parse_paras(__colon : boolean;end_of_paras : ttoken) : tnode;
+    function parse_paras(__colon,__namedpara : boolean;end_of_paras : ttoken) : tnode;
 
     { the ID token has to be consumed before calling this function }
     procedure do_member_read(classh:tobjectdef;getaddr : boolean;sym : tsym;var p1 : tnode;var again : boolean;callflags:tcallnodeflags);
@@ -240,10 +240,11 @@ implementation
       end;
 
 
-    function parse_paras(__colon : boolean;end_of_paras : ttoken) : tnode;
+    function parse_paras(__colon,__namedpara : boolean;end_of_paras : ttoken) : tnode;
       var
-         p1,p2 : tnode;
-         prev_in_args : boolean;
+         p1,p2,argname : tnode;
+         prev_in_args,
+         old_named_args_allowed,
          old_allow_array_constructor : boolean;
       begin
          if token=end_of_paras then
@@ -254,14 +255,42 @@ implementation
          { save old values }
          prev_in_args:=in_args;
          old_allow_array_constructor:=allow_array_constructor;
+         old_named_args_allowed:=named_args_allowed;
          { set para parsing values }
          in_args:=true;
+         named_args_allowed:=false;
          inc(parsing_para_level);
          allow_array_constructor:=true;
          p2:=nil;
          repeat
-           p1:=comp_expr(true);
-           p2:=ccallparanode.create(p1,p2);
+           if __namedpara then
+             begin
+               if token=_COMMA then
+                 begin
+                   { empty parameter }
+                   p2:=ccallparanode.create(nil,p2);
+                   consume(_COMMA);
+                 end
+               else
+                 begin
+                   named_args_allowed:=true;
+                   p1:=comp_expr(true);
+                   named_args_allowed:=false;
+                   if found_arg_name then
+                     begin
+                       argname:=p1;
+                       p1:=comp_expr(true);
+                       p2:=ccallparanode.create(p1,p2);
+                       tcallparanode(p2).named:=argname;
+                     end;
+                   found_arg_name:=false;
+                 end;
+             end
+           else
+             begin
+               p1:=comp_expr(true);
+               p2:=ccallparanode.create(p1,p2);
+             end;
            { it's for the str(l:5,s); }
            if __colon and (token=_COLON) then
              begin
@@ -280,6 +309,7 @@ implementation
          allow_array_constructor:=old_allow_array_constructor;
          dec(parsing_para_level);
          in_args:=prev_in_args;
+         named_args_allowed:=old_named_args_allowed;
          parse_paras:=p2;
       end;
 
@@ -756,7 +786,7 @@ implementation
             begin
               if try_to_consume(_LKLAMMER) then
                begin
-                 paras:=parse_paras(false,_RKLAMMER);
+                 paras:=parse_paras(false,false,_RKLAMMER);
                  consume(_RKLAMMER);
                end
               else
@@ -785,7 +815,7 @@ implementation
             begin
               if try_to_consume(_LKLAMMER) then
                begin
-                 paras:=parse_paras(true,_RKLAMMER);
+                 paras:=parse_paras(true,false,_RKLAMMER);
                  consume(_RKLAMMER);
                end
               else
@@ -797,7 +827,7 @@ implementation
           in_str_x_string :
             begin
               consume(_LKLAMMER);
-              paras:=parse_paras(true,_RKLAMMER);
+              paras:=parse_paras(true,false,_RKLAMMER);
               consume(_RKLAMMER);
               p1 := geninlinenode(l,false,paras);
               statement_syssym := p1;
@@ -1008,7 +1038,7 @@ implementation
               begin
                 if try_to_consume(_LKLAMMER) then
                  begin
-                   para:=parse_paras(false,_RKLAMMER);
+                   para:=parse_paras(false,false,_RKLAMMER);
                    consume(_RKLAMMER);
                  end;
               end;
@@ -1104,7 +1134,7 @@ implementation
            begin
              if try_to_consume(_LECKKLAMMER) then
                begin
-                 paras:=parse_paras(false,_RECKKLAMMER);
+                 paras:=parse_paras(false,false,_RECKKLAMMER);
                  consume(_RECKKLAMMER);
                end;
            end;
@@ -1301,14 +1331,54 @@ implementation
            pc    : pchar;
            len   : longint;
            srsym : tsym;
+           unit_found,
            possible_error : boolean;
            srsymtable : tsymtable;
            hdef  : tdef;
            static_name : string;
+           storedpattern : string;
          begin
            { allow post fix operators }
            again:=true;
-           consume_sym(srsym,srsymtable);
+
+           { first check for identifier }
+           if token<>_ID then
+             begin
+               srsym:=generrorsym;
+               srsymtable:=nil;
+               consume(_ID);
+             end
+           else
+             begin
+               searchsym(pattern,srsym,srsymtable);
+
+               { handle unit specification like System.Writeln }
+               unit_found:=try_consume_unitsym(srsym,srsymtable);
+               storedpattern:=pattern;
+               consume(_ID);
+
+               { named parameter support }
+               found_arg_name:=false;
+
+               if not(unit_found) and
+                  named_args_allowed and
+                  (token=_ASSIGNMENT) then
+                  begin
+                    found_arg_name:=true;
+                    p1:=cstringconstnode.createstr(storedpattern);
+                    consume(_ASSIGNMENT);
+                    exit;
+                  end;
+               { if nothing found give error and return errorsym }
+               if assigned(srsym) then
+                 check_hints(srsym,srsym.symoptions)
+               else
+                 begin
+                   identifier_not_found(orgpattern);
+                   srsym:=generrorsym;
+                   srsymtable:=nil;
+                 end;
+             end;
 
            { Access to funcret or need to call the function? }
            if (srsym.typ in [absolutevarsym,localvarsym,paravarsym]) and
@@ -1616,7 +1686,7 @@ implementation
                     p1:=cerrornode.create;
                     if try_to_consume(_LKLAMMER) then
                      begin
-                       parse_paras(false,_RKLAMMER);
+                       parse_paras(false,false,_RKLAMMER);
                        consume(_RKLAMMER);
                      end;
                   end;
@@ -1783,7 +1853,6 @@ implementation
           srsym  : tsym;
           srsymtable : tsymtable;
           classh     : tobjectdef;
-
         label
           skipreckklammercheck;
         begin
@@ -1969,8 +2038,23 @@ implementation
                            consume(_ID);
                          end;
                        variantdef:
-                         { dispatch call }
-                         try_to_consume(_ID);
+                         begin
+                           { dispatch call? }
+                           if token=_ID then
+                             begin
+                               consume(_ID);
+                               if try_to_consume(_LKLAMMER) then
+                                 begin
+                                   p2:=parse_paras(false,true,_RKLAMMER);
+                                   consume(_RKLAMMER);
+                                   p1:=translate_vardisp_call(p1,p2);
+                                 end
+                               else
+                                 p2:=nil;
+                             end
+                           else { Error }
+                             Consume(_ID);
+                          end;
                        classrefdef:
                          begin
                            if token=_ID then
@@ -2052,7 +2136,7 @@ implementation
                          begin
                            if try_to_consume(_LKLAMMER) then
                              begin
-                               p2:=parse_paras(false,_RKLAMMER);
+                               p2:=parse_paras(false,false,_RKLAMMER);
                                consume(_RKLAMMER);
                                p1:=ccallnode.create_procvar(p2,p1);
                                { proc():= is never possible }

+ 4 - 4
compiler/pinline.pas

@@ -460,7 +460,7 @@ implementation
         result := cerrornode.create;
 
         consume(_LKLAMMER);
-        paras:=parse_paras(false,_RKLAMMER);
+        paras:=parse_paras(false,false,_RKLAMMER);
         consume(_RKLAMMER);
         if not assigned(paras) then
          begin
@@ -587,7 +587,7 @@ implementation
         result := cerrornode.create;
 
         consume(_LKLAMMER);
-        paras:=parse_paras(false,_RKLAMMER);
+        paras:=parse_paras(false,false,_RKLAMMER);
         consume(_RKLAMMER);
         if not assigned(paras) then
          begin
@@ -625,7 +625,7 @@ implementation
         result := cerrornode.create;
 
         consume(_LKLAMMER);
-        paras:=parse_paras(false,_RKLAMMER);
+        paras:=parse_paras(false,false,_RKLAMMER);
         consume(_RKLAMMER);
         if not assigned(paras) then
          begin
@@ -684,7 +684,7 @@ implementation
         result := cerrornode.create;
 
         consume(_LKLAMMER);
-        paras:=parse_paras(false,_RKLAMMER);
+        paras:=parse_paras(false,false,_RKLAMMER);
         consume(_RKLAMMER);
         if not assigned(paras) then
          begin