فهرست منبع

+ typecasting support for variables, but be carefull as word,byte can't
be used because they are reserved assembler keywords

peter 25 سال پیش
والد
کامیت
8900400a2c
3فایلهای تغییر یافته به همراه185 افزوده شده و 68 حذف شده
  1. 92 40
      compiler/ra386att.pas
  2. 76 27
      compiler/ra386int.pas
  3. 17 1
      compiler/rautils.pas

+ 92 - 40
compiler/ra386att.pas

@@ -345,7 +345,7 @@ begin
               {               - field of object/record                         }
               {               - directive.                                     }
          begin
-           if (prevasmtoken=AS_ID) then
+           if (prevasmtoken in [AS_ID,AS_RPAREN]) then
             begin
               c:=current_scanner^.asmgetchar;
               actasmtoken:=AS_DOT;
@@ -1201,7 +1201,9 @@ end;
 
 Procedure T386ATTOperand.BuildOperand;
 var
+  tempstr,tempstr2,
   expr : string;
+  l,k : longint;
 
   procedure AddLabelOperand(hl:pasmlabel);
   begin
@@ -1242,7 +1244,7 @@ var
      inc(l,BuildConstExpression(true,false));
     if opr.typ=OPR_REFERENCE then
      begin
-       if hasdot and (opr.ref.options=ref_parafixup) then
+       if hasdot and (not hastype) and (opr.ref.options=ref_parafixup) then
         Message(asmr_e_cannot_access_field_directly_for_parameters);
        inc(opr.ref.offset,l)
      end
@@ -1270,9 +1272,29 @@ var
         BuildReference;
       AS_ID: { only a variable is allowed ... }
         Begin
-          if not SetupVar(actasmpattern,false) then
-            Message(asmr_e_invalid_reference_syntax);
+          tempstr:=actasmpattern;
           Consume(AS_ID);
+          { typecasting? }
+          if (actasmtoken=AS_LPAREN) and
+             SearchType(tempstr) then
+           begin
+             hastype:=true;
+             Consume(AS_LPAREN);
+             tempstr2:=actasmpattern;
+             Consume(AS_ID);
+             Consume(AS_RPAREN);
+             if not SetupVar(tempstr2,false) then
+              Message1(sym_e_unknown_id,tempstr2);
+           end
+          else
+           if not SetupVar(tempstr,false) then
+            Message1(sym_e_unknown_id,tempstr);
+          { record.field ? }
+          if actasmtoken=AS_DOT then
+           begin
+             BuildRecordOffsetSize(tempstr,l,k);
+             inc(opr.ref.offset,l);
+           end;
           case actasmtoken of
             AS_END,
             AS_SEPARATOR,
@@ -1293,7 +1315,6 @@ var
 var
   tempreg : tregister;
   hl      : PAsmLabel;
-  l       : longint;
 Begin
   expr:='';
   case actasmtoken of
@@ -1374,47 +1395,74 @@ Begin
            else
             begin
               InitRef;
-              if SetupVar(actasmpattern,false) then
+              expr:=actasmpattern;
+              Consume(AS_ID);
+              { typecasting? }
+              if (actasmtoken=AS_LPAREN) and
+                 SearchType(expr) then
                begin
-                 expr:=actasmpattern;
+                 hastype:=true;
+                 Consume(AS_LPAREN);
+                 tempstr:=actasmpattern;
                  Consume(AS_ID);
-                 MaybeRecordOffset;
-                 { add a constant expression? }
-                 if (actasmtoken=AS_PLUS) then
+                 Consume(AS_RPAREN);
+                 if SetupVar(tempstr,false) then
                   begin
-                    l:=BuildConstExpression(true,false);
-                    if opr.typ=OPR_CONSTANT then
-                     inc(opr.val,l)
-                    else
-                     inc(opr.ref.offset,l);
+                    MaybeRecordOffset;
+                    { add a constant expression? }
+                    if (actasmtoken=AS_PLUS) then
+                     begin
+                       l:=BuildConstExpression(true,false);
+                       if opr.typ=OPR_CONSTANT then
+                        inc(opr.val,l)
+                       else
+                        inc(opr.ref.offset,l);
+                     end
                   end
+                 else
+                  Message1(sym_e_unknown_id,tempstr);
                end
               else
-               Begin
-                 { look for special symbols ... }
-                 if actasmpattern = '__RESULT' then
-                   SetUpResult
-                 else
-                  if actasmpattern = '__SELF' then
-                   SetupSelf
-                 else
-                  if actasmpattern = '__OLDEBP' then
-                   SetupOldEBP
-                 else
-                   { check for direct symbolic names   }
-                   { only if compiling the system unit }
-                   if (cs_compilesystem in aktmoduleswitches) then
-                    begin
-                      if not SetupDirectVar(actasmpattern) then
-                       Begin
-                         { not found, finally ... add it anyways ... }
-                         Message1(asmr_w_id_supposed_external,actasmpattern);
-                         opr.ref.symbol:=newasmsymbol(actasmpattern);
-                       end;
-                    end
+               begin
+                 if SetupVar(expr,false) then
+                  begin
+                    MaybeRecordOffset;
+                    { add a constant expression? }
+                    if (actasmtoken=AS_PLUS) then
+                     begin
+                       l:=BuildConstExpression(true,false);
+                       if opr.typ=OPR_CONSTANT then
+                        inc(opr.val,l)
+                       else
+                        inc(opr.ref.offset,l);
+                     end
+                  end
                  else
-                   Message1(sym_e_unknown_id,actasmpattern);
-                 Consume(AS_ID);
+                  Begin
+                    { look for special symbols ... }
+                    if expr = '__RESULT' then
+                      SetUpResult
+                    else
+                     if expr = '__SELF' then
+                      SetupSelf
+                    else
+                     if expr = '__OLDEBP' then
+                      SetupOldEBP
+                    else
+                      { check for direct symbolic names   }
+                      { only if compiling the system unit }
+                      if (cs_compilesystem in aktmoduleswitches) then
+                       begin
+                         if not SetupDirectVar(expr) then
+                          Begin
+                            { not found, finally ... add it anyways ... }
+                            Message1(asmr_w_id_supposed_external,expr);
+                            opr.ref.symbol:=newasmsymbol(expr);
+                          end;
+                       end
+                    else
+                      Message1(sym_e_unknown_id,expr);
+                  end;
                end;
             end;
          end;
@@ -2000,7 +2048,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.79  2000-05-18 17:05:16  peter
+  Revision 1.80  2000-05-23 20:36:28  peter
+    + typecasting support for variables, but be carefull as word,byte can't
+      be used because they are reserved assembler keywords
+
+  Revision 1.79  2000/05/18 17:05:16  peter
     * fixed size of const parameters in asm readers
 
   Revision 1.78  2000/05/12 21:57:02  pierre

+ 76 - 27
compiler/ra386int.pas

@@ -980,6 +980,7 @@ type
 Procedure T386IntelOperand.BuildReference;
 var
   k,l : longint;
+  tempstr2,
   tempstr,hs : string;
   code : integer;
   hreg,
@@ -1033,9 +1034,22 @@ Begin
              oldbase:=opr.ref.base;
              opr.ref.base:=R_NO;
              tempstr:=actasmpattern;
-             if not SetupVar(tempstr,GotOffset) then
-               Message1(sym_e_unknown_id,tempstr);
              Consume(AS_ID);
+             { typecasting? }
+             if (actasmtoken=AS_LPAREN) and
+                SearchType(tempstr) then
+              begin
+                hastype:=true;
+                Consume(AS_LPAREN);
+                tempstr2:=actasmpattern;
+                Consume(AS_ID);
+                Consume(AS_RPAREN);
+                if not SetupVar(tempstr2,GotOffset) then
+                 Message1(sym_e_unknown_id,tempstr2);
+              end
+             else
+              if not SetupVar(tempstr,GotOffset) then
+               Message1(sym_e_unknown_id,tempstr);
              { record.field ? }
              if actasmtoken=AS_DOT then
               begin
@@ -1228,6 +1242,7 @@ end;
 
 Procedure T386IntelOperand.BuildOperand;
 var
+  tempstr,
   expr    : string;
   tempreg : tregister;
   l       : longint;
@@ -1286,16 +1301,19 @@ var
      end;
     if actasmtoken in [AS_PLUS,AS_MINUS] then
      inc(l,BuildConstExpression);
-    if opr.typ=OPR_REFERENCE then
+    if (opr.typ=OPR_REFERENCE) then
      begin
        { don't allow direct access to fields of parameters, becuase that
-         will generate buggy code }
-       case opr.ref.options of
-         ref_parafixup :
-           Message(asmr_e_cannot_access_field_directly_for_parameters);
-         ref_selffixup :
-           Message(asmr_e_cannot_access_object_field_directly);
-       end;
+         will generate buggy code. Allow it only for explicit typecasting }
+       if (not hastype) then
+        begin
+          case opr.ref.options of
+            ref_parafixup :
+              Message(asmr_e_cannot_access_field_directly_for_parameters);
+            ref_selffixup :
+              Message(asmr_e_cannot_access_object_field_directly);
+          end;
+        end;
        inc(opr.ref.offset,l)
      end
     else
@@ -1379,29 +1397,56 @@ Begin
             { is it a normal variable ? }
              Begin
                InitRef;
-               if SetupVar(actasmpattern,false) then
+               expr:=actasmpattern;
+               Consume(AS_ID);
+               { typecasting? }
+               if (actasmtoken=AS_LPAREN) and
+                  SearchType(expr) then
                 begin
-                  expr:=actasmpattern;
+                  hastype:=true;
+                  Consume(AS_LPAREN);
+                  tempstr:=actasmpattern;
                   Consume(AS_ID);
-                  MaybeRecordOffset;
-                  { add a constant expression? }
-                  if (actasmtoken=AS_PLUS) then
+                  Consume(AS_RPAREN);
+                  if SetupVar(tempstr,false) then
                    begin
-                     l:=BuildConstExpression;
-                     if opr.typ=OPR_CONSTANT then
-                      inc(opr.val,l)
-                     else
-                      inc(opr.ref.offset,l);
+                     MaybeRecordOffset;
+                     { add a constant expression? }
+                     if (actasmtoken=AS_PLUS) then
+                      begin
+                        l:=BuildConstExpression;
+                        if opr.typ=OPR_CONSTANT then
+                         inc(opr.val,l)
+                        else
+                         inc(opr.ref.offset,l);
+                      end
                    end
+                  else
+                   Message1(sym_e_unknown_id,tempstr);
                 end
                else
-                Begin
-                  { not a variable, check special variables.. }
-                  if actasmpattern = 'SELF' then
-                   SetupSelf
+                begin
+                  if SetupVar(expr,false) then
+                   begin
+                     MaybeRecordOffset;
+                     { add a constant expression? }
+                     if (actasmtoken=AS_PLUS) then
+                      begin
+                        l:=BuildConstExpression;
+                        if opr.typ=OPR_CONSTANT then
+                         inc(opr.val,l)
+                        else
+                         inc(opr.ref.offset,l);
+                      end
+                   end
                   else
-                   Message1(sym_e_unknown_id,actasmpattern);
-                  Consume(AS_ID);
+                   Begin
+                     { not a variable, check special variables.. }
+                     if expr = 'SELF' then
+                      SetupSelf
+                     else
+                      Message1(sym_e_unknown_id,expr);
+                   end;
                 end;
              end;
            { handle references }
@@ -1833,7 +1878,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.70  2000-05-18 17:05:16  peter
+  Revision 1.71  2000-05-23 20:36:28  peter
+    + typecasting support for variables, but be carefull as word,byte can't
+      be used because they are reserved assembler keywords
+
+  Revision 1.70  2000/05/18 17:05:16  peter
     * fixed size of const parameters in asm readers
 
   Revision 1.69  2000/05/12 21:57:02  pierre

+ 17 - 1
compiler/rautils.pas

@@ -88,6 +88,7 @@ type
   POperand = ^TOperand;
   TOperand = object
     size   : topsize;
+    hastype,          { if the operand has typecasted variable }
     hasvar : boolean; { if the operand is loaded with a variable }
     opr    : TOprRec;
     constructor init;
@@ -184,6 +185,7 @@ Function EscapeToPascal(const s:string): string;
 ---------------------------------------------------------------------}
 
 Function GetRecordOffsetSize(s:string;Var Offset: longint;var Size:longint):boolean;
+Function SearchType(const hs:string): Boolean;
 Function SearchRecordType(const s:string): boolean;
 Function SearchIConstant(const s:string; var l:longint): boolean;
 
@@ -649,6 +651,7 @@ end;
 constructor TOperand.init;
 begin
   size:=S_NO;
+  hastype:=false;
   hasvar:=false;
   FillChar(Opr,sizeof(Opr),0);
 end;
@@ -1147,6 +1150,15 @@ end;
                       Symbol table helper routines
 ****************************************************************************}
 
+Function SearchType(const hs:string): Boolean;
+begin
+  getsym(hs,false);
+  SearchType:=assigned(srsym) and
+             (srsym^.typ=typesym);
+end;
+
+
+
 Function SearchRecordType(const s:string): boolean;
 Begin
   SearchRecordType:=false;
@@ -1516,7 +1528,11 @@ end;
 end.
 {
   $Log$
-  Revision 1.44  2000-05-22 12:47:52  pierre
+  Revision 1.45  2000-05-23 20:36:28  peter
+    + typecasting support for variables, but be carefull as word,byte can't
+      be used because they are reserved assembler keywords
+
+  Revision 1.44  2000/05/22 12:47:52  pierre
    fix wrong handling of var para for size bug 961
 
   Revision 1.43  2000/05/18 17:05:16  peter