mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-30 23:13:40 +02:00
+ rec.field(%esi) support
+ [esi+rec.field] support
This commit is contained in:
parent
f986459350
commit
ce3e2aec84
@ -228,6 +228,8 @@ Type
|
||||
Procedure OpPop(var _Operator:TExprOperator);
|
||||
end;
|
||||
|
||||
{ Evaluate an expression string to a longint }
|
||||
Function CalculateExpression(const expression: string): longint;
|
||||
|
||||
{---------------------------------------------------------------------}
|
||||
{ String routines }
|
||||
@ -546,6 +548,15 @@ Begin
|
||||
end;
|
||||
|
||||
|
||||
Function CalculateExpression(const expression: string): longint;
|
||||
var
|
||||
expr: TExprParse;
|
||||
Begin
|
||||
expr.Init;
|
||||
CalculateExpression := expr.Evaluate(expression);
|
||||
expr.Done;
|
||||
end;
|
||||
|
||||
{*************************************************************************}
|
||||
{ String conversions/utils }
|
||||
{*************************************************************************}
|
||||
@ -657,6 +668,7 @@ end;
|
||||
'7': vs:=vs shl 3+7;
|
||||
else
|
||||
begin
|
||||
Message(assem_f_error_converting_octal);
|
||||
OctalToDec := '';
|
||||
exit;
|
||||
end;
|
||||
@ -683,6 +695,7 @@ end;
|
||||
vs:=vs shl 1+1
|
||||
else
|
||||
begin
|
||||
Message(assem_f_error_converting_bin);
|
||||
BinaryToDec := '';
|
||||
exit;
|
||||
end;
|
||||
@ -719,6 +732,7 @@ end;
|
||||
'F': vs:=vs shl 4+15;
|
||||
else
|
||||
begin
|
||||
Message(assem_f_error_converting_hex);
|
||||
HexToDec := '';
|
||||
exit;
|
||||
end;
|
||||
@ -1788,7 +1802,11 @@ end;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.16 1998-12-11 00:02:44 peter
|
||||
Revision 1.17 1998-12-23 22:55:55 peter
|
||||
+ rec.field(%esi) support
|
||||
+ [esi+rec.field] support
|
||||
|
||||
Revision 1.16 1998/12/11 00:02:44 peter
|
||||
+ globtype,tokens,version unit splitted from globals
|
||||
|
||||
Revision 1.15 1998/11/17 00:26:11 peter
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2006,228 +2006,212 @@ var
|
||||
|
||||
|
||||
|
||||
|
||||
Function CalculateExpression(expression: string): longint;
|
||||
var
|
||||
expr: TExprParse;
|
||||
Begin
|
||||
expr.Init;
|
||||
CalculateExpression := expr.Evaluate(expression);
|
||||
expr.Done;
|
||||
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 }
|
||||
{ AS_COMMA or AS_SEPARATOR token. }
|
||||
{ Warning: This is called recursively. }
|
||||
{*********************************************************************}
|
||||
var
|
||||
toffset,tsize : longint;
|
||||
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
|
||||
begin
|
||||
Message(assem_e_syntax_error);
|
||||
toffset:=0;
|
||||
tsize:=0;
|
||||
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. }
|
||||
{*********************************************************************}
|
||||
var
|
||||
toffset,tsize : longint;
|
||||
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
|
||||
begin
|
||||
Message(assem_e_syntax_error);
|
||||
toffset:=0;
|
||||
tsize:=0;
|
||||
end;
|
||||
inc(offset,toffset);
|
||||
size:=tsize;
|
||||
Consume(AS_ID);
|
||||
if actasmtoken=AS_DOT then
|
||||
begin
|
||||
GetRecordOffsetSize(expr,toffset,tsize);
|
||||
inc(offset,toffset);
|
||||
size:=tsize;
|
||||
Consume(AS_ID);
|
||||
case actasmtoken of
|
||||
AS_SEPARATOR,
|
||||
AS_COMMA : exit;
|
||||
AS_DOT : begin
|
||||
GetRecordOffsetSize(expr,toffset,tsize);
|
||||
inc(offset,toffset);
|
||||
size:=tsize;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
Begin
|
||||
Message(assem_e_syntax_error);
|
||||
repeat
|
||||
consume(actasmtoken)
|
||||
until (actasmtoken = AS_SEPARATOR) or (actasmtoken = AS_COMMA);
|
||||
end;
|
||||
end;
|
||||
|
||||
else
|
||||
Begin
|
||||
Message(assem_e_syntax_error);
|
||||
repeat
|
||||
consume(actasmtoken)
|
||||
until (actasmtoken = AS_SEPARATOR) or (actasmtoken = AS_COMMA);
|
||||
exit;
|
||||
end;
|
||||
|
||||
Function BuildRefExpression: longint;
|
||||
{*********************************************************************}
|
||||
{ FUNCTION BuildExpression: longint }
|
||||
{ Description: This routine calculates a constant expression to }
|
||||
{ a given value. The return value is the value calculated from }
|
||||
{ the expression. }
|
||||
{ The following tokens (not strings) are recognized: }
|
||||
{ (,),SHL,SHR,/,*,NOT,OR,XOR,AND,MOD,+/-,numbers,ID to constants. }
|
||||
{*********************************************************************}
|
||||
{ ENTRY: On entry the token should be any valid expression token. }
|
||||
{ EXIT: On Exit the token points to any token after the closing }
|
||||
{ RBRACKET }
|
||||
{ ERROR RECOVERY: Tries to find COMMA or SEPARATOR token by consuming }
|
||||
{ invalid tokens. }
|
||||
{*********************************************************************}
|
||||
var
|
||||
tempstr,expr : string;
|
||||
l,k : longint;
|
||||
errorflag : boolean;
|
||||
Begin
|
||||
errorflag := FALSE;
|
||||
tempstr := '';
|
||||
expr := '';
|
||||
{ tell tokenizer that we are in }
|
||||
{ an expression. }
|
||||
inexpression := TRUE;
|
||||
Repeat
|
||||
Case actasmtoken of
|
||||
AS_LPAREN:
|
||||
Begin
|
||||
Consume(AS_LPAREN);
|
||||
expr := expr + '(';
|
||||
end;
|
||||
AS_RPAREN:
|
||||
Begin
|
||||
Consume(AS_RPAREN);
|
||||
expr := expr + ')';
|
||||
end;
|
||||
AS_SHL:
|
||||
Begin
|
||||
Consume(AS_SHL);
|
||||
expr := expr + '<';
|
||||
end;
|
||||
AS_SHR:
|
||||
Begin
|
||||
Consume(AS_SHR);
|
||||
expr := expr + '>';
|
||||
end;
|
||||
AS_SLASH:
|
||||
Begin
|
||||
Consume(AS_SLASH);
|
||||
expr := expr + '/';
|
||||
end;
|
||||
AS_MOD:
|
||||
Begin
|
||||
Consume(AS_MOD);
|
||||
expr := expr + '%';
|
||||
end;
|
||||
AS_STAR:
|
||||
Begin
|
||||
Consume(AS_STAR);
|
||||
expr := expr + '*';
|
||||
end;
|
||||
AS_PLUS:
|
||||
Begin
|
||||
Consume(AS_PLUS);
|
||||
expr := expr + '+';
|
||||
end;
|
||||
AS_MINUS:
|
||||
Begin
|
||||
Consume(AS_MINUS);
|
||||
expr := expr + '-';
|
||||
end;
|
||||
AS_AND:
|
||||
Begin
|
||||
Consume(AS_AND);
|
||||
expr := expr + '&';
|
||||
end;
|
||||
AS_NOT:
|
||||
Begin
|
||||
Consume(AS_NOT);
|
||||
expr := expr + '~';
|
||||
end;
|
||||
AS_XOR:
|
||||
Begin
|
||||
Consume(AS_XOR);
|
||||
expr := expr + '^';
|
||||
end;
|
||||
AS_OR:
|
||||
Begin
|
||||
Consume(AS_OR);
|
||||
expr := expr + '|';
|
||||
end;
|
||||
AS_INTNUM:
|
||||
Begin
|
||||
expr := expr + actasmpattern;
|
||||
Consume(AS_INTNUM);
|
||||
end;
|
||||
AS_BINNUM:
|
||||
Begin
|
||||
expr:=expr+BinaryToDec(actasmpattern);
|
||||
Consume(AS_BINNUM);
|
||||
end;
|
||||
AS_HEXNUM:
|
||||
Begin
|
||||
expr:=expr+HexToDec(actasmpattern);
|
||||
Consume(AS_HEXNUM);
|
||||
end;
|
||||
AS_OCTALNUM:
|
||||
Begin
|
||||
expr:=expr+OctalToDec(actasmpattern);
|
||||
Consume(AS_OCTALNUM);
|
||||
end;
|
||||
AS_ID:
|
||||
Begin
|
||||
tempstr:=actasmpattern;
|
||||
consume(AS_ID);
|
||||
if actasmtoken=AS_DOT then
|
||||
begin
|
||||
GetRecordOffsetSize(tempstr,l,k);
|
||||
str(l, tempstr);
|
||||
expr := expr + tempstr;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if SearchIConstant(tempstr,l) then
|
||||
begin
|
||||
str(l, tempstr);
|
||||
expr := expr + tempstr;
|
||||
end
|
||||
else
|
||||
Message1(assem_e_invalid_const_symbol,tempstr);
|
||||
end;
|
||||
end;
|
||||
AS_RBRACKET: { End of reference }
|
||||
Begin
|
||||
if not ErrorFlag then
|
||||
BuildRefExpression := CalculateExpression(expr)
|
||||
else
|
||||
BuildRefExpression := 0;
|
||||
Consume(AS_RBRACKET);
|
||||
{ no longer in an expression }
|
||||
inexpression := FALSE;
|
||||
exit;
|
||||
end;
|
||||
end
|
||||
else
|
||||
Begin
|
||||
Message(assem_e_syntax_error);
|
||||
repeat
|
||||
consume(actasmtoken)
|
||||
until (actasmtoken = AS_SEPARATOR) or (actasmtoken = AS_COMMA);
|
||||
{ write error only once. }
|
||||
if not errorflag then
|
||||
Message(assem_e_invalid_constant_expression);
|
||||
BuildRefExpression := 0;
|
||||
if actasmtoken in [AS_COMMA,AS_SEPARATOR] then
|
||||
exit;
|
||||
{ consume tokens until we find COMMA or SEPARATOR }
|
||||
Consume(actasmtoken);
|
||||
errorflag := TRUE;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Function BuildRefExpression: longint;
|
||||
{*********************************************************************}
|
||||
{ FUNCTION BuildExpression: longint }
|
||||
{ Description: This routine calculates a constant expression to }
|
||||
{ a given value. The return value is the value calculated from }
|
||||
{ the expression. }
|
||||
{ The following tokens (not strings) are recognized: }
|
||||
{ (,),SHL,SHR,/,*,NOT,OR,XOR,AND,MOD,+/-,numbers,ID to constants. }
|
||||
{*********************************************************************}
|
||||
{ ENTRY: On entry the token should be any valid expression token. }
|
||||
{ EXIT: On Exit the token points to any token after the closing }
|
||||
{ RBRACKET }
|
||||
{ ERROR RECOVERY: Tries to find COMMA or SEPARATOR token by consuming }
|
||||
{ invalid tokens. }
|
||||
{*********************************************************************}
|
||||
var tempstr: string;
|
||||
expr: string;
|
||||
l,k : longint;
|
||||
errorflag : boolean;
|
||||
Begin
|
||||
errorflag := FALSE;
|
||||
tempstr := '';
|
||||
expr := '';
|
||||
{ tell tokenizer that we are in }
|
||||
{ an expression. }
|
||||
inexpression := TRUE;
|
||||
Repeat
|
||||
Case actasmtoken of
|
||||
AS_LPAREN: Begin
|
||||
Consume(AS_LPAREN);
|
||||
expr := expr + '(';
|
||||
end;
|
||||
AS_RPAREN: Begin
|
||||
Consume(AS_RPAREN);
|
||||
expr := expr + ')';
|
||||
end;
|
||||
AS_SHL: Begin
|
||||
Consume(AS_SHL);
|
||||
expr := expr + '<';
|
||||
end;
|
||||
AS_SHR: Begin
|
||||
Consume(AS_SHR);
|
||||
expr := expr + '>';
|
||||
end;
|
||||
AS_SLASH: Begin
|
||||
Consume(AS_SLASH);
|
||||
expr := expr + '/';
|
||||
end;
|
||||
AS_MOD: Begin
|
||||
Consume(AS_MOD);
|
||||
expr := expr + '%';
|
||||
end;
|
||||
AS_STAR: Begin
|
||||
Consume(AS_STAR);
|
||||
expr := expr + '*';
|
||||
end;
|
||||
AS_PLUS: Begin
|
||||
Consume(AS_PLUS);
|
||||
expr := expr + '+';
|
||||
end;
|
||||
AS_MINUS: Begin
|
||||
Consume(AS_MINUS);
|
||||
expr := expr + '-';
|
||||
end;
|
||||
AS_AND: Begin
|
||||
Consume(AS_AND);
|
||||
expr := expr + '&';
|
||||
end;
|
||||
AS_NOT: Begin
|
||||
Consume(AS_NOT);
|
||||
expr := expr + '~';
|
||||
end;
|
||||
AS_XOR: Begin
|
||||
Consume(AS_XOR);
|
||||
expr := expr + '^';
|
||||
end;
|
||||
AS_OR: Begin
|
||||
Consume(AS_OR);
|
||||
expr := expr + '|';
|
||||
end;
|
||||
{ End of reference }
|
||||
AS_RBRACKET: Begin
|
||||
if not ErrorFlag then
|
||||
BuildRefExpression := CalculateExpression(expr)
|
||||
else
|
||||
BuildRefExpression := 0;
|
||||
Consume(AS_RBRACKET);
|
||||
{ no longer in an expression }
|
||||
inexpression := FALSE;
|
||||
exit;
|
||||
end;
|
||||
AS_ID:
|
||||
Begin
|
||||
tempstr:=actasmpattern;
|
||||
consume(AS_ID);
|
||||
if actasmtoken=AS_DOT then
|
||||
begin
|
||||
GetRecordOffsetSize(tempstr,l,k);
|
||||
str(l, tempstr);
|
||||
expr := expr + tempstr;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if SearchIConstant(tempstr,l) then
|
||||
begin
|
||||
str(l, tempstr);
|
||||
expr := expr + tempstr;
|
||||
end
|
||||
else
|
||||
Message1(assem_e_invalid_const_symbol,tempstr);
|
||||
end;
|
||||
end;
|
||||
AS_INTNUM: Begin
|
||||
expr := expr + actasmpattern;
|
||||
Consume(AS_INTNUM);
|
||||
end;
|
||||
AS_BINNUM: Begin
|
||||
tempstr := BinaryToDec(actasmpattern);
|
||||
if tempstr = '' then
|
||||
Message(assem_f_error_converting_bin);
|
||||
expr:=expr+tempstr;
|
||||
Consume(AS_BINNUM);
|
||||
end;
|
||||
|
||||
AS_HEXNUM: Begin
|
||||
tempstr := HexToDec(actasmpattern);
|
||||
if tempstr = '' then
|
||||
Message(assem_f_error_converting_hex);
|
||||
expr:=expr+tempstr;
|
||||
Consume(AS_HEXNUM);
|
||||
end;
|
||||
AS_OCTALNUM: Begin
|
||||
tempstr := OctalToDec(actasmpattern);
|
||||
if tempstr = '' then
|
||||
Message(assem_f_error_converting_octal);
|
||||
expr:=expr+tempstr;
|
||||
Consume(AS_OCTALNUM);
|
||||
end;
|
||||
else
|
||||
Begin
|
||||
{ write error only once. }
|
||||
if not errorflag then
|
||||
Message(assem_e_invalid_constant_expression);
|
||||
BuildRefExpression := 0;
|
||||
if actasmtoken in [AS_COMMA,AS_SEPARATOR] then exit;
|
||||
{ consume tokens until we find COMMA or SEPARATOR }
|
||||
Consume(actasmtoken);
|
||||
errorflag := TRUE;
|
||||
end;
|
||||
end;
|
||||
Until false;
|
||||
end;
|
||||
end;
|
||||
Until false;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
@ -2580,148 +2564,151 @@ var
|
||||
|
||||
|
||||
|
||||
Procedure BuildReference(var instr: TInstruction);
|
||||
{*********************************************************************}
|
||||
{ EXIT CONDITION: On exit the routine should point to either the }
|
||||
{ AS_COMMA or AS_SEPARATOR token. }
|
||||
{ On entry: contains the register after the opening bracket if any. }
|
||||
{*********************************************************************}
|
||||
var
|
||||
reg:string;
|
||||
segreg: boolean;
|
||||
negative: boolean;
|
||||
expr: string;
|
||||
Begin
|
||||
expr := '';
|
||||
if instr.operands[operandnum].operandtype <> OPR_REFERENCE then
|
||||
Begin
|
||||
Message(assem_e_syn_no_ref_with_brackets);
|
||||
InitAsmRef(instr);
|
||||
consume(AS_REGISTER);
|
||||
end
|
||||
else
|
||||
Begin
|
||||
{ save the reg }
|
||||
reg := actasmpattern;
|
||||
{ is the syntax of the form: [REG:REG...] }
|
||||
consume(AS_REGISTER);
|
||||
if actasmtoken = AS_COLON then
|
||||
begin
|
||||
segreg := TRUE;
|
||||
Message(assem_e_expression_form_not_supported);
|
||||
if instr.operands[operandnum].ref.segment <> R_NO then
|
||||
Procedure BuildReference(var instr: TInstruction);
|
||||
{*********************************************************************}
|
||||
{ EXIT CONDITION: On exit the routine should point to either the }
|
||||
{ AS_COMMA or AS_SEPARATOR token. }
|
||||
{ On entry: contains the register after the opening bracket if any. }
|
||||
{*********************************************************************}
|
||||
var
|
||||
reg:string;
|
||||
segreg: boolean;
|
||||
negative: boolean;
|
||||
expr: string;
|
||||
Begin
|
||||
expr := '';
|
||||
if instr.operands[operandnum].operandtype <> OPR_REFERENCE then
|
||||
Begin
|
||||
Message(assem_e_syn_no_ref_with_brackets);
|
||||
InitAsmRef(instr);
|
||||
consume(AS_REGISTER);
|
||||
end
|
||||
else
|
||||
Begin
|
||||
{ save the reg }
|
||||
reg := actasmpattern;
|
||||
consume(AS_REGISTER);
|
||||
{ is the syntax of the form: [REG:REG...] }
|
||||
if actasmtoken = AS_COLON then
|
||||
begin
|
||||
segreg := TRUE;
|
||||
Message(assem_e_expression_form_not_supported);
|
||||
if instr.operands[operandnum].ref.segment <> R_NO then
|
||||
Message(assem_e_defining_seg_more_than_once);
|
||||
instr.operands[operandnum].ref.segment := findsegment(reg);
|
||||
{ Here we should process the syntax of the form }
|
||||
{ [reg:reg...] }
|
||||
{!!!!!!!!!!!!!!!!!!!!!!!! }
|
||||
end
|
||||
{ This is probably of the following syntax: }
|
||||
{ SREG:[REG...] where SReg: is optional. }
|
||||
{ Therefore we immediately say that reg }
|
||||
{ is the base. }
|
||||
else
|
||||
Begin
|
||||
if instr.operands[operandnum].ref.base <> R_NO then
|
||||
instr.operands[operandnum].ref.segment := findsegment(reg);
|
||||
{ Here we should process the syntax of the form }
|
||||
{ [reg:reg...] }
|
||||
end
|
||||
else { SREG:[REG...] where SReg: is optional. }
|
||||
Begin
|
||||
if instr.operands[operandnum].ref.base <> R_NO then
|
||||
Message(assem_e_defining_base_more_than_once);
|
||||
instr.operands[operandnum].ref.base := findregister(reg);
|
||||
end;
|
||||
{ we process this type of syntax immediately... }
|
||||
case actasmtoken of
|
||||
instr.operands[operandnum].ref.base := findregister(reg);
|
||||
end;
|
||||
|
||||
{ REG:[REG].Field.Field ... }
|
||||
{ REG:[REG].Field[REG].Field... }
|
||||
AS_RBRACKET: Begin
|
||||
Consume(AS_RBRACKET);
|
||||
{ check for record fields }
|
||||
if actasmtoken = AS_DOT then
|
||||
BuildRecordOffset(instr,'');
|
||||
if (actasmtoken = AS_SEPARATOR) or (actasmtoken = AS_COMMA) then
|
||||
exit
|
||||
else
|
||||
Message(assem_e_syn_reference);
|
||||
end;
|
||||
{ REG:[REG +/- ...].Field.Field ... }
|
||||
AS_PLUS,AS_MINUS: Begin
|
||||
if actasmtoken = AS_MINUS then
|
||||
Begin
|
||||
expr := '-';
|
||||
negative := TRUE
|
||||
end
|
||||
else
|
||||
Begin
|
||||
negative := FALSE;
|
||||
expr := '+';
|
||||
end;
|
||||
Consume(actasmtoken);
|
||||
{ REG:[REG+REG+/-...].Field.Field }
|
||||
if actasmtoken = AS_REGISTER then
|
||||
Begin
|
||||
if negative then
|
||||
Message(assem_e_negative_index_register);
|
||||
if instr.operands[operandnum].ref.index <> R_NO then
|
||||
Message(assem_e_defining_index_more_than_once);
|
||||
instr.operands[operandnum].ref.index := findregister(actasmpattern);
|
||||
Consume(AS_REGISTER);
|
||||
case actasmtoken of
|
||||
AS_RBRACKET: { REG:[REG+REG].Field.Field... }
|
||||
Begin
|
||||
Consume(AS_RBRACKET);
|
||||
Case actasmtoken of
|
||||
AS_DOT: BuildRecordOffset(instr,'');
|
||||
AS_COMMA,AS_SEPARATOR: exit;
|
||||
else
|
||||
Message(assem_e_syntax_error);
|
||||
end
|
||||
end;
|
||||
AS_PLUS,AS_MINUS: { REG:[REG+REG+/-expr... }
|
||||
Begin
|
||||
if instr.operands[operandnum].ref.offset <> 0 then
|
||||
Message(assem_f_internal_error_in_buildreference);
|
||||
instr.operands[operandnum].ref.offset :=
|
||||
BuildRefExpression;
|
||||
case actasmtoken of
|
||||
AS_DOT: BuildRecordOffset(instr,'');
|
||||
AS_COMMA,AS_SEPARATOR: ;
|
||||
else
|
||||
Message(assem_e_syntax_error);
|
||||
end; { end case }
|
||||
end;
|
||||
AS_STAR: Begin { REG:[REG+REG*SCALING...].Field.Field... }
|
||||
BuildScaling(instr);
|
||||
end;
|
||||
else
|
||||
Begin
|
||||
Message(assem_e_syntax_error);
|
||||
end;
|
||||
end; { end case }
|
||||
end
|
||||
else if actasmtoken = AS_STAR then
|
||||
{ REG:[REG*SCALING ... ] }
|
||||
Begin
|
||||
BuildScaling(instr);
|
||||
end
|
||||
else
|
||||
{ REG:[REG+expr].Field.Field }
|
||||
Begin
|
||||
if instr.operands[operandnum].ref.offset <> 0 then
|
||||
Message(assem_f_internal_error_in_buildreference);
|
||||
instr.operands[operandnum].ref.offset := BuildRefExpression;
|
||||
case actasmtoken of
|
||||
AS_DOT: BuildRecordOffset(instr,'');
|
||||
AS_COMMA,AS_SEPARATOR: ;
|
||||
else
|
||||
Message(assem_e_syntax_error);
|
||||
end; { end case }
|
||||
end; { end if }
|
||||
end; { end this case }
|
||||
{ REG:[REG*scaling] ... }
|
||||
AS_STAR: Begin
|
||||
BuildScaling(instr);
|
||||
end;
|
||||
end;
|
||||
end; { end outer if }
|
||||
end;
|
||||
{ we process this type of syntax immediately... }
|
||||
case actasmtoken of
|
||||
{ SREG:[REG].Field.Field ... }
|
||||
{ SREG:[REG].Field[REG].Field... }
|
||||
AS_RBRACKET:
|
||||
Begin
|
||||
Consume(AS_RBRACKET);
|
||||
{ check for record fields }
|
||||
if actasmtoken = AS_DOT then
|
||||
BuildRecordOffset(instr,'');
|
||||
if (actasmtoken = AS_SEPARATOR) or (actasmtoken = AS_COMMA) then
|
||||
exit
|
||||
else
|
||||
Message(assem_e_syn_reference);
|
||||
end;
|
||||
|
||||
{ SREG:[REG +/- ...].Field.Field ... }
|
||||
AS_PLUS,
|
||||
AS_MINUS:
|
||||
Begin
|
||||
if actasmtoken = AS_MINUS then
|
||||
Begin
|
||||
expr := '-';
|
||||
negative := TRUE
|
||||
end
|
||||
else
|
||||
Begin
|
||||
negative := FALSE;
|
||||
expr := '+';
|
||||
end;
|
||||
Consume(actasmtoken);
|
||||
{ REG:[REG+REG+/-...].Field.Field }
|
||||
if actasmtoken = AS_REGISTER then
|
||||
Begin
|
||||
if negative then
|
||||
Message(assem_e_negative_index_register);
|
||||
if instr.operands[operandnum].ref.index <> R_NO then
|
||||
Message(assem_e_defining_index_more_than_once);
|
||||
instr.operands[operandnum].ref.index := findregister(actasmpattern);
|
||||
Consume(AS_REGISTER);
|
||||
case actasmtoken of
|
||||
AS_RBRACKET: { SREG:[REG+REG].Field.Field... }
|
||||
Begin
|
||||
Consume(AS_RBRACKET);
|
||||
Case actasmtoken of
|
||||
AS_DOT: BuildRecordOffset(instr,'');
|
||||
AS_COMMA,
|
||||
AS_SEPARATOR: exit;
|
||||
else
|
||||
Message(assem_e_syntax_error);
|
||||
end;
|
||||
end;
|
||||
AS_PLUS,
|
||||
AS_MINUS: { REG:[REG+REG+/-expr... }
|
||||
Begin
|
||||
if instr.operands[operandnum].ref.offset <> 0 then
|
||||
Message(assem_f_internal_error_in_buildreference);
|
||||
instr.operands[operandnum].ref.offset:=BuildRefExpression;
|
||||
case actasmtoken of
|
||||
AS_DOT: BuildRecordOffset(instr,'');
|
||||
AS_COMMA,
|
||||
AS_SEPARATOR: ;
|
||||
else
|
||||
Message(assem_e_syntax_error);
|
||||
end;
|
||||
end;
|
||||
AS_STAR: { REG:[REG+REG*SCALING...].Field.Field... }
|
||||
begin
|
||||
BuildScaling(instr);
|
||||
end;
|
||||
else
|
||||
Message(assem_e_syntax_error);
|
||||
end; { end case }
|
||||
end
|
||||
else
|
||||
{ REG:[REG*(+/-)SCALING ... ] }
|
||||
if actasmtoken = AS_STAR then
|
||||
Begin
|
||||
BuildScaling(instr);
|
||||
end
|
||||
else
|
||||
{ REG:[REG+expr].Field.Field }
|
||||
Begin
|
||||
if instr.operands[operandnum].ref.offset <> 0 then
|
||||
Message(assem_f_internal_error_in_buildreference);
|
||||
instr.operands[operandnum].ref.offset := BuildRefExpression;
|
||||
case actasmtoken of
|
||||
AS_DOT: BuildRecordOffset(instr,'');
|
||||
AS_COMMA,
|
||||
AS_SEPARATOR: ;
|
||||
else
|
||||
Message(assem_e_syntax_error);
|
||||
end;
|
||||
end; { end if }
|
||||
end; { end this case }
|
||||
|
||||
AS_STAR: { REG:[REG*scaling] ... }
|
||||
Begin
|
||||
BuildScaling(instr);
|
||||
end;
|
||||
end;
|
||||
end; { end outer if }
|
||||
end;
|
||||
|
||||
|
||||
Procedure BuildBracketExpression(var Instr: TInstruction; var_prefix: boolean);
|
||||
@ -3517,7 +3504,11 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.18 1998-12-11 00:03:43 peter
|
||||
Revision 1.19 1998-12-23 22:55:57 peter
|
||||
+ rec.field(%esi) support
|
||||
+ [esi+rec.field] support
|
||||
|
||||
Revision 1.18 1998/12/11 00:03:43 peter
|
||||
+ globtype,tokens,version unit splitted from globals
|
||||
|
||||
Revision 1.17 1998/12/08 23:03:46 jonas
|
||||
|
Loading…
Reference in New Issue
Block a user