Branch: Tag:

2007-03-03

2007-03-03 16:46:13 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Added support for string widths to the type system.

Rev: src/encode.c:1.240
Rev: src/language.yacc:1.373
Rev: src/pike_types.c:1.262

2:   || 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.261 2007/01/10 19:09:14 grubba Exp $ + || $Id: pike_types.c,v 1.262 2007/03/03 16:46:13 grubba Exp $   */      #include "global.h"
158:    case T_OBJECT: return "object";    case T_PROGRAM: return "program";    case T_STRING: return "string"; +  case PIKE_T_NSTRING: return "narrow_string";    case T_TYPE: return "type";    case T_ZERO: return "zero";    case T_VOID: return "void";
204:    * NOT type -    * '0'-'9' - -    * FLOAT - - -  * STRING - - +  * STRING bitwidth (int) - Width added in 7.7    * TYPE type -    * PROGRAM type -    * MIXED - -
651:    TYPE_STACK_DEBUG("push_int_type");   }    + void debug_push_string_type(INT32 bitwidth) + { +  if ((bitwidth < 0) || (bitwidth > 32)) { +  my_yyerror("Invalid string width: %ld (expected 0..32).", +  (long)bitwidth); +  bitwidth = 32; +  } +  +  *(++Pike_compiler->type_stackp) = mk_type(T_STRING, +  (void *)(ptrdiff_t)bitwidth, +  NULL, 0); +  +  TYPE_STACK_DEBUG("push_string_type"); + } +    void debug_push_object_type(int flag, INT32 id)   {    *(++Pike_compiler->type_stackp) = mk_type(T_OBJECT,
753:    case PIKE_T_NAME:    default:    /* Should not occur. */ -  Pike_fatal("Unsupported argument to push_type().\n"); +  Pike_fatal("Unsupported argument to push_type(): %d\n", type);    break;    -  case T_FLOAT: +     case T_STRING: -  +  Pike_fatal("String types should not be created with push_type().\n"); +  break; +  +  case T_FLOAT:    case T_MIXED:    case T_VOID:    case T_ZERO:
992:    }    if (field & BIT_BASIC) {    if (field & BIT_STRING) { -  push_type(T_STRING); +  push_string_type(32);    push_type(T_OR);    }    if (field & BIT_TYPE) {
1227:          case 's': -  if(!strcmp(buf,"string")) { push_type(T_STRING); break; } +  if(!strcmp(buf,"string")) { +  while(ISSPACE(**s)) ++*s; +  if(**s == '(') +  { +  INT32 bitwidth; +  ++*s; +  while(ISSPACE(**s)) ++*s; +  bitwidth=STRTOL((const char *)*s,(char **)s,0); +  while(ISSPACE(**s)) ++*s; +  if(**s != ')') yyerror("Missing ')' in string width."); +  else +  ++*s; +  push_string_type(bitwidth); +  } else { +  push_string_type(32); +  } +  break; +  }    goto bad_type;       case 'v':
1556: Inside #if defined(PIKE_DEBUG)
   break;    }    case T_FLOAT: fprintf(stderr, "float"); break; -  case T_STRING: fprintf(stderr, "string"); break; +  case T_STRING: +  { +  INT32 bitwidth = CAR_TO_INT(s); +  if (bitwidth != 32) { +  fprintf(stderr, "string(%d)", bitwidth); +  } else { +  fprintf(stderr, "string"); +  } +  break; +  }    case T_TYPE:    fprintf(stderr, "type(");    simple_describe_type(s->car);
1671:      static void low_describe_type(struct pike_type *t)   { +  char buffer[100]; +     check_c_stack(1024);    /**** FIXME: ****/    switch(t->type)
1716:       if(min!=MIN_INT32 || max!=MAX_INT32)    { -  char buffer[100]; +     sprintf(buffer,"(%ld..%ld)",(long)min,(long)max);    my_strcat(buffer);    }
1746:    }    break;    -  case T_STRING: my_strcat("string"); break; +  case T_STRING: +  { +  INT32 bitwidth=CAR_TO_INT(t); +  my_strcat("string"); +  if (bitwidth != 32) { +  sprintf(buffer,"(%ld)",(long)bitwidth); +  my_strcat(buffer); +  } +  break; +  }    case T_TYPE:    my_strcat("type(");    my_describe_type(t->car);
2051:    push_int_type(min1, max1);    }    } +  else if (t1->type == T_STRING && t2->type == T_STRING) { +  INT32 w1 = CAR_TO_INT(t1); +  INT32 w2 = CAR_TO_INT(t2); +  if (w1 >= w2) { +  push_finished_type(t1); +  } else { +  push_finished_type(t2); +  } +  }    else if (t1->type == T_SCOPE)    {    if (t2->type == T_SCOPE) {
2248:    low_and_pike_types(t1, t2->cdr);    push_scope_type(CAR_TO_INT(t2));    } -  else if((t1->type == t2->type) && -  ((t1->type == T_STRING) || -  (t1->type == T_FLOAT))) +  else if ((t1->type == T_STRING) && (t2->type == T_STRING)) { +  INT32 w1, w2; +  w1 = CAR_TO_INT(t1); +  w2 = CAR_TO_INT(t2); +  if (w1 < w2) { +  push_finished_type(t1); +  } else { +  push_finished_type(t2); +  } +  } +  else if((t1->type == T_FLOAT) && (t2->type == T_FLOAT))    {    push_finished_type(t1);    }
3388:    array_cnt = 0;    goto recurse;    -  case T_FLOAT: +     case T_STRING: -  +  { +  INT32 awidth = CAR_TO_INT(a); +  INT32 bwidth = CAR_TO_INT(b); +  return awidth <= bwidth; +  } +  +  case T_FLOAT:    case T_ZERO:    case T_VOID:    case T_MIXED:
3669:    return low_index_type(t->cdr, index_type, n);       case T_STRING: /* always int */ +  { +  int width = CAR_TO_INT(t); +  if (width != 32) { +  /* Narrow string */ +  type_stack_mark(); +  push_int_type(0, (1<<width)-1); +  return pop_unfinished_type(); +  } +  } +  /* FALL_THROUGH */    case T_MULTISET: /* always int */    add_ref(int_type_string);    return int_type_string;
4587:    push_type(T_TYPE);    return pop_unfinished_type();    +  case T_STRING: +  type_stack_mark(); +  if (s->u.string->len) { +  /* FIXME: Could be extended to detect 7-bit strings, etc. */ +  push_string_type(8<<s->u.string->size_shift); +  } else { +  push_string_type(0); +  } +  return pop_unfinished_type(); +     default:    type_stack_mark();    push_type(s->type);
4827:    return mk_type(type, NULL, NULL, PT_SET_MARKER);       case T_FLOAT: -  case T_STRING: +     case T_MIXED:    case T_VOID:    case T_ZERO:
4836:    *cont = type_string+1;    return mk_type(type, NULL, NULL, 0);    +  case T_STRING: +  *cont = type_string + 1; +  return mk_type(T_STRING, (void *)(ptrdiff_t)32, NULL, 0); +  +  case PIKE_T_NSTRING: +  *cont = type_string + 2; /* 1 + 1 */ +  /* FIXME: Add check for valid bitwidth (0..32). */ +  return mk_type(T_STRING, (void *)(ptrdiff_t)type_string[1], NULL, 0); +     case T_INT:    *cont = type_string + 9; /* 2*sizeof(INT32) + 1 */    return mk_type(T_INT,    (void *)(ptrdiff_t)extract_type_int((char *)type_string+1), -  (void *)(ptrdiff_t)extract_type_int((char *)type_string+5), 0); +  (void *)(ptrdiff_t)extract_type_int((char *)type_string+5), +  0);       case PIKE_T_INT_UNTYPED:    *cont = type_string + 1;
5040:    case '7':    case '8':    case '9': -  case T_STRING: +     case T_FLOAT:    case T_ZERO:    case T_VOID:
5065:    }    break;    +  case T_STRING: +  { +  INT32 width = (INT32)CAR_TO_INT(t); +  my_putchar(T_STRING); +  my_putchar((width >> 24) & 0xff); +  my_putchar((width >> 16) & 0xff); +  my_putchar((width >> 8) & 0xff); +  my_putchar(width & 0xff); +  } +  break; +     case T_INT:    {    INT32 i;