From ab8edb8970d9236d84a48d079f3f2f2deed819ab Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 13 Aug 1999 21:28:36 +0000 Subject: [PATCH] * more reference types support * arraydef size returns elementsize, also for multiple indexing array --- compiler/ra386int.pas | 95 +++++++++++++++++++++++++------------ compiler/rautils.pas | 106 +++++++++++++++++++++++++++--------------- 2 files changed, 133 insertions(+), 68 deletions(-) diff --git a/compiler/ra386int.pas b/compiler/ra386int.pas index 96805c5a07..1abb7dbd4f 100644 --- a/compiler/ra386int.pas +++ b/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); + if opr.typ<>OPR_REFERENCE then + begin + opr.typ:=OPR_REFERENCE; + reset_reference(opr.Ref); + end; BuildReference; end; - if actasmtoken=AS_DOT then - begin - if expr='' then - Message(asmr_e_no_var_type_specified) - else - 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); + 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 diff --git a/compiler/rautils.pas b/compiler/rautils.pas index 37c0be20df..9640b230a6 100644 --- a/compiler/rautils.pas +++ b/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 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