pike.git / src / las.c

version» Context lines:

pike.git/src/las.c:212: Inside #if defined(PIKE_DEBUG)
   fputs("n:", stderr);    print_tree(n);    fputs("orig_n:", stderr);    print_tree(orig_n);    Pike_fatal("check_tree() lost track.\n");    }    n->parent = parent;   }   #endif    - /* FIXME: Ought to use parent pointer to avoid recursion. */ - INT32 count_args(node *n) + static int low_count_args(node *n)   {    int a,b; -  check_tree(n,0); +     -  fatal_check_c_stack(16384); -  +     if(!n) return 0;    switch(n->token)    {    case F_COMMA_EXPR:    case F_VAL_LVAL:    case F_ARG_LIST:    a=count_args(CAR(n));    if(a==-1) return -1;    b=count_args(CDR(n));    if(b==-1) return -1;    return a+b;       case F_CAST:    if(n->type == void_type_string)    return 0; -  else +     return count_args(CAR(n));       case F_SOFT_CAST:    return count_args(CAR(n));       case F_CASE:    case F_CASE_RANGE:    case F_FOR:    case F_DO:    case F_LOOP:
pike.git/src/las.c:261:    case F_RETURN:    case F_CONTINUE:    case F_FOREACH:    return 0;       case '?':    {    int tmp1,tmp2;    tmp1=count_args(CADR(n));    tmp2=count_args(CDDR(n)); -  if(tmp1==-1 || tmp2==-1) return -1; +     if(tmp1 < tmp2) return tmp1;    return tmp2;    }       case F_PUSH_ARRAY:    return -1;       case F_APPLY:    if(CAR(n)->token == F_CONSTANT &&    CAR(n)->u.sval.type == T_FUNCTION &&
pike.git/src/las.c:287:    case F_RANGE_FROM_BEG:    case F_RANGE_FROM_END:    return 1;    case F_RANGE_OPEN:    return 0;       default:    if(n->type == void_type_string) return 0;    return 1;    } +  /* NOT_REACHED */   }    -  + INT32 count_args(node *n) + { +  int total = 0; +  int a,b; +  node *orig = n; +  node *orig_parent; +  node *prev = NULL; +  check_tree(n,0); +  +  fatal_check_c_stack(16384); +  +  if(!n) return 0; +  +  orig_parent = n->parent; +  n->parent = NULL; +  +  while(1) { +  int val; +  while ((n->token == F_COMMA_EXPR) || +  (n->token == F_VAL_LVAL) || +  (n->token == F_ARG_LIST)) { +  if (CAR(n)) { +  CAR(n)->parent = n; +  n = CAR(n); +  } else if (CDR(n)) { +  CDR(n)->parent = n; +  n = CDR(n); +  } else { +  /* Unlikely, but... */ +  goto backtrack; +  } +  } +  +  /* Leaf. */ +  val = low_count_args(n); +  if (val == -1) { +  total = -1; +  break; +  } +  if (n->parent && (CAR(n->parent) == CDR(n->parent))) { +  /* Same node in both CDR and CAR ==> count twice. */ +  val *= 2; +  } +  total += val; +  +  backtrack: +  while (n->parent && +  (!CDR(n->parent) || (n == CDR(n->parent)))) { +  n = n->parent; +  } +  if (!(n = n->parent)) break; +  /* Found a parent where we haven't visited CDR. */ +  CDR(n)->parent = n; +  n = CDR(n); +  } +  +  orig->parent = orig_parent; +  +  return total; + } +    /* FIXME: Ought to use parent pointer to avoid recursion. */   struct pike_type *find_return_type(node *n)   {    struct pike_type *a, *b;       check_tree(n,0);       fatal_check_c_stack(16384);       if(!n) return 0;