Patch title: Release 91 bulk changes
Abstract:
File: /language/basic/extend.c
Key:
    Removed line
    Added line
   
// Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx
//
// This program is free software; you can redistribute it an
// modify it under the terms of the GNU General Public Licen
// as published by the Free Software Foundation.
// 
// This program is distributed in the hope that it will be u
// but WITHOUT ANY WARRANTY; without even the implied warran
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// version 2 along with this program; if not, write to the F
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA


static Void set_flag_meta(struct Expression *e,Int flag) {
// Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx
//
// This program is free software; you can redistribute it an
// modify it under the terms of the GNU General Public Licen
// as published by the Free Software Foundation.
// 
// This program is distributed in the hope that it will be u
// but WITHOUT ANY WARRANTY; without even the implied warran
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// version 2 along with this program; if not, write to the F
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA


static Void set_flag_meta(struct Expression *e,Int flag) {
  struct Function *f;
  if(e->arguments.nb!=0) return;
  if(e->arguments.nb!=0) return;
  current_function()->flags|=flag;
  f=current_function();
  f->flags|=flag;
  if(f->flags&Function_flag_has_no_side_effect)
    f->flags&=~Function_flag_has_side_effects;
  Expression_set_void_result(e); }


static Void function_meta2(struct Expression *e,Bool method)
  struct Function *function,*later; struct List hidden;
  struct Module *module; Address mark;
  struct Array *arguments; struct List *locals;
  struct GeneratorContext *gc;
  struct Expression *body;
  Int nb_arg,nb_res; Bool method_set;
  Int i,j; struct Argument *barg; struct LocalVariable *farg
  struct Relation relation; struct Instruction *i1,*i2; Arro
  struct Str *name; struct Str temp;
  #ifdef _TIMER_
    Int old;
  #endif
  #ifdef _CHECK_
    Char buffer1[16],buffer2[16]; struct Str temp2;
  #endif
  if(e->arguments.nb<(method ? 3 : 2))
    return;
  for(i=0; i<e->arguments.nb-1; i++)
    if(Expression_pure_ident(EARG(e,i))==null) return;
  if(compare_str((struct Str *)EARG(e,e->arguments.nb-1)->va
  module=e->module; check(module!=null);
  function=entry_new(G.type_Function);
  Str_concat(&function->name,Z,method && Str_len((struct Str
  function->flags|=G.default_function_flags|Function_flag_un
  ListingPosition_copy(&e->position,&function->position);
  List_build(&hidden);
  for(r=Module_first(module,&function->name); r!=G.null_cons
    later=(struct Function *)*r;
    if(entry_type(later)==G.type_Function && (later->flags&F
      later->flags|=Function_flag_hidden;
      List_append(&hidden,later); } }
  Expression_define(e,&function->name,function,Module_actual
  nb_arg=e->arguments.nb-2,nb_res=0,method_set=false;
  if(nb_arg>=(method ? 3 : 2) && compare_str((struct Str *)E
    nb_arg-=2,nb_res=1;
  if(method && nb_arg>=2 && compare_str((struct Str *)EARG(e
    nb_arg--,method_set=true;
    Str_concat(&function->name,S,&function->name,Z," :=",END
  Function_define_arguments_prototypes(function,nb_arg,nb_re
  mark=Module_mark(module);
  Module_define(module,Str_map_string(&temp,"pliant function
  arguments=(struct Array *)entry_new(G.type_Array);
  Array_resize(arguments,nb_arg+nb_res);
  Module_define(module,Str_map_string(&temp,"pliant argument
  locals=(struct List *)entry_new(G.type_List);
  Module_define(module,Str_map_string(&temp,"pliant locals")
  for(i=0; i<nb_arg+nb_res; i++) {
    if(method && i==0)
      j=0;
    eif(method_set && i==nb_arg-1)
      j=i+2;
    eif(i<nb_arg)
      j=i+1;
    else
      j=e->arguments.nb-2;
    name=(struct Str *)Expression_pure_ident(EARG(e,j));
    Str_copy(name,&function->arguments[i].name);
    barg=(struct Argument *)entry_new(G.type_Argument);
    Str_copy(name,&barg->name);
    farg=(struct LocalVariable *)entry_new(G.type_LocalVaria
    Str_copy(name,&farg->name);
    farg->function=function;
    Arrow_set((Arrow *)&farg->body,barg);
    Module_define(module,name,farg);
    Array_set_index(arguments,i,barg);
    List_append(locals,farg); }
  body=EARG(e,e->arguments.nb-1);
  Expression_compile(body);
  if(!error_notified())
    for(i=0; i<nb_arg+nb_res; i++)
      if(function->arguments[i].type==null) {
       error_notifyn(error_id_compile,Z,"Type of parameter "
        break; }
  if((function->flags&Function_flag_inline_instructions) && 
    Relation_build(&relation); Relation_set_flags(&relation,
    for(i=0; i<nb_arg+nb_res; i++)
      Arrow_set((Arrow *)&function->arguments[i].inline_argu
    for(r=List_first(&body->instructions); *r!=null; r=List_
      i1=Instruction_copy((struct Instruction *)*r,&relation
      List_append(&function->inline_instructions,i1); }
    i1=instruction(G.function_do_nothing,END);
    List_append(&function->inline_instructions,i1);
    Relation_define(&relation,(Address)-1,null,i1);
    for(r=List_first(&function->inline_instructions); r!=G.n
      i2=(struct Instruction *)*r;
      if(i2->jump==null) continue;
      i2->jump=Relation_query(&relation,i2->jump,null); chec
    Relation_destroy(&relation); }
  if(function->exe==null) {
    if(!error_notified()) {
      Function_terminate_arguments_prototypes(function,0);
      #ifdef _TIMER_
        old=timer_set(timer_optimize);
      #endif
      gc=(struct GeneratorContext *)entry_new(G.type_Generat
      if((function->flags&Function_flag_generic) && nb_arg==
        error_notifyn(error_id_compile,Z,"Generic function "
      GeneratorContext_setup(gc,body,function);
      GeneratorContext_optimize(gc);
      entry_unlock(gc);
      #ifdef _TIMER_
        timer_set(old);
      #endif
  Expression_set_void_result(e); }


static Void function_meta2(struct Expression *e,Bool method)
  struct Function *function,*later; struct List hidden;
  struct Module *module; Address mark;
  struct Array *arguments; struct List *locals;
  struct GeneratorContext *gc;
  struct Expression *body;
  Int nb_arg,nb_res; Bool method_set;
  Int i,j; struct Argument *barg; struct LocalVariable *farg
  struct Relation relation; struct Instruction *i1,*i2; Arro
  struct Str *name; struct Str temp;
  #ifdef _TIMER_
    Int old;
  #endif
  #ifdef _CHECK_
    Char buffer1[16],buffer2[16]; struct Str temp2;
  #endif
  if(e->arguments.nb<(method ? 3 : 2))
    return;
  for(i=0; i<e->arguments.nb-1; i++)
    if(Expression_pure_ident(EARG(e,i))==null) return;
  if(compare_str((struct Str *)EARG(e,e->arguments.nb-1)->va
  module=e->module; check(module!=null);
  function=entry_new(G.type_Function);
  Str_concat(&function->name,Z,method && Str_len((struct Str
  function->flags|=G.default_function_flags|Function_flag_un
  ListingPosition_copy(&e->position,&function->position);
  List_build(&hidden);
  for(r=Module_first(module,&function->name); r!=G.null_cons
    later=(struct Function *)*r;
    if(entry_type(later)==G.type_Function && (later->flags&F
      later->flags|=Function_flag_hidden;
      List_append(&hidden,later); } }
  Expression_define(e,&function->name,function,Module_actual
  nb_arg=e->arguments.nb-2,nb_res=0,method_set=false;
  if(nb_arg>=(method ? 3 : 2) && compare_str((struct Str *)E
    nb_arg-=2,nb_res=1;
  if(method && nb_arg>=2 && compare_str((struct Str *)EARG(e
    nb_arg--,method_set=true;
    Str_concat(&function->name,S,&function->name,Z," :=",END
  Function_define_arguments_prototypes(function,nb_arg,nb_re
  mark=Module_mark(module);
  Module_define(module,Str_map_string(&temp,"pliant function
  arguments=(struct Array *)entry_new(G.type_Array);
  Array_resize(arguments,nb_arg+nb_res);
  Module_define(module,Str_map_string(&temp,"pliant argument
  locals=(struct List *)entry_new(G.type_List);
  Module_define(module,Str_map_string(&temp,"pliant locals")
  for(i=0; i<nb_arg+nb_res; i++) {
    if(method && i==0)
      j=0;
    eif(method_set && i==nb_arg-1)
      j=i+2;
    eif(i<nb_arg)
      j=i+1;
    else
      j=e->arguments.nb-2;
    name=(struct Str *)Expression_pure_ident(EARG(e,j));
    Str_copy(name,&function->arguments[i].name);
    barg=(struct Argument *)entry_new(G.type_Argument);
    Str_copy(name,&barg->name);
    farg=(struct LocalVariable *)entry_new(G.type_LocalVaria
    Str_copy(name,&farg->name);
    farg->function=function;
    Arrow_set((Arrow *)&farg->body,barg);
    Module_define(module,name,farg);
    Array_set_index(arguments,i,barg);
    List_append(locals,farg); }
  body=EARG(e,e->arguments.nb-1);
  Expression_compile(body);
  if(!error_notified())
    for(i=0; i<nb_arg+nb_res; i++)
      if(function->arguments[i].type==null) {
       error_notifyn(error_id_compile,Z,"Type of parameter "
        break; }
  if((function->flags&Function_flag_inline_instructions) && 
    Relation_build(&relation); Relation_set_flags(&relation,
    for(i=0; i<nb_arg+nb_res; i++)
      Arrow_set((Arrow *)&function->arguments[i].inline_argu
    for(r=List_first(&body->instructions); *r!=null; r=List_
      i1=Instruction_copy((struct Instruction *)*r,&relation
      List_append(&function->inline_instructions,i1); }
    i1=instruction(G.function_do_nothing,END);
    List_append(&function->inline_instructions,i1);
    Relation_define(&relation,(Address)-1,null,i1);
    for(r=List_first(&function->inline_instructions); r!=G.n
      i2=(struct Instruction *)*r;
      if(i2->jump==null) continue;
      i2->jump=Relation_query(&relation,i2->jump,null); chec
    Relation_destroy(&relation); }
  if(function->exe==null) {
    if(!error_notified()) {
      Function_terminate_arguments_prototypes(function,0);
      #ifdef _TIMER_
        old=timer_set(timer_optimize);
      #endif
      gc=(struct GeneratorContext *)entry_new(G.type_Generat
      if((function->flags&Function_flag_generic) && nb_arg==
        error_notifyn(error_id_compile,Z,"Generic function "
      GeneratorContext_setup(gc,body,function);
      GeneratorContext_optimize(gc);
      entry_unlock(gc);
      #ifdef _TIMER_
        timer_set(old);
      #endif
      Function_watch_generic(function);
      if(function->flags&Function_flag_has_no_side_effect)
        function->flags&=~Function_flag_has_side_effects; }
      Function_watch_generic(function); }
  other
    check(function->flags&(Function_flag_inline_binary|Funct
    check(!(function->flags&Function_flag_inline_instruction
  Module_rewind(module,mark); 
  for(r=List_first(&hidden); r!=G.null_constant; r=List_next
    later=(struct Function *)*r; check(entry_type(later)==G.
    later->flags&=~Function_flag_hidden; }
  List_destroy(&hidden);
  if(error_notified()) {
    Str_build(&temp); Str_copy(&function->name,&temp);
    Dictionary_remove(G.general_dictionary,&temp,function);
    Str_destroy(&temp);
    return; }
  for(r=Module_first(module,&function->name); r!=G.null_cons
    r2=Module_next(module,&function->name,r);
    later=(struct Function *)*r;
    if(entry_type(later)==G.type_Function && (later->flags&(
      Function_update_uses(later,function);
      if((later->flags&Function_flag_later) && later!=functi
        Arrow_set(&later->externals,null);
        Dictionary_remove(G.general_dictionary,&function->na
  function->flags&=~Function_flag_under_construction;
  Expression_set_result(e,argument(G.type_Function,Argument_
  #ifdef _TIMER_
    bytes_count+=function->exe_size;
  #endif
  #ifdef _CHECK_
    if(G.verbose_level>=3) {
      struct Str s;
      Str_build(&s);
      ListingPosition_get(&function->position,&s);
      consolen(Z,"function ",S,&function->name,Z," at ",S,&s
      Str_destroy(&s); }
  #endif
  }



  other
    check(function->flags&(Function_flag_inline_binary|Funct
    check(!(function->flags&Function_flag_inline_instruction
  Module_rewind(module,mark); 
  for(r=List_first(&hidden); r!=G.null_constant; r=List_next
    later=(struct Function *)*r; check(entry_type(later)==G.
    later->flags&=~Function_flag_hidden; }
  List_destroy(&hidden);
  if(error_notified()) {
    Str_build(&temp); Str_copy(&function->name,&temp);
    Dictionary_remove(G.general_dictionary,&temp,function);
    Str_destroy(&temp);
    return; }
  for(r=Module_first(module,&function->name); r!=G.null_cons
    r2=Module_next(module,&function->name,r);
    later=(struct Function *)*r;
    if(entry_type(later)==G.type_Function && (later->flags&(
      Function_update_uses(later,function);
      if((later->flags&Function_flag_later) && later!=functi
        Arrow_set(&later->externals,null);
        Dictionary_remove(G.general_dictionary,&function->na
  function->flags&=~Function_flag_under_construction;
  Expression_set_result(e,argument(G.type_Function,Argument_
  #ifdef _TIMER_
    bytes_count+=function->exe_size;
  #endif
  #ifdef _CHECK_
    if(G.verbose_level>=3) {
      struct Str s;
      Str_build(&s);
      ListingPosition_get(&function->position,&s);
      consolen(Z,"function ",S,&function->name,Z," at ",S,&s
      Str_destroy(&s); }
  #endif
  }