Browse Source

Integrated the changes from trunks's postfixoperators into my own and removed the local version again.

git-svn-id: branches/svenbarth/generics@17997 -
svenbarth 14 years ago
parent
commit
6a60f9d42a
1 changed files with 1 additions and 534 deletions
  1. 1 534
      compiler/pexpr.pas

+ 1 - 534
compiler/pexpr.pas

@@ -1568,7 +1568,7 @@ implementation
                  is_dispinterface(p1.resultdef) or is_record(p1.resultdef) then
                  begin
                    { default property }
-                   protsym:=search_default_property(tobjectdef(p1.resultdef));
+                   protsym:=search_default_property(tabstractrecorddef(p1.resultdef));
                    if not(assigned(protsym)) then
                      begin
                         p1.destroy;
@@ -2298,539 +2298,6 @@ implementation
          end;
 
 
-         {---------------------------------------------
-                        PostFixOperators
-         ---------------------------------------------}
-
-      { returns whether or not p1 has been changed }
-      function postfixoperators(var p1:tnode;var again:boolean): boolean;
-
-        { tries to avoid syntax errors after invalid qualifiers }
-        procedure recoverconsume_postfixops;
-          begin
-            repeat
-              if not try_to_consume(_CARET) then
-                if try_to_consume(_POINT) then
-                  try_to_consume(_ID)
-                else if try_to_consume(_LECKKLAMMER) then
-                  begin
-                    repeat
-                      comp_expr(true,false);
-                    until not try_to_consume(_COMMA);
-                    consume(_RECKKLAMMER);
-                  end
-                else if try_to_consume(_LKLAMMER) then
-                  begin
-                    repeat
-                      comp_expr(true,false);
-                    until not try_to_consume(_COMMA);
-                    consume(_RKLAMMER);
-                  end
-                else
-                  break;
-            until false;
-          end;
-
-
-        procedure handle_variantarray;
-          var
-            p4 : tnode;
-            newstatement : tstatementnode;
-            tempresultvariant,
-            temp    : ttempcreatenode;
-            paras : tcallparanode;
-            newblock : tnode;
-            countindices : aint;
-          begin
-            { create statements with call initialize the arguments and
-              call fpc_dynarr_setlength }
-            newblock:=internalstatements(newstatement);
-
-            { get temp for array of indicies,
-              we set the real size later }
-            temp:=ctempcreatenode.create(s32inttype,4,tt_persistent,false);
-            addstatement(newstatement,temp);
-
-            countindices:=0;
-            repeat
-              p4:=comp_expr(true,false);
-
-              addstatement(newstatement,cassignmentnode.create(
-                ctemprefnode.create_offset(temp,countindices*s32inttype.size),p4));
-               inc(countindices);
-            until not try_to_consume(_COMMA);
-
-            { set real size }
-            temp.size:=countindices*s32inttype.size;
-
-            consume(_RECKKLAMMER);
-
-            { we need only a write access if a := follows }
-            if token=_ASSIGNMENT then
-              begin
-                consume(_ASSIGNMENT);
-                p4:=comp_expr(true,false);
-
-                { create call to fpc_vararray_put }
-                paras:=ccallparanode.create(cordconstnode.create
-                      (countindices,s32inttype,true),
-                   ccallparanode.create(caddrnode.create_internal
-                  (ctemprefnode.create(temp)),
-                   ccallparanode.create(ctypeconvnode.create_internal(p4,cvarianttype),
-                   ccallparanode.create(ctypeconvnode.create_internal(p1,cvarianttype)
-                     ,nil))));
-
-                addstatement(newstatement,ccallnode.createintern('fpc_vararray_put',paras));
-                addstatement(newstatement,ctempdeletenode.create(temp));
-              end
-            else
-              begin
-                { create temp for result }
-                tempresultvariant:=ctempcreatenode.create(cvarianttype,cvarianttype.size,tt_persistent,true);
-                addstatement(newstatement,tempresultvariant);
-
-                { create call to fpc_vararray_get }
-                paras:=ccallparanode.create(cordconstnode.create
-                      (countindices,s32inttype,true),
-                   ccallparanode.create(caddrnode.create_internal
-                  (ctemprefnode.create(temp)),
-                   ccallparanode.create(p1,
-                   ccallparanode.create(
-                       ctemprefnode.create(tempresultvariant)
-                     ,nil))));
-
-                addstatement(newstatement,ccallnode.createintern('fpc_vararray_get',paras));
-                addstatement(newstatement,ctempdeletenode.create(temp));
-                { the last statement should return the value as
-                  location and type, this is done be referencing the
-                  temp and converting it first from a persistent temp to
-                  normal temp }
-                addstatement(newstatement,ctempdeletenode.create_normal_temp(tempresultvariant));
-                addstatement(newstatement,ctemprefnode.create(tempresultvariant));
-              end;
-            p1:=newblock;
-          end;
-
-        var
-          protsym  : tpropertysym;
-          p2,p3  : tnode;
-          srsym  : tsym;
-          srsymtable : TSymtable;
-          structh    : tabstractrecorddef;
-          { shouldn't be used that often, so the extra overhead is ok to save
-            stack space }
-          dispatchstring : ansistring;
-          nodechanged    : boolean;
-          calltype: tdispcalltype;
-        label
-          skipreckklammercheck;
-        begin
-          result:=false;
-          again:=true;
-          while again do
-           begin
-             { we need the resultdef }
-             do_typecheckpass_changed(p1,nodechanged);
-             result:=result or nodechanged;
-
-             if codegenerror then
-              begin
-                recoverconsume_postfixops;
-                exit;
-              end;
-             { handle token }
-             case token of
-               _CARET:
-                  begin
-                    consume(_CARET);
-
-                    { support tp/mac procvar^ if the procvar returns a
-                      pointer type }
-                    if ((m_tp_procvar in current_settings.modeswitches) or
-                        (m_mac_procvar in current_settings.modeswitches)) and
-                       (p1.resultdef.typ=procvardef) and
-                       (tprocvardef(p1.resultdef).returndef.typ=pointerdef) then
-                      begin
-                        p1:=ccallnode.create_procvar(nil,p1);
-                        typecheckpass(p1);
-                      end;
-
-                    if (p1.resultdef.typ<>pointerdef) then
-                      begin
-                         { ^ as binary operator is a problem!!!! (FK) }
-                         again:=false;
-                         Message(parser_e_invalid_qualifier);
-                         recoverconsume_postfixops;
-                         p1.destroy;
-                         p1:=cerrornode.create;
-                      end
-                    else
-                      p1:=cderefnode.create(p1);
-                  end;
-
-               _LECKKLAMMER:
-                  begin
-                    if is_class_or_interface_or_object(p1.resultdef) or
-                      is_dispinterface(p1.resultdef) or is_record(p1.resultdef) then
-                      begin
-                        { default property }
-                        protsym:=search_default_property(tabstractrecorddef(p1.resultdef));
-                        if not(assigned(protsym)) then
-                          begin
-                             p1.destroy;
-                             p1:=cerrornode.create;
-                             again:=false;
-                             message(parser_e_no_default_property_available);
-                          end
-                        else
-                          begin
-                            { The property symbol is referenced indirect }
-                            protsym.IncRefCount;
-                            handle_propertysym(protsym,protsym.owner,p1);
-                          end;
-                      end
-                    else
-                      begin
-                        consume(_LECKKLAMMER);
-                        repeat
-                          { in all of the cases below, p1 is changed }
-                          case p1.resultdef.typ of
-                            pointerdef:
-                              begin
-                                 { support delphi autoderef }
-                                 if (tpointerdef(p1.resultdef).pointeddef.typ=arraydef) and
-                                    (m_autoderef in current_settings.modeswitches) then
-                                   p1:=cderefnode.create(p1);
-                                 p2:=comp_expr(true,false);
-                                 { Support Pbytevar[0..9] which returns array [0..9].}
-                                 if try_to_consume(_POINTPOINT) then
-                                   p2:=crangenode.create(p2,comp_expr(true,false));
-                                 p1:=cvecnode.create(p1,p2);
-                              end;
-                            variantdef:
-                              begin
-                                handle_variantarray;
-                                { the RECKKLAMMER is already read }
-                                goto skipreckklammercheck;
-                              end;
-                            stringdef :
-                              begin
-                                p2:=comp_expr(true,false);
-                                { Support string[0..9] which returns array [0..9] of char.}
-                                if try_to_consume(_POINTPOINT) then
-                                  p2:=crangenode.create(p2,comp_expr(true,false));
-                                p1:=cvecnode.create(p1,p2);
-                              end;
-                            arraydef:
-                              begin
-                                p2:=comp_expr(true,false);
-                                { support SEG:OFS for go32v2 Mem[] }
-                                if (target_info.system in [system_i386_go32v2,system_i386_watcom]) and
-                                   (p1.nodetype=loadn) and
-                                   assigned(tloadnode(p1).symtableentry) and
-                                   assigned(tloadnode(p1).symtableentry.owner.name) and
-                                   (tloadnode(p1).symtableentry.owner.name^='SYSTEM') and
-                                   ((tloadnode(p1).symtableentry.name='MEM') or
-                                    (tloadnode(p1).symtableentry.name='MEMW') or
-                                    (tloadnode(p1).symtableentry.name='MEML')) then
-                                  begin
-                                    if try_to_consume(_COLON) then
-                                     begin
-                                       p3:=caddnode.create(muln,cordconstnode.create($10,s32inttype,false),p2);
-                                       p2:=comp_expr(true,false);
-                                       p2:=caddnode.create(addn,p2,p3);
-                                       if try_to_consume(_POINTPOINT) then
-                                         { Support mem[$a000:$0000..$07ff] which returns array [0..$7ff] of memtype.}
-                                         p2:=crangenode.create(p2,caddnode.create(addn,comp_expr(true,false),p3.getcopy));
-                                       p1:=cvecnode.create(p1,p2);
-                                       include(tvecnode(p1).flags,nf_memseg);
-                                       include(tvecnode(p1).flags,nf_memindex);
-                                     end
-                                    else
-                                     begin
-                                       if try_to_consume(_POINTPOINT) then
-                                         { Support mem[$80000000..$80000002] which returns array [0..2] of memtype.}
-                                         p2:=crangenode.create(p2,comp_expr(true,false));
-                                       p1:=cvecnode.create(p1,p2);
-                                       include(tvecnode(p1).flags,nf_memindex);
-                                     end;
-                                  end
-                                else
-                                  begin
-                                    if try_to_consume(_POINTPOINT) then
-                                      { Support arrayvar[0..9] which returns array [0..9] of arraytype.}
-                                      p2:=crangenode.create(p2,comp_expr(true,false));
-                                    p1:=cvecnode.create(p1,p2);
-                                  end;
-                              end;
-                            else
-                              begin
-                                if p1.resultdef.typ<>undefineddef then
-                                  Message(parser_e_invalid_qualifier);
-                                p1.destroy;
-                                p1:=cerrornode.create;
-                                comp_expr(true,false);
-                                again:=false;
-                              end;
-                          end;
-                          do_typecheckpass(p1);
-                        until not try_to_consume(_COMMA);
-                        consume(_RECKKLAMMER);
-                        { handle_variantarray eats the RECKKLAMMER and jumps here }
-                      skipreckklammercheck:
-                      end;
-                  end;
-
-               _POINT :
-                  begin
-                    consume(_POINT);
-                    if (p1.resultdef.typ=pointerdef) and
-                       (m_autoderef in current_settings.modeswitches) and
-                       { don't auto-deref objc.id, because then the code
-                         below for supporting id.anyobjcmethod isn't triggered }
-                       (p1.resultdef<>objc_idtype) then
-                      begin
-                        p1:=cderefnode.create(p1);
-                        do_typecheckpass(p1);
-                      end;
-                    { procvar.<something> can never mean anything so always
-                      try to call it in case it returns a record/object/... }
-                    maybe_call_procvar(p1,false);
-
-                    case p1.resultdef.typ of
-                      recorddef:
-                        begin
-                          if token=_ID then
-                            begin
-                              structh:=tabstractrecorddef(p1.resultdef);
-                              searchsym_in_record(structh,pattern,srsym,srsymtable);
-                              if assigned(srsym) then
-                                begin
-                                  check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
-                                  consume(_ID);
-                                  do_member_read(structh,getaddr,srsym,p1,again,[]);
-                                end
-                              else
-                                begin
-                                  Message1(sym_e_id_no_member,orgpattern);
-                                  p1.destroy;
-                                  p1:=cerrornode.create;
-                                  { try to clean up }
-                                  consume(_ID);
-                                end;
-                            end
-                          else
-                          consume(_ID);
-                        end;
-                      enumdef:
-                        begin
-                          if token=_ID then
-                            begin
-                              srsym:=tsym(tenumdef(p1.resultdef).symtable.Find(pattern));
-                              p1.destroy;
-                              if assigned(srsym) and (srsym.typ=enumsym) then
-                                begin
-                                  check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
-                                  p1:=genenumnode(tenumsym(srsym));
-                                end
-                              else
-                                begin
-                                  Message1(sym_e_id_no_member,orgpattern);
-                                  p1:=cerrornode.create;
-                                end;
-                            end;
-                          consume(_ID);
-                        end;
-                       variantdef:
-                         begin
-                           { dispatch call? }
-                           { lhs := v.ident[parameters] -> property get
-                             lhs := v.ident(parameters) -> method call
-                             v.ident[parameters] := rhs -> property put
-                             v.ident(parameters) := rhs -> also property put }
-                           if token=_ID then
-                             begin
-                               dispatchstring:=orgpattern;
-                               consume(_ID);
-                               calltype:=dct_method;
-                               if try_to_consume(_LKLAMMER) then
-                                 begin
-                                   p2:=parse_paras(false,true,_RKLAMMER);
-                                   consume(_RKLAMMER);
-                                 end
-                               else if try_to_consume(_LECKKLAMMER) then
-                                 begin
-                                   p2:=parse_paras(false,true,_RECKKLAMMER);
-                                   consume(_RECKKLAMMER);
-                                   calltype:=dct_propget;
-                                 end
-                               else
-                                 p2:=nil;
-                               { property setter? }
-                               if (token=_ASSIGNMENT) and not(afterassignment) then
-                                 begin
-                                   consume(_ASSIGNMENT);
-                                   { read the expression }
-                                   p3:=comp_expr(true,false);
-                                   { concat value parameter too }
-                                   p2:=ccallparanode.create(p3,p2);
-                                   p1:=translate_disp_call(p1,p2,dct_propput,dispatchstring,0,voidtype);
-                                 end
-                               else
-                               { this is only an approximation
-                                 setting useresult if not necessary is only a waste of time, no more, no less (FK) }
-                               if afterassignment or in_args or (token<>_SEMICOLON) then
-                                 p1:=translate_disp_call(p1,p2,calltype,dispatchstring,0,cvarianttype)
-                               else
-                                 p1:=translate_disp_call(p1,p2,calltype,dispatchstring,0,voidtype);
-                             end
-                           else { Error }
-                             Consume(_ID);
-                          end;
-                       classrefdef:
-                         begin
-                           if token=_ID then
-                             begin
-                               structh:=tobjectdef(tclassrefdef(p1.resultdef).pointeddef);
-                               searchsym_in_class(tobjectdef(structh),tobjectdef(structh),pattern,srsym,srsymtable,true);
-                               if assigned(srsym) then
-                                 begin
-                                   check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
-                                   consume(_ID);
-                                   do_member_read(structh,getaddr,srsym,p1,again,[]);
-                                 end
-                               else
-                                 begin
-                                   Message1(sym_e_id_no_member,orgpattern);
-                                   p1.destroy;
-                                   p1:=cerrornode.create;
-                                   { try to clean up }
-                                   consume(_ID);
-                                 end;
-                             end
-                           else { Error }
-                             Consume(_ID);
-                         end;
-                       objectdef:
-                         begin
-                           if token=_ID then
-                             begin
-                               structh:=tobjectdef(p1.resultdef);
-                               searchsym_in_class(tobjectdef(structh),tobjectdef(structh),pattern,srsym,srsymtable,true);
-                               if assigned(srsym) then
-                                 begin
-                                    check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
-                                    consume(_ID);
-                                    do_member_read(structh,getaddr,srsym,p1,again,[]);
-                                 end
-                               else
-                                 begin
-                                    Message1(sym_e_id_no_member,orgpattern);
-                                    p1.destroy;
-                                    p1:=cerrornode.create;
-                                    { try to clean up }
-                                    consume(_ID);
-                                 end;
-                             end
-                           else { Error }
-                             Consume(_ID);
-                         end;
-                       pointerdef:
-                         begin
-                           if (p1.resultdef=objc_idtype) then
-                             begin
-                               { objc's id type can be used to call any
-                                 Objective-C method of any Objective-C class
-                                 type that's currently in scope }
-                               if search_objc_method(pattern,srsym,srsymtable) then
-                                 begin
-                                   consume(_ID);
-                                   do_proc_call(srsym,srsymtable,nil,
-                                     (getaddr and not(token in [_CARET,_POINT])),
-                                     again,p1,[cnf_objc_id_call]);
-                                   { we need to know which procedure is called }
-                                   do_typecheckpass(p1);
-                                 end
-                               else
-                                 begin
-                                   consume(_ID);
-                                   Message(parser_e_methode_id_expected);
-                                 end;
-                             end
-                           else
-                             begin
-                               Message(parser_e_invalid_qualifier);
-                               if tpointerdef(p1.resultdef).pointeddef.typ in [recorddef,objectdef,classrefdef] then
-                                 Message(parser_h_maybe_deref_caret_missing);
-                             end
-                         end;
-                       else
-                         begin
-                           if p1.resultdef.typ<>undefineddef then
-                             Message(parser_e_invalid_qualifier);
-                           p1.destroy;
-                           p1:=cerrornode.create;
-                           { Error }
-                           consume(_ID);
-                         end;
-                    end;
-                  end;
-
-               else
-                 begin
-                   { is this a procedure variable ? }
-                   if assigned(p1.resultdef) and
-                      (p1.resultdef.typ=procvardef) then
-                     begin
-                       { Typenode for typecasting or expecting a procvar }
-                       if (p1.nodetype=typen) or
-                          (
-                           assigned(getprocvardef) and
-                           equal_defs(p1.resultdef,getprocvardef)
-                          ) then
-                         begin
-                           if try_to_consume(_LKLAMMER) then
-                             begin
-                               p1:=comp_expr(true,false);
-                               consume(_RKLAMMER);
-                               p1:=ctypeconvnode.create_explicit(p1,p1.resultdef);
-                             end
-                           else
-                             again:=false
-                         end
-                       else
-                         begin
-                           if try_to_consume(_LKLAMMER) then
-                             begin
-                               p2:=parse_paras(false,false,_RKLAMMER);
-                               consume(_RKLAMMER);
-                               p1:=ccallnode.create_procvar(p2,p1);
-                               { proc():= is never possible }
-                               if token=_ASSIGNMENT then
-                                 begin
-                                   Message(parser_e_illegal_expression);
-                                   p1.free;
-                                   p1:=cerrornode.create;
-                                   again:=false;
-                                 end;
-                             end
-                           else
-                             again:=false;
-                         end;
-                     end
-                   else
-                     again:=false;
-                  end;
-             end;
-
-             { we only try again if p1 was changed }
-             if again or
-                (p1.nodetype=errorn) then
-               result:=true;
-           end; { while again }
-        end;
-
-
       {---------------------------------------------
                       Factor (Main)
       ---------------------------------------------}