* redesigned record offset parsing to support nested records

* normal compiler uses the redesigned createvarinstr()
This commit is contained in:
peter 1999-04-26 23:26:12 +00:00
parent 495ec05485
commit 9bbbfdecf9
3 changed files with 251 additions and 553 deletions

View File

@ -2453,6 +2453,15 @@ var
end;
procedure RecoverConsume(allowcomma:boolean);
begin
While not (actasmtoken in [AS_SEPARATOR,AS_END]) do
begin
if allowcomma and (actasmtoken=AS_COMMA) then
break;
Consume(actasmtoken);
end;
end;
@ -2639,49 +2648,33 @@ var
Procedure GetRecordOffsetSize(const expr: string;var offset:longint;var size:longint);
{*********************************************************************}
{ PROCEDURE GetRecordOffsetSize }
Procedure BuildRecordOffsetSize(const expr: string;var offset:longint;var size:longint);
{ Description: This routine builds up a record offset after a AS_DOT }
{ token is encountered. }
{ On entry actasmtoken should be equal to AS_DOT }
{*********************************************************************}
{ EXIT CONDITION: On exit the routine should point to either the }
{ ERROR RECOVER: read until AS_COMMA or AS_SEPARATOR token. }
{ Warning: This is called recursively. }
{*********************************************************************}
var
toffset,tsize : longint;
s : string;
Begin
offset:=0;
size:=0;
Consume(AS_DOT);
if actasmtoken = AS_ID then
Begin
if not GetTypeOffsetSize(expr,actasmpattern,toffset,tsize) and
not GetVarOffsetSize(expr,actasmpattern,toffset,tsize) then
s:=expr;
while (actasmtoken=AS_DOT) do
begin
Consume(AS_DOT);
if actasmtoken=AS_ID then
begin
s:=s+'.'+actasmpattern;
Consume(AS_ID);
end
else
begin
Message(assem_e_syntax_error);
toffset:=0;
tsize:=0;
RecoverConsume(true);
break;
end;
inc(offset,toffset);
size:=tsize;
Consume(AS_ID);
if actasmtoken=AS_DOT then
begin
GetRecordOffsetSize(expr,toffset,tsize);
inc(offset,toffset);
size:=tsize;
end;
end
else
Begin
Message(assem_e_syntax_error);
repeat
consume(actasmtoken)
until (actasmtoken = AS_SEPARATOR) or (actasmtoken = AS_COMMA);
end;
if not GetRecordOffsetSize(s,offset,size) then
Message(assem_e_syntax_error);
end;
@ -2815,7 +2808,7 @@ Begin
consume(AS_ID);
if actasmtoken=AS_DOT then
begin
GetRecordOffsetSize(tempstr,l,k);
BuildRecordOffsetSize(tempstr,l,k);
str(l, tempstr);
expr := expr + tempstr;
end
@ -3350,7 +3343,7 @@ Begin
Consume(AS_ID);
if actasmtoken=AS_DOT then
begin
GetRecordOffsetSize(expr,toffset,tsize);
BuildRecordOffsetSize(expr,toffset,tsize);
inc(instr.operands[operandnum].ref.offset,toffset);
SetOperandSize(instr,operandnum,tsize);
end;
@ -3967,7 +3960,11 @@ end.
{
$Log$
Revision 1.38 1999-04-21 21:42:22 pierre
Revision 1.39 1999-04-26 23:26:12 peter
* redesigned record offset parsing to support nested records
* normal compiler uses the redesigned createvarinstr()
Revision 1.38 1999/04/21 21:42:22 pierre
* wrong log for v1.37 corrected
Revision 1.37 1999/04/21 16:31:41 pierre

View File

@ -1893,8 +1893,15 @@ var
actasmtoken := gettoken;
end;
procedure RecoverConsume(allowcomma:boolean);
begin
While not (actasmtoken in [AS_SEPARATOR,AS_END]) do
begin
if allowcomma and (actasmtoken=AS_COMMA) then
break;
Consume(actasmtoken);
end;
end;
function findregister(const s : string): tregister;
@ -2077,50 +2084,33 @@ var
End;
Procedure GetRecordOffsetSize(const expr: string;var offset:longint;var size:longint);
{*********************************************************************}
{ PROCEDURE GetRecordOffsetSize }
{ Description: This routine builds up a record offset after a AS_DOT }
{ token is encountered. }
{ On entry actasmtoken should be equal to AS_DOT }
{*********************************************************************}
{ EXIT CONDITION: On exit the routine should point to either the }
{ ERROR RECOVER: read until AS_COMMA or AS_SEPARATOR token. }
{ Warning: This is called recursively. }
{*********************************************************************}
Procedure BuildRecordOffsetSize(const expr: string;var offset:longint;var size:longint);
{ Description: This routine builds up a record offset after a AS_DOT }
{ token is encountered. }
{ On entry actasmtoken should be equal to AS_DOT }
var
toffset,tsize : longint;
s : string;
Begin
offset:=0;
size:=0;
Consume(AS_DOT);
if actasmtoken = AS_ID then
Begin
if not GetTypeOffsetSize(expr,actasmpattern,toffset,tsize) and
not GetVarOffsetSize(expr,actasmpattern,toffset,tsize) then
s:=expr;
while (actasmtoken=AS_DOT) do
begin
Consume(AS_DOT);
if actasmtoken=AS_ID then
begin
s:=s+'.'+actasmpattern;
Consume(AS_ID);
end
else
begin
Message(assem_e_syntax_error);
toffset:=0;
tsize:=0;
RecoverConsume(true);
break;
end;
inc(offset,toffset);
size:=tsize;
Consume(AS_ID);
if actasmtoken=AS_DOT then
begin
GetRecordOffsetSize(expr,toffset,tsize);
inc(offset,toffset);
size:=tsize;
end;
end
else
Begin
Message(assem_e_syntax_error);
repeat
consume(actasmtoken)
until (actasmtoken = AS_SEPARATOR) or (actasmtoken = AS_COMMA);
end;
if not GetRecordOffsetSize(s,offset,size) then
Message(assem_e_syntax_error);
end;
@ -2243,7 +2233,7 @@ Begin
consume(AS_ID);
if actasmtoken=AS_DOT then
begin
GetRecordOffsetSize(tempstr,l,k);
BuildRecordOffsetSize(tempstr,l,k);
str(l, tempstr);
expr := expr + tempstr;
end
@ -2321,7 +2311,7 @@ end;
{ var_name.typefield.typefield }
if (varname <> '') then
Begin
if GetVarOffsetSize(varname,actasmpattern,toffset,tsize) then
if GetRecordOffsetSize(varname+'.'+actasmpattern,toffset,tsize) then
Begin
Inc(instr.operands[operandnum].ref.offset,tOffset);
SetOperandSize(instr,operandnum,tsize);
@ -2355,7 +2345,7 @@ end;
{ [ref].typefield.typefield ... }
{ basetpyename is already set up... now look for fields. }
Begin
if GetTypeOffsetSize(basetypename,actasmpattern,tOffset,Tsize) then
if GetRecordOffsetSize(basetypename+'.'+actasmpattern,tOffset,Tsize) then
Begin
Inc(instr.operands[operandnum].ref.offset,tOffset);
SetOperandSize(instr,operandnum,Tsize);
@ -2486,7 +2476,7 @@ end;
consume(AS_ID);
if actasmtoken=AS_DOT then
begin
GetRecordOffsetSize(tempstr,l,k);
BuildRecordOffsetSize(tempstr,l,k);
str(l, tempstr);
expr := expr + tempstr;
end
@ -2831,7 +2821,7 @@ end;
var
l:longint;
again : boolean;
Begin
Consume(AS_LBRACKET);
initAsmRef(instr);
@ -3629,7 +3619,11 @@ begin
end.
{
$Log$
Revision 1.29 1999-04-19 09:44:26 pierre
Revision 1.30 1999-04-26 23:26:13 peter
* redesigned record offset parsing to support nested records
* normal compiler uses the redesigned createvarinstr()
Revision 1.29 1999/04/19 09:44:26 pierre
* accept several previously refused syntax, still uncomplete
Revision 1.28 1999/04/18 00:32:23 pierre

View File

@ -277,8 +277,7 @@ Type
{---------------------------------------------------------------------}
Procedure SetOperandSize(var instr:TInstruction;operandnum,size:longint);
Function GetVarOffsetSize(const base,field:string;Var Offset: longint;var Size:longint):boolean;
Function GetTypeOffsetSize(const base,field: string;Var Offset: longint;var Size:longint):boolean;
Function GetRecordOffsetSize(s:string;Var Offset: longint;var Size:longint):boolean;
Function SearchIConstant(const s:string; var l:longint): boolean;
Function SearchLabel(const s: string; var hl: plabel): boolean;
Function CreateVarInstr(var Instr: TInstruction; const hs:string;
@ -1087,485 +1086,189 @@ end;
end;
Function GetVarOffsetSize(const base,field:string;Var Offset: longint;var Size:longint):boolean;
{ search and returns the offset and size of records/objects of the base }
{ with field name setup in field. }
{ returns FALSE if not found. }
{ used when base is a variable or a typed constant name. }
var
sym:psym;
p: psym;
Begin
GetVarOffsetSize := FALSE;
Offset := 0;
{ local list }
if assigned(aktprocsym) then
begin
if assigned(aktprocsym^.definition^.localst) then
sym:=aktprocsym^.definition^.localst^.search(base)
else
sym:=nil;
if assigned(sym) then
Function GetRecordOffsetSize(s:string;Var Offset: longint;var Size:longint):boolean;
{ search and returns the offset and size of records/objects of the base }
{ with field name setup in field. }
{ returns FALSE if not found. }
{ used when base is a variable or a typed constant name. }
var
st : psymtable;
sym : psym;
i : longint;
base : string;
Begin
GetRecordOffsetSize := FALSE;
Offset:=0;
Size:=0;
i:=pos('.',s);
if i=0 then
i:=255;
base:=Copy(s,1,i-1);
delete(s,1,i);
getsym(base,false);
sym:=srsym;
st:=nil;
{ we can start with a var,type,typedconst }
case sym^.typ of
varsym :
begin
{ field of local record variable. }
if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.deftype=recorddef) then
begin
p:=pvarsym(precdef(pvarsym(sym)^.definition)^.symtable^.search(field));
if assigned(pvarsym(p)) then
Begin
Offset := pvarsym(p)^.address;
Size:=PVarsym(p)^.getsize;
GetVarOffsetSize := TRUE;
Exit;
end;
end
else
if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.deftype=objectdef) then
begin
if assigned(pobjectdef(pvarsym(sym)^.definition)^.publicsyms) then
begin
p:=pvarsym(pobjectdef(pvarsym(sym)^.definition)^.publicsyms^.search(field));
if assigned(pvarsym(p)) then
Begin
Offset := pvarsym(p)^.address;
Size:=PVarsym(p)^.getsize;
GetVarOffsetSize := TRUE;
Exit;
end;
end;
end;
end
else
begin
{ field of local record parameter to routine. }
if assigned(aktprocsym^.definition^.parast) then
sym:=aktprocsym^.definition^.parast^.search(base)
else
sym:=nil;
if assigned(sym) then
case pvarsym(sym)^.definition^.deftype of
recorddef :
st:=precdef(pvarsym(sym)^.definition)^.symtable;
objectdef :
st:=pobjectdef(pvarsym(sym)^.definition)^.publicsyms;
end;
end;
typesym :
begin
case ptypesym(sym)^.definition^.deftype of
recorddef :
st:=precdef(ptypesym(sym)^.definition)^.symtable;
objectdef :
st:=pobjectdef(ptypesym(sym)^.definition)^.publicsyms;
end;
end;
typedconstsym :
begin
case pvarsym(sym)^.definition^.deftype of
recorddef :
st:=precdef(ptypedconstsym(sym)^.definition)^.symtable;
objectdef :
st:=pobjectdef(ptypedconstsym(sym)^.definition)^.publicsyms;
end;
end;
end;
{ now walk all recordsymtables }
while assigned(st) and (s<>'') do
begin
{ load next field in base }
i:=pos('.',s);
if i=0 then
i:=255;
base:=Copy(s,1,i-1);
delete(s,1,i);
sym:=st^.search(base);
st:=nil;
case sym^.typ of
varsym :
begin
if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.deftype=recorddef)
then
begin
p:=pvarsym(precdef(pvarsym(sym)^.definition)^.symtable^.search(field));
if assigned(p) then
Begin
Offset := pvarsym(p)^.address;
Size:=PVarsym(p)^.getsize;
GetVarOffsetSize := TRUE;
Exit;
end;
end { endif }
else
if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.deftype=objectdef) then
begin
if assigned(pobjectdef(pvarsym(sym)^.definition)^.publicsyms) then
begin
p:=pvarsym(pobjectdef(pvarsym(sym)^.definition)^.publicsyms^.search(field));
if assigned(pvarsym(p)) then
Begin
Offset := pvarsym(p)^.address;
Size:=PVarsym(p)^.getsize;
GetVarOffsetSize := TRUE;
Exit;
end;
end;
end;
inc(Offset,pvarsym(sym)^.address);
Size:=PVarsym(sym)^.getsize;
case pvarsym(sym)^.definition^.deftype of
recorddef :
st:=precdef(pvarsym(sym)^.definition)^.symtable;
objectdef :
st:=pobjectdef(pvarsym(sym)^.definition)^.publicsyms;
end;
end;
end;
end; { endif assigned(aktprocsym) }
{ not found.. .now look for global variables. }
getsym(base,false);
sym:=srsym;
if assigned(sym) then
Begin
{ field of global record variable. }
if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.deftype=recorddef) then
begin
p:=pvarsym(precdef(pvarsym(sym)^.definition)^.symtable^.search(field));
if assigned(p) then
Begin
Offset := pvarsym(p)^.address;
Size:=PVarsym(p)^.getsize;
GetVarOffsetSize := TRUE;
Exit;
end;
end
else
{ field of global record type constant. }
if (sym^.typ=typedconstsym) and (ptypedconstsym(sym)^.definition^.deftype=recorddef)
then
begin
p:=pvarsym(precdef(pvarsym(sym)^.definition)^.symtable^.search(field));
if assigned(p) then
Begin
Offset := pvarsym(p)^.address;
Size:=PVarsym(p)^.getsize;
GetVarOffsetSize := TRUE;
Exit;
end;
end
else
if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.deftype=objectdef) then
begin
if assigned(pobjectdef(pvarsym(sym)^.definition)^.publicsyms) then
begin
p:=pvarsym(pobjectdef(pvarsym(sym)^.definition)^.publicsyms^.search(field));
if assigned(pvarsym(p)) then
Begin
Offset := pvarsym(p)^.address;
Size:=PVarsym(p)^.getsize;
GetVarOffsetSize := TRUE;
Exit;
end;
end;
end;
end; { end looking for global variables .. }
end;
end;
end;
GetRecordOffsetSize:=(s='');
end;
Function GetTypeOffsetSize(const base,field: string;Var Offset: longint;var Size:longint):boolean;
{ search and returns the offset of records/objects of the base }
{ with field name setup in field. }
{ returns 0 if not found. }
{ used when base is a variable or a typed constant name. }
var
sym:psym;
p: psym;
Begin
Offset := 0;
GetTypeOffsetSize := FALSE;
{ local list }
if assigned(aktprocsym) then
begin
if assigned(aktprocsym^.definition^.localst) then
sym:=aktprocsym^.definition^.localst^.search(base)
else
sym:=nil;
if assigned(sym) then
Function CreateVarInstr(var Instr: TInstruction; const hs:string;operandnum:byte): Boolean;
{ search and sets up the correct fields in the Instr record }
{ for the NON-constant identifier passed to the routine. }
{ if not found returns FALSE. }
var
sym : psym;
Begin
CreateVarInstr := FALSE;
{ are we in a routine ? }
getsym(hs,false);
sym:=srsym;
if sym=nil then
exit;
case sym^.typ of
varsym :
begin
{ field of local record type. }
if (sym^.typ=typesym) and (ptypesym(sym)^.definition^.deftype=recorddef) then
begin
p:=precdef(ptypesym(sym)^.definition)^.symtable^.search(field);
if assigned(p) then
Begin
Offset := pvarsym(p)^.address;
Size:=PVarsym(p)^.getsize;
GetTypeOffsetSize := TRUE;
Exit;
end;
end;
end
else
begin
{ field of local record type to routine. }
if assigned(aktprocsym^.definition^.parast) then
sym:=aktprocsym^.definition^.parast^.search(base)
else
sym:=nil;
if assigned(sym) then
{ we always assume in asm statements that }
{ that the variable is valid. }
pvarsym(sym)^.is_valid:=1;
inc(pvarsym(sym)^.refs);
case pvarsym(sym)^.owner^.symtabletype of
unitsymtable,
globalsymtable,
staticsymtable :
instr.operands[operandnum].ref.symbol:=newasmsymbol(pvarsym(sym)^.mangledname);
parasymtable :
begin
instr.operands[operandnum].ref.base := procinfo.framepointer;
instr.operands[operandnum].ref.offset := pvarsym(sym)^.address+aktprocsym^.definition^.parast^.address_fixup;
end;
localsymtable :
begin
if (pvarsym(sym)^.var_options and vo_is_external)<>0 then
instr.operands[operandnum].ref.symbol:=newasmsymbol(pvarsym(sym)^.mangledname)
else
begin
instr.operands[operandnum].ref.base := procinfo.framepointer;
instr.operands[operandnum].ref.offset := -(pvarsym(sym)^.address);
end;
end;
end;
case pvarsym(sym)^.definition^.deftype of
orddef,
enumdef,
floatdef :
SetOperandSize(instr,operandnum,pvarsym(sym)^.getsize);
arraydef :
SetOperandSize(instr,operandnum,parraydef(pvarsym(sym)^.definition)^.elesize)
end;
CreateVarInstr := TRUE;
Exit;
end;
typedconstsym :
begin
instr.operands[operandnum].ref.symbol:=newasmsymbol(ptypedconstsym(sym)^.mangledname);
case ptypedconstsym(sym)^.definition^.deftype of
orddef,
enumdef,
floatdef :
SetOperandSize(instr,operandnum,ptypedconstsym(sym)^.getsize);
arraydef :
SetOperandSize(instr,operandnum,parraydef(ptypedconstsym(sym)^.definition)^.elesize)
end;
CreateVarInstr := TRUE;
Exit;
end;
constsym :
begin
if pconstsym(sym)^.consttype in [constint,constchar,constbool] then
begin
if (sym^.typ=typesym) and (ptypesym(sym)^.definition^.deftype=recorddef)
then
begin
p:=precdef(ptypesym(sym)^.definition)^.symtable^.search(field);
if assigned(p) then
Begin
Offset := pvarsym(p)^.address;
GetTypeOffsetSize := TRUE;
Exit;
end;
end; { endif }
end; {endif }
end; { endif }
end;
{ not found.. .now look for global types. }
getsym(base,false);
sym:=srsym;
if assigned(sym) then
Begin
{ field of global record types. }
if (sym^.typ=typesym) and (ptypesym(sym)^.definition^.deftype=recorddef) then
begin
p:=precdef(ptypesym(sym)^.definition)^.symtable^.search(field);
if assigned(p) then
Begin
Offset := pvarsym(p)^.address;
Size:=PVarsym(p)^.getsize;
GetTypeOffsetSize := TRUE;
Exit;
end
end
else
{ public field names of objects }
if (sym^.typ=typesym) and (ptypesym(sym)^.definition^.deftype=objectdef)then
begin
if assigned(pobjectdef(ptypesym(sym)^.definition)^.publicsyms) then
Begin
p:=pobjectdef(ptypesym(sym)^.definition)^.publicsyms^.search(field);
if assigned(p) then
Begin
Offset := pvarsym(p)^.address;
Size:=PVarsym(p)^.getsize;
GetTypeOffsetSize := TRUE;
Exit;
end
end;
end;
end; { end looking for global variables .. }
instr.operands[operandnum].operandtype:=OPR_CONSTANT;
instr.operands[operandnum].val:=pconstsym(sym)^.value;
CreateVarInstr := TRUE;
Exit;
end;
end;
typesym :
begin
if ptypesym(sym)^.definition^.deftype in [recorddef,objectdef] then
begin
instr.operands[operandnum].operandtype:=OPR_CONSTANT;
instr.operands[operandnum].val:=0;
CreateVarInstr := TRUE;
Exit;
end;
end;
procsym :
begin
if assigned(pprocsym(sym)^.definition^.nextoverloaded) then
Message(assem_w_calling_overload_func);
instr.operands[operandnum].operandtype:=OPR_SYMBOL;
instr.operands[operandnum].symbol:=newasmsymbol(pprocsym(sym)^.definition^.mangledname);
CreateVarInstr := TRUE;
Exit;
end;
else
begin
Message(assem_e_unsupported_symbol_type);
exit;
end;
end;
Function CreateVarInstr(var Instr: TInstruction; const hs:string;operandnum:byte): Boolean;
{ search and sets up the correct fields in the Instr record }
{ for the NON-constant identifier passed to the routine. }
{ if not found returns FALSE. }
var
sym : psym;
l : longint;
Begin
CreateVarInstr := FALSE;
{ are we in a routine ? }
if assigned(aktprocsym) then
begin
{ search the local list for the name of this variable. }
if assigned(aktprocsym^.definition^.localst) then
sym:=aktprocsym^.definition^.localst^.search(hs)
else
sym:=nil;
if assigned(sym) then
begin
case sym^.typ of
varsym : begin
{ we always assume in asm statements that }
{ that the variable is valid. }
pvarsym(sym)^.is_valid:=1;
inc(pvarsym(sym)^.refs);
if (pvarsym(sym)^.owner^.symtabletype=staticsymtable) or
((pvarsym(sym)^.var_options and vo_is_external)<>0) then
begin
instr.operands[operandnum].ref.symbol:=newasmsymbol(pvarsym(sym)^.mangledname);
end
else
begin
instr.operands[operandnum].ref.base := procinfo.framepointer;
instr.operands[operandnum].ref.offset := -(pvarsym(sym)^.address);
end;
{ the current size is NOT overriden if it already }
{ exists, such as in the case of a byte ptr, in }
{ front of the identifier. }
if (instr.operands[operandnum].size = S_NO) or (instr.operands[operandnum].overriden = FALSE) then
Begin
case pvarsym(sym)^.getsize of
1: instr.operands[operandnum].size := S_B;
2: instr.operands[operandnum].size := S_W{ could be S_IS};
4: instr.operands[operandnum].size := S_L{ could be S_IL or S_FS};
8: instr.operands[operandnum].size := S_IQ{ could be S_D or S_FL};
extended_size: instr.operands[operandnum].size := S_FX;
else
{ this is in the case where the instruction is LEA }
{ or something like that, in that case size is not }
{ important. }
instr.operands[operandnum].size := S_NO;
end; { end case }
end;
{ ok, finished for this var }
CreateVarInstr := TRUE;
Exit;
end;
typedconstsym : begin
{ we always assume in asm statements that }
{ that the variable is valid. }
instr.operands[operandnum].ref.symbol:=newasmsymbol(pvarsym(sym)^.mangledname);
{ the current size is NOT overriden if it already }
{ exists, such as in the case of a byte ptr, in }
{ front of the identifier. }
if (instr.operands[operandnum].size = S_NO) or (instr.operands[operandnum].overriden = FALSE) then
Begin
case ptypedconstsym(sym)^.getsize of
1: instr.operands[operandnum].size := S_B;
2: instr.operands[operandnum].size := S_W{ could be S_IS};
4: instr.operands[operandnum].size := S_L{ could be S_IL or S_FS};
8: instr.operands[operandnum].size := S_IQ{ could be S_D or S_FL};
extended_size: instr.operands[operandnum].size := S_FX;
else
instr.operands[operandnum].size := S_NO;
end; { end case }
end;
{ ok, finished for this var }
CreateVarInstr := TRUE;
Exit;
end;
constsym : begin
if pconstsym(sym)^.consttype in [constint,constchar,constbool] then
begin
instr.operands[operandnum].operandtype:=OPR_CONSTANT;
instr.operands[operandnum].val:=pconstsym(sym)^.value;
CreateVarInstr := TRUE;
Exit;
end;
end;
typesym : begin
if ptypesym(sym)^.definition^.deftype in [recorddef,objectdef] then
begin
instr.operands[operandnum].operandtype:=OPR_CONSTANT;
instr.operands[operandnum].val:=0;
CreateVarInstr := TRUE;
Exit;
end;
end;
procsym : begin
instr.operands[operandnum].operandtype:=OPR_SYMBOL;
instr.operands[operandnum].symbol:=newasmsymbol(pprocsym(sym)^.definition^.mangledname);
CreateVarInstr := TRUE;
Exit;
end
else
begin
Message(assem_e_unsupported_symbol_type);
exit;
end;
end;
end;
{ now check for parameters passed to routine }
if assigned(aktprocsym^.definition^.parast) then
sym:=aktprocsym^.definition^.parast^.search(hs)
else
sym:=nil;
if assigned(sym) then
begin
case sym^.typ of
varsym : begin
if pvarsym(sym)^.islocalcopy then
l:=-pvarsym(sym)^.address
else
begin
l:=pvarsym(sym)^.address;
{ set offset }
inc(l,aktprocsym^.definition^.parast^.address_fixup);
end;
pvarsym(sym)^.is_valid:=1;
inc(pvarsym(sym)^.refs);
instr.operands[operandnum].ref.base := procinfo.framepointer;
instr.operands[operandnum].ref.offset := l;
{ the current size is NOT overriden if it already }
{ exists, such as in the case of a byte ptr, in }
{ front of the identifier. }
if (instr.operands[operandnum].size = S_NO) or (instr.operands[operandnum].overriden = FALSE) then
Begin
case pvarsym(sym)^.getsize of
1: instr.operands[operandnum].size := S_B;
2: instr.operands[operandnum].size := S_W;
4: instr.operands[operandnum].size := S_L;
8: instr.operands[operandnum].size := S_IQ;
extended_size: instr.operands[operandnum].size := S_FX;
else
{ this is in the case where the instruction is LEA }
{ or something like that, in that case size is not }
{ important. }
instr.operands[operandnum].size := S_NO;
end; { end case }
end; { endif }
CreateVarInstr := TRUE;
Exit;
end;
else
begin
Message(assem_e_unsupported_symbol_type);
exit;
end;
end; { case }
end; { endif }
end;
{ not found.. .now look for global variables. }
getsym(hs,false);
sym:=srsym;
if assigned(sym) then
Begin
case sym^.typ of
varsym,
typedconstsym : Begin
if sym^.typ=varsym then
inc(pvarsym(sym)^.refs);
instr.operands[operandnum].ref.symbol:=newasmsymbol(sym^.mangledname);
{ the current size is NOT overriden if it already }
{ exists, such as in the case of a byte ptr, in }
{ front of the identifier. }
if (instr.operands[operandnum].size = S_NO) or (instr.operands[operandnum].overriden = FALSE) then
Begin
case pvarsym(sym)^.getsize of
1: instr.operands[operandnum].size := S_B;
2: instr.operands[operandnum].size := S_W;
4: instr.operands[operandnum].size := S_L;
8: instr.operands[operandnum].size := S_IQ;
else
{ this is in the case where the instruction is LEA }
{ or something like that, in that case size is not }
{ important. }
instr.operands[operandnum].size := S_NO;
end;
end
else
if (instr.operands[operandnum].size = S_NO) and (sym^.typ = typedconstsym) then
Begin
{ only these are valid sizes, otherwise prefixes are }
{ required. }
case ptypedconstsym(sym)^.definition^.size of
1: instr.operands[operandnum].size := S_B;
2: instr.operands[operandnum].size := S_W;
4: instr.operands[operandnum].size := S_L;
8: instr.operands[operandnum].size := S_IQ;
else
{ this is in the case where the instruction is LEA }
{ or something like that, in that case size is not }
{ important. }
instr.operands[operandnum].size := S_NO;
end;
end; { endif }
CreateVarInstr := TRUE;
Exit;
end;
constsym : begin
if pconstsym(sym)^.consttype in [constint,constchar,constbool] then
begin
instr.operands[operandnum].operandtype:=OPR_CONSTANT;
instr.operands[operandnum].val:=pconstsym(sym)^.value;
CreateVarInstr := TRUE;
Exit;
end;
end;
typesym : begin
if ptypesym(sym)^.definition^.deftype in [recorddef,objectdef] then
begin
instr.operands[operandnum].operandtype:=OPR_CONSTANT;
instr.operands[operandnum].val:=0;
CreateVarInstr := TRUE;
Exit;
end;
end;
procsym : begin
if assigned(pprocsym(sym)^.definition^.nextoverloaded) then
Message(assem_w_calling_overload_func);
instr.operands[operandnum].operandtype:=OPR_SYMBOL;
instr.operands[operandnum].size:=S_L;
instr.operands[operandnum].symbol:=newasmsymbol(pprocsym(sym)^.definition^.mangledname);
CreateVarInstr := TRUE;
Exit;
end;
else
begin
Message(assem_e_unsupported_symbol_type);
exit;
end;
end; {case}
end; { end looking for global variables .. }
end;
end;
Function SearchLabel(const s: string; var hl: plabel): boolean;
@ -1791,7 +1494,11 @@ end;
end.
{
$Log$
Revision 1.8 1999-03-31 13:55:19 peter
Revision 1.9 1999-04-26 23:26:14 peter
* redesigned record offset parsing to support nested records
* normal compiler uses the redesigned createvarinstr()
Revision 1.8 1999/03/31 13:55:19 peter
* assembler inlining working for ag386bin
Revision 1.7 1999/03/24 23:17:23 peter