pike.git / src / docode.c

version» Context lines:

pike.git/src/docode.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: docode.c,v 1.180 2004/10/28 20:13:47 mast Exp $ + || $Id: docode.c,v 1.181 2004/10/30 11:38:25 mast Exp $   */      #include "global.h"   #include "las.h"   #include "program.h"   #include "pike_types.h"   #include "stralloc.h"   #include "interpret.h"   #include "constants.h"   #include "array.h"
pike.git/src/docode.c:586:    n->name);    emit1(F_CONSTANT, DO_NOT_WARN((INT32)tmp1));    break;       default:    my_yyerror("docode: Failed to make svalue for builtin %s",func);    }    free_node(n);   }    + static void emit_range (node *n DO_IF_DEBUG (COMMA int num_args)) + { +  node *low = CADR (n), *high = CDDR (n); +  int bound_types; +  +  switch (low->token) { +  case F_RANGE_FROM_BEG: bound_types = RANGE_LOW_FROM_BEG; break; +  case F_RANGE_FROM_END: bound_types = RANGE_LOW_FROM_END; break; +  case F_RANGE_OPEN: bound_types = RANGE_LOW_OPEN; break; + #ifdef PIKE_DEBUG +  default: +  Pike_fatal ("Unexpected node %d as range lower bound.\n", low->token); + #endif +  } +  +  switch (high->token) { +  case F_RANGE_FROM_BEG: bound_types |= RANGE_HIGH_FROM_BEG; break; +  case F_RANGE_FROM_END: bound_types |= RANGE_HIGH_FROM_END; break; +  case F_RANGE_OPEN: bound_types |= RANGE_HIGH_OPEN; break; + #ifdef PIKE_DEBUG +  default: +  Pike_fatal ("Unexpected node %d as range upper bound.\n", high->token); + #endif +  } +  + #ifdef PIKE_DEBUG +  { +  int expected_args; +  switch (bound_types & (RANGE_LOW_OPEN|RANGE_HIGH_OPEN)) { +  case 0: +  expected_args = 2; break; +  case RANGE_LOW_OPEN: +  case RANGE_HIGH_OPEN: +  expected_args = 1; break; +  case RANGE_LOW_OPEN|RANGE_HIGH_OPEN: +  expected_args = 0; break; +  } +  if (num_args != expected_args) +  Pike_fatal ("Wrong number of args to o_range opcode. Expected %d, got %d.\n", +  expected_args, num_args); +  } + #endif +  +  emit1 (F_RANGE, bound_types); + } +    static int do_docode2(node *n, int flags)   {    ptrdiff_t tmp1,tmp2,tmp3;    int ret;       if(!n) return 0;       if(flags & DO_LVALUE)    {    switch(n->token)
pike.git/src/docode.c:929:    case F_XOR:    case F_LSH:    case F_RSH:    case F_ADD:    case F_MOD:    case F_SUBTRACT:    case F_DIVIDE:    case F_MULTIPLY:    if(node_is_eq(CDR(n),CAAR(n)))    { +  int num_args;    tmp1=do_docode(CDR(n),DO_LVALUE);    if(match_types(CDR(n)->type, array_type_string) ||    match_types(CDR(n)->type, string_type_string) ||    match_types(CDR(n)->type, object_type_string) ||    match_types(CDR(n)->type, multiset_type_string) ||    match_types(CDR(n)->type, mapping_type_string))    { -  switch(do_docode(check_node_hash(CDAR(n)), 0)) +  num_args = do_docode(check_node_hash(CDAR(n)), 0); +  switch (num_args)    { -  +  case 0: emit0(F_LTOSVAL1); break;    case 1: emit0(F_LTOSVAL2); break;    case 2: emit0(F_LTOSVAL3); break;   #ifdef PIKE_DEBUG    default:    Pike_fatal("Arglebargle glop-glyf?\n");   #endif    }    }else{    emit0(F_LTOSVAL); -  do_docode(check_node_hash(CDAR(n)), 0); +  num_args = do_docode(check_node_hash(CDAR(n)), 0);    }    -  +  if (CAR (n)->token == F_RANGE) +  emit_range (CAR (n) DO_IF_DEBUG (COMMA num_args)); +  else    emit0(CAR(n)->token);       emit0(n->token);    return n->token==F_ASSIGN;    }       default:    switch(CDR(n)->token)    {    case F_LOCAL:
pike.git/src/docode.c:1048:    case F_XOR:    case F_OR:    case F_AND:    case F_NOT:    case F_COMPL:    case F_NEGATE:    Pike_fatal("Optimizer error.\n");       case F_RANGE:    tmp1=do_docode(CAR(n),DO_NOT_COPY_TOPLEVEL); -  if(do_docode(CDR(n),DO_NOT_COPY)!=2) -  Pike_fatal("Compiler internal error (at %ld).\n",(long)lex.current_line); -  emit0(n->token); +  { + #ifdef PIKE_DEBUG +  int num_args = + #endif +  do_docode (CDR (n), DO_NOT_COPY); +  emit_range (n DO_IF_DEBUG (COMMA num_args));    return DO_NOT_WARN((INT32)tmp1); -  +  }    -  +  /* The special bound type nodes are simply ignored when the +  * arglist to the range operator is coded. emit_range looks at +  * them later on instead. */ +  case F_RANGE_FROM_BEG: +  case F_RANGE_FROM_END: +  return do_docode (CAR (n), flags); +  case F_RANGE_OPEN: +  return 0; +     case F_INC:    case F_POST_INC:    if(CAR(n)->token == F_AUTO_MAP_MARKER)    {    int depth=0;    int ret=0;    node *tmp=CAR(n);    while(tmp->token == F_AUTO_MAP_MARKER)    {    depth++;
pike.git/src/docode.c:1271:    BLOCK_END;    return 0;    }          BLOCK_BEGIN;       if(CAR(arr) && CAR(arr)->token==F_RANGE)    {    node *range = CAR(arr); -  node **a1=my_get_arg(&_CDR(range),0); -  node **a2=my_get_arg(&_CDR(range),1); -  if(a2[0]->token==F_CONSTANT && -  a2[0]->u.sval.type==T_INT && -  a2[0]->u.sval.u.integer==MAX_INT_TYPE && -  match_types (a1[0]->type, int_type_string)) +  node *low = CADR(range); +  node *high = CDDR(range); +  if(high->token == F_RANGE_OPEN && +  low->token == F_RANGE_FROM_BEG && +  match_types (low->type, int_type_string))    {    /* Optimize foreach(x[start..],y). */    do_docode (CAR(range), DO_NOT_COPY_TOPLEVEL);    do_docode (CDR(arr), DO_NOT_COPY|DO_LVALUE); -  do_docode (*a1, DO_NOT_COPY); +  do_docode (CAR(low), DO_NOT_COPY);    goto foreach_arg_pushed;    }    }    do_docode(arr,DO_NOT_COPY);    emit0(F_CONST0);    current_stack_depth++;    foreach_arg_pushed:    PUSH_CLEANUP_FRAME(do_pop, 4);       PUSH_STATEMENT_LABEL;
pike.git/src/docode.c:1560:    emit1(F_APPLY, DO_NOT_WARN((INT32)tmp1));    }    }    free_node(foo);    POP_AND_DONT_CLEANUP;    return 1;    }       case F_ARG_LIST:    case F_COMMA_EXPR: +  case ':':    {    node *root = n;    node *parent = n->parent;       /* Avoid a bit of recursion by traversing the graph... */    n->parent = NULL;    tmp1 = 0;    next_car:    while (CAR(n) &&    ((CAR(n)->token == F_ARG_LIST) ||