pike.git / src / las.c

version» Context lines:

pike.git/src/las.c:1:   /*\   ||| This file a part of Pike, and is copyright by Fredrik Hubinette   ||| Pike is distributed as GPL (General Public License)   ||| See the files COPYING and DISCLAIMER for more information.   \*/   /**/   #include "global.h" - RCSID("$Id: las.c,v 1.267 2001/09/24 17:01:41 grubba Exp $"); + RCSID("$Id: las.c,v 1.268 2001/09/28 00:01:45 hubbe Exp $");      #include "language.h"   #include "interpret.h"   #include "las.h"   #include "array.h"   #include "object.h"   #include "stralloc.h"   #include "dynamic_buffer.h"   #include "lex.h"   #include "pike_types.h"
pike.git/src/las.c:844:    res->type=0;    res->name=0;    res->node_info=0;    res->tree_info=0;    res->parent=0;    return res;   }      #define mkemptynode() dmalloc_touch(node *, debug_mkemptynode())    +  + static int is_automap_arg_list(node *n) + { +  if(!n) return 0; +  switch(n->token) +  { +  default: return 0; +  case F_ARG_LIST: +  return is_automap_arg_list(CAR(n)) || +  is_automap_arg_list(CDR(n)); +  +  case F_AUTO_MAP_MARKER: return 1; +  } + } +  +    node *debug_mknode(short token, node *a, node *b)   {    node *res;    -  +  switch(token) +  { +  case F_APPLY: +  if(is_automap_arg_list(b)) +  token=F_AUTO_MAP; +  break; +  +  case F_INDEX: +  switch((is_automap_arg_list(a) << 1) | +  is_automap_arg_list(b)) +  { +  case 1: +  res=mkefuncallnode("rows",mknode(F_ARG_LIST,a,copy_node(CAR(b)))); +  free_node(b); +  return res; +  +  case 2: +  res=mkefuncallnode("column",mknode(F_ARG_LIST,copy_node(CAR(a)),b)); +  free_node(a); +  return res; +  +  case 3: +  return mkefuncallnode("`[]",mknode(F_ARG_LIST,a,b)); +  } +  } +    #if defined(PIKE_DEBUG) && !defined(SHARED_NODES)    if(b && a==b)    fatal("mknode: a and be are the same!\n");    if ((token == F_CAST) || (token == F_SOFT_CAST))    fatal("Attempt to create a cast-node with mknode()!\n");   #endif       check_tree(a,0);    check_tree(b,0);   
pike.git/src/las.c:882:       switch(token)    {    case F_CATCH:    res->node_info |= OPT_SIDE_EFFECT;    if (a) {    res->tree_info |= a->tree_info & ~OPT_BREAK;    }    break;    +  case F_AUTO_MAP:    case F_APPLY:    {    unsigned INT16 opt_flags = OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND;    struct identifier *i = NULL;       if (a) {    switch(a->token) {    case F_CONSTANT:    switch(a->u.sval.type)    {
pike.git/src/las.c:1163:      node *debug_mkapplynode(node *func,node *args)   {    return mknode(F_APPLY, func, args);   }      node *debug_mkefuncallnode(char *function, node *args)   {    struct pike_string *name;    node *n; -  name = findstring(function); +  name = make_shared_string(function);    if(!name || !(n=find_module_identifier(name,0)))    { -  +  free_string(name);    my_yyerror("Internally used efun undefined: %s",function);    return mkintnode(0);    } -  +  free_string(name);    n = mkapplynode(n, args);    return n;   }      node *debug_mkopernode(char *oper_id, node *arg1, node *arg2)   {    if(arg1 && arg2)    arg1=mknode(F_ARG_LIST,arg1,arg2);       return mkefuncallnode(oper_id, arg1);
pike.git/src/las.c:1618: Inside #if defined(SHARED_NODES)
   {    n=defrost_node(n);    _CAR(n)=tmp;    n=freeze_node(n);    }   #else    _CAR(n)=tmp;   #endif    break;    +  case F_AUTO_MAP:    case F_APPLY:    if(CAR(n)->token == F_CONSTANT &&    CAR(n)->u.sval.type == T_FUNCTION &&    CAR(n)->u.sval.subtype == FUNCTION_BUILTIN &&    CAR(n)->u.sval.u.efun->name &&    CAR(n)->u.sval.u.efun->name->str[0]=='`')    {    /* FALL THROUGH */    }else{    tmp=mknode(F_ARG_LIST, CDR(n), arg);
pike.git/src/las.c:2232:       return 0;   }      node **my_get_arg(node **a,int n) { return low_get_arg(a,&n); }      node **is_call_to(node *n, c_fun f)   {    switch(n->token)    { +  case F_AUTO_MAP:    case F_APPLY:    if(CAR(n) &&    CAR(n)->token == F_CONSTANT &&    CAR(n)->u.sval.type == T_FUNCTION &&    CAR(n)->u.sval.subtype == FUNCTION_BUILTIN &&    CAR(n)->u.sval.u.efun->function == f)    return &_CDR(n);    }    return 0;   }
pike.git/src/las.c:2415:    free(s);    break;    }       case F_VAL_LVAL:    low_print_tree(_CAR(foo),0);    fprintf(stderr, ",&");    low_print_tree(_CDR(foo),0);    return;    +  case F_AUTO_MAP: +  fprintf(stderr, "__automap__ "); +  low_print_tree(_CAR(foo),0); +  fprintf(stderr, "("); +  low_print_tree(_CDR(foo),0); +  fprintf(stderr, ")"); +  return; +  case F_AUTO_MAP_MARKER: +  low_print_tree(_CAR(foo),0); +  fprintf(stderr, "[*]"); +  return;    case F_APPLY:    low_print_tree(_CAR(foo),0);    fprintf(stderr, "(");    low_print_tree(_CDR(foo),0);    fprintf(stderr, ")");    return;       case F_NORMAL_STMT_LABEL:    case F_CUSTOM_STMT_LABEL:    fprintf(stderr, "%s:", _CAR(foo)->u.sval.u.string->str);
pike.git/src/las.c:2833: Inside #if defined(PIKE_DEBUG)
   fprintf(stderr, "external %d:%d is written\n",    Pike_compiler->new_program->id, n->u.id.number);    }   #endif /* PIKE_DEBUG */    *find_q(&(p->externals), n->u.id.number,    Pike_compiler->new_program->id) = VAR_USED;    }    break;       case F_APPLY: +  case F_AUTO_MAP:    if(n->tree_info & OPT_SIDE_EFFECT) {    p->ext_flags = VAR_USED;    }    break;    -  +  case F_AUTO_MAP_MARKER: +  find_written_vars(CAR(n), p, lvalue); +  break; +     case F_INDEX:    case F_ARROW:    find_written_vars(CAR(n), p, lvalue);    find_written_vars(CDR(n), p, 0);    break;       case F_INC:    case F_DEC:    case F_POST_INC:    case F_POST_DEC:
pike.git/src/las.c:3237:    if (!CAR(n) || (CAR(n)->type == void_type_string)) {    my_yyerror("Assigning a void expression.");    copy_pike_type(n->type, void_type_string);    break;    } else if(CAR(n) && CDR(n)) {    /* Ensure that the type-fields are up to date. */    fix_type_field(CAR(n));    fix_type_field(CDR(n));    if (!pike_types_le(CAR(n)->type, CDR(n)->type)) {    /* a["b"]=c and a->b=c can be valid when a is an array */ -  if (CDR(n)->token != F_INDEX && CDR(n)->token != F_ARROW && +  if (CDR(n)->token != F_INDEX && +  CDR(n)->token != F_ARROW &&    !match_types(CDR(n)->type,CAR(n)->type)) {    yytype_error("Bad type in assignment.",    CDR(n)->type, CAR(n)->type, 0);    } else if (lex.pragmas & ID_STRICT_TYPES) {    struct pike_string *t1 = describe_type(CAR(n)->type);    struct pike_string *t2 = describe_type(CDR(n)->type);   #ifdef PIKE_DEBUG    if (l_flag > 0) {    fprintf(stderr, "Warning: Invalid assignment: ");    print_tree(n);
pike.git/src/las.c:3277:    } else {    type_a=CAR(n)->type;    type_b=CDR(n)->type;    if(!check_indexing(type_a, type_b, n))    if(!Pike_compiler->catch_level)    my_yyerror("Indexing on illegal type.");    n->type=index_type(type_a, type_b,n);    }    break;    +  case F_AUTO_MAP_MARKER: +  if (!CAR(n) || (CAR(n)->type == void_type_string)) { +  my_yyerror("Indexing a void expression."); +  /* The optimizer converts this to an expression returning 0. */ +  copy_pike_type(n->type, zero_type_string); +  } else { +  type_a=CAR(n)->type; +  if(!check_indexing(type_a, int_type_string, n)) +  if(!Pike_compiler->catch_level) +  my_yyerror("[*] on non-array."); +  n->type=index_type(type_a, int_type_string, n); +  } +  break; +  +  case F_AUTO_MAP:    case F_APPLY:    if (!CAR(n) || (CAR(n)->type == void_type_string)) {    my_yyerror("Calling a void expression.");    } else {    struct pike_type *f; /* Expected type. */    struct pike_type *s; /* Actual type */    char *name;    INT32 max_args,args;      #if defined(USE_PIKE_TYPE) && defined(NEW_ARG_CHECK)       args = 0;       copy_pike_type(f, CAR(n)->type);       f = new_check_call(CAR(n), &args, f, CDR(n));       if (f && (n->type = get_ret_type(f))) {    /* Type/argument-check OK. */    free_type(f); -  +  if(n->token == F_AUTO_MAP) +  { +  push_finished_type(n->type); +  push_type(T_ARRAY); +  free_type(n->type); +  n->type = pop_type(); +  }    break;    }      #else /* !(USE_PIKE_TYPE && NEW_ARG_CHECK) */       push_type(T_MIXED); /* match any return type */    push_type(T_VOID); /* even void */    push_type(T_OR);       push_type(T_VOID); /* not varargs */
pike.git/src/las.c:3326:    (lex.pragmas & ID_STRICT_TYPES) &&    !(n->node_info & OPT_WEAK_TYPE));    args = count_arguments(s);    max_args = count_arguments(f);    if(max_args<0) max_args = 0x7fffffff;          if (n->type) {    /* Type/argument-check OK. */    free_type(s); +  +  if(n->token == F_AUTO_MAP) +  { +  push_finished_type(n->type); +  push_type(T_ARRAY); +  free_type(n->type); +  n->type = pop_type(); +  } +     break;    }       switch(CAR(n)->token)    {   #if 0 /* FIXME */    case F_TRAMPOLINE:   #endif    case F_IDENTIFIER:    name=ID_FROM_INT(Pike_compiler->new_program, CAR(n)->u.id.number)->name->str;
pike.git/src/las.c:4024: Inside #if defined(SHARED_NODES) && !defined(IN_TPIKE)
   int i;       MEMCPY(catch_usage, usage, MAX_LOCAL);    find_usage(CAR(n), usage, switch_u, cont_u, catch_usage, catch_usage);    for(i=0; i < MAX_LOCAL; i++) {    usage[i] |= catch_usage[i];    }    return;    }    +  case F_AUTO_MAP:    case F_APPLY:    {    int i;       /* catch_usage is restored if the function throws an error. */    for (i=0; i < MAX_LOCAL; i++) {    usage[i] |= catch_u[i];    }    find_usage(CDR(n), usage, switch_u, cont_u, break_u, catch_u);    find_usage(CAR(n), usage, switch_u, cont_u, break_u, catch_u);
pike.git/src/las.c:4316: Inside #if defined(SHARED_NODES) && !defined(IN_TPIKE)
   MEMCPY(catch_usage, usage, MAX_LOCAL);    car = low_localopt(CAR(n), usage, switch_u, cont_u, catch_usage,    catch_usage);    for(i=0; i < MAX_LOCAL; i++) {    usage[i] |= catch_usage[i];    }    return mknode(F_CATCH, car, 0);    }    break;    +  case F_AUTO_MAP:    case F_APPLY:    {    int i;       /* catch_usage is restored if the function throws an error. */    for (i=0; i < MAX_LOCAL; i++) {    usage[i] |= catch_u[i];    }    cdr = low_localopt(CDR(n), usage, switch_u, cont_u, break_u, catch_u);    car = low_localopt(CAR(n), usage, switch_u, cont_u, break_u, catch_u); -  return mknode(F_APPLY, car, cdr); +  return mknode(n->token, car, cdr);    }       case F_LVALUE_LIST:    cdr = low_localopt(CDR(n), usage, switch_u, cont_u, break_u, catch_u);    if (CAR(n)) {    if ((CAR(n)->token == F_LOCAL) && (!CAR(n)->u.integer.b)) {    /* Array assignment of local variable. */    if (!(usage[CDR(n)->u.integer.a] & 1)) {    /* Variable isn't used. */    /* FIXME: Warn? */