pike.git / src / pike_types.c

version» Context lines:

pike.git/src/pike_types.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: pike_types.c,v 1.301 2007/04/26 17:24:48 grubba Exp $ + || $Id: pike_types.c,v 1.302 2007/04/27 13:55:15 grubba Exp $   */      #include "global.h"   #include <ctype.h>   #include "svalue.h"   #include "pike_types.h"   #include "stralloc.h"   #include "stuff.h"   #include "array.h"   #include "program.h"
pike.git/src/pike_types.c:1034:    break;    }    }    push_type(type);       TYPE_STACK_DEBUG("push_reverse_type");   }      /* The marker_set is used as follows:    * -  * PT_FLAG_MARKER_n Indicates that marker #n may be replaced. +  * PT_FLAG_MARKER_n Indicates that marker #n should be kept after +  * expansion.    * -  * PT_FLAG_ASSIGN_n Indicates that there's a prior assign to marker #n. -  * The marker should thus be kept. +  * PT_FLAG_ASSIGN_n Indicates that the assign to marker #n should +  * NOT be removed.    */   static void debug_push_finished_type_with_markers(struct pike_type *type,    struct pike_type **markers,    INT32 marker_set)   { -  +  INT32 car_set, cdr_set;    recurse:   #ifdef PIKE_TYPE_DEBUG    if (l_flag > 2) { -  fprintf(stderr, -  "push_finished_type_with_markers((%d[%x]),..., 0x%08x)...\n", -  type->type, type->flags, marker_set); +  fprintf(stderr, "push_finished_type_with_markers(("); +  simple_describe_type(type); +  fprintf(stderr, "),..., 0x%08x)...\n", marker_set);    }   #endif /* PIKE_TYPE_DEBUG */ -  if (!(type->flags & (marker_set /*| (marker_set << PT_ASSIGN_SHIFT)*/))) { -  /* No unassigned markers in this sub-tree */ +  /* We need to replace if there are any markers, or if there's a +  * non-masked assign. +  */ +  if (!(type->flags & (~marker_set | PT_FLAG_MARKER) & PT_FLAG_MARK_ASSIGN)) { +  /* Nothing to replace in this subtree. */   #ifdef PIKE_TYPE_DEBUG    if (l_flag > 2) { -  fprintf(stderr, "No unassigned markers in this subtree.\n"); +  fprintf(stderr, "Nothing to replace in this subtree.\n");    simple_describe_type(type);    fprintf(stderr, "\n");    }   #endif /* PIKE_TYPE_DEBUG */    push_finished_type(type);    return;    }    if ((type->type >= '0') && (type->type <= '9')) { -  +  /* Marker. */    unsigned int m = type->type - '0';   #ifdef PIKE_TYPE_DEBUG    if ((l_flag > 2) && m) {    fprintf(stderr, "Marker %d: %p.\n", m, markers[m]);    }   #endif /* PIKE_TYPE_DEBUG */ -  if ((marker_set & (PT_FLAG_MARKER_0 << m)) && markers[m]) { -  type = dmalloc_touch(struct pike_type *, markers[m]); -  if (marker_set & (PT_FLAG_ASSIGN_0 << m)) { -  /* There's a corresponding assignment, -  * so we need to keep the marker as well. -  */ +  if (markers[m]) { +  /* The marker has a value. */ +  struct pike_type *type = dmalloc_touch(struct pike_type *, markers[m]);   #ifdef PIKE_TYPE_DEBUG    if (l_flag > 2) { -  fprintf(stderr, "Keep marker or with marker value.\n"); +  fprintf(stderr, "Marker value.\n");    }   #endif -  +  /* FIXME: We probably ought to switch to the other marker set here. */    markers[m] = NULL; -  push_type('0' + m); -  push_finished_type_with_markers(type, markers, -  marker_set & ~(PT_FLAG_MARKER_0 << m)); -  push_type(T_OR); +  push_finished_type_with_markers(type, markers, 0); +  if (markers[m]) free_type(markers[m]);    markers[m] = dmalloc_touch(struct pike_type *, type);    } else { -  /* It's a marker we're cleared to replace. */ +  /* The marker has not been set. */   #ifdef PIKE_TYPE_DEBUG    if (l_flag > 2) { -  fprintf(stderr, "Killed marker.\n"); +  fprintf(stderr, "No marker value.\n");    }   #endif -  marker_set &= ~(PT_FLAG_MARKER_0 << m); -  goto recurse; +     } -  } else if (marker_set & (PT_FLAG_ASSIGN_0 << m)) { -  /* Keep the marker as-is. */ +  if (marker_set & (PT_FLAG_MARKER_0 << m)) { +  /* The marker should be kept. */   #ifdef PIKE_TYPE_DEBUG    if (l_flag > 2) { -  fprintf(stderr, "Keep marker and no marker value.\n"); +  fprintf(stderr, "Keep marker.\n");    }   #endif    push_type(type->type); -  } else { - #ifdef PIKE_TYPE_DEBUG -  if (l_flag > 2) { -  fprintf(stderr, "Killed marker and no marker value.\n"); -  } - #endif +  if (markers[m]) push_type(T_OR); +  } else if (!markers[m]) {    push_type(T_ZERO);    }    TYPE_STACK_DEBUG("push_finished_type_with_markers");    return;    } else if (type->type == T_ASSIGN) { -  +  /* Assign. */    int marker = PTR_TO_INT(type->car);   #ifdef PIKE_TYPE_DEBUG    if (l_flag > 2) {    fprintf(stderr, "Assign to marker %"PRINTPTRDIFFT"d.\n",    CAR_TO_INT(type));    }   #endif /* PIKE_TYPE_DEBUG */ -  if ((marker_set & (PT_FLAG_ASSIGN_0 << marker)) && markers[marker]) -  { -  /* The marker has already been set. Remove it. */ -  type = type->cdr; -  goto recurse; +  if (marker_set & (PT_FLAG_ASSIGN_0 << marker)) { +  /* The assignment should be kept as-is. */ + #ifdef PIKE_TYPE_DEBUG +  if (l_flag > 2) { +  fprintf(stderr, "Keep assignment.\n");    } -  /* Remove the corresponding marker from the set to replace. */ -  marker_set &= ~(PT_FLAG_MARKER_0 << marker); -  push_finished_type_with_markers(type->cdr, markers, marker_set); + #endif /* PIKE_TYPE_DEBUG */ +  /* Clear the flag. */ +  push_finished_type_with_markers(type->cdr, markers, +  marker_set & +  ~(PT_FLAG_ASSIGN_0 << marker));    push_assign_type('0' + marker);    TYPE_STACK_DEBUG("push_finished_type_with_markers");    return; -  +  } else { + #ifdef PIKE_TYPE_DEBUG +  if (l_flag > 2) { +  fprintf(stderr, "Strip assignment.\n"); +  } + #endif /* PIKE_TYPE_DEBUG */ +  type = type->cdr; +  goto recurse; +  }    } else if (type->type == PIKE_T_NAME) {    /* Strip the name, since it won't be correct anymore. */    type = type->cdr;    goto recurse; -  +  } else if (type->type == PIKE_T_ATTRIBUTE) { +  /* Keep the attribute. */ +  push_finished_type_with_markers(type->cdr, markers, marker_set); +  push_type_attribute((struct pike_string *)type->car);    }    /* FIXME: T_SCOPE */ -  +  +  if (type->car) { +  /* Keep markers for assigns in the car. */ +  cdr_set = marker_set | +  ((type->car->flags & PT_FLAG_ASSIGN)>>PT_ASSIGN_SHIFT); +  } else { +  cdr_set = marker_set; +  } +  if (type->cdr) { +  /* Keep assigns for markers in the cdr. */ +  car_set = marker_set | +  ((type->cdr->flags & PT_FLAG_MARKER)<<PT_ASSIGN_SHIFT); +  } else { +  car_set = marker_set; +  } +     if ((type->type == T_OR) || (type->type == T_AND)) {    /* Special case handling for implicit zero. */    /* FIXME: Probably ought to use {or,and}_pike_types() here.    * Problem is that they may mess with the markers...    */       type_stack_mark(); -  /* We want to keep markers that have assigns. */ -  push_finished_type_with_markers(type->cdr, markers, -  marker_set | -  (type->car->flags & PT_FLAG_ASSIGN)); +  /* We want to keep markers that have assigns in the car. */ +  push_finished_type_with_markers(type->cdr, markers, cdr_set);    if (type->type == T_OR) {    struct pike_type *first = pop_type();    struct pike_type *second;    struct pike_type *res; -  push_finished_type_with_markers(type->car, markers, marker_set); +  push_finished_type_with_markers(type->car, markers, car_set);    second = pop_unfinished_type();    push_finished_type(res = or_pike_types(first, second, 1));    free_type(second);    free_type(first);    free_type(res);    } else if (peek_type_stack() == zero_type_string) {    pop_stack_mark();    } else {    type_stack_mark(); -  push_finished_type_with_markers(type->car, markers, marker_set); +  push_finished_type_with_markers(type->car, markers, car_set);    if (peek_type_stack() == zero_type_string) {    free_type(pop_unfinished_type());    free_type(pop_unfinished_type());    push_finished_type(zero_type_string);    } else {    pop_stack_mark();    pop_stack_mark();    push_type(T_AND);    }    } -  } else if (type->type == PIKE_T_ATTRIBUTE) { -  /* Keep the attribute. */ -  push_finished_type_with_markers(type->cdr, markers, marker_set); -  push_type_attribute((struct pike_string *)type->car); +     } else {    if (type->cdr) { -  /* We want to keep markers that have assigns. */ -  push_finished_type_with_markers(type->cdr, markers, -  marker_set | -  (type->car->flags & PT_FLAG_ASSIGN)); +  /* In all other cases type->cdr will be a valid node if is not NULL. */ +  push_finished_type_with_markers(type->cdr, markers, cdr_set);    }    /* In all other cases type->car will be a valid node. */ -  push_finished_type_with_markers(type->car, markers, marker_set); +  push_finished_type_with_markers(type->car, markers, car_set);    /* push_type has sufficient magic to recreate the type. */    push_type(type->type);    }    TYPE_STACK_DEBUG("push_finished_type_with_markers");   }      static void push_type_field(TYPE_FIELD field)   {    field &= (BIT_BASIC|BIT_COMPLEX);    if (!field) {
pike.git/src/pike_types.c:3149:    int m = CAR_TO_INT(a);    struct pike_type *tmp;      #ifdef PIKE_DEBUG    if ((m < 0) || (m > 9)) {    Pike_fatal("marker out of range: %d\n", m);    }   #endif /* PIKE_DEBUG */       type_stack_mark(); -  push_finished_type_with_markers(b, b_markers, PT_FLAG_MARKER); +  push_finished_type_with_markers(b, b_markers, 0);    tmp = pop_unfinished_type();       type_stack_mark();    low_or_pike_types(a_markers[m], tmp, 0);    if(a_markers[m]) free_type(a_markers[m]);    free_type(tmp);    a_markers[m] = pop_unfinished_type();      #ifdef PIKE_TYPE_DEBUG    if (l_flag>2) {
pike.git/src/pike_types.c:3251:    return a;       case T_ASSIGN:    ret = low_match_types(a, b->cdr, flags);    if(ret && (a->type != T_VOID))    {    int m = CAR_TO_INT(b);    struct pike_type *tmp;       type_stack_mark(); -  push_finished_type_with_markers(a, a_markers, PT_FLAG_MARKER); +  push_finished_type_with_markers(a, a_markers, 0);    tmp=pop_unfinished_type();       type_stack_mark();    low_or_pike_types(b_markers[m], tmp, 0);    if(b_markers[m]) free_type(b_markers[m]);    free_type(tmp);    b_markers[m] = pop_unfinished_type();   #ifdef PIKE_TYPE_DEBUG    if (l_flag>2) {    dynamic_buffer save_buf;
pike.git/src/pike_types.c:3703:    case T_ASSIGN:    ret = low_pike_types_le(a->cdr, b, array_cnt, flags);    if(ret && (b->type != T_VOID))    {    int m = CAR_TO_INT(a);    struct pike_type *tmp;    int i;       type_stack_mark();    if (flags & LE_A_B_SWAPPED) { -  push_finished_type_with_markers(b, a_markers, PT_FLAG_MARKER); +  push_finished_type_with_markers(b, a_markers, 0);    } else { -  push_finished_type_with_markers(b, b_markers, PT_FLAG_MARKER); +  push_finished_type_with_markers(b, b_markers, 0);    }    for(i=array_cnt; i > 0; i--)    push_type(T_ARRAY);    tmp=pop_unfinished_type();       type_stack_mark();    if (flags & LE_A_B_SWAPPED) {    low_or_pike_types(b_markers[m], tmp, 0);    if(b_markers[m]) free_type(b_markers[m]);    free_type(tmp);
pike.git/src/pike_types.c:3816:    case T_ASSIGN:    ret = low_pike_types_le(a, b->cdr, array_cnt, flags);    if(ret && (a->type != T_VOID))    {    int m = CAR_TO_INT(b);    struct pike_type *tmp;    int i;       type_stack_mark();    if (flags & LE_A_B_SWAPPED) { -  push_finished_type_with_markers(a, b_markers, PT_FLAG_MARKER); +  push_finished_type_with_markers(a, b_markers, 0);    } else { -  push_finished_type_with_markers(a, a_markers, PT_FLAG_MARKER); +  push_finished_type_with_markers(a, a_markers, 0);    }    for(i = array_cnt; i < 0; i++)    push_type(T_ARRAY);    tmp=pop_unfinished_type();       type_stack_mark();    if (flags & LE_A_B_SWAPPED) {    low_or_pike_types(a_markers[m], tmp, 0);    if(a_markers[m]) free_type(a_markers[m]);    free_type(tmp);
pike.git/src/pike_types.c:4295:    switch(a->type)    {    case T_FUNCTION:    a = a->cdr;    while(a->type == T_FUNCTION) {    a = a->cdr;    }    /* FALL_THROUGH */    case T_MANY:    a = a->cdr; -  push_finished_type_with_markers(a, a_markers, PT_FLAG_MARKER); +  push_finished_type_with_markers(a, a_markers, 0);    return 1;       case T_PROGRAM:    push_finished_type(a->car);    return 1;       default:    push_type(T_MIXED);    return 1;    }
pike.git/src/pike_types.c:5754: Inside #if defined(PIKE_DEBUG)
   if (l_flag>2) {    fprintf(stderr, "%*sMore arguments required.\n", indent*2+2, "");    }   #endif /* PIKE_DEBUG */    res = NULL;    if (tmp) free_type(tmp);    break;    }    }    type_stack_mark(); -  push_finished_type_with_markers(fun_type, b_markers, PT_FLAG_MARKER); +  push_finished_type_with_markers(fun_type, b_markers, 0);    res = pop_unfinished_type();    if (tmp) free_type(tmp);       if ((Pike_compiler->compiler_pass == 2) && sval) {    while (tmp2->type == PIKE_T_NAME) {    tmp2 = tmp2->cdr;    }       if (tmp2->type == PIKE_T_ATTRIBUTE) {    /* Perform extra argument checking based on the attribute. */
pike.git/src/pike_types.c:6075: Inside #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, "Ok, cleaning up markers... ");    }   #endif /* PIKE_DEBUG */       type_stack_mark();       /* Get rid of any remaining markers. */    clear_markers(); -  push_finished_type_with_markers(res, a_markers, PT_FLAG_MARKER); +  push_finished_type_with_markers(res, a_markers, 0);       free_type(res);       while(array_cnt--) {    push_type(PIKE_T_ARRAY);    }      #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, "Done.\n");