mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-04 04:17:53 +01:00
+ parsing of disp variant invokes
git-svn-id: trunk@5162 -
This commit is contained in:
parent
409ee19a83
commit
be2b715d3c
@ -1003,7 +1003,7 @@ implementation
|
||||
floatdef:
|
||||
result:=tfloatdef(p).typ in [s64currency,s64real,s32real];
|
||||
stringdef:
|
||||
result:=tstringdef(p).string_typ in [st_shortstring,st_ansistring];
|
||||
result:=tstringdef(p).string_typ in [st_ansistring,st_widestring];
|
||||
variantdef:
|
||||
result:=true;
|
||||
end;
|
||||
|
||||
@ -145,6 +145,7 @@ interface
|
||||
|
||||
tcallparanode = class(tbinarynode)
|
||||
public
|
||||
named : tnode;
|
||||
callparaflags : tcallparaflags;
|
||||
parasym : tparavarsym;
|
||||
used_by_callnode : boolean;
|
||||
@ -167,6 +168,7 @@ interface
|
||||
tcallparanodeclass = class of tcallparanode;
|
||||
|
||||
function reverseparameters(p: tcallparanode): tcallparanode;
|
||||
function translate_vardisp_call(p1,p2 : tnode) : tnode;
|
||||
|
||||
var
|
||||
ccallnode : tcallnodeclass;
|
||||
@ -218,6 +220,27 @@ type
|
||||
end;
|
||||
|
||||
|
||||
function translate_vardisp_call(p1,p2 : tnode) : tnode;
|
||||
var
|
||||
statements : tstatementnode;
|
||||
result_data : ttempcreatenode;
|
||||
begin
|
||||
result:=internalstatements(statements);
|
||||
|
||||
{ get temp for the result }
|
||||
result_data:=ctempcreatenode.create(colevarianttype,colevarianttype.size,tt_persistent,true);
|
||||
addstatement(statements,result_data);
|
||||
|
||||
{ build parameters }
|
||||
|
||||
{ first, count parameters }
|
||||
|
||||
{ clean up }
|
||||
addstatement(statements,ctempdeletenode.create_normal_temp(result_data));
|
||||
addstatement(statements,ctemprefnode.create(result_data));
|
||||
end;
|
||||
|
||||
|
||||
procedure maybe_load_para_in_temp(var p:tnode);
|
||||
|
||||
function is_simple_node(hp:tnode):boolean;
|
||||
|
||||
@ -320,6 +320,7 @@ implementation
|
||||
important for the IDE }
|
||||
afterassignment:=false;
|
||||
in_args:=false;
|
||||
named_args_allowed:=false;
|
||||
got_addrn:=false;
|
||||
getprocvardef:=nil;
|
||||
|
||||
|
||||
@ -41,6 +41,9 @@ interface
|
||||
|
||||
{ true, if we are parsing arguments }
|
||||
in_args : boolean = false;
|
||||
|
||||
{ true, if we are parsing arguments allowing named parameters }
|
||||
named_args_allowed : boolean = false;
|
||||
|
||||
{ true, if we got an @ to get the address }
|
||||
got_addrn : boolean = false;
|
||||
@ -57,6 +60,9 @@ interface
|
||||
|
||||
{ true, if we should ignore an equal in const x : 1..2=2 }
|
||||
ignore_equal : boolean;
|
||||
|
||||
{ true, if we found a name for a named arg }
|
||||
found_arg_name : boolean;
|
||||
|
||||
|
||||
procedure identifier_not_found(const s:string);
|
||||
@ -175,8 +181,8 @@ implementation
|
||||
{ check if a symbol contains the hint directive, and if so gives out a hint
|
||||
if required.
|
||||
|
||||
If this code is changed, it's like that consume_sym_orgid must be changed
|
||||
as well (FK)
|
||||
If this code is changed, it's likly that consume_sym_orgid and factor_read_id
|
||||
must be changed as well (FK)
|
||||
}
|
||||
function consume_sym(var srsym:tsym;var srsymtable:tsymtable):boolean;
|
||||
begin
|
||||
|
||||
@ -45,7 +45,7 @@ interface
|
||||
|
||||
function node_to_propaccesslist(p1:tnode):tpropaccesslist;
|
||||
|
||||
function parse_paras(__colon : boolean;end_of_paras : ttoken) : tnode;
|
||||
function parse_paras(__colon,__namedpara : boolean;end_of_paras : ttoken) : tnode;
|
||||
|
||||
{ the ID token has to be consumed before calling this function }
|
||||
procedure do_member_read(classh:tobjectdef;getaddr : boolean;sym : tsym;var p1 : tnode;var again : boolean;callflags:tcallnodeflags);
|
||||
@ -240,10 +240,11 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function parse_paras(__colon : boolean;end_of_paras : ttoken) : tnode;
|
||||
function parse_paras(__colon,__namedpara : boolean;end_of_paras : ttoken) : tnode;
|
||||
var
|
||||
p1,p2 : tnode;
|
||||
prev_in_args : boolean;
|
||||
p1,p2,argname : tnode;
|
||||
prev_in_args,
|
||||
old_named_args_allowed,
|
||||
old_allow_array_constructor : boolean;
|
||||
begin
|
||||
if token=end_of_paras then
|
||||
@ -254,14 +255,42 @@ implementation
|
||||
{ save old values }
|
||||
prev_in_args:=in_args;
|
||||
old_allow_array_constructor:=allow_array_constructor;
|
||||
old_named_args_allowed:=named_args_allowed;
|
||||
{ set para parsing values }
|
||||
in_args:=true;
|
||||
named_args_allowed:=false;
|
||||
inc(parsing_para_level);
|
||||
allow_array_constructor:=true;
|
||||
p2:=nil;
|
||||
repeat
|
||||
p1:=comp_expr(true);
|
||||
p2:=ccallparanode.create(p1,p2);
|
||||
if __namedpara then
|
||||
begin
|
||||
if token=_COMMA then
|
||||
begin
|
||||
{ empty parameter }
|
||||
p2:=ccallparanode.create(nil,p2);
|
||||
consume(_COMMA);
|
||||
end
|
||||
else
|
||||
begin
|
||||
named_args_allowed:=true;
|
||||
p1:=comp_expr(true);
|
||||
named_args_allowed:=false;
|
||||
if found_arg_name then
|
||||
begin
|
||||
argname:=p1;
|
||||
p1:=comp_expr(true);
|
||||
p2:=ccallparanode.create(p1,p2);
|
||||
tcallparanode(p2).named:=argname;
|
||||
end;
|
||||
found_arg_name:=false;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
p1:=comp_expr(true);
|
||||
p2:=ccallparanode.create(p1,p2);
|
||||
end;
|
||||
{ it's for the str(l:5,s); }
|
||||
if __colon and (token=_COLON) then
|
||||
begin
|
||||
@ -280,6 +309,7 @@ implementation
|
||||
allow_array_constructor:=old_allow_array_constructor;
|
||||
dec(parsing_para_level);
|
||||
in_args:=prev_in_args;
|
||||
named_args_allowed:=old_named_args_allowed;
|
||||
parse_paras:=p2;
|
||||
end;
|
||||
|
||||
@ -756,7 +786,7 @@ implementation
|
||||
begin
|
||||
if try_to_consume(_LKLAMMER) then
|
||||
begin
|
||||
paras:=parse_paras(false,_RKLAMMER);
|
||||
paras:=parse_paras(false,false,_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
end
|
||||
else
|
||||
@ -785,7 +815,7 @@ implementation
|
||||
begin
|
||||
if try_to_consume(_LKLAMMER) then
|
||||
begin
|
||||
paras:=parse_paras(true,_RKLAMMER);
|
||||
paras:=parse_paras(true,false,_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
end
|
||||
else
|
||||
@ -797,7 +827,7 @@ implementation
|
||||
in_str_x_string :
|
||||
begin
|
||||
consume(_LKLAMMER);
|
||||
paras:=parse_paras(true,_RKLAMMER);
|
||||
paras:=parse_paras(true,false,_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
p1 := geninlinenode(l,false,paras);
|
||||
statement_syssym := p1;
|
||||
@ -1008,7 +1038,7 @@ implementation
|
||||
begin
|
||||
if try_to_consume(_LKLAMMER) then
|
||||
begin
|
||||
para:=parse_paras(false,_RKLAMMER);
|
||||
para:=parse_paras(false,false,_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
end;
|
||||
end;
|
||||
@ -1104,7 +1134,7 @@ implementation
|
||||
begin
|
||||
if try_to_consume(_LECKKLAMMER) then
|
||||
begin
|
||||
paras:=parse_paras(false,_RECKKLAMMER);
|
||||
paras:=parse_paras(false,false,_RECKKLAMMER);
|
||||
consume(_RECKKLAMMER);
|
||||
end;
|
||||
end;
|
||||
@ -1301,14 +1331,54 @@ implementation
|
||||
pc : pchar;
|
||||
len : longint;
|
||||
srsym : tsym;
|
||||
unit_found,
|
||||
possible_error : boolean;
|
||||
srsymtable : tsymtable;
|
||||
hdef : tdef;
|
||||
static_name : string;
|
||||
storedpattern : string;
|
||||
begin
|
||||
{ allow post fix operators }
|
||||
again:=true;
|
||||
consume_sym(srsym,srsymtable);
|
||||
|
||||
{ first check for identifier }
|
||||
if token<>_ID then
|
||||
begin
|
||||
srsym:=generrorsym;
|
||||
srsymtable:=nil;
|
||||
consume(_ID);
|
||||
end
|
||||
else
|
||||
begin
|
||||
searchsym(pattern,srsym,srsymtable);
|
||||
|
||||
{ handle unit specification like System.Writeln }
|
||||
unit_found:=try_consume_unitsym(srsym,srsymtable);
|
||||
storedpattern:=pattern;
|
||||
consume(_ID);
|
||||
|
||||
{ named parameter support }
|
||||
found_arg_name:=false;
|
||||
|
||||
if not(unit_found) and
|
||||
named_args_allowed and
|
||||
(token=_ASSIGNMENT) then
|
||||
begin
|
||||
found_arg_name:=true;
|
||||
p1:=cstringconstnode.createstr(storedpattern);
|
||||
consume(_ASSIGNMENT);
|
||||
exit;
|
||||
end;
|
||||
{ if nothing found give error and return errorsym }
|
||||
if assigned(srsym) then
|
||||
check_hints(srsym,srsym.symoptions)
|
||||
else
|
||||
begin
|
||||
identifier_not_found(orgpattern);
|
||||
srsym:=generrorsym;
|
||||
srsymtable:=nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Access to funcret or need to call the function? }
|
||||
if (srsym.typ in [absolutevarsym,localvarsym,paravarsym]) and
|
||||
@ -1616,7 +1686,7 @@ implementation
|
||||
p1:=cerrornode.create;
|
||||
if try_to_consume(_LKLAMMER) then
|
||||
begin
|
||||
parse_paras(false,_RKLAMMER);
|
||||
parse_paras(false,false,_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
end;
|
||||
end;
|
||||
@ -1783,7 +1853,6 @@ implementation
|
||||
srsym : tsym;
|
||||
srsymtable : tsymtable;
|
||||
classh : tobjectdef;
|
||||
|
||||
label
|
||||
skipreckklammercheck;
|
||||
begin
|
||||
@ -1969,8 +2038,23 @@ implementation
|
||||
consume(_ID);
|
||||
end;
|
||||
variantdef:
|
||||
{ dispatch call }
|
||||
try_to_consume(_ID);
|
||||
begin
|
||||
{ dispatch call? }
|
||||
if token=_ID then
|
||||
begin
|
||||
consume(_ID);
|
||||
if try_to_consume(_LKLAMMER) then
|
||||
begin
|
||||
p2:=parse_paras(false,true,_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
p1:=translate_vardisp_call(p1,p2);
|
||||
end
|
||||
else
|
||||
p2:=nil;
|
||||
end
|
||||
else { Error }
|
||||
Consume(_ID);
|
||||
end;
|
||||
classrefdef:
|
||||
begin
|
||||
if token=_ID then
|
||||
@ -2052,7 +2136,7 @@ implementation
|
||||
begin
|
||||
if try_to_consume(_LKLAMMER) then
|
||||
begin
|
||||
p2:=parse_paras(false,_RKLAMMER);
|
||||
p2:=parse_paras(false,false,_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
p1:=ccallnode.create_procvar(p2,p1);
|
||||
{ proc():= is never possible }
|
||||
|
||||
@ -460,7 +460,7 @@ implementation
|
||||
result := cerrornode.create;
|
||||
|
||||
consume(_LKLAMMER);
|
||||
paras:=parse_paras(false,_RKLAMMER);
|
||||
paras:=parse_paras(false,false,_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
if not assigned(paras) then
|
||||
begin
|
||||
@ -587,7 +587,7 @@ implementation
|
||||
result := cerrornode.create;
|
||||
|
||||
consume(_LKLAMMER);
|
||||
paras:=parse_paras(false,_RKLAMMER);
|
||||
paras:=parse_paras(false,false,_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
if not assigned(paras) then
|
||||
begin
|
||||
@ -625,7 +625,7 @@ implementation
|
||||
result := cerrornode.create;
|
||||
|
||||
consume(_LKLAMMER);
|
||||
paras:=parse_paras(false,_RKLAMMER);
|
||||
paras:=parse_paras(false,false,_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
if not assigned(paras) then
|
||||
begin
|
||||
@ -684,7 +684,7 @@ implementation
|
||||
result := cerrornode.create;
|
||||
|
||||
consume(_LKLAMMER);
|
||||
paras:=parse_paras(false,_RKLAMMER);
|
||||
paras:=parse_paras(false,false,_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
if not assigned(paras) then
|
||||
begin
|
||||
|
||||
Loading…
Reference in New Issue
Block a user