mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 11:09:42 +02:00
* Make new/dispose system functions instead of keywords
This commit is contained in:
parent
3c1f350827
commit
7215d46735
@ -55,6 +55,8 @@ const
|
||||
in_typeinfo_x = 43;
|
||||
in_setlength_x = 44;
|
||||
in_finalize_x = 45;
|
||||
in_new_x = 46;
|
||||
in_dispose_x = 47;
|
||||
|
||||
{ Internal constant functions }
|
||||
in_const_trunc = 100;
|
||||
@ -102,7 +104,10 @@ const
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.3 2001-07-09 21:15:40 peter
|
||||
Revision 1.4 2001-10-24 11:51:39 marco
|
||||
* Make new/dispose system functions instead of keywords
|
||||
|
||||
Revision 1.3 2001/07/09 21:15:40 peter
|
||||
* Length made internal
|
||||
* Add array support for Length
|
||||
|
||||
|
@ -217,6 +217,241 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function new_dispose_statement(is_new:boolean) : tnode;
|
||||
var
|
||||
p,p2 : tnode;
|
||||
again : boolean; { dummy for do_proc_call }
|
||||
destructorname : stringid;
|
||||
sym : tsym;
|
||||
classh : tobjectdef;
|
||||
destructorpos,
|
||||
storepos : tfileposinfo;
|
||||
begin
|
||||
consume(_LKLAMMER);
|
||||
p:=comp_expr(true);
|
||||
{ calc return type }
|
||||
{ cleartempgen; }
|
||||
set_varstate(p,(not is_new));
|
||||
{ constructor,destructor specified }
|
||||
if try_to_consume(_COMMA) then
|
||||
begin
|
||||
{ extended syntax of new and dispose }
|
||||
{ function styled new is handled in factor }
|
||||
{ destructors have no parameters }
|
||||
destructorname:=pattern;
|
||||
destructorpos:=akttokenpos;
|
||||
consume(_ID);
|
||||
|
||||
if (p.resulttype.def.deftype<>pointerdef) then
|
||||
begin
|
||||
Message1(type_e_pointer_type_expected,p.resulttype.def.typename);
|
||||
p.free;
|
||||
p:=factor(false);
|
||||
p.free;
|
||||
consume(_RKLAMMER);
|
||||
new_dispose_statement:=cerrornode.create;
|
||||
exit;
|
||||
end;
|
||||
{ first parameter must be an object or class }
|
||||
if tpointerdef(p.resulttype.def).pointertype.def.deftype<>objectdef then
|
||||
begin
|
||||
Message(parser_e_pointer_to_class_expected);
|
||||
p.free;
|
||||
new_dispose_statement:=factor(false);
|
||||
consume_all_until(_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
exit;
|
||||
end;
|
||||
{ check, if the first parameter is a pointer to a _class_ }
|
||||
classh:=tobjectdef(tpointerdef(p.resulttype.def).pointertype.def);
|
||||
if is_class(classh) then
|
||||
begin
|
||||
Message(parser_e_no_new_or_dispose_for_classes);
|
||||
new_dispose_statement:=factor(false);
|
||||
consume_all_until(_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
exit;
|
||||
end;
|
||||
{ search cons-/destructor, also in parent classes }
|
||||
storepos:=akttokenpos;
|
||||
akttokenpos:=destructorpos;
|
||||
sym:=search_class_member(classh,destructorname);
|
||||
akttokenpos:=storepos;
|
||||
|
||||
{ the second parameter of new/dispose must be a call }
|
||||
{ to a cons-/destructor }
|
||||
if (not assigned(sym)) or (sym.typ<>procsym) then
|
||||
begin
|
||||
if is_new then
|
||||
Message(parser_e_expr_have_to_be_constructor_call)
|
||||
else
|
||||
Message(parser_e_expr_have_to_be_destructor_call);
|
||||
p.free;
|
||||
new_dispose_statement:=cerrornode.create;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if is_new then
|
||||
p2:=chnewnode.create
|
||||
else
|
||||
p2:=chdisposenode.create(p);
|
||||
do_resulttypepass(p2);
|
||||
p2.resulttype:=tpointerdef(p.resulttype.def).pointertype;
|
||||
if is_new then
|
||||
do_member_read(false,sym,p2,again)
|
||||
else
|
||||
begin
|
||||
if (m_tp in aktmodeswitches) then
|
||||
do_member_read(false,sym,p2,again)
|
||||
else
|
||||
begin
|
||||
p2:=ccallnode.create(nil,tprocsym(sym),sym.owner,p2);
|
||||
{ support dispose(p,done()); }
|
||||
if try_to_consume(_LKLAMMER) then
|
||||
begin
|
||||
if not try_to_consume(_RKLAMMER) then
|
||||
begin
|
||||
Message(parser_e_no_paras_for_destructor);
|
||||
consume_all_until(_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ we need the real called method }
|
||||
{ cleartempgen;}
|
||||
do_resulttypepass(p2);
|
||||
if not codegenerror then
|
||||
begin
|
||||
if is_new then
|
||||
begin
|
||||
if (tcallnode(p2).procdefinition.proctypeoption<>potype_constructor) then
|
||||
Message(parser_e_expr_have_to_be_constructor_call);
|
||||
p2:=cnewnode.create(p2);
|
||||
do_resulttypepass(p2);
|
||||
p2.resulttype:=p.resulttype;
|
||||
p2:=cassignmentnode.create(p,p2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (tcallnode(p2).procdefinition.proctypeoption<>potype_destructor) then
|
||||
Message(parser_e_expr_have_to_be_destructor_call);
|
||||
end;
|
||||
end;
|
||||
new_dispose_statement:=p2;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (p.resulttype.def.deftype<>pointerdef) then
|
||||
Begin
|
||||
Message1(type_e_pointer_type_expected,p.resulttype.def.typename);
|
||||
new_dispose_statement:=cerrornode.create;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (tpointerdef(p.resulttype.def).pointertype.def.deftype=objectdef) and
|
||||
(oo_has_vmt in tobjectdef(tpointerdef(p.resulttype.def).pointertype.def).objectoptions) then
|
||||
Message(parser_w_use_extended_syntax_for_objects);
|
||||
if (tpointerdef(p.resulttype.def).pointertype.def.deftype=orddef) and
|
||||
(torddef(tpointerdef(p.resulttype.def).pointertype.def).typ=uvoid) then
|
||||
begin
|
||||
if (m_tp in aktmodeswitches) or
|
||||
(m_delphi in aktmodeswitches) then
|
||||
Message(parser_w_no_new_dispose_on_void_pointers)
|
||||
else
|
||||
Message(parser_e_no_new_dispose_on_void_pointers);
|
||||
end;
|
||||
|
||||
if is_new then
|
||||
new_dispose_statement:=csimplenewdisposenode.create(simplenewn,p)
|
||||
else
|
||||
new_dispose_statement:=csimplenewdisposenode.create(simpledisposen,p);
|
||||
end;
|
||||
end;
|
||||
consume(_RKLAMMER);
|
||||
end;
|
||||
|
||||
|
||||
function new_function : tnode;
|
||||
var
|
||||
p1,p2 : tnode;
|
||||
classh : tobjectdef;
|
||||
sym : tsym;
|
||||
again : boolean; { dummy for do_proc_call }
|
||||
begin
|
||||
consume(_LKLAMMER);
|
||||
p1:=factor(false);
|
||||
if p1.nodetype<>typen then
|
||||
begin
|
||||
Message(type_e_type_id_expected);
|
||||
p1.destroy;
|
||||
p1:=cerrornode.create;
|
||||
do_resulttypepass(p1);
|
||||
end;
|
||||
|
||||
if (p1.resulttype.def.deftype<>pointerdef) then
|
||||
Message1(type_e_pointer_type_expected,p1.resulttype.def.typename)
|
||||
else
|
||||
if token=_RKLAMMER then
|
||||
begin
|
||||
if (tpointerdef(p1.resulttype.def).pointertype.def.deftype=objectdef) and
|
||||
(oo_has_vmt in tobjectdef(tpointerdef(p1.resulttype.def).pointertype.def).objectoptions) then
|
||||
Message(parser_w_use_extended_syntax_for_objects);
|
||||
p2:=cnewnode.create(nil);
|
||||
do_resulttypepass(p2);
|
||||
p2.resulttype:=p1.resulttype;
|
||||
p1.destroy;
|
||||
p1:=p2;
|
||||
consume(_RKLAMMER);
|
||||
end
|
||||
else
|
||||
begin
|
||||
p2:=chnewnode.create;
|
||||
do_resulttypepass(p2);
|
||||
p2.resulttype:=tpointerdef(p1.resulttype.def).pointertype;
|
||||
consume(_COMMA);
|
||||
afterassignment:=false;
|
||||
{ determines the current object defintion }
|
||||
classh:=tobjectdef(p2.resulttype.def);
|
||||
if classh.deftype<>objectdef then
|
||||
Message(parser_e_pointer_to_class_expected)
|
||||
else
|
||||
begin
|
||||
{ check for an abstract class }
|
||||
if (oo_has_abstract in classh.objectoptions) then
|
||||
Message(sym_e_no_instance_of_abstract_object);
|
||||
{ search the constructor also in the symbol tables of
|
||||
the parents }
|
||||
sym:=nil;
|
||||
while assigned(classh) do
|
||||
begin
|
||||
sym:=tsym(classh.symtable.search(pattern));
|
||||
if assigned(sym) then
|
||||
break;
|
||||
classh:=classh.childof;
|
||||
end;
|
||||
consume(_ID);
|
||||
do_member_read(false,sym,p2,again);
|
||||
{ we need to know which procedure is called }
|
||||
do_resulttypepass(p2);
|
||||
if (p2.nodetype<>calln) or
|
||||
(assigned(tcallnode(p2).procdefinition) and
|
||||
(tcallnode(p2).procdefinition.proctypeoption<>potype_constructor)) then
|
||||
Message(parser_e_expr_have_to_be_constructor_call);
|
||||
end;
|
||||
p2:=cnewnode.create(p2);
|
||||
do_resulttypepass(p2);
|
||||
p2.resulttype:=p1.resulttype;
|
||||
p1.destroy;
|
||||
p1:=p2;
|
||||
consume(_RKLAMMER);
|
||||
end;
|
||||
new_function:=p1;
|
||||
end;
|
||||
|
||||
|
||||
function statement_syssym(l : longint) : tnode;
|
||||
var
|
||||
p1,p2,paras : tnode;
|
||||
@ -224,6 +459,20 @@ implementation
|
||||
begin
|
||||
prev_in_args:=in_args;
|
||||
case l of
|
||||
|
||||
in_new_x :
|
||||
begin
|
||||
if afterassignment or in_args then
|
||||
statement_syssym:=new_function
|
||||
else
|
||||
statement_syssym:=new_dispose_statement(true);
|
||||
end;
|
||||
|
||||
in_dispose_x :
|
||||
begin
|
||||
statement_syssym:=new_dispose_statement(false);
|
||||
end;
|
||||
|
||||
in_ord_x :
|
||||
begin
|
||||
consume(_LKLAMMER);
|
||||
@ -1052,7 +1301,9 @@ implementation
|
||||
end;
|
||||
|
||||
syssym :
|
||||
p1:=statement_syssym(tsyssym(srsym).number);
|
||||
begin
|
||||
p1:=statement_syssym(tsyssym(srsym).number);
|
||||
end;
|
||||
|
||||
typesym :
|
||||
begin
|
||||
@ -1687,90 +1938,14 @@ implementation
|
||||
again:=false;
|
||||
if token=_ID then
|
||||
begin
|
||||
if idtoken=_NEW then
|
||||
begin
|
||||
consume(_NEW);
|
||||
consume(_LKLAMMER);
|
||||
p1:=factor(false);
|
||||
if p1.nodetype<>typen then
|
||||
begin
|
||||
Message(type_e_type_id_expected);
|
||||
p1.destroy;
|
||||
p1:=cerrornode.create;
|
||||
do_resulttypepass(p1);
|
||||
end;
|
||||
factor_read_id(p1,again);
|
||||
if again then
|
||||
begin
|
||||
check_tokenpos;
|
||||
|
||||
if (p1.resulttype.def.deftype<>pointerdef) then
|
||||
Message1(type_e_pointer_type_expected,p1.resulttype.def.typename)
|
||||
else
|
||||
if token=_RKLAMMER then
|
||||
begin
|
||||
if (tpointerdef(p1.resulttype.def).pointertype.def.deftype=objectdef) and
|
||||
(oo_has_vmt in tobjectdef(tpointerdef(p1.resulttype.def).pointertype.def).objectoptions) then
|
||||
Message(parser_w_use_extended_syntax_for_objects);
|
||||
p2:=cnewnode.create(nil);
|
||||
do_resulttypepass(p2);
|
||||
p2.resulttype:=p1.resulttype;
|
||||
p1.destroy;
|
||||
p1:=p2;
|
||||
consume(_RKLAMMER);
|
||||
end
|
||||
else
|
||||
begin
|
||||
p2:=chnewnode.create;
|
||||
do_resulttypepass(p2);
|
||||
p2.resulttype:=tpointerdef(p1.resulttype.def).pointertype;
|
||||
consume(_COMMA);
|
||||
afterassignment:=false;
|
||||
{ determines the current object defintion }
|
||||
classh:=tobjectdef(p2.resulttype.def);
|
||||
if classh.deftype<>objectdef then
|
||||
Message(parser_e_pointer_to_class_expected)
|
||||
else
|
||||
begin
|
||||
{ check for an abstract class }
|
||||
if (oo_has_abstract in classh.objectoptions) then
|
||||
Message(sym_e_no_instance_of_abstract_object);
|
||||
{ search the constructor also in the symbol tables of
|
||||
the parents }
|
||||
sym:=nil;
|
||||
while assigned(classh) do
|
||||
begin
|
||||
sym:=tsym(classh.symtable.search(pattern));
|
||||
if assigned(sym) then
|
||||
break;
|
||||
classh:=classh.childof;
|
||||
end;
|
||||
consume(_ID);
|
||||
do_member_read(false,sym,p2,again);
|
||||
{ we need to know which procedure is called }
|
||||
do_resulttypepass(p2);
|
||||
if (p2.nodetype<>calln) or
|
||||
(assigned(tcallnode(p2).procdefinition) and
|
||||
(tcallnode(p2).procdefinition.proctypeoption<>potype_constructor)) then
|
||||
Message(parser_e_expr_have_to_be_constructor_call);
|
||||
end;
|
||||
p2:=cnewnode.create(p2);
|
||||
do_resulttypepass(p2);
|
||||
p2.resulttype:=p1.resulttype;
|
||||
p1.destroy;
|
||||
p1:=p2;
|
||||
consume(_RKLAMMER);
|
||||
end;
|
||||
postfixoperators(p1,again);
|
||||
end
|
||||
else
|
||||
begin
|
||||
factor_read_id(p1,again);
|
||||
|
||||
if again then
|
||||
begin
|
||||
check_tokenpos;
|
||||
|
||||
{ handle post fix operators }
|
||||
postfixoperators(p1,again);
|
||||
end;
|
||||
end;
|
||||
{ handle post fix operators }
|
||||
postfixoperators(p1,again);
|
||||
end;
|
||||
end
|
||||
else
|
||||
case token of
|
||||
@ -2333,7 +2508,10 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.46 2001-10-21 13:10:51 peter
|
||||
Revision 1.47 2001-10-24 11:51:39 marco
|
||||
* Make new/dispose system functions instead of keywords
|
||||
|
||||
Revision 1.46 2001/10/21 13:10:51 peter
|
||||
* better support for indexed properties
|
||||
|
||||
Revision 1.45 2001/10/21 12:33:07 peter
|
||||
|
@ -873,171 +873,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function new_dispose_statement : tnode;
|
||||
var
|
||||
p,p2 : tnode;
|
||||
again : boolean; { dummy for do_proc_call }
|
||||
destructorname : stringid;
|
||||
sym : tsym;
|
||||
classh : tobjectdef;
|
||||
destructorpos,
|
||||
storepos : tfileposinfo;
|
||||
is_new : boolean;
|
||||
begin
|
||||
if try_to_consume(_NEW) then
|
||||
is_new:=true
|
||||
else
|
||||
begin
|
||||
consume(_DISPOSE);
|
||||
is_new:=false;
|
||||
end;
|
||||
consume(_LKLAMMER);
|
||||
p:=comp_expr(true);
|
||||
{ calc return type }
|
||||
cleartempgen;
|
||||
set_varstate(p,(not is_new));
|
||||
{ constructor,destructor specified }
|
||||
if try_to_consume(_COMMA) then
|
||||
begin
|
||||
{ extended syntax of new and dispose }
|
||||
{ function styled new is handled in factor }
|
||||
{ destructors have no parameters }
|
||||
destructorname:=pattern;
|
||||
destructorpos:=akttokenpos;
|
||||
consume(_ID);
|
||||
|
||||
if (p.resulttype.def.deftype<>pointerdef) then
|
||||
begin
|
||||
Message1(type_e_pointer_type_expected,p.resulttype.def.typename);
|
||||
p.free;
|
||||
p:=factor(false);
|
||||
p.free;
|
||||
consume(_RKLAMMER);
|
||||
new_dispose_statement:=cerrornode.create;
|
||||
exit;
|
||||
end;
|
||||
{ first parameter must be an object or class }
|
||||
if tpointerdef(p.resulttype.def).pointertype.def.deftype<>objectdef then
|
||||
begin
|
||||
Message(parser_e_pointer_to_class_expected);
|
||||
p.free;
|
||||
new_dispose_statement:=factor(false);
|
||||
consume_all_until(_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
exit;
|
||||
end;
|
||||
{ check, if the first parameter is a pointer to a _class_ }
|
||||
classh:=tobjectdef(tpointerdef(p.resulttype.def).pointertype.def);
|
||||
if is_class(classh) then
|
||||
begin
|
||||
Message(parser_e_no_new_or_dispose_for_classes);
|
||||
new_dispose_statement:=factor(false);
|
||||
consume_all_until(_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
exit;
|
||||
end;
|
||||
{ search cons-/destructor, also in parent classes }
|
||||
storepos:=akttokenpos;
|
||||
akttokenpos:=destructorpos;
|
||||
sym:=search_class_member(classh,destructorname);
|
||||
akttokenpos:=storepos;
|
||||
|
||||
{ the second parameter of new/dispose must be a call }
|
||||
{ to a cons-/destructor }
|
||||
if (not assigned(sym)) or (sym.typ<>procsym) then
|
||||
begin
|
||||
if is_new then
|
||||
Message(parser_e_expr_have_to_be_constructor_call)
|
||||
else
|
||||
Message(parser_e_expr_have_to_be_destructor_call);
|
||||
p.free;
|
||||
new_dispose_statement:=cerrornode.create;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if is_new then
|
||||
p2:=chnewnode.create
|
||||
else
|
||||
p2:=chdisposenode.create(p);
|
||||
do_resulttypepass(p2);
|
||||
p2.resulttype:=tpointerdef(p.resulttype.def).pointertype;
|
||||
if is_new then
|
||||
do_member_read(false,sym,p2,again)
|
||||
else
|
||||
begin
|
||||
if (m_tp in aktmodeswitches) then
|
||||
do_member_read(false,sym,p2,again)
|
||||
else
|
||||
begin
|
||||
p2:=ccallnode.create(nil,tprocsym(sym),sym.owner,p2);
|
||||
{ support dispose(p,done()); }
|
||||
if try_to_consume(_LKLAMMER) then
|
||||
begin
|
||||
if not try_to_consume(_RKLAMMER) then
|
||||
begin
|
||||
Message(parser_e_no_paras_for_destructor);
|
||||
consume_all_until(_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ we need the real called method }
|
||||
cleartempgen;
|
||||
do_resulttypepass(p2);
|
||||
if not codegenerror then
|
||||
begin
|
||||
if is_new then
|
||||
begin
|
||||
if (tcallnode(p2).procdefinition.proctypeoption<>potype_constructor) then
|
||||
Message(parser_e_expr_have_to_be_constructor_call);
|
||||
p2:=cnewnode.create(p2);
|
||||
do_resulttypepass(p2);
|
||||
p2.resulttype:=p.resulttype;
|
||||
p2:=cassignmentnode.create(p,p2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (tcallnode(p2).procdefinition.proctypeoption<>potype_destructor) then
|
||||
Message(parser_e_expr_have_to_be_destructor_call);
|
||||
end;
|
||||
end;
|
||||
new_dispose_statement:=p2;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (p.resulttype.def.deftype<>pointerdef) then
|
||||
Begin
|
||||
Message1(type_e_pointer_type_expected,p.resulttype.def.typename);
|
||||
new_dispose_statement:=cerrornode.create;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (tpointerdef(p.resulttype.def).pointertype.def.deftype=objectdef) and
|
||||
(oo_has_vmt in tobjectdef(tpointerdef(p.resulttype.def).pointertype.def).objectoptions) then
|
||||
Message(parser_w_use_extended_syntax_for_objects);
|
||||
if (tpointerdef(p.resulttype.def).pointertype.def.deftype=orddef) and
|
||||
(torddef(tpointerdef(p.resulttype.def).pointertype.def).typ=uvoid) then
|
||||
begin
|
||||
if (m_tp in aktmodeswitches) or
|
||||
(m_delphi in aktmodeswitches) then
|
||||
Message(parser_w_no_new_dispose_on_void_pointers)
|
||||
else
|
||||
Message(parser_e_no_new_dispose_on_void_pointers);
|
||||
end;
|
||||
|
||||
if is_new then
|
||||
new_dispose_statement:=csimplenewdisposenode.create(simplenewn,p)
|
||||
else
|
||||
new_dispose_statement:=csimplenewdisposenode.create(simpledisposen,p);
|
||||
end;
|
||||
end;
|
||||
consume(_RKLAMMER);
|
||||
end;
|
||||
|
||||
|
||||
function statement : tnode;
|
||||
var
|
||||
p : tnode;
|
||||
@ -1114,36 +949,34 @@ implementation
|
||||
Message(scan_f_end_of_file);
|
||||
else
|
||||
begin
|
||||
if (idtoken=_NEW) or (idtoken=_DISPOSE) then
|
||||
code:=new_dispose_statement
|
||||
else
|
||||
begin
|
||||
p:=expr;
|
||||
p:=expr;
|
||||
|
||||
if p.nodetype=labeln then
|
||||
begin
|
||||
{ the pointer to the following instruction }
|
||||
{ isn't a very clean way }
|
||||
tlabelnode(p).left:=statement{$ifdef FPCPROCVAR}(){$endif};
|
||||
{ be sure to have left also resulttypepass }
|
||||
resulttypepass(tlabelnode(p).left);
|
||||
end;
|
||||
if p.nodetype=labeln then
|
||||
begin
|
||||
{ the pointer to the following instruction }
|
||||
{ isn't a very clean way }
|
||||
tlabelnode(p).left:=statement{$ifdef FPCPROCVAR}(){$endif};
|
||||
{ be sure to have left also resulttypepass }
|
||||
resulttypepass(tlabelnode(p).left);
|
||||
end;
|
||||
|
||||
{ blockn support because a read/write is changed into a blocknode }
|
||||
{ with a separate statement for each read/write operation (JM) }
|
||||
{ the same is true for val() if the third parameter is not 32 bit }
|
||||
if not(p.nodetype in [calln,assignn,breakn,inlinen,continuen,labeln,blockn]) then
|
||||
Message(cg_e_illegal_expression);
|
||||
{ specify that we don't use the value returned by the call }
|
||||
{ Question : can this be also improtant
|
||||
for inlinen ??
|
||||
it is used for :
|
||||
- dispose of temp stack space
|
||||
- dispose on FPU stack }
|
||||
if p.nodetype=calln then
|
||||
exclude(p.flags,nf_return_value_used);
|
||||
code:=p;
|
||||
end;
|
||||
{ blockn support because a read/write is changed into a blocknode }
|
||||
{ with a separate statement for each read/write operation (JM) }
|
||||
{ the same is true for val() if the third parameter is not 32 bit }
|
||||
if not(p.nodetype in [calln,assignn,breakn,inlinen,continuen,labeln,blockn,
|
||||
simplenewn,simpledisposen]) then
|
||||
Message(cg_e_illegal_expression);
|
||||
|
||||
{ specify that we don't use the value returned by the call }
|
||||
{ Question : can this be also improtant
|
||||
for inlinen ??
|
||||
it is used for :
|
||||
- dispose of temp stack space
|
||||
- dispose on FPU stack }
|
||||
if p.nodetype=calln then
|
||||
exclude(p.flags,nf_return_value_used);
|
||||
|
||||
code:=p;
|
||||
end;
|
||||
end;
|
||||
if assigned(code) then
|
||||
@ -1282,7 +1115,10 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.39 2001-10-17 22:41:04 florian
|
||||
Revision 1.40 2001-10-24 11:51:39 marco
|
||||
* Make new/dispose system functions instead of keywords
|
||||
|
||||
Revision 1.39 2001/10/17 22:41:04 florian
|
||||
* several widechar fixes, case works now
|
||||
|
||||
Revision 1.38 2001/10/16 15:10:35 jonas
|
||||
|
@ -76,6 +76,8 @@ begin
|
||||
p.insert(tsyssym.create('SetLength',in_setlength_x));
|
||||
p.insert(tsyssym.create('Finalize',in_finalize_x));
|
||||
p.insert(tsyssym.create('Length',in_length_x));
|
||||
p.insert(tsyssym.create('New',in_new_x));
|
||||
p.insert(tsyssym.create('Dispose',in_dispose_x));
|
||||
end;
|
||||
|
||||
|
||||
@ -275,7 +277,10 @@ end;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.19 2001-08-30 20:13:53 peter
|
||||
Revision 1.20 2001-10-24 11:51:39 marco
|
||||
* Make new/dispose system functions instead of keywords
|
||||
|
||||
Revision 1.19 2001/08/30 20:13:53 peter
|
||||
* rtti/init table updates
|
||||
* rttisym for reusable global rtti/init info
|
||||
* support published for interfaces
|
||||
|
@ -106,7 +106,6 @@ type
|
||||
_FAR,
|
||||
_FOR,
|
||||
_MOD,
|
||||
_NEW,
|
||||
_NIL,
|
||||
_NOT,
|
||||
_OUT,
|
||||
@ -167,7 +166,6 @@ type
|
||||
_ASMNAME,
|
||||
_CPPDECL,
|
||||
_DEFAULT,
|
||||
_DISPOSE,
|
||||
_DYNAMIC,
|
||||
_EXPORTS,
|
||||
_FINALLY,
|
||||
@ -331,7 +329,6 @@ const
|
||||
(str:'FAR' ;special:false;keyword:m_none;op:NOTOKEN),
|
||||
(str:'FOR' ;special:false;keyword:m_all;op:NOTOKEN),
|
||||
(str:'MOD' ;special:false;keyword:m_all;op:_OP_MOD),
|
||||
(str:'NEW' ;special:false;keyword:m_none;op:NOTOKEN),
|
||||
(str:'NIL' ;special:false;keyword:m_all;op:NOTOKEN),
|
||||
(str:'NOT' ;special:false;keyword:m_all;op:_OP_NOT),
|
||||
(str:'OUT' ;special:false;keyword:m_none;op:NOTOKEN),
|
||||
@ -392,7 +389,6 @@ const
|
||||
(str:'ASMNAME' ;special:false;keyword:m_none;op:NOTOKEN),
|
||||
(str:'CPPDECL' ;special:false;keyword:m_none;op:NOTOKEN),
|
||||
(str:'DEFAULT' ;special:false;keyword:m_none;op:NOTOKEN),
|
||||
(str:'DISPOSE' ;special:false;keyword:m_all;op:NOTOKEN),
|
||||
(str:'DYNAMIC' ;special:false;keyword:m_none;op:NOTOKEN),
|
||||
(str:'EXPORTS' ;special:false;keyword:m_all;op:NOTOKEN),
|
||||
(str:'FINALLY' ;special:false;keyword:m_class;op:NOTOKEN),
|
||||
@ -501,7 +497,10 @@ end;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.14 2001-10-23 21:49:43 peter
|
||||
Revision 1.15 2001-10-24 11:51:39 marco
|
||||
* Make new/dispose system functions instead of keywords
|
||||
|
||||
Revision 1.14 2001/10/23 21:49:43 peter
|
||||
* $calling directive and -Cc commandline patch added
|
||||
from Pavel Ozerski
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user