Browse Source

* more reference types support
* arraydef size returns elementsize, also for multiple indexing array

peter 26 years ago
parent
commit
ab8edb8970
2 changed files with 132 additions and 67 deletions
  1. 64 29
      compiler/ra386int.pas
  2. 68 38
      compiler/rautils.pas

+ 64 - 29
compiler/ra386int.pas

@@ -960,7 +960,8 @@ Begin
            Message(asmr_e_local_symbol_not_allowed_as_ref);
           GotStar:=false;
           GotPlus:=false;
-          if SearchIConstant(actasmpattern,l) then
+          if SearchIConstant(actasmpattern,l) or
+             SearchRecordType(actasmpattern) then
            begin
              l:=BuildRefConstExpression;
              GotPlus:=(prevasmtoken=AS_PLUS);
@@ -1138,6 +1139,12 @@ end;
 
 
 Procedure T386IntelOperand.BuildOperand;
+var
+  expr,
+  tempstr : string;
+  tempreg : tregister;
+  l       : longint;
+  hl      : PAsmLabel;
 
   procedure AddLabelOperand(hl:pasmlabel);
   begin
@@ -1153,14 +1160,49 @@ Procedure T386IntelOperand.BuildOperand;
      end;
   end;
 
-var
-  expr,
-  tempstr : string;
-  tempreg : tregister;
-  l,
-  toffset,
-  tsize   : longint;
-  hl      : PAsmLabel;
+  procedure MaybeRecordOffset;
+  var
+    l,
+    toffset,
+    tsize   : longint;
+  begin
+    l:=0;
+    if actasmtoken=AS_DOT then
+     begin
+       { if no type was specified before the [] then we expect the
+         first ID to be the type }
+       if expr='' then
+         begin
+           consume(AS_DOT);
+           if actasmtoken=AS_ID then
+            begin
+              expr:=actasmpattern;
+              consume(AS_ID);
+              { now the next one must the be the dot }
+              if actasmtoken<>AS_DOT then
+               begin
+                 Message(asmr_e_building_record_offset);
+                 expr:='';
+               end;
+            end
+           else
+            Message(asmr_e_no_var_type_specified)
+         end;
+       if expr<>'' then
+         begin
+           BuildRecordOffsetSize(expr,toffset,tsize);
+           inc(l,toffset);
+           SetSize(tsize);
+         end;
+     end;
+    if actasmtoken in [AS_PLUS,AS_MINUS] then
+     inc(l,BuildConstExpression);
+    if opr.typ=OPR_REFERENCE then
+     inc(opr.ref.offset,l)
+    else
+     inc(opr.val,l);
+  end;
+
 Begin
   tempstr:='';
   expr:='';
@@ -1246,32 +1288,19 @@ Begin
                   else
                    Message1(sym_e_unknown_id,actasmpattern);
                 end;
-               l:=0;
                expr:=actasmpattern;
                Consume(AS_ID);
+               MaybeRecordOffset;
                if actasmtoken=AS_LBRACKET then
                 begin
-                  opr.typ:=OPR_REFERENCE;
-                  reset_reference(opr.Ref);
-                  BuildReference;
-                end;
-               if actasmtoken=AS_DOT then
-                begin
-                  if expr='' then
-                   Message(asmr_e_no_var_type_specified)
-                  else
+                  if opr.typ<>OPR_REFERENCE then
                    begin
-                     BuildRecordOffsetSize(expr,toffset,tsize);
-                     inc(l,toffset);
-                     SetSize(tsize);
+                     opr.typ:=OPR_REFERENCE;
+                     reset_reference(opr.Ref);
                    end;
+                  BuildReference;
                 end;
-               if actasmtoken in [AS_PLUS,AS_MINUS] then
-                inc(l,BuildConstExpression);
-               if opr.typ=OPR_REFERENCE then
-                inc(opr.ref.offset,l)
-               else
-                inc(opr.val,l);
+               MaybeRecordOffset;
              end;
          end;
       end;
@@ -1301,7 +1330,9 @@ Begin
 
     AS_LBRACKET: { a variable reference, register ref. or a constant reference }
       Begin
+        InitRef;
         BuildReference;
+        MaybeRecordOffset;
       end;
 
     AS_SEG :
@@ -1669,7 +1700,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.42  1999-08-04 00:23:27  florian
+  Revision 1.43  1999-08-13 21:28:36  peter
+    * more reference types support
+    * arraydef size returns elementsize, also for multiple indexing array
+
+  Revision 1.42  1999/08/04 00:23:27  florian
     * renamed i386asm and i386base to cpuasm and cpubase
 
   Revision 1.41  1999/07/24 11:17:16  peter

+ 68 - 38
compiler/rautils.pas

@@ -178,6 +178,7 @@ Function EscapeToPascal(const s:string): string;
 ---------------------------------------------------------------------}
 
 Function GetRecordOffsetSize(s:string;Var Offset: longint;var Size:longint):boolean;
+Function SearchRecordType(const s:string): boolean;
 Function SearchIConstant(const s:string; var l:longint): boolean;
 
 
@@ -654,7 +655,7 @@ end;
 
 Procedure TOperand.SetSize(_size:longint);
 begin
-  if (size = S_NO) then
+  if (size = S_NO) and (_size<extended_size) then
    Begin
      case _size of
       1 : size:=S_B;
@@ -720,6 +721,7 @@ Function TOperand.SetupVar(const hs:string): Boolean;
 { if not found returns FALSE.                               }
 var
   sym : psym;
+  harrdef : parraydef;
 Begin
   SetupVar:=false;
 { are we in a routine ? }
@@ -766,7 +768,15 @@ Begin
           floatdef :
             SetSize(pvarsym(sym)^.getsize);
           arraydef :
-            SetSize(parraydef(pvarsym(sym)^.definition)^.elesize)
+            begin
+              { for arrays try to get the element size, take care of
+                multiple indexes }
+              harrdef:=Parraydef(PVarsym(sym)^.definition);
+              while assigned(harrdef^.definition) and
+                    (harrdef^.definition^.deftype=arraydef) do
+               harrdef:=parraydef(harrdef^.definition);
+              SetSize(harrdef^.elesize);
+            end;
         end;
         hasvar:=true;
         SetupVar:=true;
@@ -782,7 +792,15 @@ Begin
           floatdef :
             SetSize(ptypedconstsym(sym)^.getsize);
           arraydef :
-            SetSize(parraydef(ptypedconstsym(sym)^.definition)^.elesize)
+            begin
+              { for arrays try to get the element size, take care of
+                multiple indexes }
+              harrdef:=Parraydef(PVarsym(sym)^.definition);
+              while assigned(harrdef^.definition) and
+                    (harrdef^.definition^.deftype=arraydef) do
+               harrdef:=parraydef(harrdef^.definition);
+              SetSize(harrdef^.elesize);
+            end;
         end;
         hasvar:=true;
         SetupVar:=true;
@@ -1038,6 +1056,27 @@ end;
                       Symbol table helper routines
 ****************************************************************************}
 
+Function SearchRecordType(const s:string): boolean;
+Begin
+  SearchRecordType:=false;
+{ Check the constants in symtable }
+  getsym(s,false);
+  if srsym <> nil then
+   Begin
+     case srsym^.typ of
+       typesym :
+         begin
+           if ptypesym(srsym)^.definition^.deftype in [recorddef,objectdef] then
+            begin
+              SearchRecordType:=true;
+              exit;
+            end;
+         end;
+     end;
+   end;
+end;
+
+
 Function SearchIConstant(const s:string; var l:longint): boolean;
 {**********************************************************************}
 {  Description: Searches for a CONSTANT of name s in either the local  }
@@ -1047,46 +1086,22 @@ Function SearchIConstant(const s:string; var l:longint): boolean;
 { Remarks: Also handle TRUE and FALSE returning in those cases 1 and 0 }
 {  respectively.                                                       }
 {**********************************************************************}
-var
-  sym: psym;
 Begin
   SearchIConstant:=false;
-  { check for TRUE or FALSE reserved words first }
+{ check for TRUE or FALSE reserved words first }
   if s = 'TRUE' then
    Begin
      SearchIConstant:=TRUE;
      l:=1;
-   end
-  else
-   if s = 'FALSE' then
-    Begin
-      SearchIConstant:=TRUE;
-      l:=0;
-    end
-  else
-   if assigned(aktprocsym) then
-    Begin
-      if assigned(aktprocsym^.definition) then
-       Begin
-       { Check the local constants }
-         if assigned(aktprocsym^.definition^.localst) and
-            (lexlevel >= normal_function_level) then
-          sym:=aktprocsym^.definition^.localst^.search(s)
-         else
-          sym:=nil;
-         if assigned(sym) then
-          Begin
-            if (sym^.typ = constsym) and
-               (pconstsym(sym)^.consttype in [constord,constint,constchar,constbool]) then
-             Begin
-               l:=pconstsym(sym)^.value;
-               SearchIConstant:=TRUE;
-               exit;
-             end;
-          end;
-       end;
-    end;
-  { Check the global constants }
+     exit;
+   end;
+  if s = 'FALSE' then
+   Begin
+     SearchIConstant:=TRUE;
+     l:=0;
+     exit;
+   end;
+{ Check the constants in symtable }
   getsym(s,false);
   if srsym <> nil then
    Begin
@@ -1112,6 +1127,7 @@ Function GetRecordOffsetSize(s:string;Var Offset: longint;var Size:longint):bool
 { used when base is a variable or a typed constant name.       }
 var
   st   : psymtable;
+  harrdef : parraydef;
   sym  : psym;
   i    : longint;
   base : string;
@@ -1174,6 +1190,16 @@ Begin
            inc(Offset,pvarsym(sym)^.address);
            Size:=PVarsym(sym)^.getsize;
            case pvarsym(sym)^.definition^.deftype of
+             arraydef :
+               begin
+                 { for arrays try to get the element size, take care of
+                   multiple indexes }
+                 harrdef:=Parraydef(PVarsym(sym)^.definition);
+                 while assigned(harrdef^.definition) and
+                       (harrdef^.definition^.deftype=arraydef) do
+                  harrdef:=parraydef(harrdef^.definition);
+                 size:=harrdef^.elesize;
+               end;
              recorddef :
                st:=precorddef(pvarsym(sym)^.definition)^.symtable;
              objectdef :
@@ -1378,7 +1404,11 @@ end;
 end.
 {
   $Log$
-  Revision 1.22  1999-08-04 00:23:28  florian
+  Revision 1.23  1999-08-13 21:28:38  peter
+    * more reference types support
+    * arraydef size returns elementsize, also for multiple indexing array
+
+  Revision 1.22  1999/08/04 00:23:28  florian
     * renamed i386asm and i386base to cpuasm and cpubase
 
   Revision 1.21  1999/08/03 22:03:12  peter