Browse Source

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

peter 25 years ago
parent
commit
8900400a2c
3 changed files with 185 additions and 68 deletions
  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