cb22561995-10-11Fredrik Hübinette (Hubbe) /*\
3e9a462002-01-16Martin Nilsson ||| This file is part of Pike. For copyright information see COPYRIGHT.
06983f1996-09-22Fredrik Hübinette (Hubbe) ||| Pike is distributed as GPL (General Public License)
cb22561995-10-11Fredrik Hübinette (Hubbe) ||| See the files COPYING and DISCLAIMER for more information. \*/
8670791999-02-28Henrik Grubbström (Grubba) /**/
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "global.h"
663cbf2002-05-15Henrik Grubbström (Grubba) RCSID("$Id: pike_types.c,v 1.185 2002/05/15 14:48:29 grubba Exp $");
5267b71995-08-09Fredrik Hübinette (Hubbe) #include <ctype.h> #include "svalue.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "pike_types.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "stralloc.h" #include "stuff.h" #include "array.h" #include "program.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "constants.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "object.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "multiset.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "mapping.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
b8cda21997-01-21Fredrik Hübinette (Hubbe) #include "las.h" #include "language.h"
93dd411999-11-23Henrik Grubbström (Grubba) #include "lex.h"
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #include "pike_memory.h"
6c39401999-10-28Fredrik Hübinette (Hubbe) #include "bignum.h"
fbafd01999-12-12Henrik Grubbström (Grubba) #include "main.h"
f76b4c2000-05-11Henrik Grubbström (Grubba) #include "opcodes.h"
71a9672001-03-03Henrik Grubbström (Grubba) #include "block_alloc.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5528582000-12-01Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
eaa4da2001-10-04Fredrik Hübinette (Hubbe) /* #define PIKE_TYPE_DEBUG */
5528582000-12-01Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
02f0631999-11-24Fredrik Hübinette (Hubbe) 
71a9672001-03-03Henrik Grubbström (Grubba) /* * Flags used by low_match_types(). */ #define A_EXACT 1 #define B_EXACT 2 #define NO_MAX_ARGS 4 #define NO_SHORTCUTS 8 /* * Flags used by pike_types_le() */ #define LE_WEAK_OBJECTS 1 /* Perform weaker checking of objects. */ #ifdef USE_PIKE_TYPE /* Number of entries in the struct pike_type hash-table. */ #define PIKE_TYPE_HASH_SIZE 32768 #endif /* USE_PIKE_TYPE */ #ifdef PIKE_TYPE_DEBUG static int indent=0; #endif
1d53281996-11-25Fredrik Hübinette (Hubbe) int max_correct_args;
71a9672001-03-03Henrik Grubbström (Grubba) PMOD_EXPORT struct pike_type *string_type_string; PMOD_EXPORT struct pike_type *int_type_string; PMOD_EXPORT struct pike_type *float_type_string; PMOD_EXPORT struct pike_type *function_type_string; PMOD_EXPORT struct pike_type *object_type_string; PMOD_EXPORT struct pike_type *program_type_string; PMOD_EXPORT struct pike_type *array_type_string; PMOD_EXPORT struct pike_type *multiset_type_string; PMOD_EXPORT struct pike_type *mapping_type_string; PMOD_EXPORT struct pike_type *type_type_string; PMOD_EXPORT struct pike_type *mixed_type_string; PMOD_EXPORT struct pike_type *void_type_string; PMOD_EXPORT struct pike_type *zero_type_string; PMOD_EXPORT struct pike_type *any_type_string; PMOD_EXPORT struct pike_type *weak_type_string; /* array|mapping|multiset|function */
94b2fb2001-03-28Henrik Grubbström (Grubba) #if defined(USE_PIKE_TYPE) && defined(DEBUG_MALLOC) struct pike_type_location *all_pike_type_locations = NULL; #endif /* USE_PIKE_TYPE && DEBUG_MALLOC */
71a9672001-03-03Henrik Grubbström (Grubba) static struct pike_type *a_markers[10], *b_markers[10]; static struct program *implements_a; static struct program *implements_b; #ifdef PIKE_DEBUG void TYPE_STACK_DEBUG(const char *fun) { #if 0 fprintf(stderr, "%25s(): stack_depth:%ld mark_stack_depth:%ld\n", fun, (long)(Pike_compiler->type_stackp - type_stack), (long)(Pike_compiler->pike_type_mark_stackp - pike_type_mark_stack)); #endif /* 0 */ } #endif /* PIKE_DEBUG */ static void clear_markers(void) { unsigned int e; for(e=0;e<NELEM(a_markers);e++) { if(a_markers[e]) { free_type(a_markers[e]); a_markers[e]=0; } if(b_markers[e]) { free_type(b_markers[e]); b_markers[e]=0; } } } struct pike_type *debug_pop_type(void) { struct pike_type *t = pop_unfinished_type(); TYPE_STACK_DEBUG("pop_type"); type_stack_mark(); return t; } struct pike_type *debug_compiler_pop_type(void) { TYPE_STACK_DEBUG("compiler_pop_type"); if(Pike_compiler->num_parse_error) { /* This could be fixed to check if the type * is correct and then return it, I just didn't feel * like writing the checking code today. / Hubbe */ type_stack_pop_to_mark(); type_stack_mark(); add_ref(mixed_type_string); return mixed_type_string; }else{ return debug_pop_type(); } } char *get_name_of_type(int t) { switch(t) { case T_ARRAY: return "array"; case T_FLOAT: return "float"; case T_FUNCTION: return "function"; case T_INT: return "int"; case T_LVALUE: return "lvalue"; case T_MAPPING: return "mapping"; case T_MULTISET: return "multiset"; case T_OBJECT: return "object"; case T_PROGRAM: return "program"; case T_STRING: return "string"; case T_TYPE: return "type"; case T_ZERO: return "zero"; case T_VOID: return "void";
638fe92001-08-20Martin Stjernholm  case T_STORAGE: return "object storage";
71a9672001-03-03Henrik Grubbström (Grubba)  case T_MAPPING_DATA: return "mapping_data";
638fe92001-08-20Martin Stjernholm  case T_PIKE_FRAME: return "pike_frame";
71a9672001-03-03Henrik Grubbström (Grubba)  default: return "unknown"; } } #define TWOT(X,Y) (((X) << 8)+(Y)) #ifdef USE_PIKE_TYPE static int low_pike_types_le(struct pike_type *a, struct pike_type *b, int array_cnt, unsigned int flags); static int low_check_indexing(struct pike_type *type, struct pike_type *index_type, node *n); static void internal_parse_type(char **s); /* * New and improved type representation system. * * This representation is new in Pike 7.3. * * Node: Car: Cdr: * --------------------------------------------- * SCOPE num vars (int) type * ASSIGN variable (int) type
ce88d62001-03-19Henrik Grubbström (Grubba)  * NAME name (string) type
71a9672001-03-03Henrik Grubbström (Grubba)  * FUNCTION type FUNCTION|MANY * MANY many type return type
ce88d62001-03-19Henrik Grubbström (Grubba)  * RING type type
71a9672001-03-03Henrik Grubbström (Grubba)  * TUPLE type type * MAPPING index type value type * OR type type * AND type type * ARRAY type - * MULTISET type - * NOT type - * '0'-'9' - - * FLOAT - - * STRING - -
9b5a822001-03-29Henrik Grubbström (Grubba)  * TYPE type -
6d33d82001-03-28Henrik Grubbström (Grubba)  * PROGRAM type -
71a9672001-03-03Henrik Grubbström (Grubba)  * MIXED - - * VOID - - * ZERO - - * UNKNOWN - - * INT min (int) max (int) * OBJECT implements/is object id(int) * * Note that the cdr of a FUNCTION is a valid FUNCTION for the rest of * the arguments. * * Note also that functions that don't take any arguments, or just * a many argument just have a MANY node, and no FUNCTION node. * */ #define PIKE_TYPE_CHUNK 128 BLOCK_ALLOC(pike_type, PIKE_TYPE_CHUNK) static struct pike_type **pike_type_hash = NULL; static size_t pike_type_hash_size = 0;
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_free_type(struct pike_type *t)
71a9672001-03-03Henrik Grubbström (Grubba) { loop:
9b5a822001-03-29Henrik Grubbström (Grubba)  if (!(--(((struct pike_type *)debug_malloc_pass(t))->refs))) {
71a9672001-03-03Henrik Grubbström (Grubba)  unsigned INT32 hash = t->hash % pike_type_hash_size; struct pike_type **t2 = pike_type_hash + hash; struct pike_type *car, *cdr; unsigned INT32 type;
9b5a822001-03-29Henrik Grubbström (Grubba)  while (*t2) { if (*t2 == t) { *t2 = t->next; break; }
71a9672001-03-03Henrik Grubbström (Grubba)  t2 = &((*t2)->next); } car = t->car; cdr = t->cdr; type = t->type;
9b5a822001-03-29Henrik Grubbström (Grubba)  really_free_pike_type((struct pike_type *)debug_malloc_pass(t));
71a9672001-03-03Henrik Grubbström (Grubba)  /* FIXME: Recursion: Should we use a stack? */ switch(type) { case T_FUNCTION: case T_MANY: case T_TUPLE: case T_MAPPING: case T_OR: case T_AND:
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
71a9672001-03-03Henrik Grubbström (Grubba)  /* Free car & cdr */ free_type(car);
9b5a822001-03-29Henrik Grubbström (Grubba)  t = (struct pike_type *)debug_malloc_pass(cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  goto loop; case T_ARRAY: case T_MULTISET: case T_NOT:
9b5a822001-03-29Henrik Grubbström (Grubba)  case T_TYPE: case T_PROGRAM:
71a9672001-03-03Henrik Grubbström (Grubba)  /* Free car */
9b5a822001-03-29Henrik Grubbström (Grubba)  t = (struct pike_type *)debug_malloc_pass(car);
71a9672001-03-03Henrik Grubbström (Grubba)  goto loop; case T_SCOPE: case T_ASSIGN: /* Free cdr */
9b5a822001-03-29Henrik Grubbström (Grubba)  t = (struct pike_type *)debug_malloc_pass(cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  goto loop;
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: free_string((struct pike_string *)car);
9b5a822001-03-29Henrik Grubbström (Grubba)  t = (struct pike_type *)debug_malloc_pass(cdr);
f62c412001-03-05Henrik Grubbström (Grubba)  goto loop;
9b5a822001-03-29Henrik Grubbström (Grubba)  #ifdef PIKE_DEBUG case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case T_FLOAT: case T_STRING: case T_MIXED: case T_VOID: case T_ZERO: case PIKE_T_UNKNOWN: case T_INT: case T_OBJECT: break; default: fatal("free_type(): Unhandled type-node: %d\n", type); break; #endif /* PIKE_DEBUG */
71a9672001-03-03Henrik Grubbström (Grubba)  } } } /* Flags used as flag_method: */ #define PT_COPY_CAR 1 #define PT_COPY_CDR 2 #define PT_COPY_BOTH 3 #define PT_SET_MARKER 4
9b5a822001-03-29Henrik Grubbström (Grubba) static inline struct pike_type *debug_mk_type(unsigned INT32 type, struct pike_type *car, struct pike_type *cdr, int flag_method)
71a9672001-03-03Henrik Grubbström (Grubba) { unsigned INT32 hash = DO_NOT_WARN((unsigned INT32) ((ptrdiff_t)type*0x10204081)^
5f29fd2001-03-05Henrik Grubbström (Grubba)  (0x8003*(ptrdiff_t)car)^
2bed1e2001-03-05Henrik Grubbström (Grubba)  ~(0x10001*(ptrdiff_t)cdr));
71a9672001-03-03Henrik Grubbström (Grubba)  unsigned INT32 index = hash % pike_type_hash_size; struct pike_type *t; for(t = pike_type_hash[index]; t; t = t->next) { if ((t->hash == hash) && (t->type == type) && (t->car == car) && (t->cdr == cdr)) {
9b5a822001-03-29Henrik Grubbström (Grubba)  /* Free car & cdr as appropriate. */
f62c412001-03-05Henrik Grubbström (Grubba)  switch(type) { case T_FUNCTION: case T_MANY: case T_TUPLE: case T_MAPPING: case T_OR: case T_AND:
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
f62c412001-03-05Henrik Grubbström (Grubba)  /* Free car & cdr */
9b5a822001-03-29Henrik Grubbström (Grubba)  free_type((struct pike_type *)debug_malloc_pass(car)); free_type((struct pike_type *)debug_malloc_pass(cdr));
f62c412001-03-05Henrik Grubbström (Grubba)  break; case T_ARRAY: case T_MULTISET: case T_NOT:
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_TYPE: case T_PROGRAM:
f62c412001-03-05Henrik Grubbström (Grubba)  /* Free car */
9b5a822001-03-29Henrik Grubbström (Grubba)  free_type((struct pike_type *)debug_malloc_pass(car));
f62c412001-03-05Henrik Grubbström (Grubba)  break; case T_SCOPE: case T_ASSIGN: /* Free cdr */
9b5a822001-03-29Henrik Grubbström (Grubba)  free_type((struct pike_type *)debug_malloc_pass(cdr));
f62c412001-03-05Henrik Grubbström (Grubba)  break; case PIKE_T_NAME:
9b5a822001-03-29Henrik Grubbström (Grubba)  free_string((struct pike_string *)debug_malloc_pass(car)); free_type((struct pike_type *)debug_malloc_pass(cdr)); break; #ifdef PIKE_DEBUG case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case T_FLOAT: case T_STRING: case T_MIXED: case T_VOID: case T_ZERO: case PIKE_T_UNKNOWN: case T_INT: case T_OBJECT: break; default: fatal("mk_type(): Unhandled type-node: %d\n", type);
f62c412001-03-05Henrik Grubbström (Grubba)  break;
9b5a822001-03-29Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
f62c412001-03-05Henrik Grubbström (Grubba)  }
9b5a822001-03-29Henrik Grubbström (Grubba)  add_ref((struct pike_type *)debug_malloc_pass(t));
71a9672001-03-03Henrik Grubbström (Grubba)  return t; } }
9b5a822001-03-29Henrik Grubbström (Grubba)  debug_malloc_pass(t = alloc_pike_type());
71a9672001-03-03Henrik Grubbström (Grubba)  t->refs = 1; t->type = type; t->flags = 0; t->car = car; t->cdr = cdr; t->hash = hash; t->next = pike_type_hash[index]; pike_type_hash[index] = t; if (flag_method) { if (flag_method == PT_SET_MARKER) { t->flags = PT_FLAG_MARKER; } else { if (car && (flag_method & PT_COPY_CAR)) { t->flags = car->flags; } if (cdr && (flag_method & PT_COPY_CDR)) { t->flags |= cdr->flags; } } }
9b5a822001-03-29Henrik Grubbström (Grubba) #ifdef DEBUG_MALLOC switch(type) { case T_FUNCTION: case T_MANY: case T_TUPLE: case T_MAPPING: case T_OR: case T_AND: case PIKE_T_RING: debug_malloc_pass(car); debug_malloc_pass(cdr); break; case T_ARRAY: case T_MULTISET: case T_NOT: case T_TYPE: case T_PROGRAM: debug_malloc_pass(car); break; case T_SCOPE: case T_ASSIGN: debug_malloc_pass(cdr); break; case PIKE_T_NAME: debug_malloc_pass(car); debug_malloc_pass(cdr); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case T_FLOAT: case T_STRING: case T_MIXED: case T_VOID: case T_ZERO: case PIKE_T_UNKNOWN: case T_INT: case T_OBJECT: break; default: fatal("mk_type(): Unhandled type-node: %d\n", type); break; } #endif /* DEBUG_MALLOC */
71a9672001-03-03Henrik Grubbström (Grubba)  return t; }
9b5a822001-03-29Henrik Grubbström (Grubba) #ifdef DEBUG_MALLOC #define mk_type(T,CAR,CDR,FLAG) ((struct pike_type *)debug_malloc_pass(debug_mk_type(T,CAR,CDR,FLAG))) #else /* !DEBUG_MALLOC */ #define mk_type debug_mk_type #endif /* DEBUG_MALLOC */
71a9672001-03-03Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_check_type_string(struct pike_type *s)
71a9672001-03-03Henrik Grubbström (Grubba) { /* FIXME: Add verification code here */ }
9b5a822001-03-29Henrik Grubbström (Grubba) 
71a9672001-03-03Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */ struct pike_type *type_stack[PIKE_TYPE_STACK_SIZE]; struct pike_type **pike_type_mark_stack[PIKE_TYPE_STACK_SIZE/4]; ptrdiff_t pop_stack_mark(void) { Pike_compiler->pike_type_mark_stackp--; if(Pike_compiler->pike_type_mark_stackp<pike_type_mark_stack) fatal("Type mark stack underflow\n"); TYPE_STACK_DEBUG("pop_stack_mark"); return Pike_compiler->type_stackp - *Pike_compiler->pike_type_mark_stackp; } void type_stack_pop_to_mark(void) { pop_stack_mark();
5b368e2001-03-31Henrik Grubbström (Grubba)  while(Pike_compiler->type_stackp > *Pike_compiler->pike_type_mark_stackp) { free_type(*(Pike_compiler->type_stackp--)); }
71a9672001-03-03Henrik Grubbström (Grubba)  TYPE_STACK_DEBUG("type_stack_pop_to_mark"); }
9b5a822001-03-29Henrik Grubbström (Grubba) struct pike_type *debug_peek_type_stack(void) { return *(Pike_compiler->type_stackp); } void debug_push_int_type(INT32 min, INT32 max)
71a9672001-03-03Henrik Grubbström (Grubba) { *(++Pike_compiler->type_stackp) = mk_type(T_INT, (void *)(ptrdiff_t)min, (void *)(ptrdiff_t)max, 0); TYPE_STACK_DEBUG("push_int_type"); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_object_type(int flag, INT32 id)
71a9672001-03-03Henrik Grubbström (Grubba) { *(++Pike_compiler->type_stackp) = mk_type(T_OBJECT, (void *)(ptrdiff_t)flag, (void *)(ptrdiff_t)id, 0); TYPE_STACK_DEBUG("push_object_type"); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_object_type_backwards(int flag, INT32 id)
71a9672001-03-03Henrik Grubbström (Grubba) { push_object_type(flag, id); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_scope_type(int level)
71a9672001-03-03Henrik Grubbström (Grubba) { *Pike_compiler->type_stackp = mk_type(T_SCOPE, (void *)(ptrdiff_t)level, *Pike_compiler->type_stackp, PT_COPY_CDR); TYPE_STACK_DEBUG("push_scope_type"); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_assign_type(int marker)
71a9672001-03-03Henrik Grubbström (Grubba) {
9e6f6f2001-03-18Henrik Grubbström (Grubba)  marker -= '0';
c02ce62001-03-18Per Hedbor #ifdef PIKE_DEBUG
9e6f6f2001-03-18Henrik Grubbström (Grubba)  if ((marker < 0) || (marker > 9)) { fatal("Bad assign marker: %ld\n", marker);
54f8ac2001-03-17Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG */
9e6f6f2001-03-18Henrik Grubbström (Grubba) 
71a9672001-03-03Henrik Grubbström (Grubba)  *Pike_compiler->type_stackp = mk_type(T_ASSIGN, (void *)(ptrdiff_t)marker, *Pike_compiler->type_stackp, PT_COPY_CDR); TYPE_STACK_DEBUG("push_assign_type"); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_type_name(struct pike_string *name)
f62c412001-03-05Henrik Grubbström (Grubba) { /* fprintf(stderr, "push_type_name(\"%s\")\n", name->str); */ add_ref(name); *Pike_compiler->type_stackp = mk_type(PIKE_T_NAME, (void *)name, *Pike_compiler->type_stackp, PT_COPY_CDR); TYPE_STACK_DEBUG("push_type_name"); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_finished_type(struct pike_type *t)
71a9672001-03-03Henrik Grubbström (Grubba) {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(*(++Pike_compiler->type_stackp), t);
71a9672001-03-03Henrik Grubbström (Grubba)  TYPE_STACK_DEBUG("push_finished_type"); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_type(unsigned INT16 type)
71a9672001-03-03Henrik Grubbström (Grubba) { /* fprintf(stderr, "push_type(%d)\n", type); */ switch(type) { case T_FUNCTION: case T_MANY: case T_TUPLE: case T_MAPPING: case T_OR: case T_AND:
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
71a9672001-03-03Henrik Grubbström (Grubba)  /* Make a new type of the top two types. */ --Pike_compiler->type_stackp; *Pike_compiler->type_stackp = mk_type(type, *(Pike_compiler->type_stackp+1), *Pike_compiler->type_stackp, PT_COPY_BOTH); break; case T_ARRAY: case T_MULTISET: case T_NOT:
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE:
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM:
71a9672001-03-03Henrik Grubbström (Grubba)  /* Make a new type of the top type, and put it in car. */ *Pike_compiler->type_stackp = mk_type(type, *Pike_compiler->type_stackp, NULL, PT_COPY_CAR); break; case T_SCOPE: case T_ASSIGN: case T_INT: case T_OBJECT:
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME:
71a9672001-03-03Henrik Grubbström (Grubba)  default: /* Should not occurr. */
9e6f6f2001-03-18Henrik Grubbström (Grubba)  fatal("Unsupported argument to push_type().\n");
71a9672001-03-03Henrik Grubbström (Grubba)  break; case T_FLOAT: case T_STRING: case T_MIXED: case T_VOID: case T_ZERO: case PIKE_T_UNKNOWN: /* Leaf type. */ *(++Pike_compiler->type_stackp) = mk_type(type, NULL, NULL, 0); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* Marker. */ *(++Pike_compiler->type_stackp) = mk_type(type, NULL, NULL, PT_SET_MARKER); break; } TYPE_STACK_DEBUG("push_type"); } /* Pop one level of types. This is the inverse of push_type() */
5b368e2001-03-31Henrik Grubbström (Grubba) void debug_pop_type_stack(unsigned INT16 expected)
71a9672001-03-03Henrik Grubbström (Grubba) { struct pike_type *top; if(Pike_compiler->type_stackp<type_stack) fatal("Type stack underflow\n");
2be1db2001-04-18Henrik Grubbström (Grubba)  top = *(Pike_compiler->type_stackp); /* Special case... */ if (top->type == T_MIXED) return; /* Probably due to an earlier error */ Pike_compiler->type_stackp--;
5b368e2001-03-31Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if ((top->type != expected) && (top->type != PIKE_T_NAME)) { fatal("Unexpected type on stack: %d (expected %d)\n", top->type, expected); } #endif /* PIKE_DEBUG */ /* OPTIMIZE: It looks like this function is always called with * expected == T_ARRAY. */
71a9672001-03-03Henrik Grubbström (Grubba)  switch(top->type) { case T_FUNCTION: case T_MANY: case T_TUPLE: case T_MAPPING: case T_OR: case T_AND:
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
71a9672001-03-03Henrik Grubbström (Grubba)  /* Both car & cdr. */ push_finished_type(top->cdr); push_finished_type(top->car); break; case T_ARRAY: case T_MULTISET: case T_NOT:
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE:
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM:
71a9672001-03-03Henrik Grubbström (Grubba)  /* car */ push_finished_type(top->car); break; case T_SCOPE: case T_ASSIGN: /* cdr */ push_finished_type(top->cdr); break; case T_INT: case T_OBJECT: case T_FLOAT: case T_STRING: case T_MIXED: case T_VOID: case T_ZERO: case PIKE_T_UNKNOWN: case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* Leaf */ break;
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: /* Pop the name and recurse. */ push_finished_type(top->cdr);
5b368e2001-03-31Henrik Grubbström (Grubba)  pop_type_stack(expected);
f62c412001-03-05Henrik Grubbström (Grubba)  break;
71a9672001-03-03Henrik Grubbström (Grubba)  default: Pike_error("pop_type_stack(): Unhandled node type: %d\n", top->type); } free_type(top); TYPE_STACK_DEBUG("pop_type_stack"); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_reverse_type(unsigned INT16 type)
71a9672001-03-03Henrik Grubbström (Grubba) { /* fprintf(stderr, "push_reverse_type(%d)\n", type); */ switch(type) { case T_FUNCTION: case T_MANY: case T_TUPLE: case T_MAPPING: case T_OR: case T_AND:
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
71a9672001-03-03Henrik Grubbström (Grubba)  { /* Binary type-node. -- swap the types. */ struct pike_type *tmp = Pike_compiler->type_stackp[0]; Pike_compiler->type_stackp[0] = Pike_compiler->type_stackp[-1]; Pike_compiler->type_stackp[-1] = tmp; break; } } push_type(type); TYPE_STACK_DEBUG("push_reverse_type"); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_finished_type_with_markers(struct pike_type *type, struct pike_type **markers)
71a9672001-03-03Henrik Grubbström (Grubba) { recurse: #if 0 fprintf(stderr, "push_finished_type_with_markers((%d[%x]),...)...\n", type->type, type->flags); #endif /* 0 */ if (!(type->flags & PT_FLAG_MARKER)) { /* No markers in this sub-tree */ #if 0 fprintf(stderr, "No markers in this subtree.\n"); #endif /* 0 */ push_finished_type(type); return; } if ((type->type >= '0') && (type->type <= '9')) { unsigned int m = type->type - '0'; if (markers[m]) { type = markers[m]; #if 0 fprintf(stderr, "Marker %d.\n", m); #endif /* 0 */ goto recurse; } else { push_type(T_ZERO); } TYPE_STACK_DEBUG("push_finished_type_with_markers"); return; } if (type->type == T_ASSIGN) { /* Strip assign */ #if 0
9e6f6f2001-03-18Henrik Grubbström (Grubba)  fprintf(stderr, "Assign to marker %d.\n", ((ptrdiff_t)type->car));
71a9672001-03-03Henrik Grubbström (Grubba) #endif /* 0 */ type = type->cdr; goto recurse; }
f62c412001-03-05Henrik Grubbström (Grubba)  if (type->type == PIKE_T_NAME) { /* Strip the name, since it won't be correct anymore. */ type = type->cdr; goto recurse; }
71a9672001-03-03Henrik Grubbström (Grubba)  /* FIXME: T_SCOPE */ if (type->cdr) { push_finished_type_with_markers(type->cdr, markers); } /* In all other cases type->car will be a valid node. */ push_finished_type_with_markers(type->car, markers); /* push_type has sufficient magic to recreate the type. */ push_type(type->type); TYPE_STACK_DEBUG("push_finished_type_with_markers"); } INT32 extract_type_int(char *p) { int e; INT32 ret=0; for(e=0;e<(int)sizeof(INT32);e++) ret=(ret<<8) | EXTRACT_UCHAR(p+e); return ret; } struct pike_type *debug_pop_unfinished_type(void) { ptrdiff_t len; len = pop_stack_mark(); if (len != 1) { fatal("pop_unfinished_type(): Unexpected len: %d\n", len); } TYPE_STACK_DEBUG("pop_unfinished_type"); return *(Pike_compiler->type_stackp--); } /******/ static void internal_parse_typeA(char **_s) { char buf[80]; unsigned int len; unsigned char **s = (unsigned char **)_s; while(ISSPACE(**s)) ++*s; len=0; for(len=0;isidchar(EXTRACT_UCHAR(s[0]+len));len++) { if(len>=sizeof(buf)) Pike_error("Buffer overflow in parse_type\n"); buf[len] = s[0][len]; } buf[len]=0; *s += len; switch(buf[0]) { case 'z': if(!strcmp(buf,"zero")) { push_type(T_ZERO); break; } goto bad_type; case 'i': if(!strcmp(buf,"int")) { while(ISSPACE(**s)) ++*s; if(**s=='(') { INT32 min,max; ++*s; while(ISSPACE(**s)) ++*s; min=STRTOL((char *)*s,(char **)s,0); while(ISSPACE(**s)) ++*s; if(s[0][0]=='.' && s[0][1]=='.') s[0]+=2; else Pike_error("Missing .. in integer type.\n"); while(ISSPACE(**s)) ++*s; max=STRTOL((char *)*s,(char **)s,0); while(ISSPACE(**s)) ++*s; if(**s != ')') Pike_error("Missing ')' in integer range.\n"); ++*s; push_int_type(min, max); }else{ push_int_type(MIN_INT32, MAX_INT32); } break; } goto bad_type; case 'f': if(!strcmp(buf,"function")) { while(ISSPACE(**s)) ++*s; if(**s == '(') { int nargs = 0; ++*s; while(ISSPACE(**s)) ++*s; while(1) { if(**s == ':') { push_type(T_VOID); break; } internal_parse_type(_s); if(**s==',') { nargs++; ++*s; while(ISSPACE(**s)) ++*s; } else if(s[0][0]=='.' && s[0][1]=='.' && s[0][2]=='.') { *s+=3; while(ISSPACE(**s)) ++*s; if(**s != ':') Pike_error("Missing ':' after ... in function type.\n"); break; } else { nargs++; } } ++*s; internal_parse_type(_s); /* return type */ push_reverse_type(T_MANY); while (nargs-- > 0) { push_reverse_type(T_FUNCTION); } if(**s != ')') Pike_error("Missing ')' in function type.\n"); ++*s; }else{ push_type(T_VOID); push_type(T_MIXED); push_type(T_OR); push_type(T_VOID); push_type(T_ZERO); push_type(T_OR); push_type(T_MANY); } break; } if(!strcmp(buf,"float")) { push_type(T_FLOAT); break; } goto bad_type; case 'o': if(!strcmp(buf,"object")) {
c02ce62001-03-18Per Hedbor  while(ISSPACE(**s)) ++*s; if(**s == '(') /* object({is,implements} id) */ { int is = 1, id; ++*s; if( **s != 'i' ) goto bad_type; ++*s; if( **s == 'm' ) is = 0; while( isidchar( **s ) ) ++*s; while( ISSPACE(**s) ) ++*s; if( !**s ) goto bad_type; id = atoi( *s ); while( **s >= '0' && **s <= '9' ) ++*s; while(ISSPACE(**s)) ++*s; if( !**s || **s != ')' ) goto bad_type; ++*s; push_object_type(is, id); } else push_object_type(0, 0);
71a9672001-03-03Henrik Grubbström (Grubba)  break; } goto bad_type; case 'p':
6d33d82001-03-28Henrik Grubbström (Grubba)  if(!strcmp(buf,"program")) { push_object_type(0, 0); push_type(T_PROGRAM); break; }
71a9672001-03-03Henrik Grubbström (Grubba)  goto bad_type; case 's': if(!strcmp(buf,"string")) { push_type(T_STRING); break; } goto bad_type; case 'v': if(!strcmp(buf,"void")) { push_type(T_VOID); break; } goto bad_type; case 't': if (!strcmp(buf,"tuple")) { while(ISSPACE(**s)) ++*s; if(**s == '(') { ++*s; internal_parse_type(_s); if(**s != ',') Pike_error("Expecting ','.\n"); ++*s; internal_parse_type(_s); if(**s != ')') Pike_error("Expecting ')'.\n"); ++*s; }else{ push_type(T_MIXED); push_type(T_MIXED); } push_reverse_type(T_TUPLE); break; }
54f8ac2001-03-17Henrik Grubbström (Grubba)  /* FIXME: Handle type(T) */ if(!strcmp(buf,"type")) { push_type(T_MIXED); push_type(T_TYPE); break; }
71a9672001-03-03Henrik Grubbström (Grubba)  goto bad_type; case 'm': if(!strcmp(buf,"mixed")) { push_type(T_MIXED); break; } if(!strcmp(buf,"mapping")) { while(ISSPACE(**s)) ++*s; if(**s == '(') { ++*s; internal_parse_type(_s); if(**s != ':') Pike_error("Expecting ':'.\n"); ++*s; internal_parse_type(_s); if(**s != ')') Pike_error("Expecting ')'.\n"); ++*s; }else{ push_type(T_MIXED); push_type(T_MIXED); } push_reverse_type(T_MAPPING); break; } if(!strcmp(buf,"multiset")) { while(ISSPACE(**s)) ++*s; if(**s == '(') { ++*s; internal_parse_type(_s); if(**s != ')') Pike_error("Expecting ')'.\n"); ++*s; }else{ push_type(T_MIXED); } push_type(T_MULTISET); break; } goto bad_type; case 'u': if(!strcmp(buf,"unknown")) { push_type(PIKE_T_UNKNOWN); break; } goto bad_type; case 'a': if(!strcmp(buf,"array")) { while(ISSPACE(**s)) ++*s; if(**s == '(') { ++*s; internal_parse_type(_s); if(**s != ')') Pike_error("Expecting ')'.\n"); ++*s; }else{ push_type(T_MIXED); } push_type(T_ARRAY); break; } goto bad_type; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if(atoi(buf)<10) { while(ISSPACE(**s)) ++*s; if(**s=='=') { ++*s; internal_parse_type(_s); push_assign_type(buf[0]); }else{ push_type(buf[0]); } break; } default: bad_type: Pike_error("Couldn't parse type. (%s)\n",buf); } while(ISSPACE(**s)) ++*s; } static void internal_parse_typeB(char **s) { while(ISSPACE(**((unsigned char **)s))) ++*s; switch(**s) { case '!': ++*s; internal_parse_typeB(s); push_type(T_NOT); break; case '(': ++*s; internal_parse_type(s); while(ISSPACE(**((unsigned char **)s))) ++*s; if(**s != ')') Pike_error("Expecting ')'.\n"); ++*s; break; default: internal_parse_typeA(s); } } static void internal_parse_typeCC(char **s) { internal_parse_typeB(s); while(ISSPACE(**((unsigned char **)s))) ++*s; while(**s == '*') { ++*s; while(ISSPACE(**((unsigned char **)s))) ++*s; push_type(T_ARRAY); } } static void internal_parse_typeC(char **s) { internal_parse_typeCC(s); if(**s == '&') { ++*s; internal_parse_typeC(s); push_reverse_type(T_AND); } } static void internal_parse_type(char **s) { internal_parse_typeC(s); while(**s == '|') { ++*s; internal_parse_typeC(s); push_type(T_OR); } } /* This function is used when adding simul efuns so that * the types for the functions can be easily stored in strings. * It takes a string on the exact same format as Pike and returns a type * struct. */ struct pike_type *parse_type(char *s) { struct pike_type *ret; #ifdef PIKE_DEBUG struct pike_type **ts=Pike_compiler->type_stackp; struct pike_type ***ptms=Pike_compiler->pike_type_mark_stackp; #endif /* fprintf(stderr, "parse_type(\"%s\")...\n", s); */ TYPE_STACK_DEBUG("parse_type"); type_stack_mark(); internal_parse_type(&s); if( *s ) fatal("Extra junk at end of type definition.\n"); ret=pop_unfinished_type(); #ifdef PIKE_DEBUG if(ts!=Pike_compiler->type_stackp || ptms!=Pike_compiler->pike_type_mark_stackp) fatal("Type stack whacked in parse_type.\n"); #endif return ret; } #ifdef PIKE_DEBUG /* FIXME: */ void stupid_describe_type_string(char *a, ptrdiff_t len) { ptrdiff_t e; for(e=0;e<len;e++) {
35ce412001-03-27Henrik Grubbström (Grubba)  if(e) fprintf(stderr, " ");
71a9672001-03-03Henrik Grubbström (Grubba)  switch(EXTRACT_UCHAR(a+e)) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "%c",EXTRACT_UCHAR(a+e));
71a9672001-03-03Henrik Grubbström (Grubba)  break;
35ce412001-03-27Henrik Grubbström (Grubba)  case T_SCOPE: fprintf(stderr, "scope"); break; case T_TUPLE: fprintf(stderr, "tuple"); break; case T_ASSIGN: fprintf(stderr, "="); break;
71a9672001-03-03Henrik Grubbström (Grubba)  case T_INT: { INT32 min=extract_type_int(a+e+1); INT32 max=extract_type_int(a+e+1+sizeof(INT32));
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "int");
71a9672001-03-03Henrik Grubbström (Grubba)  if(min!=MIN_INT32 || max!=MAX_INT32)
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "(%ld..%ld)",(long)min,(long)max);
71a9672001-03-03Henrik Grubbström (Grubba)  e+=sizeof(INT32)*2; break; }
35ce412001-03-27Henrik Grubbström (Grubba)  case T_FLOAT: fprintf(stderr, "float"); break; case T_STRING: fprintf(stderr, "string"); break; case T_TYPE: fprintf(stderr, "type"); break; case T_PROGRAM: fprintf(stderr, "program"); break;
71a9672001-03-03Henrik Grubbström (Grubba)  case T_OBJECT:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "object(%s %ld)",
71a9672001-03-03Henrik Grubbström (Grubba)  EXTRACT_UCHAR(a+e+1)?"is":"implements", (long)extract_type_int(a+e+2)); e+=sizeof(INT32)+1; break;
35ce412001-03-27Henrik Grubbström (Grubba)  case T_FUNCTION: fprintf(stderr, "function"); break; case T_ARRAY: fprintf(stderr, "array"); break; case T_MAPPING: fprintf(stderr, "mapping"); break; case T_MULTISET: fprintf(stderr, "multiset"); break;
71a9672001-03-03Henrik Grubbström (Grubba) 
35ce412001-03-27Henrik Grubbström (Grubba)  case PIKE_T_UNKNOWN: fprintf(stderr, "unknown"); break; case T_MANY: fprintf(stderr, "many"); break; case T_OR: fprintf(stderr, "or"); break; case T_AND: fprintf(stderr, "and"); break; case T_NOT: fprintf(stderr, "not"); break; case T_VOID: fprintf(stderr, "void"); break; case T_ZERO: fprintf(stderr, "zero"); break; case T_MIXED: fprintf(stderr, "mixed"); break;
71a9672001-03-03Henrik Grubbström (Grubba) 
35ce412001-03-27Henrik Grubbström (Grubba)  default: fprintf(stderr, "%d",EXTRACT_UCHAR(a+e)); break;
71a9672001-03-03Henrik Grubbström (Grubba)  } }
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "\n");
71a9672001-03-03Henrik Grubbström (Grubba) } void simple_describe_type(struct pike_type *s) { if (s) { switch(s->type) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "%d", s->type-'0');
71a9672001-03-03Henrik Grubbström (Grubba)  break;
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "{ %s = ", ((struct pike_string *)s->car)->str);
f62c412001-03-05Henrik Grubbström (Grubba)  simple_describe_type(s->cdr);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, " }");
f62c412001-03-05Henrik Grubbström (Grubba)  break;
71a9672001-03-03Henrik Grubbström (Grubba)  case T_SCOPE:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "scope(%ld, ", (long)(ptrdiff_t)s->car);
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->cdr);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ")");
71a9672001-03-03Henrik Grubbström (Grubba)  break; case T_TUPLE:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "tuple(");
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->car);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ", ");
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->cdr);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ")");
71a9672001-03-03Henrik Grubbström (Grubba)  break; case T_ASSIGN:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "%ld = ", (long)(ptrdiff_t)s->car);
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->cdr); break; case T_INT: { INT32 min = (ptrdiff_t)s->car; INT32 max = (ptrdiff_t)s->cdr;
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "int");
71a9672001-03-03Henrik Grubbström (Grubba)  if(min!=MIN_INT32 || max!=MAX_INT32)
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "(%ld..%ld)",(long)min,(long)max);
71a9672001-03-03Henrik Grubbström (Grubba)  break; }
35ce412001-03-27Henrik Grubbström (Grubba)  case T_FLOAT: fprintf(stderr, "float"); break; case T_STRING: fprintf(stderr, "string"); break;
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "type(");
54f8ac2001-03-17Henrik Grubbström (Grubba)  simple_describe_type(s->car);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ")");
54f8ac2001-03-17Henrik Grubbström (Grubba)  break;
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM: fprintf(stderr, "program("); simple_describe_type(s->car); fprintf(stderr, ")"); break;
71a9672001-03-03Henrik Grubbström (Grubba)  case T_OBJECT:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "object(%s %ld)",
71a9672001-03-03Henrik Grubbström (Grubba)  s->car?"is":"implements", (long)(ptrdiff_t)s->cdr); break; case T_FUNCTION: case T_MANY:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "function(");
71a9672001-03-03Henrik Grubbström (Grubba)  while(s->type == T_FUNCTION) { simple_describe_type(s->car); s = s->cdr; if ((s->type == T_FUNCTION) || (s->car->type != T_VOID)) {
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ", ");
71a9672001-03-03Henrik Grubbström (Grubba)  } } if (s->car->type != T_VOID) { simple_describe_type(s->car);
9b5a822001-03-29Henrik Grubbström (Grubba)  fprintf(stderr, "...");
71a9672001-03-03Henrik Grubbström (Grubba)  }
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ":");
9b5a822001-03-29Henrik Grubbström (Grubba)  simple_describe_type(s->cdr);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ")");
71a9672001-03-03Henrik Grubbström (Grubba)  break; case T_ARRAY:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "array(");
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->car);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ")");
71a9672001-03-03Henrik Grubbström (Grubba)  break; case T_MAPPING:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "mapping(");
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->car);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ":");
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->cdr);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ")");
71a9672001-03-03Henrik Grubbström (Grubba)  break; case T_MULTISET:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "multiset(");
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->car);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ")");
71a9672001-03-03Henrik Grubbström (Grubba)  break;
35ce412001-03-27Henrik Grubbström (Grubba)  case PIKE_T_UNKNOWN: fprintf(stderr, "unknown"); break;
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "ring(");
ce88d62001-03-19Henrik Grubbström (Grubba)  simple_describe_type(s->car);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "°");
ce88d62001-03-19Henrik Grubbström (Grubba)  simple_describe_type(s->cdr);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ")");
ce88d62001-03-19Henrik Grubbström (Grubba)  break;
71a9672001-03-03Henrik Grubbström (Grubba)  case T_OR:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "or(");
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->car);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "|");
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->cdr);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ")");
71a9672001-03-03Henrik Grubbström (Grubba)  break; case T_AND:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "and(");
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->car);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "&");
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->cdr);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ")");
71a9672001-03-03Henrik Grubbström (Grubba)  break; case T_NOT:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "not(");
71a9672001-03-03Henrik Grubbström (Grubba)  simple_describe_type(s->car);
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, ")");
71a9672001-03-03Henrik Grubbström (Grubba)  break;
35ce412001-03-27Henrik Grubbström (Grubba)  case T_VOID: fprintf(stderr, "void"); break; case T_ZERO: fprintf(stderr, "zero"); break; case T_MIXED: fprintf(stderr, "mixed"); break;
71a9672001-03-03Henrik Grubbström (Grubba)  default:
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "Unknown type node: %d, %p:%p",
71a9672001-03-03Henrik Grubbström (Grubba)  s->type, s->car, s->cdr); break; } } else {
35ce412001-03-27Henrik Grubbström (Grubba)  fprintf(stderr, "NULL");
71a9672001-03-03Henrik Grubbström (Grubba)  } }
9b5a822001-03-29Henrik Grubbström (Grubba)  #ifdef DEBUG_MALLOC void describe_all_types(void) { unsigned INT32 index; for(index = 0; index < pike_type_hash_size; index++) { struct pike_type *t; for (t = pike_type_hash[index]; t; t = t->next) { if (t->refs) { fprintf(stderr, "Type at 0x%p: ", t); simple_describe_type(t); fprintf(stderr, " (refs:%ld)\n", (long)t->refs); } } } } #endif /* DEBUG_MALLOC */
71a9672001-03-03Henrik Grubbström (Grubba) #endif static void low_describe_type(struct pike_type *t) { /**** FIXME: ****/ switch(t->type) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': my_putchar(t->type); break; case T_ASSIGN: my_putchar('(');
9e6f6f2001-03-18Henrik Grubbström (Grubba)  my_putchar('0' + (ptrdiff_t)t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  my_putchar('=');
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  my_putchar(')'); break; case T_SCOPE: my_putchar('{'); my_putchar((ptrdiff_t)t->car); my_putchar(',');
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  my_putchar('}'); break; case T_TUPLE: my_putchar('[');
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  my_putchar(',');
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  my_putchar(']'); break; case T_VOID: my_strcat("void"); break; case T_ZERO: my_strcat("zero"); break; case T_MIXED: my_strcat("mixed"); break; case PIKE_T_UNKNOWN: my_strcat("unknown"); break; case T_INT: { INT32 min=(ptrdiff_t)t->car; INT32 max=(ptrdiff_t)t->cdr; my_strcat("int"); if(min!=MIN_INT32 || max!=MAX_INT32) { char buffer[100]; sprintf(buffer,"(%ld..%ld)",(long)min,(long)max); my_strcat(buffer); } break; } case T_FLOAT: my_strcat("float"); break;
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM: my_strcat("program("); my_describe_type(t->car); my_strcat(")"); break;
71a9672001-03-03Henrik Grubbström (Grubba)  case T_OBJECT: if (t->cdr) { char buffer[100]; sprintf(buffer,"object(%s %ld)", t->car?"is":"implements", (long)(ptrdiff_t)t->cdr); my_strcat(buffer); }else{ my_strcat("object"); } break; case T_STRING: my_strcat("string"); break;
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE: my_strcat("type("); my_describe_type(t->car); my_strcat(")"); break;
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: if (!((struct pike_string *)t->car)->size_shift) { my_strcat("{ "); my_binary_strcat(((struct pike_string *)t->car)->str, ((struct pike_string *)t->car)->len); my_strcat(" = "); my_describe_type(t->cdr); my_strcat(" }"); } else { my_describe_type(t->cdr); } break;
71a9672001-03-03Henrik Grubbström (Grubba)  case T_FUNCTION: case T_MANY: { int s; my_strcat("function"); if(t->type == T_MANY && t->cdr->type == T_OR && ((t->cdr->car->type == T_MIXED && t->cdr->cdr->type == T_VOID) || (t->cdr->cdr->type == T_MIXED && t->cdr->car->type == T_VOID)) && (t->car->type == T_ZERO || (t->car->type == T_OR && ((t->car->car->type == T_ZERO && t->car->cdr->type == T_VOID) || (t->car->cdr->type == T_ZERO && t->car->car->type == T_VOID))))) { /* function == function(zero...:mixed|void) or * function(zero|void...:mixed|void) */ /* done */ } else { my_strcat("("); s=0; while(t->type != T_MANY) { if(s++) my_strcat(", ");
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  t = t->cdr; } if(t->car->type != T_VOID) { if(s++) my_strcat(", ");
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  my_strcat(" ..."); } my_strcat(" : ");
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  my_strcat(")"); } break; } case T_ARRAY: my_strcat("array"); if(t->car->type != T_MIXED) { my_strcat("(");
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  my_strcat(")"); } break; case T_MULTISET: my_strcat("multiset"); if(t->car->type != T_MIXED) { my_strcat("(");
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  my_strcat(")"); } break; case T_NOT: my_strcat("!"); if (t->car->type > T_NOT) { my_strcat("(");
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  my_strcat(")"); } else {
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  } break;
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: /* FIXME: Should be renumbered for correct parenthesing. */ my_strcat("("); my_describe_type(t->car); my_strcat(")°("); my_describe_type(t->cdr); my_strcat(")"); break;
71a9672001-03-03Henrik Grubbström (Grubba)  case T_OR: if (t->car->type > T_OR) { my_strcat("(");
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  my_strcat(")"); } else {
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  } my_strcat(" | "); if (t->cdr->type > T_OR) { my_strcat("(");
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  my_strcat(")"); } else {
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  } break; case T_AND: if (t->car->type > T_AND) { my_strcat("(");
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  my_strcat(")"); } else {
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  } my_strcat(" & "); if (t->cdr->type > T_AND) { my_strcat("(");
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  my_strcat(")"); } else {
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  } break; case T_MAPPING: my_strcat("mapping"); if(t->car->type != T_MIXED || t->cdr->type != T_MIXED) { my_strcat("(");
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  my_strcat(":");
f62c412001-03-05Henrik Grubbström (Grubba)  my_describe_type(t->cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  my_strcat(")"); } break; default: { char buf[20]; my_strcat("unknown code("); sprintf(buf, "%d", t->type); my_strcat(buf); my_strcat(")"); break; } } } void my_describe_type(struct pike_type *type) { low_describe_type(type); } struct pike_string *describe_type(struct pike_type *type) { check_type_string(type); if(!type) return make_shared_string("mixed"); init_buf(); low_describe_type(type); return free_buf(); } /******/ static int low_is_same_type(struct pike_type *a, struct pike_type *b) { return a == b; } TYPE_T compile_type_to_runtime_type(struct pike_type *t) { switch(t->type) {
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: return compile_type_to_runtime_type(t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  case T_OR: { TYPE_T tmp = compile_type_to_runtime_type(t->car); if(tmp == compile_type_to_runtime_type(t->cdr)) return tmp; /* FALL_THROUGH */ } case T_TUPLE: /* FIXME: Shouldn't occur/should be converted to array? */ /* FALL_THROUGH */ default: return T_MIXED; case T_ZERO: return T_INT; case T_SCOPE:
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME:
71a9672001-03-03Henrik Grubbström (Grubba)  return compile_type_to_runtime_type(t->cdr); case T_MANY: return T_FUNCTION; case T_ARRAY: case T_MAPPING: case T_MULTISET: case T_OBJECT: case T_PROGRAM: case T_FUNCTION: case T_STRING: case T_TYPE: case T_INT: case T_FLOAT: return t->type; } } static int low_find_exact_type_match(struct pike_type *needle, struct pike_type *haystack, unsigned int separator) { while(haystack->type == separator) { if(low_find_exact_type_match(needle, haystack->car, separator)) return 1; haystack = haystack->cdr; } return low_is_same_type(needle, haystack); } static void very_low_or_pike_types(struct pike_type *to_push, struct pike_type *not_push) { while(to_push->type == T_OR) { very_low_or_pike_types(to_push->car, not_push); to_push = to_push->cdr; } /* FIXME: * this might use the 'le' operator */ if(!low_find_exact_type_match(to_push, not_push, T_OR)) { push_finished_type(to_push); push_type(T_OR); } } static void low_or_pike_types(struct pike_type *t1, struct pike_type *t2, int zero_implied) { if(!t1) { if(!t2) push_type(T_VOID); else push_finished_type(t2); } else if((!t2) || (t2->type == T_ZERO && zero_implied) ) { push_finished_type(t1); } else if (t1->type == T_ZERO && zero_implied) { push_finished_type(t2); } else if(t1->type == T_MIXED || t2->type == T_MIXED) { push_type(T_MIXED); } else if(t1->type == T_INT && t2->type == T_INT) { INT32 min, max;
0c30122001-03-31Henrik Grubbström (Grubba)  if ((((ptrdiff_t)t1->cdr) + 1 < (ptrdiff_t)t2->car) || (((ptrdiff_t)t2->cdr) + 1 < (ptrdiff_t)t1->car)) {
cdeb542001-03-31Henrik Grubbström (Grubba)  /* No overlap. */ push_finished_type(t1); push_finished_type(t2); push_type(T_OR); } else { /* Overlap */ min = MINIMUM((ptrdiff_t)t1->car, (ptrdiff_t)t2->car); max = MAXIMUM((ptrdiff_t)t1->cdr, (ptrdiff_t)t2->cdr); push_int_type(min, max); }
71a9672001-03-03Henrik Grubbström (Grubba)  } else if (t1->type == T_SCOPE) { if (t2->type == T_SCOPE) { low_or_pike_types(t1->cdr, t2->cdr, zero_implied); if (t1->car > t2->car) push_scope_type((ptrdiff_t)t1->car); else push_scope_type((ptrdiff_t)t2->car); } else { low_or_pike_types(t1->cdr, t2, zero_implied); push_scope_type((ptrdiff_t)t1->car); } } else if (t2->type == T_SCOPE) { low_or_pike_types(t1, t2->cdr, zero_implied); push_scope_type((ptrdiff_t)t2->car); push_type(T_SCOPE); } else { push_finished_type(t1); very_low_or_pike_types(t2,t1); } } struct pike_type *or_pike_types(struct pike_type *a, struct pike_type *b, int zero_implied) { type_stack_mark(); low_or_pike_types(a,b,1 /*zero_implied*/); return pop_unfinished_type(); } static void very_low_and_pike_types(struct pike_type *to_push, struct pike_type *not_push) { while(to_push->type == T_AND) { very_low_and_pike_types(to_push->car, not_push); to_push = to_push->cdr; } if(!low_find_exact_type_match(to_push, not_push, T_AND)) { push_finished_type(to_push); push_type(T_AND); } } static void even_lower_and_pike_types(struct pike_type *t1, struct pike_type *t2) { while(t2->type == T_OR) { even_lower_and_pike_types(t1, t2->car); t2 = t2->cdr; } if (t1->type == t2->type) { if (t1->type == T_INT) { INT32 i1, i2; INT32 upper_bound, lower_bound; i1 = (ptrdiff_t)t1->cdr; i2 = (ptrdiff_t)t2->cdr; upper_bound = MINIMUM(i1,i2); i1 = (ptrdiff_t)t1->car; i2 = (ptrdiff_t)t2->car; lower_bound = MAXIMUM(i1,i2); if (upper_bound >= lower_bound) { push_int_type(lower_bound, upper_bound); push_type(T_OR); } } else { push_finished_type(t1); push_type(T_OR); } } } static int lower_and_pike_types(struct pike_type *t1, struct pike_type *t2) { int is_complex = 0; while(t1->type == T_OR) { is_complex |= lower_and_pike_types(t1->car, t2); t1 = t1->cdr; } switch(t1->type) { case T_ZERO: case T_VOID: break; case T_STRING: case T_FLOAT: case T_INT: even_lower_and_pike_types(t1, t2); break; default: return 1; } return is_complex; } static int low_and_push_complex_pike_type(struct pike_type *type) { int is_complex = 0; while(type->type == T_OR) { int new_complex; new_complex = low_and_push_complex_pike_type(type->car); if (new_complex) { if (is_complex) { push_type(T_OR); } else { is_complex = 1; } } type = type->cdr; } switch(type->type) { case T_VOID: case T_ZERO: case T_STRING: case T_FLOAT: case T_INT: /* Simple type. Already handled. */ break; default: push_finished_type(type); if (is_complex) { push_type(T_OR); } return 1; } return is_complex; } static void low_and_pike_types(struct pike_type *t1, struct pike_type *t2) { if(!t1 || t1->type == T_VOID || !t2 || t2->type == T_VOID) { push_type(T_VOID); } else if(t1->type == T_ZERO || t2->type == T_ZERO) { push_type(T_ZERO); } else if(t1->type == T_MIXED) { push_finished_type(t2); } else if(t2->type == T_MIXED) { push_finished_type(t1); } else if(t1->type == T_INT && t2->type == T_INT) { INT32 i1,i2; INT32 upper_bound, lower_bound; i1 = (ptrdiff_t)t1->cdr; i2 = (ptrdiff_t)t2->cdr; upper_bound = MINIMUM(i1,i2); i1 = (ptrdiff_t)t1->car; i2 = (ptrdiff_t)t2->car; lower_bound = MAXIMUM(i1,i2); if (upper_bound >= lower_bound) { push_int_type(lower_bound, upper_bound); } else { /* No overlap! */ /* FIXME: Warn? */ push_type(T_VOID); } } else if (t1->type == T_SCOPE) { if (t2->type == T_SCOPE) { low_and_pike_types(t1->cdr, t2->cdr); if (t1->car > t2->car) push_scope_type((ptrdiff_t)t1->car); else push_scope_type((ptrdiff_t)t2->car); } else { low_and_pike_types(t1->cdr, t2); push_scope_type((ptrdiff_t)t1->car); } } else if (t2->type == T_SCOPE) { low_and_pike_types(t1, t2->cdr); push_scope_type((ptrdiff_t)t2->car); } else if((t1->type == t2->type) && ((t1->type == T_STRING) ||
6d33d82001-03-28Henrik Grubbström (Grubba)  (t1->type == T_FLOAT)))
71a9672001-03-03Henrik Grubbström (Grubba)  { push_finished_type(t1); } else if(low_pike_types_le(t1, t2, 0, 0)) { push_finished_type(t1); } else if(low_pike_types_le(t2, t1, 0, 0)) { push_finished_type(t2); } else { push_type(T_ZERO); if (lower_and_pike_types(t1, t2)) { /* t1 contains complex types. */ if (low_and_push_complex_pike_type(t2)) { /* t2 also contains complex types. */ low_and_push_complex_pike_type(t1); push_type(T_AND); push_type(T_OR); } } /* push_finished_type(t1); */ /* very_low_and_pike_types(t2,t1); */ } } struct pike_type *and_pike_types(struct pike_type *a, struct pike_type *b) { type_stack_mark(); low_and_pike_types(a, b); return pop_unfinished_type(); } static struct pike_type *low_object_lfun_type(struct pike_type *t, short lfun) { struct program *p; int i; p = id_to_program((ptrdiff_t)t->cdr); if(!p) return 0; i=FIND_LFUN(p, lfun); if(i==-1) return 0; return ID_FROM_INT(p, i)->type; } /******/ /* * match two type strings, return zero if they don't match, and return * the part of 'a' that _did_ match if it did. */ static struct pike_type *low_match_types(struct pike_type *a, struct pike_type *b, int flags) #ifdef PIKE_TYPE_DEBUG { int e; char *s; static struct pike_type *low_match_types2(struct pike_type *a, struct pike_type *b, int flags); if (l_flag>2) { init_buf(); for(e=0;e<indent;e++) my_strcat(" "); my_strcat("low_match_types("); my_describe_type(a); my_strcat(",\n"); for(e=0;e<indent;e++) my_strcat(" "); my_strcat(" "); my_describe_type(b); my_strcat(",\n"); for(e=0;e<indent;e++) my_strcat(" "); my_strcat(" "); if (flags) { int f = 0; if (flags & A_EXACT) { my_strcat("A_EXACT"); f = 1; } if (flags & B_EXACT) { if (f) { my_strcat(" | "); } my_strcat("B_EXACT"); f = 1; } if (flags & NO_MAX_ARGS) { if (f) { my_strcat(" | "); } my_strcat("NO_MAX_ARGS"); f = 1; } if (flags & NO_SHORTCUTS) { if (f) { my_strcat(" | "); } my_strcat("NO_SHORTCUTS"); f = 1; } } else { my_strcat("0"); } my_strcat(");\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); indent++; } a = low_match_types2(a, b, flags); if (l_flag>2) { indent--; init_buf(); for(e=0;e<indent;e++) my_strcat(" "); my_strcat("= "); if(a) my_describe_type(a); else my_strcat("NULL"); my_strcat("\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); } return a; } static struct pike_type *low_match_types2(struct pike_type *a, struct pike_type *b, int flags) #endif { int correct_args; struct pike_type *ret; if(a == b) return a; switch(a->type) { case T_AND: ret = low_match_types(a->car, b, flags); if(!ret) return 0; return low_match_types(a->cdr, b, flags); case T_OR: ret = low_match_types(a->car, b, flags); if(ret && !(flags & NO_SHORTCUTS)) return ret; if(ret) { low_match_types(a->cdr, b, flags); return ret; }else{ return low_match_types(a->cdr, b, flags); }
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: return low_match_types(a->car, b, flags);
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: return low_match_types(a->cdr, b, flags);
71a9672001-03-03Henrik Grubbström (Grubba)  case T_NOT: if(low_match_types(a->car, b, (flags ^ B_EXACT ) | NO_MAX_ARGS)) return 0; return a; case T_ASSIGN: ret = low_match_types(a->cdr, b, flags); if(ret && (b->type != T_VOID)) {
9e6f6f2001-03-18Henrik Grubbström (Grubba)  int m = (ptrdiff_t)a->car;
71a9672001-03-03Henrik Grubbström (Grubba)  struct pike_type *tmp;
9e6f6f2001-03-18Henrik Grubbström (Grubba)  #ifdef PIKE_DEBUG if ((m < 0) || (m > 9)) { fatal("marker out of range: %d\n", m); } #endif /* PIKE_DEBUG */
71a9672001-03-03Henrik Grubbström (Grubba)  type_stack_mark(); push_finished_type_with_markers(b, b_markers); 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) { char *s; int e; init_buf(); for(e=0;e<indent;e++) my_strcat(" "); my_strcat("a_markers["); my_putchar((char)(m+'0')); my_strcat("]="); my_describe_type(a_markers[m]); my_strcat("\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); } #endif #ifdef PIKE_DEBUG if((ptrdiff_t)a_markers[m]->type == m+'0') fatal("Cyclic type!\n"); #endif } return ret; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { int m = a->type - '0'; if(a_markers[m]) { #ifdef PIKE_DEBUG if(a_markers[m]->type == a->type) fatal("Cyclic type!\n"); if(a_markers[m]->type == T_OR && a_markers[m]->car->type == a->type) fatal("Cyclic type!\n"); #endif return low_match_types(a_markers[m], b, flags); } else return low_match_types(mixed_type_string, b, flags); } } switch(b->type) { case T_AND: ret = low_match_types(a, b->car, flags); if(!ret) return 0; return low_match_types(a, b->cdr, flags); case T_OR: ret = low_match_types(a, b->car, flags); if(ret && !(flags & NO_SHORTCUTS)) return ret; if(ret) { low_match_types(a, b->cdr, flags); return ret; }else{ return low_match_types(a, b->cdr, flags); }
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: return low_match_types(a, b->car, flags);
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: return low_match_types(a, b->cdr, flags);
71a9672001-03-03Henrik Grubbström (Grubba)  case T_NOT: if(low_match_types(a, b->car, (flags ^ A_EXACT ) | NO_MAX_ARGS)) return 0; return a; case T_ASSIGN: ret = low_match_types(a, b->cdr, flags); if(ret && (a->type != T_VOID)) {
9e6f6f2001-03-18Henrik Grubbström (Grubba)  int m = (ptrdiff_t)b->car;
71a9672001-03-03Henrik Grubbström (Grubba)  struct pike_type *tmp; type_stack_mark(); push_finished_type_with_markers(a, a_markers); 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) { char *s; int e; init_buf(); for(e=0;e<indent;e++) my_strcat(" "); my_strcat("b_markers["); my_putchar((char)(m+'0')); my_strcat("]="); my_describe_type(b_markers[m]); my_strcat("\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); } #endif #ifdef PIKE_DEBUG if((ptrdiff_t)b_markers[m]->type == m+'0') fatal("Cyclic type!\n"); #endif } return ret; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': {
339b7c2001-06-05Henrik Grubbström (Grubba)  int m = b->type - '0';
71a9672001-03-03Henrik Grubbström (Grubba)  if(b_markers[m]) { #ifdef PIKE_DEBUG if(b_markers[m]->type == b->type) fatal("Cyclic type!\n"); #endif return low_match_types(a, b_markers[m], flags); } else return low_match_types(a, mixed_type_string, flags); } } /* 'mixed' matches anything */ if((a->type == T_ZERO || a->type == T_MIXED) && !(flags & (A_EXACT|B_EXACT)) && (b->type != T_VOID)) { #if 1 switch(b->type) { /* These types can contain sub-types */ case T_ARRAY: low_match_types(array_type_string, b, flags); break; case T_MAPPING: low_match_types(mapping_type_string, b, flags); break; case T_FUNCTION: case T_MANY: low_match_types(function_type_string, b, flags); break; case T_MULTISET: low_match_types(multiset_type_string, b, flags); break; } #endif return a; } if((b->type == T_ZERO || b->type == T_MIXED) && !(flags & (A_EXACT|B_EXACT)) && (a->type != T_VOID)) { #if 1 switch(a->type) { /* These types can contain sub-types */ case T_ARRAY: low_match_types(a, array_type_string, flags); break; case T_MAPPING: low_match_types(a, mapping_type_string, flags); break; case T_FUNCTION: case T_MANY: low_match_types(a, function_type_string, flags); break; case T_MULTISET: low_match_types(a, multiset_type_string, flags); break; } #endif return a; } /* Special cases (tm) */ switch(TWOT(a->type, b->type)) { case TWOT(T_PROGRAM, T_FUNCTION): case TWOT(T_FUNCTION, T_PROGRAM): case TWOT(T_PROGRAM, T_MANY): case TWOT(T_MANY, T_PROGRAM):
6d33d82001-03-28Henrik Grubbström (Grubba)  /* FIXME: Should look at the sub-type of the program * to determine the prototype to use. */
71a9672001-03-03Henrik Grubbström (Grubba)  return a; case TWOT(T_OBJECT, T_FUNCTION): case TWOT(T_OBJECT, T_MANY): { struct pike_type *s; if((s = low_object_lfun_type(a, LFUN_CALL))) return low_match_types(s, b, flags); if (flags & B_EXACT) { /* A function isn't an object */ return 0; } return a; } case TWOT(T_FUNCTION, T_OBJECT): case TWOT(T_MANY, T_OBJECT): { struct pike_type *s; if((s=low_object_lfun_type(b, LFUN_CALL))) return low_match_types(a, s, flags); if (flags & A_EXACT) { /* A function isn't an object */ return 0; } return a; } case TWOT(T_INT, T_ZERO): { if ((((ptrdiff_t)a->car) > 0) || (((ptrdiff_t)a->cdr) < 0)) { return 0; } return a; } case TWOT(T_ZERO, T_INT): { if ((((ptrdiff_t)b->car) > 0) || (((ptrdiff_t)b->cdr) < 0)) { return 0; } return a; } case TWOT(T_FUNCTION, T_FUNCTION): case TWOT(T_FUNCTION, T_MANY): case TWOT(T_MANY, T_FUNCTION): case TWOT(T_MANY, T_MANY): ret = a; correct_args=0; while ((a->type != T_MANY) || (b->type != T_MANY)) { struct pike_type *a_tmp, *b_tmp; a_tmp = a->car; if (a->type == T_FUNCTION) { a = a->cdr; } b_tmp = b->car; if (b->type == T_FUNCTION) { b = b->cdr; } if(!low_match_types(a_tmp, b_tmp, (flags | NO_MAX_ARGS) & ~(A_EXACT|B_EXACT))) return 0; if(++correct_args > max_correct_args) if(!(flags & NO_MAX_ARGS)) max_correct_args=correct_args; } /* check the 'many' type */ if(b->car->type != T_VOID && a->car->type != T_VOID) { if(!low_match_types(a->car, b->car, (flags | NO_MAX_ARGS) & ~(A_EXACT|B_EXACT))) return 0; } if(!(flags & NO_MAX_ARGS)) max_correct_args=0x7fffffff; /* check the returntype */ a = a->cdr; b = b->cdr; if ((b->type == T_VOID) && (a->type != T_VOID)) { /* Promote b to a function returning zero. */ if (!low_match_types(a, zero_type_string, flags & ~(A_EXACT|B_EXACT))) return 0; } else if ((a->type == T_VOID) && (b->type != T_VOID)) { /* Promote a to a function returning zero. */ if(!low_match_types(zero_type_string, b, flags & ~(A_EXACT|B_EXACT))) return 0; } else if(!low_match_types(a, b, flags & ~(A_EXACT|B_EXACT))) return 0; return ret; } if(a->type != b->type) return 0; ret=a; switch(a->type) { case T_MAPPING: if(!low_match_types(a->car, b->car, flags & ~(A_EXACT|B_EXACT))) return 0; if(!low_match_types(a->cdr, b->cdr, flags & ~(A_EXACT|B_EXACT))) return 0; break; case T_OBJECT: #if 0 if(a->cdr || b->cdr) { fprintf(stderr,"Type match1: "); stupid_describe_type(a,type_length(a)); fprintf(stderr,"Type match2: "); stupid_describe_type(b,type_length(b)); } #endif /* object(* 0) matches any object */ if(!a->cdr || !b->cdr) break; /* object(x *) =? object(x *) */ if(a->car == b->car) { /* x? */ if(a->car) { /* object(1 x) =? object(1 x) */ if(a->cdr != b->cdr) return 0; }else{ /* object(0 *) =? object(0 *) */ /* FIXME: Ought to check the implements relation */ break; } } { struct program *ap,*bp; ap = id_to_program((ptrdiff_t)a->cdr); bp = id_to_program((ptrdiff_t)b->cdr); if(!ap || !bp) break; #if 0 /* FIXME: Temporary kludge. * match_types() currently seems to need to be symetric. */ if (!implements(ap,bp) && !implements(bp,ap)) return 0; #else /* !1 */ if(a->car) { if(!implements(implements_a=ap,implements_b=bp)) return 0; }else{ if(!implements(implements_a=bp,implements_b=ap)) return 0; } #endif /* 1 */ } break; case T_INT: { INT32 amin = (ptrdiff_t)a->car; INT32 amax = (ptrdiff_t)a->cdr; INT32 bmin = (ptrdiff_t)b->car; INT32 bmax = (ptrdiff_t)b->cdr; if(amin > bmax || bmin > amax) return 0; break; }
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM:
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE:
71a9672001-03-03Henrik Grubbström (Grubba)  case T_MULTISET: case T_ARRAY: if(!low_match_types(a->car, b->car, flags & ~(A_EXACT|B_EXACT))) return 0; case T_FLOAT: case T_STRING: case T_ZERO: case T_VOID: case T_MIXED: break; default: fatal("Error in type string.\n"); } return ret; } /* * Check the partial ordering relation. * * mixed * * int float string program function object * * zero * * void * * Note that non-destructive operations are assumed. * ie it's assumed that calling a function(mapping(string|int:string|int):void) * with a mapping(int:int) won't change the type of the mapping after the * operation. */ static int low_pike_types_le(struct pike_type *a, struct pike_type *b, int array_cnt, unsigned int flags) #ifdef PIKE_TYPE_DEBUG { int e; char *s; static int low_pike_types_le2(struct pike_type *a, struct pike_type *b, int array_cnt, unsigned int flags); int res; char buf[50]; if (l_flag>2) { init_buf(); for(e=0;e<indent;e++) my_strcat(" "); my_strcat("low_pike_types_le("); my_describe_type(a); my_strcat(",\n"); for(e=0;e<indent;e++) my_strcat(" "); my_strcat(" "); my_describe_type(b); my_strcat(",\n"); for(e=0;e<indent;e++) my_strcat(" "); my_strcat(" "); sprintf(buf, "%d", array_cnt); my_strcat(buf); my_strcat(", "); sprintf(buf, "0x%08x", flags); my_strcat(buf); my_strcat(");\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); indent++; } res = low_pike_types_le2(a, b, array_cnt, flags); if (l_flag>2) { indent--; for(e=0;e<indent;e++) fprintf(stderr, " "); fprintf(stderr, "= %d\n", res); } return res; } static int low_pike_types_le2(struct pike_type *a, struct pike_type *b, int array_cnt, unsigned int flags) #endif /* PIKE_TYPE_DEBUG */ { int ret; recurse: #if 0 fprintf(stderr, "low_pike_types_le(%d, %d, %d, 0x%08x)\n", a->type, b->type, array_cnt, flags); #endif /* 0 */ if(a == b) return 1; switch(a->type) { case T_AND: /* OK if either of the parts is a subset. */ /* FIXME: What if b also contains an AND? */ ret = low_pike_types_le(a->car, b, array_cnt, flags); if(ret) return ret; a = a->cdr; goto recurse; case T_OR: /* OK, if both of the parts are a subset */ if (a->car->type == T_VOID) { /* Special case for T_VOID */ /* FIXME: Should probably be handled as T_ZERO. */ a = a->cdr; goto recurse; } else { ret = low_pike_types_le(a->car, b, array_cnt, flags); if (!ret) return 0; if (a->cdr->type == T_VOID) { /* Special case for T_VOID */ /* FIXME: Should probably be handled as T_ZERO. */ return 1; } else { a = a->cdr; goto recurse; } }
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: a = a->car; goto recurse;
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: a = a->cdr; goto recurse;
71a9672001-03-03Henrik Grubbström (Grubba)  case T_NOT: if (b->type == T_NOT) { struct pike_type *tmp = a->car; a = b->car; b = tmp; array_cnt = -array_cnt; goto recurse; } if (a->car->type == T_NOT) { a = a->car->car; goto recurse; } if (low_pike_types_le(a->car, b, array_cnt, flags)) { return 0; } /* FIXME: This is wrong... */ return !low_pike_types_le(b, a->car, -array_cnt, flags); case T_ASSIGN: ret = low_pike_types_le(a->cdr, b, array_cnt, flags); if(ret && (b->type != T_VOID)) {
9e6f6f2001-03-18Henrik Grubbström (Grubba)  int m = (ptrdiff_t)a->car;
71a9672001-03-03Henrik Grubbström (Grubba)  struct pike_type *tmp; int i; type_stack_mark(); push_finished_type_with_markers(b, b_markers); for(i=array_cnt; i > 0; i--) push_type(T_ARRAY); 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) { char *s; int e; init_buf(); for(e=0;e<indent;e++) my_strcat(" "); my_strcat("a_markers["); my_putchar((char)(m+'0')); my_strcat("]="); my_describe_type(a_markers[m]); my_strcat("\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); } #endif } return ret; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': {
ff36302001-03-31Henrik Grubbström (Grubba)  int m = a->type - '0';
71a9672001-03-03Henrik Grubbström (Grubba)  if(a_markers[m]) { a = a_markers[m]; } else { a = mixed_type_string; } goto recurse; } } switch(b->type) { case T_AND: /* OK, if a is a subset of both parts. */ ret = low_pike_types_le(a, b->car, array_cnt, flags); if(!ret) return 0; b = b->cdr; goto recurse; case T_OR: /* OK if a is a subset of either of the parts. */ ret=low_pike_types_le(a, b->car, array_cnt, flags); if (ret) return ret; b = b->cdr; goto recurse;
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: b = b->car; goto recurse;
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: b = b->cdr; goto recurse;
71a9672001-03-03Henrik Grubbström (Grubba)  case T_NOT: if (b->car->type == T_NOT) { b = b->car->car; goto recurse; } if (low_pike_types_le(a, b->car, array_cnt, flags)) { return 0; } /* FIXME: This is wrong... */ return !low_pike_types_le(b->car, a, -array_cnt, flags); case T_ASSIGN: ret = low_pike_types_le(a, b->cdr, array_cnt, flags); if(ret && (a->type != T_VOID)) {
9e6f6f2001-03-18Henrik Grubbström (Grubba)  int m = (ptrdiff_t)b->car;
71a9672001-03-03Henrik Grubbström (Grubba)  struct pike_type *tmp; int i; type_stack_mark(); push_finished_type_with_markers(a, a_markers); for(i = array_cnt; i < 0; i++) push_type(T_ARRAY); 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) { char *s; int e; init_buf(); for(e=0;e<indent;e++) my_strcat(" "); my_strcat("b_markers["); my_putchar((char)(m+'0')); my_strcat("]="); my_describe_type(b_markers[m]); my_strcat("\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); } #endif } return ret; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': {
ff36302001-03-31Henrik Grubbström (Grubba)  int m = b->type - '0';
71a9672001-03-03Henrik Grubbström (Grubba)  if(b_markers[m]) { b = b_markers[m]; } else { b = mixed_type_string; } goto recurse; } } if ((array_cnt < 0) && (b->type == T_ARRAY)) { while (b->type == T_ARRAY) { b = b->car; if (!++array_cnt) break; } goto recurse; } else if ((array_cnt > 0) && (a->type == T_ARRAY)) { while (a->type == T_ARRAY) { a = a->car; if (!--array_cnt) break; } goto recurse; } /* NOTE: void only matches void. */ if (a->type == T_VOID) { /* void <= any_type */ if (array_cnt >= 0) { /* !array(void) */ if (!array_cnt && (b->type == T_VOID)) { return 1; } return 0; } } if (b->type == T_VOID) { if (array_cnt <= 0) { /* !array(void) */ return 0; } } if (b->type == T_MIXED) { /* any_type <= 'mixed' */ if (array_cnt <= 0) { /* !array(mixed) */ return 1; } } if (a->type == T_MIXED) { if (array_cnt >= 0) { /* !array(mixed) */ return 0; } } if (a->type == T_ZERO) { /* void <= zero <= any_type */ if (array_cnt >= 0) { /* !array(zero) */ return 1; } } if (b->type == T_ZERO) { if (array_cnt <= 0) { /* !array(zero) */ return 0; } } /* Special cases (tm) */ switch(TWOT(a->type, b->type)) { case TWOT(T_PROGRAM, T_FUNCTION): case TWOT(T_FUNCTION, T_PROGRAM): case TWOT(T_PROGRAM, T_MANY): case TWOT(T_MANY, T_PROGRAM): /* FIXME: Not really... Should check the return value. */
6d33d82001-03-28Henrik Grubbström (Grubba)  /* FIXME: Should also look at the subtype of the program. */
71a9672001-03-03Henrik Grubbström (Grubba)  return 1; case TWOT(T_OBJECT, T_FUNCTION): case TWOT(T_OBJECT, T_MANY): { if((a = low_object_lfun_type(a, LFUN_CALL))) { goto recurse; } return 1; } case TWOT(T_FUNCTION, T_OBJECT): case TWOT(T_MANY, T_OBJECT): { if((b=low_object_lfun_type(b, LFUN_CALL))) { goto recurse; } return 1; } case TWOT(T_FUNCTION, T_ARRAY): case TWOT(T_MANY, T_ARRAY): { while (b->type == T_ARRAY) { b = b->car; array_cnt++; } goto recurse; } case TWOT(T_ARRAY, T_FUNCTION): case TWOT(T_ARRAY, T_MANY): { while (a->type == T_ARRAY) { a = a->car; array_cnt--; } goto recurse; } case TWOT(T_FUNCTION, T_FUNCTION): case TWOT(T_FUNCTION, T_MANY): case TWOT(T_MANY, T_FUNCTION): /* * function(A...:B) <= function(C...:D) iff C <= A && B <= D */ /* * function(:int) <= function(int:int) * function(int|string:int) <= function(int:int) * function(:int) <= function(:void) * function(string:int) != function(int:int) * function(int:int) != function(:int) * * FIXME: Enforcing of all required arguments? */ while((a->type != T_MANY) || (b->type != T_MANY)) { struct pike_type *a_tmp, *b_tmp; a_tmp = a->car; if (a->type == T_FUNCTION) { a = a->cdr; } b_tmp = b->car; if (b->type == T_FUNCTION) { b = b->cdr; } if (a_tmp->type != T_VOID) { if (!low_pike_types_le(b_tmp, a_tmp, 0, flags)) { return 0; } } } /* FALL_THROUGH */ case TWOT(T_MANY, T_MANY): /* check the 'many' type */ if ((a->car->type != T_VOID) && (b->car->type != T_VOID)) { if (!low_pike_types_le(b->car, a->car, 0, flags)) { return 0; } } a = a->cdr; b = b->cdr; /* check the returntype */ /* FIXME: Check array_cnt */ if ((b->type != T_VOID) && (a->type != T_VOID)) { if(!low_pike_types_le(a, b, array_cnt, flags)) return 0; } return 1; } if(a->type != b->type) return 0; if (array_cnt) return 0; switch(a->type) { case T_MAPPING: /* * mapping(A:B) <= mapping(C:D) iff A <= C && B <= D. */ if(!low_pike_types_le(a->car, b->car, 0, flags)) return 0; array_cnt = 0; a = a->cdr; b = b->cdr; goto recurse; case T_OBJECT: #if 0 if(a->cdr || b->cdr) { fprintf(stderr,"Type match1: "); stupid_describe_type(a,type_length(a)); fprintf(stderr,"Type match2: "); stupid_describe_type(b,type_length(b)); } #endif /* * object(0|1 x) <= object(0|1 0) * object(0|1 0) <=! object(0|1 !0) * object(1 x) <= object(0|1 x) * object(1 x) <= object(1 y) iff x == y * object(1 x) <= object(0 y) iff x implements y * Not WEAK_OBJECTS: * object(0 x) <= object(0 y) iff x implements y * WEAK_OBJECTS: * object(0 x) <= object(0 y) iff x is_compatible y */ /* object(* 0) matches any object */ if(!b->cdr) return 1; if(!a->cdr) return 0; if ((a->car || !b->car) && (a->cdr == b->cdr)) return 1; if (b->car) { return 0; } { struct program *ap = id_to_program((ptrdiff_t)a->cdr); struct program *bp = id_to_program((ptrdiff_t)b->cdr); if (!ap || !bp) { /* Shouldn't happen... */ return 0; } if ((flags & LE_WEAK_OBJECTS) && (!a->car)) { return is_compatible(implements_a=ap, implements_b=bp); } return implements(implements_a=ap, implements_b=bp); } break; case T_INT: { INT32 amin = (ptrdiff_t)a->car; INT32 amax = (ptrdiff_t)a->cdr; INT32 bmin = (ptrdiff_t)b->car; INT32 bmax = (ptrdiff_t)b->cdr; if(amin < bmin || amax > bmax) return 0; break; }
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE:
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM:
71a9672001-03-03Henrik Grubbström (Grubba)  case T_MULTISET: case T_ARRAY: a = a->car; b = b->car; array_cnt = 0; goto recurse; case T_FLOAT: case T_STRING: case T_ZERO: case T_VOID: case T_MIXED: break; default: fatal("Error in type string.\n"); } return 1; } /* * Check the function parameters. * Note: The difference between this function, and pike_types_le() * is the more lenient check for T_OR, and the handling of T_ARRAY. */ int strict_check_call(struct pike_type *fun_type, struct pike_type *arg_type) { while ((fun_type->type == T_OR) || (fun_type->type == T_ARRAY)) { if (fun_type->type == T_OR) { int res = strict_check_call(fun_type->car, arg_type); if (res) return res; fun_type = fun_type->cdr; } else { fun_type = fun_type->car; } } return low_pike_types_le(fun_type, arg_type, 0, 0); } /* * Check validity of soft-cast. * Note: This uses a weaker check of function arguments, since * people get confused otherwise. */ int check_soft_cast(struct pike_type *to, struct pike_type *from) { return low_pike_types_le(to, from, 0, LE_WEAK_OBJECTS); } /* * Return the return type from a function call. */ static int low_get_return_type(struct pike_type *a, struct pike_type *b) { int tmp; switch(a->type) { case T_OR: { struct pike_type *o1, *o2; o1=o2=0; type_stack_mark(); if(low_get_return_type(a->car, b)) { o1=pop_unfinished_type(); type_stack_mark(); } if(low_get_return_type(a->cdr, b)) o2=pop_unfinished_type(); else pop_stack_mark(); if(!o1 && !o2) return 0; low_or_pike_types(o1, o2, 0); if(o1) free_type(o1); if(o2) free_type(o2); return 1; } case T_AND: type_stack_mark(); tmp = low_get_return_type(a->car, b); type_stack_pop_to_mark(); if(!tmp) return 0; return low_get_return_type(a->cdr, b);
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: return low_get_return_type(a->car, b);
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: return low_get_return_type(a->cdr, b);
71a9672001-03-03Henrik Grubbström (Grubba)  case T_ARRAY: tmp = low_get_return_type(a->car, b); if(!tmp) return 0; push_type(T_ARRAY); return 1; } a = low_match_types(a, b, NO_SHORTCUTS); if(a) { #if 0 if ((lex.pragmas & ID_STRICT_TYPES) && !low_pike_types_le(a, b, 0, 0)) { yywarning("Type mismatch"); } #endif /* 0 */ 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 ); return 1; case T_PROGRAM:
6d33d82001-03-28Henrik Grubbström (Grubba)  push_finished_type(a->car);
71a9672001-03-03Henrik Grubbström (Grubba)  return 1; default: push_type(T_MIXED); return 1; } } return 0; } int match_types(struct pike_type *a, struct pike_type *b) { check_type_string(a); check_type_string(b); clear_markers(); return !!low_match_types(a, b, 0); } int pike_types_le(struct pike_type *a,struct pike_type *b) { check_type_string(a); check_type_string(b); clear_markers(); return low_pike_types_le(a, b, 0, 0); } #ifdef DEBUG_MALLOC #define low_index_type(X,Y,Z) ((struct pike_type *)debug_malloc_pass(debug_low_index_type((X),(Y),(Z)))) #else #define low_index_type debug_low_index_type #endif /* FIXME, add the index */ static struct pike_type *debug_low_index_type(struct pike_type *t, struct pike_type *index_type, node *n) { struct pike_type *tmp; struct program *p; switch(low_check_indexing(t, index_type, n)) { case 0: return 0; case -1: add_ref(zero_type_string); return zero_type_string; }
f62c412001-03-05Henrik Grubbström (Grubba)  while(t->type == PIKE_T_NAME) { t = t->cdr; } while(index_type->type == PIKE_T_NAME) { index_type = index_type->cdr; }
71a9672001-03-03Henrik Grubbström (Grubba)  switch(t->type) { case T_OBJECT: { p = id_to_program((ptrdiff_t)t->cdr); comefrom_int_index: if(p && n) { INT32 i; if(n->token == F_ARROW) { /* FIXME: make this stricter */ if((i=FIND_LFUN(p,LFUN_ARROW))!=-1) { /* FIXME: function_type_string should be replaced with something * derived from type_string */ if(i!=-1 && (tmp=check_call(function_type_string, ID_FROM_INT(p, i)->type, 0))) return tmp; add_ref(mixed_type_string); return mixed_type_string; } }else{ if((i=FIND_LFUN(p,LFUN_INDEX)) != -1) { /* FIXME: function_type_string should be replaced with something * derived from type_string */ if(i!=-1 && (tmp=check_call(function_type_string, ID_FROM_INT(p, i)->type, 0))) return tmp; add_ref(mixed_type_string); return mixed_type_string; } } if(CDR(n)->token == F_CONSTANT && CDR(n)->u.sval.type==T_STRING) { i = find_shared_string_identifier(CDR(n)->u.sval.u.string, p); if(i==-1) { add_ref(mixed_type_string); return mixed_type_string; }else{ #if 0 if(t->car || (p->identifier_references[i].id_flags & ID_NOMASK) || (ID_FROM_INT(p, i)->identifier_flags & IDENTIFIER_PROTOTYPED)) { #endif add_ref(ID_FROM_INT(p, i)->type); return ID_FROM_INT(p, i)->type; #if 0 }else{ add_ref(mixed_type_string); return mixed_type_string; } #endif } } } } default: add_ref(mixed_type_string); return mixed_type_string; case T_MIXED: if (lex.pragmas & ID_STRICT_TYPES) { yywarning("Indexing mixed."); } add_ref(mixed_type_string); return mixed_type_string; case T_INT: #ifdef AUTO_BIGNUM /* Don't force Gmp.mpz to be loaded here since this function * is called long before the master object is compiled... * /Hubbe */ p=get_auto_bignum_program_or_zero(); goto comefrom_int_index; #endif case T_ZERO: case T_TYPE:
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
71a9672001-03-03Henrik Grubbström (Grubba)  case T_VOID: case T_FLOAT: return 0; case T_OR: { struct pike_type *a,*b; a = low_index_type(t->car, index_type, n); b = low_index_type(t->cdr, index_type,n); if(!b) return a; if(!a) return b; type_stack_mark(); low_or_pike_types(a,b,1); free_type(a); free_type(b); return pop_unfinished_type(); } case T_AND: /* FIXME: Shouldn't both branches be looked at? */ return low_index_type(t->cdr, index_type, n); case T_STRING: /* always int */ case T_MULTISET: /* always int */ add_ref(int_type_string); return int_type_string; case T_MAPPING: add_ref(t = t->cdr); return t; case T_ARRAY: { struct pike_type *a; if(low_pike_types_le(string_type_string, index_type, 0, 0) && (a = low_index_type(t->car, string_type_string, n))) { /* Possible to index the array with a string. */ type_stack_mark(); push_finished_type(a); free_type(a); push_type(T_ARRAY); if (low_match_types(int_type_string, index_type, 0)) { /* Also possible to index the array with an int. */ push_finished_type(t->car); push_type(T_OR); } return pop_unfinished_type(); } if (low_match_types(int_type_string, index_type, 0)) { /* Possible to index the array with an int. */ add_ref(t->car); return t->car; } /* Bad index type. */ return 0; } } } struct pike_type *index_type(struct pike_type *type, struct pike_type *index_type, node *n) { struct pike_type *t; clear_markers(); t = low_index_type(type, index_type, n); if(!t) {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(t, mixed_type_string);
71a9672001-03-03Henrik Grubbström (Grubba)  } return t; }
663cbf2002-05-15Henrik Grubbström (Grubba) #ifdef DEBUG_MALLOC #define low_range_type(X,Y,Z) ((struct pike_type *)debug_malloc_pass(debug_low_range_type((X),(Y),(Z)))) #else #define low_range_type debug_low_range_type #endif /* FIXME, add the index * * FIXME: Is the above fixme valid for this function too? */ static struct pike_type *debug_low_range_type(struct pike_type *t, struct pike_type *index1_type, struct pike_type *index2_type) { struct pike_type *tmp; struct program *p; while(t->type == PIKE_T_NAME) { t = t->cdr; } while(index1_type->type == PIKE_T_NAME) { index1_type = index1_type->cdr; } while(index2_type->type == PIKE_T_NAME) { index2_type = index2_type->cdr; } switch(t->type) { case T_OBJECT: { p = id_to_program((ptrdiff_t)t->cdr); if(p) { INT32 i; if((i = FIND_LFUN(p, LFUN_INDEX)) != -1) { struct pike_type *call_type = NULL; /* FIXME: function_type_string should be replaced with something * derived from type_string */ type_stack_mark(); push_finished_type(mixed_type_string); push_finished_type(void_type_string); push_type(T_OR); /* Return type */ push_finished_type(void_type_string); /* Many type */ push_type(T_MANY); push_finished_type(index2_type); /* arg2 type */ push_type(T_FUNCTION); push_finished_type(index1_type); /* arg1 type */ push_type(T_FUNCTION); call_type = pop_unfinished_type(); if((tmp = check_call(call_type, ID_FROM_INT(p, i)->type, 0))) { free_type(call_type); return tmp; } add_ref(mixed_type_string); return mixed_type_string; } yywarning("Ranging object without index operator."); return 0; } if (lex.pragmas & ID_STRICT_TYPES) { yywarning("Ranging generic object."); } add_ref(mixed_type_string); return mixed_type_string; } case T_MIXED: if (lex.pragmas & ID_STRICT_TYPES) { yywarning("Ranging mixed."); } add_ref(mixed_type_string); return mixed_type_string; case T_INT: case T_ZERO: case T_TYPE: case PIKE_T_RING: case T_VOID: case T_FLOAT: case T_MULTISET: case T_MAPPING: /* Illegal range operation. */ /* FIXME: Strict type warning. */ return 0; case T_ARRAY: case T_STRING: /* Check that the index types are compatible with int. */ { struct pike_type *a; if (!low_match_types(int_type_string, index1_type, 0)) { struct pike_string *s = describe_type(t); yywarning("Bad argument 1 to range operator on %s.", s->str); free_string(s); yyexplain_nonmatching_types(int_type_string, index1_type, YYTE_IS_WARNING); /* Bad index1 type. */ return 0; } if (!low_match_types(int_type_string, index2_type, 0)) { struct pike_string *s = describe_type(t); yywarning("Bad argument 2 to range operator on %s.", s->str); free_string(s); yyexplain_nonmatching_types(int_type_string, index2_type, YYTE_IS_WARNING); /* Bad index2 type. */ return 0; } } /* FALLTHROUGH */ default: /* Identity. */ add_ref(t); return t; case T_OR: { struct pike_type *a,*b; a = low_range_type(t->car, index1_type, index2_type); b = low_range_type(t->cdr, index1_type, index2_type); if(!b) return a; if(!a) return b; type_stack_mark(); low_or_pike_types(a,b,1); free_type(a); free_type(b); return pop_unfinished_type(); } case T_AND: /* FIXME: Shouldn't both branches be looked at? */ return low_range_type(t->cdr, index1_type, index2_type); } } struct pike_type *range_type(struct pike_type *type, struct pike_type *index1_type, struct pike_type *index2_type) { struct pike_type *t; clear_markers(); t = low_range_type(type, index1_type, index2_type); if(!t) { yyerror("Invalid range operation."); copy_pike_type(t, type); } return t; }
71a9672001-03-03Henrik Grubbström (Grubba)  static struct pike_type *low_array_value_type(struct pike_type *arr_t) { struct pike_type *res = NULL; struct pike_type *sub_t; while (arr_t->type == T_OR) { sub_t = low_array_value_type(arr_t->car); arr_t = arr_t->cdr; if (sub_t) { if (res) { struct pike_type *new = or_pike_types(res, sub_t, 1); free_type(res); free_type(sub_t); res = new; } else { res = sub_t; } } } if (arr_t->type != T_ARRAY) return res;
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(sub_t, arr_t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  if (res) { struct pike_type *new = or_pike_types(res, sub_t, 1); free_type(res); free_type(sub_t); return new; } return sub_t; } struct pike_type *array_value_type(struct pike_type *array_type) { struct pike_type *t = low_array_value_type(array_type); if (!t) {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(t, mixed_type_string);
71a9672001-03-03Henrik Grubbström (Grubba)  } return t; } #ifdef DEBUG_MALLOC #define low_key_type(X,Y) ((struct pike_type *)debug_malloc_pass(debug_low_key_type((X),(Y)))) #else #define low_key_type debug_low_key_type #endif /* FIXME, add the index */ static struct pike_type *debug_low_key_type(struct pike_type *t, node *n) { switch(t->type) { case T_OBJECT: { struct program *p = id_to_program((ptrdiff_t)t->cdr); if(p && n) { if(n->token == F_ARROW) { if(FIND_LFUN(p,LFUN_ARROW)!=-1 || FIND_LFUN(p,LFUN_ASSIGN_ARROW)!=-1) { add_ref(mixed_type_string); return mixed_type_string; } }else{ if(FIND_LFUN(p,LFUN_INDEX) != -1 || FIND_LFUN(p,LFUN_ASSIGN_INDEX) != -1) { add_ref(mixed_type_string); return mixed_type_string; } } } add_ref(string_type_string); return string_type_string; } default: add_ref(mixed_type_string); return mixed_type_string; case T_VOID: case T_ZERO: case T_TYPE:
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
71a9672001-03-03Henrik Grubbström (Grubba)  case T_FLOAT: case T_INT: return 0; case T_OR: { struct pike_type *a,*b; a = low_key_type(t->car, n); b = low_key_type(t->cdr, n); if(!b) return a; if(!a) return b; type_stack_mark(); low_or_pike_types(a,b,1); free_type(a); free_type(b); return pop_unfinished_type(); } case T_AND: /* FIXME: Shouldn't this look at both branches? */ return low_key_type(t->cdr, n);
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: return low_key_type(t->cdr, n);
71a9672001-03-03Henrik Grubbström (Grubba)  case T_ARRAY: case T_STRING: /* always int */ add_ref(int_type_string); return int_type_string; case T_MAPPING: case T_MULTISET:
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(t, t->car);
71a9672001-03-03Henrik Grubbström (Grubba)  return t; } } struct pike_type *key_type(struct pike_type *type, node *n) { struct pike_type *t; clear_markers(); t = low_key_type(type,n); if(!t) {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(t, mixed_type_string);
71a9672001-03-03Henrik Grubbström (Grubba)  } return t; } static int low_check_indexing(struct pike_type *type, struct pike_type *index_type, node *n) { switch(type->type) { case T_OR: return low_check_indexing(type->car, index_type, n) || low_check_indexing(type->cdr, index_type, n); case T_AND: return low_check_indexing(type->car, index_type, n) && low_check_indexing(type->cdr, index_type, n); case T_NOT: return low_check_indexing(type->car, index_type, n) != 1;
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: return low_check_indexing(type->cdr, index_type, n);
71a9672001-03-03Henrik Grubbström (Grubba)  case T_ARRAY: if(low_match_types(string_type_string, index_type, 0) && low_check_indexing(type->car, index_type, n)) return 1; case T_STRING: return !!low_match_types(int_type_string, index_type, 0); case T_OBJECT: { struct program *p = id_to_program((ptrdiff_t)type->cdr); if(p) { if(n->token == F_ARROW) { if(FIND_LFUN(p,LFUN_ARROW)!=-1 || FIND_LFUN(p,LFUN_ASSIGN_ARROW)!=-1) return 1; }else{ if(FIND_LFUN(p,LFUN_INDEX)!=-1 || FIND_LFUN(p,LFUN_ASSIGN_INDEX)!=-1) return 1; } return !!low_match_types(string_type_string, index_type,0); }else{ return 1; } } case T_MULTISET: case T_MAPPING: /* FIXME: Why -1 and not 0? */ return low_match_types(type->car, index_type, 0) ? 1 : -1; #ifdef AUTO_BIGNUM case T_INT: #endif case T_PROGRAM: return !!low_match_types(string_type_string, index_type, 0); case T_MIXED: return 1; default: return 0; } } int check_indexing(struct pike_type *type, struct pike_type *index_type, node *n) { check_type_string(type); check_type_string(index_type); return low_check_indexing(type, index_type, n); } static int low_count_arguments(struct pike_type *q) { int num=0, num2; switch(q->type) { case T_OR: num = low_count_arguments(q->car); num2 = low_count_arguments(q->cdr); if(num<0 && num2>0) return num; if(num2<0 && num>0) return num2; if(num2<0 && num<0) return ~num>~num2?num:num2; return num>num2?num:num2; case T_AND: num = low_count_arguments(q->car); num2 = low_count_arguments(q->cdr); if(num<0 && num2>0) return num2; if(num2<0 && num>0) return num; if(num2<0 && num<0) return ~num<~num2?num:num2; return num<num2?num:num2;
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: return low_count_arguments(q->cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  default: return 0x7fffffff; case T_FUNCTION: while(q->type == T_FUNCTION) { num++; q = q->cdr; } /* FALL_THROUGH */ case T_MANY: q = q->car; if(q->type != T_VOID) return ~num; return num; } } /* Count the number of arguments for a funciton type. * return -1-n if the function can take number of arguments * >= n (varargs) */ int count_arguments(struct pike_type *s) { check_type_string(s); return low_count_arguments(s); } static int low_minimum_arguments(struct pike_type *q) { int num; switch(q->type) { case T_OR: case T_AND: return MAXIMUM(low_count_arguments(q->car), low_count_arguments(q->cdr)); default: return 0;
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: return low_minimum_arguments(q->cdr);
71a9672001-03-03Henrik Grubbström (Grubba)  case T_FUNCTION: num = 0; while(q->type == T_FUNCTION) { if(low_match_types(void_type_string, q->car, B_EXACT)) return num; num++; q = q->cdr; } return num; case T_MANY: return 0; } } /* Count the minimum number of arguments for a funciton type. */ int minimum_arguments(struct pike_type *s) { int ret; check_type_string(s); ret = low_minimum_arguments(s); #if 0 fprintf(stderr,"minimum_arguments("); simple_describe_type(s); fprintf(stderr," ) -> %d\n",ret); #endif return ret; } struct pike_type *check_call(struct pike_type *args, struct pike_type *type, int strict) { check_type_string(args); check_type_string(type); clear_markers(); type_stack_mark(); max_correct_args=0; if(low_get_return_type(type, args)) { if (strict) { if (!strict_check_call(type, args)) { struct pike_string *type_t = describe_type(type); struct pike_type *func_zero_type; MAKE_CONSTANT_TYPE(func_zero_type, tFuncV(tNone,tZero,tMix)); if (!low_pike_types_le(type, func_zero_type, 0, 0)) { yywarning("Calling non-function value."); yywarning("Type called: %s", type_t->str); } else { struct pike_string *arg_t = describe_type(args); yywarning("Arguments not strictly compatible."); yywarning("Expected: %s", type_t->str); yywarning("Got : %s", arg_t->str); free_string(arg_t); } free_type(func_zero_type); free_string(type_t); } } return pop_unfinished_type(); }else{ pop_stack_mark(); return 0; } } INT32 get_max_args(struct pike_type *type) { INT32 ret,tmp=max_correct_args; check_type(type->type); clear_markers(); type = check_call(function_type_string, type, 0); if(type) free_type(type); ret=max_correct_args; max_correct_args=tmp; return tmp; }
6d33d82001-03-28Henrik Grubbström (Grubba) /* NOTE: type loses a reference. */ struct pike_type *new_check_call(node *fun, int *argno, struct pike_type *type, node *args) { struct pike_type *tmp_type = NULL; while (args && (args->token == F_ARG_LIST)) { type = new_check_call(fun, argno, type, CAR(args)); args = CDR(args); } if (!args) { return type; } switch(type->type) { case T_NOT: break; case T_FUNCTION: if (!pike_types_le(args->type, type->car)) { if (!match_types(args->type, type->car)) { /* Bad arg */ } else { /* Not strict arg */ } }
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(tmp_type, type->cdr);
6d33d82001-03-28Henrik Grubbström (Grubba)  free_type(type); type = tmp_type; (*argno)++; break; case T_MANY: if (!pike_types_le(args->type, type->car)) { if (!match_types(args->type, type->car)) { /* Bad arg */ } else { /* Not strict arg */ } } (*argno)++; break; } return type; }
71a9672001-03-03Henrik Grubbström (Grubba)  struct pike_type *zzap_function_return(struct pike_type *a, INT32 id) { switch(a->type) { case T_OR: { struct pike_type *ar, *br, *ret=0; ar = zzap_function_return(a->car, id); br = zzap_function_return(a->cdr, id); if(ar && br) ret = or_pike_types(ar, br, 0); if(ar) free_type(ar); if(br) free_type(br); return ret; } case T_FUNCTION: case T_MANY: { int nargs=0; type_stack_mark(); while(a->type == T_FUNCTION) { push_finished_type(a->car); nargs++; a = a->cdr; } push_finished_type(a->car); push_object_type(1, id); push_reverse_type(T_MANY); while(nargs-- > 0) { push_reverse_type(T_FUNCTION); } return pop_unfinished_type(); } case T_ARRAY: return zzap_function_return(a->car, id);
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: return zzap_function_return(a->cdr, id);
71a9672001-03-03Henrik Grubbström (Grubba)  case T_MIXED: /* I wonder when this occurrs, but apparently it does... */ /* FIXME: */ type_stack_mark(); push_object_type(1, id); push_type(T_VOID); push_type(T_MIXED); push_type(T_OR); push_type(T_MANY); return pop_unfinished_type(); } /* This error is bogus /Hubbe fatal("zzap_function_return() called with unexpected value: %d\n", EXTRACT_UCHAR(a)); */ return NULL; } struct pike_type *get_type_of_svalue(struct svalue *s) { struct pike_type *ret; switch(s->type) { case T_FUNCTION: if(s->subtype == FUNCTION_BUILTIN) {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(ret, s->u.efun->type);
71a9672001-03-03Henrik Grubbström (Grubba)  }else{ struct program *p; p=s->u.object->prog; if(!p) {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(ret, zero_type_string);
71a9672001-03-03Henrik Grubbström (Grubba)  }else{
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(ret, ID_FROM_INT(p,s->subtype)->type);
71a9672001-03-03Henrik Grubbström (Grubba)  } } return ret; case T_ARRAY: { struct pike_type *arg_type;
5b15bb2001-12-10Martin Stjernholm  struct array *a = s->u.array;
71a9672001-03-03Henrik Grubbström (Grubba) #if 0 int i; /* FIXME: Circular structures? */
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(arg_type, zero_type_string);
71a9672001-03-03Henrik Grubbström (Grubba)  for (i = 0; i < a->size; i++) { struct pike_type *tmp1 = get_type_of_svalue(a->item+i); struct pike_type *tmp2 = or_pike_types(arg_type, tmp1, 1); free_type(arg_type); free_type(tmp1); arg_type = tmp2; } #else /* !0 */ if (a->size)
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(arg_type, mixed_type_string);
71a9672001-03-03Henrik Grubbström (Grubba)  else
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(arg_type, zero_type_string);
71a9672001-03-03Henrik Grubbström (Grubba) #endif /* 0 */ type_stack_mark(); push_finished_type(arg_type); free_type(arg_type); push_type(s->type); return pop_unfinished_type(); }
5b15bb2001-12-10Martin Stjernholm  case T_MULTISET: type_stack_mark(); if (multiset_sizeof(s->u.multiset)) { push_type(T_MIXED); } else { push_type(T_ZERO); } push_type(T_MULTISET); return pop_unfinished_type();
71a9672001-03-03Henrik Grubbström (Grubba)  case T_MAPPING: type_stack_mark(); if (m_sizeof(s->u.mapping)) { push_type(T_MIXED); push_type(T_MIXED); } else { push_type(T_ZERO); push_type(T_ZERO); } push_type(T_MAPPING); return pop_unfinished_type(); case T_OBJECT: type_stack_mark(); if(s->u.object->prog) { #ifdef AUTO_BIGNUM if(is_bignum_object(s->u.object)) { push_int_type(MIN_INT32, MAX_INT32); } else #endif { push_object_type(1, s->u.object->prog->id); } }else{ /* Destructed object */ push_type(T_ZERO); } return pop_unfinished_type(); case T_INT: if(s->u.integer) { type_stack_mark(); /* Fixme, check that the integer is in range of MIN_INT32 .. MAX_INT32! */ push_int_type(s->u.integer, s->u.integer); return pop_unfinished_type(); }else{
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(ret, zero_type_string);
71a9672001-03-03Henrik Grubbström (Grubba)  return ret; } case T_PROGRAM: {
6d33d82001-03-28Henrik Grubbström (Grubba)  /* FIXME: An alternative would be to push program(object(1,p->id)). */
71a9672001-03-03Henrik Grubbström (Grubba)  struct pike_type *a; struct pike_string *tmp; int id; if(s->u.program->identifiers) { id=FIND_LFUN(s->u.program,LFUN_CREATE); if(id>=0) { a = ID_FROM_INT(s->u.program, id)->type; if((a = zzap_function_return(a, s->u.program->id))) return a; tmp=describe_type(ID_FROM_INT(s->u.program, id)->type); /* yywarning("Failed to zzap function return for type: %s.", tmp->str);*/ free_string(tmp); } } else { if((a = zzap_function_return(function_type_string, s->u.program->id))) return a; } type_stack_mark(); push_object_type(1, s->u.program->id); push_type(T_VOID); push_type(T_MANY); return pop_unfinished_type(); }
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE: type_stack_mark(); push_finished_type(s->u.type); push_type(T_TYPE); return pop_unfinished_type();
71a9672001-03-03Henrik Grubbström (Grubba)  default: type_stack_mark(); push_type(s->type); return pop_unfinished_type(); } } static struct pike_type *low_object_type_to_program_type(struct pike_type *obj_t) { struct pike_type *res = NULL; struct pike_type *sub; struct svalue sval; int id; while(obj_t->type == T_OR) { sub = low_object_type_to_program_type(obj_t->car); if (!sub) { if (res) { free_type(res); } return NULL; } if (res) { struct pike_type *tmp = or_pike_types(res, sub, 1); free_type(res); free_type(sub); res = tmp; } else { res = sub; } obj_t = obj_t->cdr; } sval.type = T_PROGRAM; if ((obj_t->type != T_OBJECT) || (!(id = (ptrdiff_t)obj_t->cdr)) || (!(sval.u.program = id_to_program(id))) || (!(sub = get_type_of_svalue(&sval)))) { if (res) { free_type(res); } return NULL; } /* FIXME: obj_t->car should propagate to the return-type in sub. */ if (res) { struct pike_type *tmp = or_pike_types(res, sub, 1); free_type(res); free_type(sub); return tmp; } return sub; } /* Used by fix_object_program_type() */ struct pike_type *object_type_to_program_type(struct pike_type *obj_t) { return low_object_type_to_program_type(obj_t); } int type_may_overload(struct pike_type *type, int lfun) { switch(type->type) { case T_ASSIGN: return type_may_overload(type->cdr, lfun); case T_FUNCTION: case T_MANY: case T_ARRAY: /* might want to check for `() */ default: return 0;
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME: return type_may_overload(type->cdr, lfun);
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: return type_may_overload(type->car, lfun);
71a9672001-03-03Henrik Grubbström (Grubba)  case T_OR: return type_may_overload(type->car, lfun) || type_may_overload(type->cdr, lfun); case T_AND: return type_may_overload(type->car, lfun) && type_may_overload(type->cdr, lfun); case T_NOT: return !type_may_overload(type->car, lfun); case T_MIXED: return 1; case T_OBJECT: { struct program *p = id_to_program((ptrdiff_t)type->cdr); if(!p) return 1; return FIND_LFUN(p, lfun)!=-1; } } } void yyexplain_nonmatching_types(struct pike_type *type_a, struct pike_type *type_b, int flags) { implements_a=0; implements_b=0; match_types(type_a, type_b); #if 0 if(!(implements_a && implements_b && type_a->str[0]==T_OBJECT && type_b->str[0]==T_OBJECT)) #endif /* 0 */ { struct pike_string *s1, *s2; s1 = describe_type(type_a); s2 = describe_type(type_b); if(flags & YYTE_IS_WARNING) { yywarning("Expected: %s",s1->str); yywarning("Got : %s",s2->str); }else{ my_yyerror("Expected: %s",s1->str); my_yyerror("Got : %s",s2->str); } free_string(s1); free_string(s2); } if(implements_a && implements_b) yyexplain_not_implements(implements_a,implements_b,flags); } /******/
9b5a822001-03-29Henrik Grubbström (Grubba)  #ifdef DEBUG_MALLOC #define low_make_pike_type(T,C) ((struct pike_type *)debug_malloc_pass(debug_low_make_pike_type(T,C))) #define low_make_function_type(T,C) ((struct pike_type *)debug_malloc_pass(debug_low_make_function_type(T,C))) #else /* !DEBUG_MALLOC */ #define low_make_pike_type debug_low_make_pike_type #define low_make_function_type debug_low_make_function_type #endif /* DEBUG_MALLOC */
71a9672001-03-03Henrik Grubbström (Grubba) 
9b5a822001-03-29Henrik Grubbström (Grubba) static struct pike_type *debug_low_make_pike_type(unsigned char *type_string, unsigned char **cont);
71a9672001-03-03Henrik Grubbström (Grubba) 
9b5a822001-03-29Henrik Grubbström (Grubba) static struct pike_type *debug_low_make_function_type(unsigned char *type_string, unsigned char **cont)
71a9672001-03-03Henrik Grubbström (Grubba) {
df9f822001-04-23Marcus Comstedt  struct pike_type *tmp;
71a9672001-03-03Henrik Grubbström (Grubba)  if (*type_string == T_MANY) {
df9f822001-04-23Marcus Comstedt  tmp = low_make_pike_type(type_string+1, cont); return mk_type(T_MANY, tmp,
71a9672001-03-03Henrik Grubbström (Grubba)  low_make_pike_type(*cont, cont), PT_COPY_BOTH); }
df9f822001-04-23Marcus Comstedt  tmp = low_make_pike_type(type_string, cont); return mk_type(T_FUNCTION, tmp,
71a9672001-03-03Henrik Grubbström (Grubba)  low_make_function_type(*cont, cont), PT_COPY_BOTH); }
9b5a822001-03-29Henrik Grubbström (Grubba) static struct pike_type *debug_low_make_pike_type(unsigned char *type_string, unsigned char **cont)
71a9672001-03-03Henrik Grubbström (Grubba) { unsigned INT32 type;
df9f822001-04-23Marcus Comstedt  struct pike_type *tmp;
71a9672001-03-03Henrik Grubbström (Grubba)  switch(type = *type_string) { case T_SCOPE: case T_ASSIGN:
9e6f6f2001-03-18Henrik Grubbström (Grubba)  if ((type_string[1] < '0') || (type_string[1] > '9')) { fatal("low_make_pike_type(): Bad marker: %d\n", type_string[1]); } return mk_type(type, (void *)(ptrdiff_t)(type_string[1] - '0'),
71a9672001-03-03Henrik Grubbström (Grubba)  low_make_pike_type(type_string+2, cont), PT_COPY_CDR); case T_FUNCTION: /* Multiple ordered values. */ /* FIXME: */ return low_make_function_type(type_string+1, cont); case T_TUPLE: case T_MAPPING:
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
71a9672001-03-03Henrik Grubbström (Grubba)  /* Order dependant */
df9f822001-04-23Marcus Comstedt  tmp = low_make_pike_type(type_string+1, cont); return mk_type(type, tmp,
71a9672001-03-03Henrik Grubbström (Grubba)  low_make_pike_type(*cont, cont), PT_COPY_BOTH); case T_OR: case T_AND: /* Order independant */ /* FIXME: */
df9f822001-04-23Marcus Comstedt  tmp = low_make_pike_type(type_string+1, cont); return mk_type(type, tmp,
71a9672001-03-03Henrik Grubbström (Grubba)  low_make_pike_type(*cont, cont), PT_COPY_BOTH); case T_ARRAY: case T_MULTISET:
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE:
71a9672001-03-03Henrik Grubbström (Grubba)  case T_NOT:
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM:
71a9672001-03-03Henrik Grubbström (Grubba)  /* Single type */ return mk_type(type, low_make_pike_type(type_string+1, cont), NULL, PT_COPY_CAR); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* Marker type */ *cont = type_string+1; return mk_type(type, NULL, NULL, PT_SET_MARKER); case T_FLOAT: case T_STRING: case T_MIXED: case T_VOID: case T_ZERO: case PIKE_T_UNKNOWN: /* Leaf type */ *cont = type_string+1; return mk_type(type, NULL, NULL, 0); case T_INT: *cont = type_string + 9; /* 2*sizeof(INT32) + 1 */ return mk_type(T_INT, (void *)(ptrdiff_t)extract_type_int(type_string+1), (void *)(ptrdiff_t)extract_type_int(type_string+5), 0); case T_OBJECT: *cont = type_string + 6; /* 1 + sizeof(INT32) + 1 */ return mk_type(T_OBJECT, (void *)(ptrdiff_t)(type_string[1]), (void *)(ptrdiff_t)extract_type_int(type_string+2), 0); default: fatal("compile_type_string(): Error in type string %d.\n", type); /* NOT_REACHED */ break; } /* NOT_REACHED */ return NULL; } /* Make a pike-type from a serialized (old-style) type. */
9b5a822001-03-29Henrik Grubbström (Grubba) struct pike_type *debug_make_pike_type(const char *serialized_type)
71a9672001-03-03Henrik Grubbström (Grubba) { return low_make_pike_type((unsigned char *)serialized_type, (unsigned char **)&serialized_type); } int pike_type_allow_premature_toss(struct pike_type *type)
9399f52001-03-03Henrik Grubbström (Grubba) {
71a9672001-03-03Henrik Grubbström (Grubba)  again:
9399f52001-03-03Henrik Grubbström (Grubba) #if 0
71a9672001-03-03Henrik Grubbström (Grubba)  fprintf(stderr, "pike_type_allow_premature_toss(): Type: %d\n", type->type);
9399f52001-03-03Henrik Grubbström (Grubba) #endif /* 0 */
71a9672001-03-03Henrik Grubbström (Grubba)  switch(type->type) { case T_NOT: return !pike_type_allow_premature_toss(type->car); case T_OBJECT: case T_MIXED: case T_FUNCTION: case T_MANY: return 0;
f62c412001-03-05Henrik Grubbström (Grubba)  case PIKE_T_NAME:
71a9672001-03-03Henrik Grubbström (Grubba)  case T_SCOPE: case T_ASSIGN: type = type->cdr; goto again;
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: type = type->car; goto again;
71a9672001-03-03Henrik Grubbström (Grubba)  case T_OR: case T_MAPPING: if(!pike_type_allow_premature_toss(type->car)) return 0; type = type->cdr; goto again; case T_AND: /* FIXME: Should probably look at both branches. */ type = type->cdr; goto again; case T_ARRAY: case T_MULTISET: type = type->car; goto again; case T_PROGRAM:
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_TYPE:
71a9672001-03-03Henrik Grubbström (Grubba)  case T_INT: case T_FLOAT: case T_STRING: case T_VOID: return 1; default: fatal("pike_type_allow_premature_toss: Unknown type code (%d)\n", ((unsigned char *)type)[-1]); /* NOT_REACHED */ return 0; }
9399f52001-03-03Henrik Grubbström (Grubba) }
71a9672001-03-03Henrik Grubbström (Grubba) 
9e6f6f2001-03-18Henrik Grubbström (Grubba) static void low_type_to_string(struct pike_type *t) { recurse: switch(t->type) { case T_ARRAY: case T_MULTISET: case T_TYPE: case T_NOT:
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM:
9e6f6f2001-03-18Henrik Grubbström (Grubba)  my_putchar(t->type); /* FALL_THROUGH */ case PIKE_T_NAME: t = t->car; goto recurse;
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
9e6f6f2001-03-18Henrik Grubbström (Grubba)  case T_TUPLE: case T_MAPPING: case T_OR: case T_AND: my_putchar(t->type); low_type_to_string(t->car); t = t->cdr; goto recurse;
a72b5e2001-03-18Henrik Grubbström (Grubba)  case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
9e6f6f2001-03-18Henrik Grubbström (Grubba)  case T_STRING: case T_FLOAT: case T_ZERO: case T_VOID: case T_MIXED: my_putchar(t->type); break; case T_OBJECT:
c02ce62001-03-18Per Hedbor  { INT32 i; my_putchar(T_OBJECT); i = (INT32)(ptrdiff_t)t->car; my_putchar( i ); i = (INT32)(ptrdiff_t)t->cdr; if( i > 65535 ) i = 0; /* Not constant between recompilations */ my_putchar((i >> 24) & 0xff); my_putchar((i >> 16) & 0xff); my_putchar((i >> 8) & 0xff); my_putchar(i & 0xff);
9e6f6f2001-03-18Henrik Grubbström (Grubba)  } break; case T_INT: { INT32 i; my_putchar(T_INT); i = (INT32)(ptrdiff_t)t->car; my_putchar((i >> 24) & 0xff); my_putchar((i >> 16) & 0xff); my_putchar((i >> 8) & 0xff); my_putchar(i & 0xff); i = (INT32)(ptrdiff_t)t->cdr; my_putchar((i >> 24) & 0xff); my_putchar((i >> 16) & 0xff); my_putchar((i >> 8) & 0xff); my_putchar(i & 0xff); } break; case T_FUNCTION: case T_MANY: my_putchar(T_FUNCTION); while(t->type == T_FUNCTION) { low_type_to_string(t->car); t = t->cdr; } my_putchar(T_MANY); low_type_to_string(t->car); t = t->cdr; goto recurse; case T_SCOPE: case T_ASSIGN: my_putchar(t->type); my_putchar('0' + (ptrdiff_t)t->car); t = t->cdr; goto recurse;
a72b5e2001-03-18Henrik Grubbström (Grubba)  default: Pike_error("low_type_to_string(): Unsupported node: %d\n", t->type); break;
9e6f6f2001-03-18Henrik Grubbström (Grubba)  } }
71a9672001-03-03Henrik Grubbström (Grubba) #else /* !USE_PIKE_TYPE */
9399f52001-03-03Henrik Grubbström (Grubba) 
bce86c1996-02-25Fredrik Hübinette (Hubbe) static void internal_parse_type(char **s);
71a9672001-03-03Henrik Grubbström (Grubba) static ptrdiff_t type_length(const char *t);
52169d1999-12-21Henrik Grubbström (Grubba) static int low_pike_types_le(char *a, char *b, int array_cnt, unsigned int flags);
2573d11999-12-22Henrik Grubbström (Grubba) static int low_check_indexing(char *type, char *index_type, node *n);
bce86c1996-02-25Fredrik Hübinette (Hubbe) 
9f68471997-03-08Fredrik Hübinette (Hubbe) #define EXTRACT_TWOT(X,Y) TWOT(EXTRACT_UCHAR(X), EXTRACT_UCHAR(Y))
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * basic types are represented by just their value in a string
f37dad1999-12-11Henrik Grubbström (Grubba)  * basic type are string, type, int, float, object and program
5267b71995-08-09Fredrik Hübinette (Hubbe)  * arrays are coded like by the value T_ARRAY followed by the * data type, if the type is not known it is T_MIXED, ie: * T_ARRAY <data type> * mappings are followed by two arguments, the first is the type * for the indices, and the second is the type of the data, ie: * T_MAPPING <indice type> <data type>
06983f1996-09-22Fredrik Hübinette (Hubbe)  * multiset works similarly to arrays.
5267b71995-08-09Fredrik Hübinette (Hubbe)  * functions are _very_ special: * they are coded like this: * T_FUNCTION <arg type> <arg type> ... <arg type> T_MANY <arg type> <return type> * note that the type after T_MANY can be T_VOID * T_MIXED matches anything except T_VOID
04966d2000-10-03Fredrik Hübinette (Hubbe)  * PIKE_T_UNKNOWN only matches T_MIXED and PIKE_T_UNKNOWN
6bc9281998-04-10Fredrik Hübinette (Hubbe)  * objects are coded thus: * T_OBJECT <0/1> <program_id> * ^
3d5c7d1999-12-12Henrik Grubbström (Grubba)  * 0 means 'implements'
6134591999-12-15Henrik Grubbström (Grubba)  * 1 means 'is' (aka 'clone of')
f37dad1999-12-11Henrik Grubbström (Grubba)  * Integers are encoded as: * T_INT <min> <max>
93dd411999-11-23Henrik Grubbström (Grubba)  * Everything except T_VOID matches T_ZERO.
5267b71995-08-09Fredrik Hübinette (Hubbe)  */
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
d68a072001-02-20Henrik Grubbström (Grubba) void check_type_string(struct pike_type *s)
b9e4ba1996-11-18Fredrik Hübinette (Hubbe) { if(debug_findstring(s) != s) fatal("Type string not shared.\n"); if(type_length(s->str) != s->len)
9e52381998-03-01Fredrik Hübinette (Hubbe)  {
18415a2001-02-27Martin Stjernholm  simple_describe_type(s);
6f95902000-08-17Henrik Grubbström (Grubba)  fatal("Length of type is wrong. (should be %ld, is %ld)\n", PTRDIFF_T_TO_LONG(type_length(s->str)), PTRDIFF_T_TO_LONG(s->len));
9e52381998-03-01Fredrik Hübinette (Hubbe)  }
b9e4ba1996-11-18Fredrik Hübinette (Hubbe) } #endif
71a9672001-03-03Henrik Grubbström (Grubba) static ptrdiff_t type_length(const char *t)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
71a9672001-03-03Henrik Grubbström (Grubba)  const char *q=t;
1347171998-04-23Fredrik Hübinette (Hubbe) one_more_type:
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(EXTRACT_UCHAR(t++)) {
9e52381998-03-01Fredrik Hübinette (Hubbe)  default:
a4a1722000-12-05Per Hedbor  fatal("Error in type string %d.\n",EXTRACT_UCHAR(t-1));
9e52381998-03-01Fredrik Hübinette (Hubbe)  /*NOTREACHED*/ break;
fc0ad41999-12-11Henrik Grubbström (Grubba)  case T_SCOPE:
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_ASSIGN: t++;
1347171998-04-23Fredrik Hübinette (Hubbe)  goto one_more_type;
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_FUNCTION: while(EXTRACT_UCHAR(t)!=T_MANY) t+=type_length(t); /* skip arguments */ t++;
fc0ad41999-12-11Henrik Grubbström (Grubba)  case T_TUPLE:
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_MAPPING:
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_OR: case T_AND: t+=type_length(t); case T_ARRAY: case T_MULTISET:
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE:
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_NOT:
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM:
1347171998-04-23Fredrik Hübinette (Hubbe)  goto one_more_type;
9e52381998-03-01Fredrik Hübinette (Hubbe)  case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case T_FLOAT: case T_STRING: case T_MIXED: case T_VOID:
93dd411999-11-23Henrik Grubbström (Grubba)  case T_ZERO:
04966d2000-10-03Fredrik Hübinette (Hubbe)  case PIKE_T_UNKNOWN:
9e52381998-03-01Fredrik Hübinette (Hubbe)  break;
b660c81999-03-01Fredrik Hübinette (Hubbe)  case T_INT: t+=sizeof(INT32)*2; break;
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_OBJECT:
6bc9281998-04-10Fredrik Hübinette (Hubbe)  t++;
9e52381998-03-01Fredrik Hübinette (Hubbe)  t+=sizeof(INT32); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } return t-q; }
7260711996-06-21Fredrik Hübinette (Hubbe) 
1347171998-04-23Fredrik Hübinette (Hubbe) unsigned char type_stack[PIKE_TYPE_STACK_SIZE]; unsigned char *pike_type_mark_stack[PIKE_TYPE_STACK_SIZE/4];
7260711996-06-21Fredrik Hübinette (Hubbe) 
e0755c2000-08-15Henrik Grubbström (Grubba) ptrdiff_t pop_stack_mark(void)
7260711996-06-21Fredrik Hübinette (Hubbe) {
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->pike_type_mark_stackp--; if(Pike_compiler->pike_type_mark_stackp<pike_type_mark_stack)
7260711996-06-21Fredrik Hübinette (Hubbe)  fatal("Type mark stack underflow\n");
bad5162000-06-23Fredrik Hübinette (Hubbe)  return Pike_compiler->type_stackp - *Pike_compiler->pike_type_mark_stackp;
7260711996-06-21Fredrik Hübinette (Hubbe) }
5b368e2001-03-31Henrik Grubbström (Grubba) void debug_pop_type_stack(unsigned INT16 expected)
7260711996-06-21Fredrik Hübinette (Hubbe) {
5b368e2001-03-31Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (Pike_compiler->type_stackp[0] != expected) { fatal("Unexpected type node: %d (expected: %d)\n", Pike_compiler->type_stackp[0], expected); } #endif /* PIKE_DEBUG */
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->type_stackp--; if(Pike_compiler->type_stackp<type_stack)
7260711996-06-21Fredrik Hübinette (Hubbe)  fatal("Type stack underflow\n"); }
71a9672001-03-03Henrik Grubbström (Grubba) 
be478c1997-08-30Henrik Grubbström (Grubba) void type_stack_pop_to_mark(void)
7260711996-06-21Fredrik Hübinette (Hubbe) {
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->type_stackp-=pop_stack_mark();
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(Pike_compiler->type_stackp<type_stack)
36feac1997-03-06Fredrik Hübinette (Hubbe)  fatal("Type stack underflow\n"); #endif
7260711996-06-21Fredrik Hübinette (Hubbe) }
be478c1997-08-30Henrik Grubbström (Grubba) void type_stack_reverse(void)
7260711996-06-21Fredrik Hübinette (Hubbe) {
393a592000-08-16Henrik Grubbström (Grubba)  ptrdiff_t a;
36feac1997-03-06Fredrik Hübinette (Hubbe)  a=pop_stack_mark();
bad5162000-06-23Fredrik Hübinette (Hubbe)  reverse((char *)(Pike_compiler->type_stackp-a),a,1);
7260711996-06-21Fredrik Hübinette (Hubbe) }
3611422001-02-20Henrik Grubbström (Grubba) static void push_type_int(INT32 i)
d2c6081996-11-07Fredrik Hübinette (Hubbe) {
393a592000-08-16Henrik Grubbström (Grubba)  ptrdiff_t e; for(e = 0; e < (ptrdiff_t)sizeof(i); e++) push_type(DO_NOT_WARN((unsigned char)((i>>(e*8)) & 0xff)));
b660c81999-03-01Fredrik Hübinette (Hubbe) }
3611422001-02-20Henrik Grubbström (Grubba) static void push_type_int_backwards(INT32 i)
91aab41999-12-13Martin Stjernholm { int e; for(e=(int)sizeof(i);e-->0;) push_type( (i>>(e*8)) & 0xff ); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_int_type(INT32 min, INT32 max)
3611422001-02-20Henrik Grubbström (Grubba) { push_type_int(max); push_type_int(min); push_type(T_INT); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_assign_type(int marker)
58c3682001-03-03Henrik Grubbström (Grubba) { push_type(marker); push_type(T_ASSIGN); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_object_type(int flag, INT32 id)
3611422001-02-20Henrik Grubbström (Grubba) { push_type_int(id); push_type(flag); push_type(T_OBJECT); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_object_type_backwards(int flag, INT32 id)
3611422001-02-20Henrik Grubbström (Grubba) { unsafe_push_type(T_OBJECT); unsafe_push_type(flag); push_type_int_backwards(id); }
b660c81999-03-01Fredrik Hübinette (Hubbe) INT32 extract_type_int(char *p) { int e; INT32 ret=0; for(e=0;e<(int)sizeof(INT32);e++) ret=(ret<<8) | EXTRACT_UCHAR(p+e); return ret;
d2c6081996-11-07Fredrik Hübinette (Hubbe) }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_unfinished_type(char *s)
7260711996-06-21Fredrik Hübinette (Hubbe) {
393a592000-08-16Henrik Grubbström (Grubba)  ptrdiff_t e;
7260711996-06-21Fredrik Hübinette (Hubbe)  e=type_length(s); for(e--;e>=0;e--) push_type(s[e]); }
27f6ba1999-11-24Fredrik Hübinette (Hubbe) static void push_unfinished_type_with_markers(char *s,
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type **am)
9e52381998-03-01Fredrik Hübinette (Hubbe) {
89da112000-08-15Henrik Grubbström (Grubba)  int d,e,c; ptrdiff_t len=type_length(s);
2a6d261998-03-25Fredrik Hübinette (Hubbe)  type_stack_mark(); for(e=0;e<len;e++)
9e52381998-03-01Fredrik Hübinette (Hubbe)  {
2a6d261998-03-25Fredrik Hübinette (Hubbe)  switch(c=EXTRACT_UCHAR(s+e))
9e52381998-03-01Fredrik Hübinette (Hubbe)  {
2a6d261998-03-25Fredrik Hübinette (Hubbe) #if 1 case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if(am[c-'0']) { push_finished_type_backwards(am[c-'0']); }else{
02f0631999-11-24Fredrik Hübinette (Hubbe)  push_type(T_ZERO);
2a6d261998-03-25Fredrik Hübinette (Hubbe)  } break; #endif
02f0631999-11-24Fredrik Hübinette (Hubbe)  case T_ASSIGN:
27f6ba1999-11-24Fredrik Hübinette (Hubbe) #if 1 e++; #else
02f0631999-11-24Fredrik Hübinette (Hubbe)  push_type(c); push_type(EXTRACT_UCHAR(s+ ++e));
27f6ba1999-11-24Fredrik Hübinette (Hubbe) #endif
02f0631999-11-24Fredrik Hübinette (Hubbe)  break;
b660c81999-03-01Fredrik Hübinette (Hubbe)  case T_INT: push_type(c); for(d=0;d<(int)sizeof(INT32)*2;d++) push_type(EXTRACT_UCHAR(s+ ++e)); break;
2a6d261998-03-25Fredrik Hübinette (Hubbe)  case T_OBJECT: push_type(c);
b660c81999-03-01Fredrik Hübinette (Hubbe)  for(d=0;d<(int)sizeof(INT32)+1;d++) push_type(EXTRACT_UCHAR(s+ ++e));
2a6d261998-03-25Fredrik Hübinette (Hubbe)  break; default: push_type(c);
9e52381998-03-01Fredrik Hübinette (Hubbe)  } }
2a6d261998-03-25Fredrik Hübinette (Hubbe)  type_stack_reverse();
9e52381998-03-01Fredrik Hübinette (Hubbe) }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_finished_type(struct pike_type *type)
7260711996-06-21Fredrik Hübinette (Hubbe) {
e0755c2000-08-15Henrik Grubbström (Grubba)  ptrdiff_t e;
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  check_type_string(type);
7260711996-06-21Fredrik Hübinette (Hubbe)  for(e=type->len-1;e>=0;e--) push_type(type->str[e]); }
9b5a822001-03-29Henrik Grubbström (Grubba) void debug_push_finished_type_backwards(struct pike_type *type)
2a6d261998-03-25Fredrik Hübinette (Hubbe) { int e;
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  check_type_string(type);
bad5162000-06-23Fredrik Hübinette (Hubbe)  MEMCPY(Pike_compiler->type_stackp, type->str, type->len); Pike_compiler->type_stackp+=type->len;
2a6d261998-03-25Fredrik Hübinette (Hubbe) }
d68a072001-02-20Henrik Grubbström (Grubba) struct pike_type *debug_pop_unfinished_type(void)
7260711996-06-21Fredrik Hübinette (Hubbe) {
393a592000-08-16Henrik Grubbström (Grubba)  ptrdiff_t len, e;
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *s;
36feac1997-03-06Fredrik Hübinette (Hubbe)  len=pop_stack_mark();
7260711996-06-21Fredrik Hübinette (Hubbe)  s=begin_shared_string(len);
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->type_stackp-=len; MEMCPY(s->str, Pike_compiler->type_stackp, len);
36feac1997-03-06Fredrik Hübinette (Hubbe)  reverse(s->str, len, 1);
b9e4ba1996-11-18Fredrik Hübinette (Hubbe)  s=end_shared_string(s);
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  check_type_string(s);
b9e4ba1996-11-18Fredrik Hübinette (Hubbe)  return s;
7260711996-06-21Fredrik Hübinette (Hubbe) }
b432bb1996-10-29Per Hedbor static void internal_parse_typeA(char **_s)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
f044a81996-12-06Fredrik Hübinette (Hubbe)  char buf[80];
5267b71995-08-09Fredrik Hübinette (Hubbe)  unsigned int len;
b432bb1996-10-29Per Hedbor  unsigned char **s = (unsigned char **)_s;
bdb5091996-09-25Fredrik Hübinette (Hubbe)  while(ISSPACE(**s)) ++*s;
5267b71995-08-09Fredrik Hübinette (Hubbe)  len=0;
f044a81996-12-06Fredrik Hübinette (Hubbe)  for(len=0;isidchar(EXTRACT_UCHAR(s[0]+len));len++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if(len>=sizeof(buf)) Pike_error("Buffer overflow in parse_type\n");
5267b71995-08-09Fredrik Hübinette (Hubbe)  buf[len] = s[0][len]; } buf[len]=0; *s += len;
1347171998-04-23Fredrik Hübinette (Hubbe)  switch(buf[0])
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
4d7b181999-12-07Fredrik Hübinette (Hubbe)  case 'z':
fc0ad41999-12-11Henrik Grubbström (Grubba)  if(!strcmp(buf,"zero")) { push_type(T_ZERO); break; }
4d7b181999-12-07Fredrik Hübinette (Hubbe)  goto bad_type;
1347171998-04-23Fredrik Hübinette (Hubbe)  case 'i':
b660c81999-03-01Fredrik Hübinette (Hubbe)  if(!strcmp(buf,"int")) {
71a9672001-03-03Henrik Grubbström (Grubba)  INT32 min = MIN_INT32, max = MAX_INT32;
b660c81999-03-01Fredrik Hübinette (Hubbe)  while(ISSPACE(**s)) ++*s; if(**s=='(') { ++*s; while(ISSPACE(**s)) ++*s;
01a9572000-02-03Henrik Grubbström (Grubba)  min=STRTOL((char *)*s,(char **)s,0);
b660c81999-03-01Fredrik Hübinette (Hubbe)  while(ISSPACE(**s)) ++*s; if(s[0][0]=='.' && s[0][1]=='.') s[0]+=2; else
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Missing .. in integer type.\n");
b660c81999-03-01Fredrik Hübinette (Hubbe)  while(ISSPACE(**s)) ++*s;
01a9572000-02-03Henrik Grubbström (Grubba)  max=STRTOL((char *)*s,(char **)s,0);
b660c81999-03-01Fredrik Hübinette (Hubbe)  while(ISSPACE(**s)) ++*s;
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if(**s != ')') Pike_error("Missing ')' in integer range.\n");
b660c81999-03-01Fredrik Hübinette (Hubbe)  ++*s; }
71a9672001-03-03Henrik Grubbström (Grubba)  push_int_type(min, max);
b660c81999-03-01Fredrik Hübinette (Hubbe)  break; }
1347171998-04-23Fredrik Hübinette (Hubbe)  goto bad_type; case 'f': if(!strcmp(buf,"function"))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
1347171998-04-23Fredrik Hübinette (Hubbe)  while(ISSPACE(**s)) ++*s; if(**s == '(')
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
1347171998-04-23Fredrik Hübinette (Hubbe)  ++*s; while(ISSPACE(**s)) ++*s; type_stack_mark(); while(1) { if(**s == ':') { push_type(T_MANY); push_type(T_VOID); break; } type_stack_mark(); type_stack_mark(); type_stack_mark(); internal_parse_type(_s); type_stack_reverse(); if(**s==',') { ++*s; while(ISSPACE(**s)) ++*s; } else if(s[0][0]=='.' && s[0][1]=='.' && s[0][2]=='.') { type_stack_reverse(); push_type(T_MANY); type_stack_reverse(); *s+=3; while(ISSPACE(**s)) ++*s;
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if(**s != ':') Pike_error("Missing ':' after ... in function type.\n");
1347171998-04-23Fredrik Hübinette (Hubbe)  break; } pop_stack_mark(); pop_stack_mark(); } ++*s; type_stack_mark(); internal_parse_type(_s); /* return type */ type_stack_reverse();
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if(**s != ')') Pike_error("Missing ')' in function type.\n");
1347171998-04-23Fredrik Hübinette (Hubbe)  ++*s; type_stack_reverse(); }else{
3688171999-11-26Fredrik Hübinette (Hubbe)  push_type(T_VOID);
1347171998-04-23Fredrik Hübinette (Hubbe)  push_type(T_MIXED);
3688171999-11-26Fredrik Hübinette (Hubbe)  push_type(T_OR); push_type(T_VOID);
a0b73f2000-01-03Martin Stjernholm  push_type(T_ZERO);
3688171999-11-26Fredrik Hübinette (Hubbe)  push_type(T_OR);
5267b71995-08-09Fredrik Hübinette (Hubbe)  push_type(T_MANY); }
1347171998-04-23Fredrik Hübinette (Hubbe)  push_type(T_FUNCTION); break; } if(!strcmp(buf,"float")) { push_type(T_FLOAT); break; } goto bad_type;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1347171998-04-23Fredrik Hübinette (Hubbe)  case 'o': if(!strcmp(buf,"object")) {
c02ce62001-03-18Per Hedbor  while(ISSPACE(**s)) ++*s; if(**s == '(') /* object({is,implements} id) */ { int is = 1, id; ++*s; if( **s != 'i' ) goto bad_type; ++*s; if( **s == 'm' ) is = 0; while( isidchar( **s ) ) ++*s; while( ISSPACE(**s) ) ++*s; if( !**s ) goto bad_type; id = atoi( *s ); while( **s >= '0' && **s <= '9' ) ++*s; while(ISSPACE(**s)) ++*s; if( !**s || **s != ')' ) goto bad_type; ++*s; push_object_type(is, id); } else push_object_type(0, 0);
1347171998-04-23Fredrik Hübinette (Hubbe)  break; } goto bad_type; case 'p':
6d33d82001-03-28Henrik Grubbström (Grubba)  if(!strcmp(buf,"program")) { push_object_type(0, 0); push_type(T_PROGRAM); break; }
1347171998-04-23Fredrik Hübinette (Hubbe)  goto bad_type; case 's': if(!strcmp(buf,"string")) { push_type(T_STRING); break; } goto bad_type; case 'v': if(!strcmp(buf,"void")) { push_type(T_VOID); break; } goto bad_type;
fc0ad41999-12-11Henrik Grubbström (Grubba)  case 't': if (!strcmp(buf,"tuple")) { while(ISSPACE(**s)) ++*s; if(**s == '(') { type_stack_mark(); ++*s; type_stack_mark(); internal_parse_type(_s); type_stack_reverse();
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if(**s != ',') Pike_error("Expecting ','.\n");
fc0ad41999-12-11Henrik Grubbström (Grubba)  ++*s; type_stack_mark(); internal_parse_type(_s); type_stack_reverse();
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if(**s != ')') Pike_error("Expecting ')'.\n");
fc0ad41999-12-11Henrik Grubbström (Grubba)  ++*s; type_stack_reverse(); }else{ push_type(T_MIXED); push_type(T_MIXED); } push_type(T_TUPLE); break; }
54f8ac2001-03-17Henrik Grubbström (Grubba)  /* FIXME: Support for type(T). */ if(!strcmp(buf,"type")) { push_type(T_MIXED); push_type(T_TYPE); break; }
fc0ad41999-12-11Henrik Grubbström (Grubba)  goto bad_type;
1347171998-04-23Fredrik Hübinette (Hubbe)  case 'm': if(!strcmp(buf,"mixed")) { push_type(T_MIXED); break; } if(!strcmp(buf,"mapping")) { while(ISSPACE(**s)) ++*s; if(**s == '(')
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
1347171998-04-23Fredrik Hübinette (Hubbe)  type_stack_mark();
5267b71995-08-09Fredrik Hübinette (Hubbe)  ++*s;
1347171998-04-23Fredrik Hübinette (Hubbe)  type_stack_mark(); internal_parse_type(_s);
5267b71995-08-09Fredrik Hübinette (Hubbe)  type_stack_reverse();
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if(**s != ':') Pike_error("Expecting ':'.\n");
1347171998-04-23Fredrik Hübinette (Hubbe)  ++*s; type_stack_mark(); internal_parse_type(_s);
5267b71995-08-09Fredrik Hübinette (Hubbe)  type_stack_reverse();
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if(**s != ')') Pike_error("Expecting ')'.\n");
1347171998-04-23Fredrik Hübinette (Hubbe)  ++*s; type_stack_reverse(); }else{ push_type(T_MIXED); push_type(T_MIXED);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
1347171998-04-23Fredrik Hübinette (Hubbe)  push_type(T_MAPPING); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
1347171998-04-23Fredrik Hübinette (Hubbe)  if(!strcmp(buf,"multiset")) { while(ISSPACE(**s)) ++*s; if(**s == '(') { ++*s; internal_parse_type(_s);
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if(**s != ')') Pike_error("Expecting ')'.\n");
1347171998-04-23Fredrik Hübinette (Hubbe)  ++*s; }else{ push_type(T_MIXED); } push_type(T_MULTISET); break; } goto bad_type; case 'u':
04966d2000-10-03Fredrik Hübinette (Hubbe)  if(!strcmp(buf,"unknown")) { push_type(PIKE_T_UNKNOWN); break; }
1347171998-04-23Fredrik Hübinette (Hubbe)  goto bad_type; case 'a': if(!strcmp(buf,"array")) { while(ISSPACE(**s)) ++*s; if(**s == '(') { ++*s; internal_parse_type(_s);
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if(**s != ')') Pike_error("Expecting ')'.\n");
1347171998-04-23Fredrik Hübinette (Hubbe)  ++*s; }else{ push_type(T_MIXED); } push_type(T_ARRAY); break; } goto bad_type; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if(atoi(buf)<10) { while(ISSPACE(**s)) ++*s; if(**s=='=') { ++*s; internal_parse_type(_s); push_type(buf[0]); push_type(T_ASSIGN); }else{ push_type(buf[0]); } break; } default: bad_type:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Couldn't parse type. (%s)\n",buf);
9e52381998-03-01Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
bdb5091996-09-25Fredrik Hübinette (Hubbe)  while(ISSPACE(**s)) ++*s;
bce86c1996-02-25Fredrik Hübinette (Hubbe) } static void internal_parse_typeB(char **s) {
2916001998-01-16Henrik Grubbström (Grubba)  while(ISSPACE(**((unsigned char **)s))) ++*s;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  switch(**s) { case '!': ++*s; internal_parse_typeB(s); push_type(T_NOT); break; case '(': ++*s;
a946c71998-03-02Fredrik Hübinette (Hubbe)  internal_parse_type(s);
2916001998-01-16Henrik Grubbström (Grubba)  while(ISSPACE(**((unsigned char **)s))) ++*s;
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if(**s != ')') Pike_error("Expecting ')'.\n");
4d7b181999-12-07Fredrik Hübinette (Hubbe)  ++*s;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  break; default: internal_parse_typeA(s); } } static void internal_parse_typeCC(char **s) { internal_parse_typeB(s);
2916001998-01-16Henrik Grubbström (Grubba)  while(ISSPACE(**((unsigned char **)s))) ++*s;
bce86c1996-02-25Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  while(**s == '*') { ++*s;
2916001998-01-16Henrik Grubbström (Grubba)  while(ISSPACE(**((unsigned char **)s))) ++*s;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  push_type(T_ARRAY);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
bce86c1996-02-25Fredrik Hübinette (Hubbe) } static void internal_parse_typeC(char **s) { type_stack_mark(); type_stack_mark(); internal_parse_typeCC(s); type_stack_reverse();
5267b71995-08-09Fredrik Hübinette (Hubbe) 
2916001998-01-16Henrik Grubbström (Grubba)  while(ISSPACE(**((unsigned char **)s))) ++*s;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  if(**s == '&') { ++*s; type_stack_mark(); internal_parse_typeC(s); type_stack_reverse(); type_stack_reverse(); push_type(T_AND); }else{ type_stack_reverse();
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
bce86c1996-02-25Fredrik Hübinette (Hubbe) } static void internal_parse_type(char **s) { internal_parse_typeC(s);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
2916001998-01-16Henrik Grubbström (Grubba)  while(ISSPACE(**((unsigned char **)s))) ++*s;
bce86c1996-02-25Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  while(**s == '|') { ++*s;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  internal_parse_typeC(s);
5267b71995-08-09Fredrik Hübinette (Hubbe)  push_type(T_OR); } } /* This function is used when adding simul efuns so that * the types for the functions can be easily stored in strings.
06983f1996-09-22Fredrik Hübinette (Hubbe)  * It takes a string on the exact same format as Pike and returns a type
5267b71995-08-09Fredrik Hübinette (Hubbe)  * struct. */
d68a072001-02-20Henrik Grubbström (Grubba) struct pike_type *parse_type(char *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *ret;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  unsigned char *ts=Pike_compiler->type_stackp; unsigned char **ptms=Pike_compiler->pike_type_mark_stackp;
fb2f661998-11-05Fredrik Hübinette (Hubbe) #endif
36feac1997-03-06Fredrik Hübinette (Hubbe)  type_stack_mark();
5267b71995-08-09Fredrik Hübinette (Hubbe)  internal_parse_type(&s); if( *s ) fatal("Extra junk at end of type definition.\n");
fb2f661998-11-05Fredrik Hübinette (Hubbe)  ret=pop_unfinished_type();
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  if(ts!=Pike_compiler->type_stackp || ptms!=Pike_compiler->pike_type_mark_stackp)
fb2f661998-11-05Fredrik Hübinette (Hubbe)  fatal("Type stack whacked in parse_type.\n"); #endif return ret;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
e0755c2000-08-15Henrik Grubbström (Grubba) void stupid_describe_type(char *a, ptrdiff_t len)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
e0755c2000-08-15Henrik Grubbström (Grubba)  ptrdiff_t e;
5267b71995-08-09Fredrik Hübinette (Hubbe)  for(e=0;e<len;e++) {
18415a2001-02-27Martin Stjernholm  if(e) fputs(" ", stderr);
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(EXTRACT_UCHAR(a+e)) {
9e52381998-03-01Fredrik Hübinette (Hubbe)  case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
18415a2001-02-27Martin Stjernholm  fprintf(stderr, "%c",EXTRACT_UCHAR(a+e));
9e52381998-03-01Fredrik Hübinette (Hubbe)  break;
fc0ad41999-12-11Henrik Grubbström (Grubba) 
18415a2001-02-27Martin Stjernholm  case T_SCOPE: fputs("scope", stderr); break; case T_TUPLE: fputs("tuple", stderr); break; case T_ASSIGN: fputs("=", stderr); break;
b660c81999-03-01Fredrik Hübinette (Hubbe)  case T_INT: { INT32 min=extract_type_int(a+e+1); INT32 max=extract_type_int(a+e+1+sizeof(INT32));
18415a2001-02-27Martin Stjernholm  fprintf(stderr, "int");
b660c81999-03-01Fredrik Hübinette (Hubbe)  if(min!=MIN_INT32 || max!=MAX_INT32)
18415a2001-02-27Martin Stjernholm  fprintf(stderr, "(%ld..%ld)",(long)min,(long)max);
b660c81999-03-01Fredrik Hübinette (Hubbe)  e+=sizeof(INT32)*2; break; }
18415a2001-02-27Martin Stjernholm  case T_FLOAT: fputs("float", stderr); break; case T_STRING: fputs("string", stderr); break; case T_TYPE: fputs("type", stderr); break; case T_PROGRAM: fputs("program", stderr); break;
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_OBJECT:
18415a2001-02-27Martin Stjernholm  fprintf(stderr, "object(%s %ld)", EXTRACT_UCHAR(a+e+1)?"is":"implements", (long)extract_type_int(a+e+2));
6bc9281998-04-10Fredrik Hübinette (Hubbe)  e+=sizeof(INT32)+1;
9e52381998-03-01Fredrik Hübinette (Hubbe)  break;
18415a2001-02-27Martin Stjernholm  case T_FUNCTION: fputs("function", stderr); break; case T_ARRAY: fputs("array", stderr); break; case T_MAPPING: fputs("mapping", stderr); break; case T_MULTISET: fputs("multiset", stderr); break;
9e52381998-03-01Fredrik Hübinette (Hubbe) 
18415a2001-02-27Martin Stjernholm  case PIKE_T_UNKNOWN: fputs("unknown", stderr); break; case T_MANY: fputs("many", stderr); break;
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: fputs("ring", stderr); break;
18415a2001-02-27Martin Stjernholm  case T_OR: fputs("or", stderr); break; case T_AND: fputs("and", stderr); break; case T_NOT: fputs("not", stderr); break; case T_VOID: fputs("void", stderr); break; case T_ZERO: fputs("zero", stderr); break; case T_MIXED: fputs("mixed", stderr); break;
9e52381998-03-01Fredrik Hübinette (Hubbe) 
18415a2001-02-27Martin Stjernholm  default: fprintf(stderr, "%d",EXTRACT_UCHAR(a+e)); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } }
0d202a1995-10-20Fredrik Hübinette (Hubbe) 
d68a072001-02-20Henrik Grubbström (Grubba) void simple_describe_type(struct pike_type *s)
0d202a1995-10-20Fredrik Hübinette (Hubbe) { stupid_describe_type(s->str,s->len);
18415a2001-02-27Martin Stjernholm  fputs("\n", stderr);
0d202a1995-10-20Fredrik Hübinette (Hubbe) }
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
3496412001-02-25Henrik Grubbström (Grubba) static char *low_describe_type(char *t)
5267b71995-08-09Fredrik Hübinette (Hubbe) { switch(EXTRACT_UCHAR(t++)) {
9e52381998-03-01Fredrik Hübinette (Hubbe)  case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': my_putchar(EXTRACT_UCHAR(t-1)); break; case T_ASSIGN: my_putchar('('); my_putchar(EXTRACT_UCHAR(t++)); my_putchar('=');
bce86c1996-02-25Fredrik Hübinette (Hubbe)  t=low_describe_type(t);
9e52381998-03-01Fredrik Hübinette (Hubbe)  my_putchar(')'); break;
fc0ad41999-12-11Henrik Grubbström (Grubba)  case T_SCOPE: my_putchar('{'); my_putchar(EXTRACT_UCHAR(t++)); my_putchar(','); t = low_describe_type(t); my_putchar('}'); break; case T_TUPLE: my_putchar('['); t = low_describe_type(t); my_putchar(','); t = low_describe_type(t); my_putchar(']'); break;
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_VOID: my_strcat("void"); break;
93dd411999-11-23Henrik Grubbström (Grubba)  case T_ZERO: my_strcat("zero"); break;
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_MIXED: my_strcat("mixed"); break;
04966d2000-10-03Fredrik Hübinette (Hubbe)  case PIKE_T_UNKNOWN: my_strcat("unknown"); break;
b660c81999-03-01Fredrik Hübinette (Hubbe)  case T_INT: { INT32 min=extract_type_int(t); INT32 max=extract_type_int(t+sizeof(INT32)); my_strcat("int"); if(min!=MIN_INT32 || max!=MAX_INT32) { char buffer[100]; sprintf(buffer,"(%ld..%ld)",(long)min,(long)max); my_strcat(buffer); } t+=sizeof(INT32)*2; break; }
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_FLOAT: my_strcat("float"); break;
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM: my_strcat("program("); t = low_describe_type(t); my_strcat(")"); break;
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_OBJECT:
b660c81999-03-01Fredrik Hübinette (Hubbe)  if(extract_type_int(t+1))
0ee27b1998-04-14Fredrik Hübinette (Hubbe)  { char buffer[100];
6134591999-12-15Henrik Grubbström (Grubba)  sprintf(buffer,"object(%s %ld)",*t?"is":"implements",
3d5c7d1999-12-12Henrik Grubbström (Grubba)  (long)extract_type_int(t+1));
0ee27b1998-04-14Fredrik Hübinette (Hubbe)  my_strcat(buffer); }else{ my_strcat("object"); }
6bc9281998-04-10Fredrik Hübinette (Hubbe)  t+=sizeof(INT32)+1;
9e52381998-03-01Fredrik Hübinette (Hubbe)  /* Prog id */ break; case T_STRING: my_strcat("string"); break;
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE: my_strcat("type("); t = low_describe_type(t); my_strcat(")"); break;
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_FUNCTION:
bce86c1996-02-25Fredrik Hübinette (Hubbe)  {
9e52381998-03-01Fredrik Hübinette (Hubbe)  int s;
4d7b181999-12-07Fredrik Hübinette (Hubbe)  my_strcat("function"); if(EXTRACT_UCHAR(t) == T_MANY &&
a0b73f2000-01-03Martin Stjernholm  ((EXTRACT_UCHAR(t+1) == T_ZERO && EXTRACT_UCHAR(t+2) == T_OR && ((EXTRACT_UCHAR(t+3) == T_MIXED && EXTRACT_UCHAR(t+4) == T_VOID) || (EXTRACT_UCHAR(t+4) == T_MIXED && EXTRACT_UCHAR(t+3) == T_VOID))) || (EXTRACT_UCHAR(t+1) == T_OR && ((EXTRACT_UCHAR(t+2) == T_ZERO && EXTRACT_UCHAR(t+3) == T_VOID) || (EXTRACT_UCHAR(t+3) == T_ZERO && EXTRACT_UCHAR(t+2) == T_VOID)) && EXTRACT_UCHAR(t+4) == T_OR && ((EXTRACT_UCHAR(t+5) == T_MIXED && EXTRACT_UCHAR(t+6) == T_VOID) || (EXTRACT_UCHAR(t+6) == T_MIXED && EXTRACT_UCHAR(t+5) == T_VOID)))))
9e52381998-03-01Fredrik Hübinette (Hubbe)  {
4d7b181999-12-07Fredrik Hübinette (Hubbe)  /* done */
a0b73f2000-01-03Martin Stjernholm  if (EXTRACT_UCHAR(t+1) == T_ZERO) { /* function(zero...:mixed|void) */
e0f7f51999-12-11Henrik Grubbström (Grubba)  t += 5; } else {
a0b73f2000-01-03Martin Stjernholm  /* function(zero|void...mixed|void) */
e0f7f51999-12-11Henrik Grubbström (Grubba)  t += 7; }
4d7b181999-12-07Fredrik Hübinette (Hubbe)  } else { my_strcat("("); s=0; while(EXTRACT_UCHAR(t) != T_MANY) { if(s++) my_strcat(", "); t=low_describe_type(t); }
9e52381998-03-01Fredrik Hübinette (Hubbe)  t++;
4d7b181999-12-07Fredrik Hübinette (Hubbe)  if(EXTRACT_UCHAR(t) == T_VOID) { t++; }else{ if(s++) my_strcat(", "); t=low_describe_type(t); my_strcat(" ..."); } my_strcat(" : ");
9e52381998-03-01Fredrik Hübinette (Hubbe)  t=low_describe_type(t);
4d7b181999-12-07Fredrik Hübinette (Hubbe)  my_strcat(")");
9e52381998-03-01Fredrik Hübinette (Hubbe)  } break;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  }
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_ARRAY:
5ac7661998-04-28Fredrik Hübinette (Hubbe)  my_strcat("array");
9e52381998-03-01Fredrik Hübinette (Hubbe)  if(EXTRACT_UCHAR(t)==T_MIXED) { t++; }else{
5ac7661998-04-28Fredrik Hübinette (Hubbe)  my_strcat("(");
9e52381998-03-01Fredrik Hübinette (Hubbe)  t=low_describe_type(t);
5ac7661998-04-28Fredrik Hübinette (Hubbe)  my_strcat(")");
9e52381998-03-01Fredrik Hübinette (Hubbe)  } break; case T_MULTISET: my_strcat("multiset"); if(EXTRACT_UCHAR(t)!=T_MIXED) { my_strcat("("); t=low_describe_type(t); my_strcat(")"); }else{ t++; } break; case T_NOT: my_strcat("!");
da996d1999-12-19Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(t) > T_NOT) { my_strcat("("); t=low_describe_type(t); my_strcat(")"); } else { t=low_describe_type(t); }
9e52381998-03-01Fredrik Hübinette (Hubbe)  break;
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: my_strcat("("); t = low_describe_type(t); my_strcat(")°("); t = low_describe_type(t); my_strcat(")"); break;
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_OR:
da996d1999-12-19Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(t) > T_OR) { my_strcat("("); t=low_describe_type(t); my_strcat(")"); } else { t=low_describe_type(t); }
9e52381998-03-01Fredrik Hübinette (Hubbe)  my_strcat(" | ");
da996d1999-12-19Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(t) > T_OR) { my_strcat("("); t=low_describe_type(t); my_strcat(")"); } else { t=low_describe_type(t); }
9e52381998-03-01Fredrik Hübinette (Hubbe)  break; case T_AND:
da996d1999-12-19Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(t) > T_AND) { my_strcat("("); t=low_describe_type(t); my_strcat(")"); } else { t=low_describe_type(t); }
9e52381998-03-01Fredrik Hübinette (Hubbe)  my_strcat(" & ");
da996d1999-12-19Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(t) > T_AND) { my_strcat("("); t=low_describe_type(t); my_strcat(")"); } else { t=low_describe_type(t); }
9e52381998-03-01Fredrik Hübinette (Hubbe)  break; case T_MAPPING: my_strcat("mapping"); if(EXTRACT_UCHAR(t)==T_MIXED && EXTRACT_UCHAR(t+1)==T_MIXED) { t+=2; }else{ my_strcat("("); t=low_describe_type(t);
e0f7f51999-12-11Henrik Grubbström (Grubba)  my_strcat(":"); t=low_describe_type(t); my_strcat(")"); } break; default: { char buf[20]; my_strcat("unknown code("); sprintf(buf, "%d", EXTRACT_UCHAR(t-1)); my_strcat(buf); my_strcat(")"); break; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } return t; }
3496412001-02-25Henrik Grubbström (Grubba) void my_describe_type(struct pike_type *type) { low_describe_type(type->str); }
d68a072001-02-20Henrik Grubbström (Grubba) struct pike_string *describe_type(struct pike_type *type)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b660c81999-03-01Fredrik Hübinette (Hubbe)  check_type_string(type);
bce86c1996-02-25Fredrik Hübinette (Hubbe)  if(!type) return make_shared_string("mixed"); init_buf();
bca0072001-02-25Henrik Grubbström (Grubba)  my_describe_type(type);
bce86c1996-02-25Fredrik Hübinette (Hubbe)  return free_buf(); }
9e52381998-03-01Fredrik Hübinette (Hubbe) static int low_is_same_type(char *a, char *b) { if(type_length(a) != type_length(b)) return 0; return !MEMCMP(a,b,type_length(a)); }
bce86c1996-02-25Fredrik Hübinette (Hubbe) static TYPE_T low_compile_type_to_runtime_type(char *t) { TYPE_T tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(EXTRACT_UCHAR(t)) { case T_OR:
bce86c1996-02-25Fredrik Hübinette (Hubbe)  t++; tmp=low_compile_type_to_runtime_type(t); if(tmp == low_compile_type_to_runtime_type(t+type_length(t))) return tmp;
fc0ad41999-12-11Henrik Grubbström (Grubba)  case T_TUPLE: /* FIXME: Shouldn't occur/should be converted to array? */ /* FALL_THROUGH */
9e52381998-03-01Fredrik Hübinette (Hubbe)  default: return T_MIXED;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
93dd411999-11-23Henrik Grubbström (Grubba)  case T_ZERO: return T_INT;
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: return low_compile_type_to_runtime_type(t+1);
fc0ad41999-12-11Henrik Grubbström (Grubba)  case T_SCOPE: return low_compile_type_to_runtime_type(t+2);
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_ARRAY: case T_MAPPING: case T_MULTISET: case T_OBJECT: case T_PROGRAM: case T_FUNCTION: case T_STRING:
fc0ad41999-12-11Henrik Grubbström (Grubba)  case T_TYPE:
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_INT: case T_FLOAT: return EXTRACT_UCHAR(t);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
d68a072001-02-20Henrik Grubbström (Grubba) TYPE_T compile_type_to_runtime_type(struct pike_type *s)
bce86c1996-02-25Fredrik Hübinette (Hubbe) { return low_compile_type_to_runtime_type(s->str); }
a946c71998-03-02Fredrik Hübinette (Hubbe) 
05fe341999-11-20Henrik Grubbström (Grubba) static int low_find_exact_type_match(char *needle, char *haystack, int separator)
a946c71998-03-02Fredrik Hübinette (Hubbe) {
05fe341999-11-20Henrik Grubbström (Grubba)  while(EXTRACT_UCHAR(haystack) == separator)
a946c71998-03-02Fredrik Hübinette (Hubbe)  { haystack++;
05fe341999-11-20Henrik Grubbström (Grubba)  if(low_find_exact_type_match(needle, haystack, separator))
a946c71998-03-02Fredrik Hübinette (Hubbe)  return 1; haystack+=type_length(haystack); } return low_is_same_type(needle, haystack); } static void very_low_or_pike_types(char *to_push, char *not_push) { while(EXTRACT_UCHAR(to_push)==T_OR) { to_push++; very_low_or_pike_types(to_push, not_push); to_push+=type_length(to_push); }
02f0631999-11-24Fredrik Hübinette (Hubbe)  /* FIXME: * this might use the 'le' operator */
05fe341999-11-20Henrik Grubbström (Grubba)  if(!low_find_exact_type_match(to_push, not_push, T_OR))
a946c71998-03-02Fredrik Hübinette (Hubbe)  { push_unfinished_type(to_push); push_type(T_OR); } }
4d7b181999-12-07Fredrik Hübinette (Hubbe) static void low_or_pike_types(char *t1, char *t2, int zero_implied)
a946c71998-03-02Fredrik Hübinette (Hubbe) { if(!t1) { if(!t2) push_type(T_VOID); else push_unfinished_type(t2); }
475ab41999-11-29Fredrik Hübinette (Hubbe)  else if((!t2)
4d7b181999-12-07Fredrik Hübinette (Hubbe)  || (EXTRACT_UCHAR(t2) == T_ZERO && zero_implied)
475ab41999-11-29Fredrik Hübinette (Hubbe)  )
a946c71998-03-02Fredrik Hübinette (Hubbe)  { push_unfinished_type(t1); }
4d7b181999-12-07Fredrik Hübinette (Hubbe)  else if (EXTRACT_UCHAR(t1) == T_ZERO && zero_implied)
93dd411999-11-23Henrik Grubbström (Grubba)  { push_unfinished_type(t2); }
a946c71998-03-02Fredrik Hübinette (Hubbe)  else if(EXTRACT_UCHAR(t1)==T_MIXED || EXTRACT_UCHAR(t2)==T_MIXED) { push_type(T_MIXED); }
b660c81999-03-01Fredrik Hübinette (Hubbe)  else if(EXTRACT_UCHAR(t1)==T_INT && EXTRACT_UCHAR(t2)==T_INT) {
327c051999-11-24Fredrik Hübinette (Hubbe)  /* FIXME: * This should only be done if the ranges are * overlapping or adjecant to each other. /Hubbe */
b660c81999-03-01Fredrik Hübinette (Hubbe)  INT32 i1,i2; i1=extract_type_int(t1+1+sizeof(INT32)); i2=extract_type_int(t2+1+sizeof(INT32)); push_type_int(MAXIMUM(i1,i2)); i1=extract_type_int(t1+1); i2=extract_type_int(t2+1); push_type_int(MINIMUM(i1,i2)); push_type(T_INT); }
fc0ad41999-12-11Henrik Grubbström (Grubba)  else if (EXTRACT_UCHAR(t1) == T_SCOPE) { if (EXTRACT_UCHAR(t2) == T_SCOPE) { low_or_pike_types(t1+2, t2+2, zero_implied); if (EXTRACT_UCHAR(t1+1) > EXTRACT_UCHAR(t2+1)) push_type(EXTRACT_UCHAR(t1+1)); else push_type(EXTRACT_UCHAR(t2+1)); } else { low_or_pike_types(t1+2, t2, zero_implied); push_type(EXTRACT_UCHAR(t1+1)); } push_type(T_SCOPE); } else if (EXTRACT_UCHAR(t2) == T_SCOPE) { low_or_pike_types(t1, t2+2, zero_implied); push_type(EXTRACT_UCHAR(t2+1)); push_type(T_SCOPE); }
a946c71998-03-02Fredrik Hübinette (Hubbe)  else { push_unfinished_type(t1); very_low_or_pike_types(t2,t1); } }
d68a072001-02-20Henrik Grubbström (Grubba) static void medium_or_pike_types(struct pike_type *a, struct pike_type *b,
4d7b181999-12-07Fredrik Hübinette (Hubbe)  int zero_implied)
a946c71998-03-02Fredrik Hübinette (Hubbe) {
4d7b181999-12-07Fredrik Hübinette (Hubbe)  low_or_pike_types( a ? a->str : 0 , b ? b->str : 0 , zero_implied);
a946c71998-03-02Fredrik Hübinette (Hubbe) }
d68a072001-02-20Henrik Grubbström (Grubba) struct pike_type *or_pike_types(struct pike_type *a, struct pike_type *b, int zero_implied)
a946c71998-03-02Fredrik Hübinette (Hubbe) { type_stack_mark();
fc0ad41999-12-11Henrik Grubbström (Grubba)  medium_or_pike_types(a,b,1 /*zero_implied*/);
a946c71998-03-02Fredrik Hübinette (Hubbe)  return pop_unfinished_type(); }
69b6ab1999-11-20Henrik Grubbström (Grubba) static void very_low_and_pike_types(char *to_push, char *not_push) { while(EXTRACT_UCHAR(to_push)==T_AND) { to_push++; very_low_and_pike_types(to_push, not_push); to_push+=type_length(to_push); }
05fe341999-11-20Henrik Grubbström (Grubba)  if(!low_find_exact_type_match(to_push, not_push, T_AND))
69b6ab1999-11-20Henrik Grubbström (Grubba)  { push_unfinished_type(to_push); push_type(T_AND); } }
85200e1999-11-21Henrik Grubbström (Grubba) static void even_lower_and_pike_types(char *t1, char *t2) { while(EXTRACT_UCHAR(t2) == T_OR) { t2++; even_lower_and_pike_types(t1, t2); t2 += type_length(t2); } if (EXTRACT_UCHAR(t1) == EXTRACT_UCHAR(t2)) { if (EXTRACT_UCHAR(t1) == T_INT) { INT32 i1,i2; INT32 upper_bound,lower_bound; i1=extract_type_int(t1+1+sizeof(INT32)); i2=extract_type_int(t2+1+sizeof(INT32)); upper_bound = MINIMUM(i1,i2); i1=extract_type_int(t1+1); i2=extract_type_int(t2+1); lower_bound = MAXIMUM(i1,i2); if (upper_bound >= lower_bound) { push_type_int(upper_bound); push_type_int(lower_bound); push_type(T_INT); push_type(T_OR); } } else { push_unfinished_type(t1); push_type(T_OR); } } } static int lower_and_pike_types(char *t1, char *t2) { int is_complex = 0; while(EXTRACT_UCHAR(t1)==T_OR) { t1++; is_complex |= lower_and_pike_types(t1, t2); t1 += type_length(t1); } switch(EXTRACT_UCHAR(t1)) {
93dd411999-11-23Henrik Grubbström (Grubba)  case T_ZERO:
85200e1999-11-21Henrik Grubbström (Grubba)  case T_VOID: break; case T_STRING: case T_FLOAT: case T_INT: even_lower_and_pike_types(t1, t2); break; default: return 1; } return is_complex; } static int low_and_push_complex_pike_type(char *type) { int is_complex = 0; while(EXTRACT_UCHAR(type) == T_OR) {
e8c6c31999-11-21Henrik Grubbström (Grubba)  int new_complex;
85200e1999-11-21Henrik Grubbström (Grubba)  type++;
b8ba151999-11-21Henrik Grubbström (Grubba)  new_complex = low_and_push_complex_pike_type(type);
e8c6c31999-11-21Henrik Grubbström (Grubba)  if (new_complex) {
bcb32d1999-11-21Henrik Grubbström (Grubba)  if (is_complex) { push_type(T_OR); } else { is_complex = 1; }
e8c6c31999-11-21Henrik Grubbström (Grubba)  }
85200e1999-11-21Henrik Grubbström (Grubba)  type += type_length(type); } switch(EXTRACT_UCHAR(type)) { case T_VOID:
93dd411999-11-23Henrik Grubbström (Grubba)  case T_ZERO:
85200e1999-11-21Henrik Grubbström (Grubba)  case T_STRING: case T_FLOAT: case T_INT: /* Simple type. Already handled. */ break; default: push_unfinished_type(type); if (is_complex) { push_type(T_OR); } return 1; } return is_complex; }
69b6ab1999-11-20Henrik Grubbström (Grubba) static void low_and_pike_types(char *t1, char *t2) {
93dd411999-11-23Henrik Grubbström (Grubba)  if(!t1 || EXTRACT_UCHAR(t1) == T_VOID || !t2 || EXTRACT_UCHAR(t2) == T_VOID)
69b6ab1999-11-20Henrik Grubbström (Grubba)  {
93dd411999-11-23Henrik Grubbström (Grubba)  push_type(T_VOID);
69b6ab1999-11-20Henrik Grubbström (Grubba)  }
93dd411999-11-23Henrik Grubbström (Grubba)  else if(EXTRACT_UCHAR(t1) == T_ZERO || EXTRACT_UCHAR(t2) == T_ZERO)
69b6ab1999-11-20Henrik Grubbström (Grubba)  {
93dd411999-11-23Henrik Grubbström (Grubba)  push_type(T_ZERO);
69b6ab1999-11-20Henrik Grubbström (Grubba)  }
784c5c1999-11-20Henrik Grubbström (Grubba)  else if(EXTRACT_UCHAR(t1)==T_MIXED)
69b6ab1999-11-20Henrik Grubbström (Grubba)  {
784c5c1999-11-20Henrik Grubbström (Grubba)  push_unfinished_type(t2); } else if(EXTRACT_UCHAR(t2)==T_MIXED) { push_unfinished_type(t1);
69b6ab1999-11-20Henrik Grubbström (Grubba)  } else if(EXTRACT_UCHAR(t1)==T_INT && EXTRACT_UCHAR(t2)==T_INT) { INT32 i1,i2; INT32 upper_bound,lower_bound; i1=extract_type_int(t1+1+sizeof(INT32)); i2=extract_type_int(t2+1+sizeof(INT32)); upper_bound = MINIMUM(i1,i2); i1=extract_type_int(t1+1); i2=extract_type_int(t2+1); lower_bound = MAXIMUM(i1,i2); if (upper_bound >= lower_bound) { push_type_int(upper_bound); push_type_int(lower_bound); push_type(T_INT); } else { /* No overlap! */ /* FIXME: Warn? */ push_type(T_VOID); } }
fc0ad41999-12-11Henrik Grubbström (Grubba)  else if (EXTRACT_UCHAR(t1) == T_SCOPE) { if (EXTRACT_UCHAR(t2) == T_SCOPE) { low_and_pike_types(t1+2, t2+2); if (EXTRACT_UCHAR(t1+1) > EXTRACT_UCHAR(t2+1)) push_type(EXTRACT_UCHAR(t1+1)); else push_type(EXTRACT_UCHAR(t2+1)); } else { low_and_pike_types(t1+2, t2); push_type(EXTRACT_UCHAR(t1+1)); } push_type(T_SCOPE); } else if (EXTRACT_UCHAR(t2) == T_SCOPE) { low_and_pike_types(t1, t2+2); push_type(EXTRACT_UCHAR(t2+1)); push_type(T_SCOPE); }
85200e1999-11-21Henrik Grubbström (Grubba)  else if((EXTRACT_UCHAR(t1)==T_STRING && EXTRACT_UCHAR(t2)==T_STRING) ||
6d33d82001-03-28Henrik Grubbström (Grubba)  (EXTRACT_UCHAR(t1)==T_FLOAT && EXTRACT_UCHAR(t2)==T_FLOAT))
69b6ab1999-11-20Henrik Grubbström (Grubba)  { push_unfinished_type(t1);
85200e1999-11-21Henrik Grubbström (Grubba)  }
52169d1999-12-21Henrik Grubbström (Grubba)  else if(low_pike_types_le(t1, t2, 0, 0))
93dd411999-11-23Henrik Grubbström (Grubba)  { push_unfinished_type(t1); }
52169d1999-12-21Henrik Grubbström (Grubba)  else if(low_pike_types_le(t2, t1, 0, 0))
93dd411999-11-23Henrik Grubbström (Grubba)  { push_unfinished_type(t2); }
85200e1999-11-21Henrik Grubbström (Grubba)  else {
93dd411999-11-23Henrik Grubbström (Grubba)  push_type(T_ZERO);
85200e1999-11-21Henrik Grubbström (Grubba)  if (lower_and_pike_types(t1, t2)) { /* t1 contains complex types. */ if (low_and_push_complex_pike_type(t2)) { /* t2 also contains complex types. */ low_and_push_complex_pike_type(t1); push_type(T_AND); push_type(T_OR); } } /* push_unfinished_type(t1); */ /* very_low_and_pike_types(t2,t1); */
69b6ab1999-11-20Henrik Grubbström (Grubba)  } }
d68a072001-02-20Henrik Grubbström (Grubba) static void medium_and_pike_types(struct pike_type *a, struct pike_type *b)
69b6ab1999-11-20Henrik Grubbström (Grubba) { low_and_pike_types( a ? a->str : 0 , b ? b->str : 0 ); }
d68a072001-02-20Henrik Grubbström (Grubba) struct pike_type *and_pike_types(struct pike_type *a, struct pike_type *b)
69b6ab1999-11-20Henrik Grubbström (Grubba) { type_stack_mark(); medium_and_pike_types(a,b); return pop_unfinished_type(); }
d68a072001-02-20Henrik Grubbström (Grubba) static struct pike_type *low_object_lfun_type(char *t, short lfun)
6bc9281998-04-10Fredrik Hübinette (Hubbe) { struct program *p; int i;
b660c81999-03-01Fredrik Hübinette (Hubbe)  p=id_to_program(extract_type_int(t+2));
6bc9281998-04-10Fredrik Hübinette (Hubbe)  if(!p) return 0;
1347171998-04-23Fredrik Hübinette (Hubbe)  i=FIND_LFUN(p, lfun); if(i==-1) return 0;
0ee27b1998-04-14Fredrik Hübinette (Hubbe)  return ID_FROM_INT(p, i)->type;
6bc9281998-04-10Fredrik Hübinette (Hubbe) }
a946c71998-03-02Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * match two type strings, return zero if they don't match, and return * the part of 'a' that _did_ match if it did. */
bce86c1996-02-25Fredrik Hübinette (Hubbe) static char *low_match_types(char *a,char *b, int flags)
02f0631999-11-24Fredrik Hübinette (Hubbe) #ifdef PIKE_TYPE_DEBUG { int e; char *s;
fbafd01999-12-12Henrik Grubbström (Grubba)  static char *low_match_types2(char *a,char *b, int flags);
02f0631999-11-24Fredrik Hübinette (Hubbe) 
6f28352000-01-15Fredrik Hübinette (Hubbe)  if (l_flag>2) {
fbafd01999-12-12Henrik Grubbström (Grubba)  init_buf();
f37dad1999-12-11Henrik Grubbström (Grubba)  for(e=0;e<indent;e++) my_strcat(" ");
fbafd01999-12-12Henrik Grubbström (Grubba)  my_strcat("low_match_types("); low_describe_type(a); if(type_length(a) + type_length(b) > 10) { my_strcat(",\n"); for(e=0;e<indent;e++) my_strcat(" "); my_strcat(" "); low_describe_type(b); my_strcat(",\n"); for(e=0;e<indent;e++) my_strcat(" "); my_strcat(" "); }else{ my_strcat(", "); low_describe_type(b); my_strcat(", ");
f37dad1999-12-11Henrik Grubbström (Grubba)  }
fbafd01999-12-12Henrik Grubbström (Grubba)  if (flags) { int f = 0; if (flags & A_EXACT) { my_strcat("A_EXACT"); f = 1;
f37dad1999-12-11Henrik Grubbström (Grubba)  }
fbafd01999-12-12Henrik Grubbström (Grubba)  if (flags & B_EXACT) { if (f) { my_strcat(" | "); } my_strcat("B_EXACT"); f = 1;
f37dad1999-12-11Henrik Grubbström (Grubba)  }
fbafd01999-12-12Henrik Grubbström (Grubba)  if (flags & NO_MAX_ARGS) { if (f) { my_strcat(" | "); } my_strcat("NO_MAX_ARGS"); f = 1;
f37dad1999-12-11Henrik Grubbström (Grubba)  }
fbafd01999-12-12Henrik Grubbström (Grubba)  if (flags & NO_SHORTCUTS) { if (f) { my_strcat(" | "); } my_strcat("NO_SHORTCUTS"); f = 1; } } else { my_strcat("0");
f37dad1999-12-11Henrik Grubbström (Grubba)  }
fbafd01999-12-12Henrik Grubbström (Grubba)  my_strcat(");\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); indent++;
02f0631999-11-24Fredrik Hübinette (Hubbe)  } a=low_match_types2(a,b,flags);
6f28352000-01-15Fredrik Hübinette (Hubbe)  if (l_flag>2) {
fbafd01999-12-12Henrik Grubbström (Grubba)  indent--; init_buf(); for(e=0;e<indent;e++) my_strcat(" "); my_strcat("= "); if(a) low_describe_type(a); else my_strcat("NULL"); my_strcat("\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); }
02f0631999-11-24Fredrik Hübinette (Hubbe)  return a; } static char *low_match_types2(char *a,char *b, int flags) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) {
1d53281996-11-25Fredrik Hübinette (Hubbe)  int correct_args;
5267b71995-08-09Fredrik Hübinette (Hubbe)  char *ret; if(a == b) return a;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  switch(EXTRACT_UCHAR(a))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
bce86c1996-02-25Fredrik Hübinette (Hubbe)  case T_AND:
5267b71995-08-09Fredrik Hübinette (Hubbe)  a++;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  ret=low_match_types(a,b,flags); if(!ret) return 0; a+=type_length(a); return low_match_types(a,b,flags); case T_OR:
5267b71995-08-09Fredrik Hübinette (Hubbe)  a++;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  ret=low_match_types(a,b,flags);
5ac7661998-04-28Fredrik Hübinette (Hubbe)  if(ret && !(flags & NO_SHORTCUTS)) return ret;
5267b71995-08-09Fredrik Hübinette (Hubbe)  a+=type_length(a);
5ac7661998-04-28Fredrik Hübinette (Hubbe)  if(ret) { low_match_types(a,b,flags); return ret; }else{ return low_match_types(a,b,flags); }
bce86c1996-02-25Fredrik Hübinette (Hubbe) 
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: return low_match_types(a+1, b, flags);
bce86c1996-02-25Fredrik Hübinette (Hubbe)  case T_NOT:
9e52381998-03-01Fredrik Hübinette (Hubbe)  if(low_match_types(a+1,b,(flags ^ B_EXACT ) | NO_MAX_ARGS))
bce86c1996-02-25Fredrik Hübinette (Hubbe)  return 0; return a;
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_ASSIGN: ret=low_match_types(a+2,b,flags);
a946c71998-03-02Fredrik Hübinette (Hubbe)  if(ret && EXTRACT_UCHAR(b)!=T_VOID)
9e52381998-03-01Fredrik Hübinette (Hubbe)  { int m=EXTRACT_UCHAR(a+1)-'0';
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *tmp;
02f0631999-11-24Fredrik Hübinette (Hubbe)  type_stack_mark(); push_unfinished_type_with_markers(b, b_markers); tmp=pop_unfinished_type();
a946c71998-03-02Fredrik Hübinette (Hubbe)  type_stack_mark();
4d7b181999-12-07Fredrik Hübinette (Hubbe)  medium_or_pike_types(a_markers[m], tmp, 0);
d68a072001-02-20Henrik Grubbström (Grubba)  if(a_markers[m]) free_type(a_markers[m]); free_type(tmp);
a946c71998-03-02Fredrik Hübinette (Hubbe)  a_markers[m]=pop_unfinished_type();
02f0631999-11-24Fredrik Hübinette (Hubbe)  #ifdef PIKE_TYPE_DEBUG
6f28352000-01-15Fredrik Hübinette (Hubbe)  if (l_flag>2) {
02f0631999-11-24Fredrik Hübinette (Hubbe)  char *s; int e; init_buf(); for(e=0;e<indent;e++) my_strcat(" "); my_strcat("a_markers[");
f258372000-09-08Henrik Grubbström (Grubba)  my_putchar((char)(m+'0'));
02f0631999-11-24Fredrik Hübinette (Hubbe)  my_strcat("]="); low_describe_type(a_markers[m]->str); my_strcat("\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); } #endif #ifdef PIKE_DEBUG if(a_markers[m]->str[0] == m+'0') fatal("Cyclic type!\n"); #endif
9e52381998-03-01Fredrik Hübinette (Hubbe)  } return ret; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { int m=EXTRACT_UCHAR(a)-'0'; if(a_markers[m])
02f0631999-11-24Fredrik Hübinette (Hubbe)  { #ifdef PIKE_DEBUG if(a_markers[m]->str[0] == EXTRACT_UCHAR(a)) fatal("Cyclic type!\n"); if(EXTRACT_UCHAR(a_markers[m]->str) == T_OR && a_markers[m]->str[1] == EXTRACT_UCHAR(a)) fatal("Cyclic type!\n"); #endif
a946c71998-03-02Fredrik Hübinette (Hubbe)  return low_match_types(a_markers[m]->str, b, flags);
02f0631999-11-24Fredrik Hübinette (Hubbe)  }
9e52381998-03-01Fredrik Hübinette (Hubbe)  else return low_match_types(mixed_type_string->str, b, flags); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
bce86c1996-02-25Fredrik Hübinette (Hubbe)  switch(EXTRACT_UCHAR(b))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
bce86c1996-02-25Fredrik Hübinette (Hubbe)  case T_AND:
5267b71995-08-09Fredrik Hübinette (Hubbe)  b++;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  ret=low_match_types(a,b,flags); if(!ret) return 0; b+=type_length(b); return low_match_types(a,b,flags); case T_OR:
5267b71995-08-09Fredrik Hübinette (Hubbe)  b++;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  ret=low_match_types(a,b,flags);
5ac7661998-04-28Fredrik Hübinette (Hubbe)  if(ret && !(flags & NO_SHORTCUTS)) return ret;
5267b71995-08-09Fredrik Hübinette (Hubbe)  b+=type_length(b);
5ac7661998-04-28Fredrik Hübinette (Hubbe)  if(ret) { low_match_types(a,b,flags); return ret; }else{ return low_match_types(a,b,flags); }
bce86c1996-02-25Fredrik Hübinette (Hubbe) 
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: return low_match_types(a, b+1, flags);
bce86c1996-02-25Fredrik Hübinette (Hubbe)  case T_NOT:
9e52381998-03-01Fredrik Hübinette (Hubbe)  if(low_match_types(a,b+1, (flags ^ A_EXACT ) | NO_MAX_ARGS))
bce86c1996-02-25Fredrik Hübinette (Hubbe)  return 0; return a;
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_ASSIGN: ret=low_match_types(a,b+2,flags);
a946c71998-03-02Fredrik Hübinette (Hubbe)  if(ret && EXTRACT_UCHAR(a)!=T_VOID)
9e52381998-03-01Fredrik Hübinette (Hubbe)  { int m=EXTRACT_UCHAR(b+1)-'0';
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *tmp;
a946c71998-03-02Fredrik Hübinette (Hubbe)  type_stack_mark();
02f0631999-11-24Fredrik Hübinette (Hubbe)  push_unfinished_type_with_markers(a, a_markers); tmp=pop_unfinished_type(); type_stack_mark();
4d7b181999-12-07Fredrik Hübinette (Hubbe)  medium_or_pike_types(b_markers[m], tmp, 0);
d68a072001-02-20Henrik Grubbström (Grubba)  if(b_markers[m]) free_type(b_markers[m]); free_type(tmp);
a946c71998-03-02Fredrik Hübinette (Hubbe)  b_markers[m]=pop_unfinished_type();
02f0631999-11-24Fredrik Hübinette (Hubbe) #ifdef PIKE_TYPE_DEBUG
6f28352000-01-15Fredrik Hübinette (Hubbe)  if (l_flag>2) {
02f0631999-11-24Fredrik Hübinette (Hubbe)  char *s; int e; init_buf(); for(e=0;e<indent;e++) my_strcat(" "); my_strcat("b_markers[");
f258372000-09-08Henrik Grubbström (Grubba)  my_putchar((char)(m+'0'));
02f0631999-11-24Fredrik Hübinette (Hubbe)  my_strcat("]="); low_describe_type(b_markers[m]->str); my_strcat("\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); } #endif #ifdef PIKE_DEBUG if(b_markers[m]->str[0] == m+'0') fatal("Cyclic type!\n"); #endif
9e52381998-03-01Fredrik Hübinette (Hubbe)  } return ret; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { int m=EXTRACT_UCHAR(b)-'0'; if(b_markers[m])
02f0631999-11-24Fredrik Hübinette (Hubbe)  { #ifdef PIKE_DEBUG if(b_markers[m]->str[0] == EXTRACT_UCHAR(b)) fatal("Cyclic type!\n"); #endif
a946c71998-03-02Fredrik Hübinette (Hubbe)  return low_match_types(a, b_markers[m]->str, flags);
02f0631999-11-24Fredrik Hübinette (Hubbe)  }
9e52381998-03-01Fredrik Hübinette (Hubbe)  else return low_match_types(a, mixed_type_string->str, flags); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
0d202a1995-10-20Fredrik Hübinette (Hubbe)  /* 'mixed' matches anything */
02f0631999-11-24Fredrik Hübinette (Hubbe) 
327c051999-11-24Fredrik Hübinette (Hubbe)  if(((EXTRACT_UCHAR(a) == T_ZERO || EXTRACT_UCHAR(a) == T_MIXED) &&
f37dad1999-12-11Henrik Grubbström (Grubba)  !(flags & (A_EXACT|B_EXACT)) &&
327c051999-11-24Fredrik Hübinette (Hubbe)  EXTRACT_UCHAR(b) != T_VOID))
02f0631999-11-24Fredrik Hübinette (Hubbe)  { #if 1 switch(EXTRACT_UCHAR(b)) { /* These types can contain sub-types */ case T_ARRAY: low_match_types(array_type_string->str,b , flags); break; case T_MAPPING: low_match_types(mapping_type_string->str,b, flags); break; case T_FUNCTION: low_match_types(function_type_string->str,b, flags); break; case T_MULTISET: low_match_types(multiset_type_string->str,b, flags); break; } #endif return a; }
327c051999-11-24Fredrik Hübinette (Hubbe)  if((( EXTRACT_UCHAR(b) == T_ZERO || EXTRACT_UCHAR(b) == T_MIXED) &&
f37dad1999-12-11Henrik Grubbström (Grubba)  !(flags & (A_EXACT|B_EXACT)) &&
02f0631999-11-24Fredrik Hübinette (Hubbe)  EXTRACT_UCHAR(a) != T_VOID)) { #if 1 switch(EXTRACT_UCHAR(a)) { /* These types can contain sub-types */ case T_ARRAY: low_match_types(a , array_type_string->str, flags); break; case T_MAPPING: low_match_types(a , mapping_type_string->str, flags); break; case T_FUNCTION: low_match_types(a , function_type_string->str, flags); break; case T_MULTISET: low_match_types(a , multiset_type_string->str, flags); break; } #endif return a; }
93dd411999-11-23Henrik Grubbström (Grubba) 
fc0ad41999-12-11Henrik Grubbström (Grubba)  /* Convert zero to int(0..0). */ if (EXTRACT_UCHAR(a) == T_ZERO) a = tInt0; if (EXTRACT_UCHAR(b) == T_ZERO) b = tInt0;
d2c6081996-11-07Fredrik Hübinette (Hubbe) 
9f68471997-03-08Fredrik Hübinette (Hubbe)  /* Special cases (tm) */ switch(EXTRACT_TWOT(a,b))
255d351997-01-26Fredrik Hübinette (Hubbe)  {
9f68471997-03-08Fredrik Hübinette (Hubbe)  case TWOT(T_PROGRAM, T_FUNCTION): case TWOT(T_FUNCTION, T_PROGRAM):
6d33d82001-03-28Henrik Grubbström (Grubba)  /* FIXME: Should look at the program subtype. */
255d351997-01-26Fredrik Hübinette (Hubbe)  return a;
f37dad1999-12-11Henrik Grubbström (Grubba) 
9f68471997-03-08Fredrik Hübinette (Hubbe)  case TWOT(T_OBJECT, T_FUNCTION):
d2c6081996-11-07Fredrik Hübinette (Hubbe)  {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *s;
6bc9281998-04-10Fredrik Hübinette (Hubbe)  if((s=low_object_lfun_type(a, LFUN_CALL)))
f37dad1999-12-11Henrik Grubbström (Grubba)  return low_match_types(s->str,b,flags); if (flags & B_EXACT) { /* A function isn't an object */ return 0; }
d2c6081996-11-07Fredrik Hübinette (Hubbe)  return a; }
9f68471997-03-08Fredrik Hübinette (Hubbe)  case TWOT(T_FUNCTION, T_OBJECT): {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *s;
6bc9281998-04-10Fredrik Hübinette (Hubbe)  if((s=low_object_lfun_type(b, LFUN_CALL)))
f37dad1999-12-11Henrik Grubbström (Grubba)  return low_match_types(a,s->str,flags); if (flags & A_EXACT) { /* A function isn't an object */ return 0; }
9f68471997-03-08Fredrik Hübinette (Hubbe)  return a; } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(EXTRACT_UCHAR(a) != EXTRACT_UCHAR(b)) return 0; ret=a; switch(EXTRACT_UCHAR(a)) { case T_FUNCTION:
1d53281996-11-25Fredrik Hübinette (Hubbe)  correct_args=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  a++; b++; while(EXTRACT_UCHAR(a)!=T_MANY || EXTRACT_UCHAR(b)!=T_MANY) { char *a_tmp,*b_tmp; if(EXTRACT_UCHAR(a)==T_MANY) { a_tmp=a+1; }else{ a_tmp=a; a+=type_length(a); } if(EXTRACT_UCHAR(b)==T_MANY) {
0d202a1995-10-20Fredrik Hübinette (Hubbe)  b_tmp=b+1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{ b_tmp=b; b+=type_length(b); }
fc0ad41999-12-11Henrik Grubbström (Grubba)  if(!low_match_types(a_tmp, b_tmp, (flags | NO_MAX_ARGS) & ~(A_EXACT|B_EXACT))) return 0;
1d53281996-11-25Fredrik Hübinette (Hubbe)  if(++correct_args > max_correct_args)
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  if(!(flags & NO_MAX_ARGS)) max_correct_args=correct_args;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } /* check the 'many' type */ a++; b++;
0d202a1995-10-20Fredrik Hübinette (Hubbe)  if(EXTRACT_UCHAR(b)==T_VOID || EXTRACT_UCHAR(a)==T_VOID)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { a+=type_length(a);
0d202a1995-10-20Fredrik Hübinette (Hubbe)  b+=type_length(b);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
fc0ad41999-12-11Henrik Grubbström (Grubba)  if(!low_match_types(a,b, (flags | NO_MAX_ARGS) & ~(A_EXACT|B_EXACT))) return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  if(!(flags & NO_MAX_ARGS)) max_correct_args=0x7fffffff;
5267b71995-08-09Fredrik Hübinette (Hubbe)  /* check the returntype */
7eda1d1999-11-26Henrik Grubbström (Grubba)  if ((EXTRACT_UCHAR(b) == T_VOID) && (EXTRACT_UCHAR(a) != T_VOID)) { /* Promote b to a function returning zero. */
fc0ad41999-12-11Henrik Grubbström (Grubba)  if (!low_match_types(a, tZero, flags & ~(A_EXACT|B_EXACT))) return 0;
7eda1d1999-11-26Henrik Grubbström (Grubba)  } else if ((EXTRACT_UCHAR(a) == T_VOID) && (EXTRACT_UCHAR(b) != T_VOID)) { /* Promote a to a function returning zero. */
fc0ad41999-12-11Henrik Grubbström (Grubba)  if(!low_match_types(tZero,b,flags & ~(A_EXACT|B_EXACT))) return 0; } else if(!low_match_types(a,b,flags & ~(A_EXACT|B_EXACT))) return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case T_MAPPING:
fc0ad41999-12-11Henrik Grubbström (Grubba)  if(!low_match_types(++a,++b,flags & ~(A_EXACT|B_EXACT))) return 0; if(!low_match_types(a+type_length(a),b+type_length(b), flags & ~(A_EXACT|B_EXACT))) return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
d2c6081996-11-07Fredrik Hübinette (Hubbe)  case T_OBJECT:
636e471998-04-15Fredrik Hübinette (Hubbe) #if 0
b660c81999-03-01Fredrik Hübinette (Hubbe)  if(extract_type_int(a+2) || extract_type_int(b+2))
636e471998-04-15Fredrik Hübinette (Hubbe)  { fprintf(stderr,"Type match1: "); stupid_describe_type(a,type_length(a));
18415a2001-02-27Martin Stjernholm  fprintf(stderr,"\nType match2: ");
636e471998-04-15Fredrik Hübinette (Hubbe)  stupid_describe_type(b,type_length(b));
18415a2001-02-27Martin Stjernholm  fputc('\n', stderr);
636e471998-04-15Fredrik Hübinette (Hubbe)  } #endif
6bc9281998-04-10Fredrik Hübinette (Hubbe)  /* object(* 0) matches any object */
b660c81999-03-01Fredrik Hübinette (Hubbe)  if(!extract_type_int(a+2) || !extract_type_int(b+2)) break;
6bc9281998-04-10Fredrik Hübinette (Hubbe)  /* object(x *) =? object(x *) */ if(EXTRACT_UCHAR(a+1) == EXTRACT_UCHAR(b+1)) { /* x? */ if(EXTRACT_UCHAR(a+1)) { /* object(1 x) =? object(1 x) */
b660c81999-03-01Fredrik Hübinette (Hubbe)  if(extract_type_int(a+2) != extract_type_int(b+2)) return 0;
6bc9281998-04-10Fredrik Hübinette (Hubbe)  }else{ /* object(0 *) =? object(0 *) */
fbafd01999-12-12Henrik Grubbström (Grubba)  /* FIXME: Ought to check the implements relation */
6bc9281998-04-10Fredrik Hübinette (Hubbe)  break; } } { struct program *ap,*bp;
b660c81999-03-01Fredrik Hübinette (Hubbe)  ap=id_to_program(extract_type_int(a+2)); bp=id_to_program(extract_type_int(b+2));
6bc9281998-04-10Fredrik Hübinette (Hubbe)  if(!ap || !bp) break;
636e471998-04-15Fredrik Hübinette (Hubbe) 
0cbc271999-12-14Fredrik Hübinette (Hubbe) #if 0
fbafd01999-12-12Henrik Grubbström (Grubba)  /* FIXME: Temporary kludge. * match_types() currently seems to need to be symetric. */ if (!implements(ap,bp) && !implements(bp,ap)) return 0; #else /* !1 */
6bc9281998-04-10Fredrik Hübinette (Hubbe)  if(EXTRACT_UCHAR(a+1)) {
20ea771999-12-15Fredrik Hübinette (Hubbe)  if(!implements(implements_a=ap,implements_b=bp))
6bc9281998-04-10Fredrik Hübinette (Hubbe)  return 0; }else{
20ea771999-12-15Fredrik Hübinette (Hubbe)  if(!implements(implements_a=bp,implements_b=ap))
6bc9281998-04-10Fredrik Hübinette (Hubbe)  return 0; }
fbafd01999-12-12Henrik Grubbström (Grubba) #endif /* 1 */
6bc9281998-04-10Fredrik Hübinette (Hubbe)  }
d2c6081996-11-07Fredrik Hübinette (Hubbe)  break;
b660c81999-03-01Fredrik Hübinette (Hubbe)  case T_INT: { INT32 amin=extract_type_int(a+1); INT32 amax=extract_type_int(a+1+sizeof(INT32)); INT32 bmin=extract_type_int(b+1); INT32 bmax=extract_type_int(b+1+sizeof(INT32)); if(amin > bmax || bmin > amax) return 0; break; }
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE:
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_ARRAY:
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM:
fc0ad41999-12-11Henrik Grubbström (Grubba)  if(!low_match_types(++a,++b,flags & ~(A_EXACT|B_EXACT))) return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_FLOAT: case T_STRING:
93dd411999-11-23Henrik Grubbström (Grubba)  case T_ZERO: case T_VOID: case T_MIXED: break; default:
a4a1722000-12-05Per Hedbor  fatal("Error in type string.\n");
93dd411999-11-23Henrik Grubbström (Grubba)  } return ret; } /* * Check the partial ordering relation. * * mixed * * int float string program function object * * zero * * void
dfda7e1999-11-25Henrik Grubbström (Grubba)  * * Note that non-destructive operations are assumed. * ie it's assumed that calling a function(mapping(string|int:string|int):void) * with a mapping(int:int) won't change the type of the mapping after the * operation.
93dd411999-11-23Henrik Grubbström (Grubba)  */
52169d1999-12-21Henrik Grubbström (Grubba) static int low_pike_types_le(char *a, char *b, int array_cnt, unsigned int flags)
ae18181999-11-25Henrik Grubbström (Grubba) #ifdef PIKE_TYPE_DEBUG { int e; char *s;
52169d1999-12-21Henrik Grubbström (Grubba)  static int low_pike_types_le2(char *a, char *b, int array_cnt, unsigned int flags);
ae18181999-11-25Henrik Grubbström (Grubba)  int res;
6134591999-12-15Henrik Grubbström (Grubba)  char buf[50];
ae18181999-11-25Henrik Grubbström (Grubba) 
6f28352000-01-15Fredrik Hübinette (Hubbe)  if (l_flag>2) {
fbafd01999-12-12Henrik Grubbström (Grubba)  init_buf();
ae18181999-11-25Henrik Grubbström (Grubba)  for(e=0;e<indent;e++) my_strcat(" ");
fbafd01999-12-12Henrik Grubbström (Grubba)  my_strcat("low_pike_types_le("); low_describe_type(a); if(type_length(a) + type_length(b) > 10) { my_strcat(",\n"); for(e=0;e<indent;e++) my_strcat(" "); my_strcat(" "); low_describe_type(b); }else{ my_strcat(", "); low_describe_type(b); }
6134591999-12-15Henrik Grubbström (Grubba)  if(type_length(a) + type_length(b) > 10) { my_strcat(",\n"); for(e=0;e<indent;e++) my_strcat(" "); my_strcat(" "); }else{ my_strcat(", "); } sprintf(buf, "%d", array_cnt); my_strcat(buf);
52169d1999-12-21Henrik Grubbström (Grubba)  my_strcat(", "); sprintf(buf, "0x%08x", flags); my_strcat(buf);
fbafd01999-12-12Henrik Grubbström (Grubba)  my_strcat(");\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); indent++;
ae18181999-11-25Henrik Grubbström (Grubba)  }
52169d1999-12-21Henrik Grubbström (Grubba)  res=low_pike_types_le2(a, b, array_cnt, flags);
ae18181999-11-25Henrik Grubbström (Grubba) 
6f28352000-01-15Fredrik Hübinette (Hubbe)  if (l_flag>2) {
fbafd01999-12-12Henrik Grubbström (Grubba)  indent--;
ae18181999-11-25Henrik Grubbström (Grubba) 
fbafd01999-12-12Henrik Grubbström (Grubba)  for(e=0;e<indent;e++) fprintf(stderr, " "); fprintf(stderr, "= %d\n", res); }
ae18181999-11-25Henrik Grubbström (Grubba)  return res; }
52169d1999-12-21Henrik Grubbström (Grubba) static int low_pike_types_le2(char *a, char *b, int array_cnt, unsigned int flags)
ae18181999-11-25Henrik Grubbström (Grubba) #endif /* PIKE_TYPE_DEBUG */
93dd411999-11-23Henrik Grubbström (Grubba) { int ret; if(a == b) return 1; switch(EXTRACT_UCHAR(a)) { case T_AND: /* OK if either of the parts is a subset. */ /* FIXME: What if b also contains an AND? */ a++;
52169d1999-12-21Henrik Grubbström (Grubba)  ret = low_pike_types_le(a, b, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  if(ret) return ret; a += type_length(a);
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, b, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  case T_OR: /* OK, if both of the parts are a subset */ a++;
144ce31999-12-19Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(a) == T_VOID) { /* Special case for T_VOID */ /* FIXME: Should probably be handled as T_ZERO. */ a += type_length(a);
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, b, array_cnt, flags);
144ce31999-12-19Henrik Grubbström (Grubba)  } else {
52169d1999-12-21Henrik Grubbström (Grubba)  ret=low_pike_types_le(a, b, array_cnt, flags);
144ce31999-12-19Henrik Grubbström (Grubba)  if (!ret) return 0; a+=type_length(a); if (EXTRACT_UCHAR(a) == T_VOID) { /* Special case for T_VOID */ /* FIXME: Should probably be handled as T_ZERO. */ return 1; } else {
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, b, array_cnt, flags);
144ce31999-12-19Henrik Grubbström (Grubba)  } }
93dd411999-11-23Henrik Grubbström (Grubba) 
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: return low_pike_types_le(a+1, b, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  case T_NOT:
72a1e91999-12-19Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(b) == T_NOT) {
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(b+1, a+1, -array_cnt, flags);
72a1e91999-12-19Henrik Grubbström (Grubba)  }
69a9431999-12-21Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(a+1) == T_NOT) {
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a+2, b, array_cnt, flags);
69a9431999-12-21Henrik Grubbström (Grubba)  }
52169d1999-12-21Henrik Grubbström (Grubba)  if (low_pike_types_le(a+1, b, array_cnt, flags)) {
72a1e91999-12-19Henrik Grubbström (Grubba)  return 0; } /* FIXME: This is wrong... */
52169d1999-12-21Henrik Grubbström (Grubba)  return !low_pike_types_le(b, a+1, -array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  case T_ASSIGN:
52169d1999-12-21Henrik Grubbström (Grubba)  ret=low_pike_types_le(a+2, b, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  if(ret && EXTRACT_UCHAR(b)!=T_VOID) { int m=EXTRACT_UCHAR(a+1)-'0';
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *tmp;
6134591999-12-15Henrik Grubbström (Grubba)  int i;
93dd411999-11-23Henrik Grubbström (Grubba)  type_stack_mark();
02f0631999-11-24Fredrik Hübinette (Hubbe)  push_unfinished_type_with_markers(b, b_markers);
6134591999-12-15Henrik Grubbström (Grubba)  for(i=array_cnt; i > 0; i--) push_type(T_ARRAY);
02f0631999-11-24Fredrik Hübinette (Hubbe)  tmp=pop_unfinished_type();
fbafd01999-12-12Henrik Grubbström (Grubba) 
02f0631999-11-24Fredrik Hübinette (Hubbe)  type_stack_mark();
4d7b181999-12-07Fredrik Hübinette (Hubbe)  medium_or_pike_types(a_markers[m], tmp, 0);
d68a072001-02-20Henrik Grubbström (Grubba)  if(a_markers[m]) free_type(a_markers[m]); free_type(tmp);
93dd411999-11-23Henrik Grubbström (Grubba)  a_markers[m]=pop_unfinished_type();
02f0631999-11-24Fredrik Hübinette (Hubbe) #ifdef PIKE_TYPE_DEBUG
6f28352000-01-15Fredrik Hübinette (Hubbe)  if (l_flag>2) {
02f0631999-11-24Fredrik Hübinette (Hubbe)  char *s; int e; init_buf(); for(e=0;e<indent;e++) my_strcat(" "); my_strcat("a_markers[");
f258372000-09-08Henrik Grubbström (Grubba)  my_putchar((char)(m+'0'));
02f0631999-11-24Fredrik Hübinette (Hubbe)  my_strcat("]="); low_describe_type(a_markers[m]->str); my_strcat("\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); } #endif
93dd411999-11-23Henrik Grubbström (Grubba)  } return ret; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { int m=EXTRACT_UCHAR(a)-'0'; if(a_markers[m])
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a_markers[m]->str, b, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  else
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(mixed_type_string->str, b, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  } } switch(EXTRACT_UCHAR(b)) { case T_AND: /* OK, if a is a subset of both parts. */ b++;
52169d1999-12-21Henrik Grubbström (Grubba)  ret = low_pike_types_le(a, b, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  if(!ret) return 0; b+=type_length(b);
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, b, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  case T_OR: /* OK if a is a subset of either of the parts. */ b++;
52169d1999-12-21Henrik Grubbström (Grubba)  ret=low_pike_types_le(a, b, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  if (ret) return ret; b+=type_length(b);
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, b, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba) 
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING: return low_pike_types_le(a, b+1, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  case T_NOT:
69a9431999-12-21Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(b+1) == T_NOT) {
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, b+2, array_cnt, flags);
69a9431999-12-21Henrik Grubbström (Grubba)  }
52169d1999-12-21Henrik Grubbström (Grubba)  if (low_pike_types_le(a, b+1, array_cnt, flags)) {
72a1e91999-12-19Henrik Grubbström (Grubba)  return 0; } /* FIXME: This is wrong... */
52169d1999-12-21Henrik Grubbström (Grubba)  return !low_pike_types_le(b+1, a, -array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  case T_ASSIGN:
52169d1999-12-21Henrik Grubbström (Grubba)  ret=low_pike_types_le(a, b+2, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  if(ret && EXTRACT_UCHAR(a)!=T_VOID) { int m=EXTRACT_UCHAR(b+1)-'0';
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *tmp;
6134591999-12-15Henrik Grubbström (Grubba)  int i;
93dd411999-11-23Henrik Grubbström (Grubba)  type_stack_mark();
02f0631999-11-24Fredrik Hübinette (Hubbe)  push_unfinished_type_with_markers(a, a_markers);
6134591999-12-15Henrik Grubbström (Grubba)  for(i = array_cnt; i < 0; i++) push_type(T_ARRAY);
02f0631999-11-24Fredrik Hübinette (Hubbe)  tmp=pop_unfinished_type(); type_stack_mark();
4d7b181999-12-07Fredrik Hübinette (Hubbe)  medium_or_pike_types(b_markers[m], tmp, 0);
d68a072001-02-20Henrik Grubbström (Grubba)  if(b_markers[m]) free_type(b_markers[m]); free_type(tmp);
93dd411999-11-23Henrik Grubbström (Grubba)  b_markers[m]=pop_unfinished_type();
02f0631999-11-24Fredrik Hübinette (Hubbe) #ifdef PIKE_TYPE_DEBUG
6f28352000-01-15Fredrik Hübinette (Hubbe)  if (l_flag>2) {
02f0631999-11-24Fredrik Hübinette (Hubbe)  char *s; int e; init_buf(); for(e=0;e<indent;e++) my_strcat(" "); my_strcat("b_markers[");
f258372000-09-08Henrik Grubbström (Grubba)  my_putchar((char)(m+'0'));
02f0631999-11-24Fredrik Hübinette (Hubbe)  my_strcat("]="); low_describe_type(b_markers[m]->str); my_strcat("\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); } #endif
93dd411999-11-23Henrik Grubbström (Grubba)  } return ret; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { int m=EXTRACT_UCHAR(b)-'0'; if(b_markers[m])
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, b_markers[m]->str, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  else
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, mixed_type_string->str, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  }
6134591999-12-15Henrik Grubbström (Grubba)  }
93dd411999-11-23Henrik Grubbström (Grubba) 
6134591999-12-15Henrik Grubbström (Grubba)  if ((array_cnt < 0) && (EXTRACT_UCHAR(b) == T_ARRAY)) { while (EXTRACT_UCHAR(b) == T_ARRAY) { b++; if (!++array_cnt) break; }
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, b, array_cnt, flags);
6134591999-12-15Henrik Grubbström (Grubba)  } else if ((array_cnt > 0) && (EXTRACT_UCHAR(a) == T_ARRAY)) { while (EXTRACT_UCHAR(a) == T_ARRAY) { a++; if (!--array_cnt) break; }
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, b, array_cnt, flags);
6134591999-12-15Henrik Grubbström (Grubba)  }
8043d51999-12-17Henrik Grubbström (Grubba)  /* NOTE: void only matches void. */ if (EXTRACT_UCHAR(a) == T_VOID) { /* void <= any_type */ if (array_cnt >= 0) { /* !array(void) */ if (!array_cnt && (EXTRACT_UCHAR(b) == T_VOID)) { return 1; } return 0;
6134591999-12-15Henrik Grubbström (Grubba)  }
93dd411999-11-23Henrik Grubbström (Grubba)  }
8043d51999-12-17Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(b) == T_VOID) { if (array_cnt <= 0) { /* !array(void) */
6134591999-12-15Henrik Grubbström (Grubba)  return 0; }
93dd411999-11-23Henrik Grubbström (Grubba)  }
8043d51999-12-17Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(b) == T_MIXED) { /* any_type <= 'mixed' */ if (array_cnt <= 0) { /* !array(mixed) */
6134591999-12-15Henrik Grubbström (Grubba)  return 1; }
93dd411999-11-23Henrik Grubbström (Grubba)  }
8043d51999-12-17Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(a) == T_MIXED) { if (array_cnt >= 0) { /* !array(mixed) */
6134591999-12-15Henrik Grubbström (Grubba)  return 0; }
93dd411999-11-23Henrik Grubbström (Grubba)  } if (EXTRACT_UCHAR(a) == T_ZERO) { /* void <= zero <= any_type */
6134591999-12-15Henrik Grubbström (Grubba)  if (array_cnt >= 0) { /* !array(zero) */ return 1; }
93dd411999-11-23Henrik Grubbström (Grubba)  } if (EXTRACT_UCHAR(b) == T_ZERO) {
6134591999-12-15Henrik Grubbström (Grubba)  if (array_cnt <= 0) { /* !array(zero) */ return 0; }
93dd411999-11-23Henrik Grubbström (Grubba)  } /* Special cases (tm) */ switch(EXTRACT_TWOT(a,b)) { case TWOT(T_PROGRAM, T_FUNCTION): case TWOT(T_FUNCTION, T_PROGRAM): /* FIXME: Not really... Should check the return value. */
6d33d82001-03-28Henrik Grubbström (Grubba)  /* FIXME: Should look at the program subtype. */
93dd411999-11-23Henrik Grubbström (Grubba)  return 1; case TWOT(T_OBJECT, T_FUNCTION): {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *s;
93dd411999-11-23Henrik Grubbström (Grubba)  if((s=low_object_lfun_type(a, LFUN_CALL)))
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(s->str, b, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  return 1; } case TWOT(T_FUNCTION, T_OBJECT): {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *s;
93dd411999-11-23Henrik Grubbström (Grubba)  if((s=low_object_lfun_type(b, LFUN_CALL)))
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, s->str, array_cnt, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  return 1; }
6134591999-12-15Henrik Grubbström (Grubba)  case TWOT(T_FUNCTION, T_ARRAY): { while (EXTRACT_UCHAR(b) == T_ARRAY) { b++; array_cnt++; }
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, b, array_cnt, flags);
6134591999-12-15Henrik Grubbström (Grubba)  } case TWOT(T_ARRAY, T_FUNCTION): { while (EXTRACT_UCHAR(a) == T_ARRAY) { a++; array_cnt--; }
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a, b, array_cnt, flags);
6134591999-12-15Henrik Grubbström (Grubba)  }
93dd411999-11-23Henrik Grubbström (Grubba)  } if(EXTRACT_UCHAR(a) != EXTRACT_UCHAR(b)) return 0;
6134591999-12-15Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(a) == T_FUNCTION) {
dfda7e1999-11-25Henrik Grubbström (Grubba)  /* * function(A...:B) <= function(C...:D) iff C <= A && B <= D */
3d12931999-11-25Henrik Grubbström (Grubba)  /* * function(:int) <= function(int:int) * function(int|string:int) <= function(int:int)
7eda1d1999-11-26Henrik Grubbström (Grubba)  * function(:int) <= function(:void)
3d12931999-11-25Henrik Grubbström (Grubba)  * function(string:int) != function(int:int) * function(int:int) != function(:int)
8043d51999-12-17Henrik Grubbström (Grubba)  * * FIXME: Enforcing of all required arguments?
3d12931999-11-25Henrik Grubbström (Grubba)  */
93dd411999-11-23Henrik Grubbström (Grubba)  a++; b++; while(EXTRACT_UCHAR(a)!=T_MANY || EXTRACT_UCHAR(b)!=T_MANY) { char *a_tmp,*b_tmp; if(EXTRACT_UCHAR(a)==T_MANY) { a_tmp=a+1; }else{ a_tmp=a; a+=type_length(a); } if(EXTRACT_UCHAR(b)==T_MANY) { b_tmp=b+1; }else{ b_tmp=b; b+=type_length(b); }
3d12931999-11-25Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(a_tmp) != T_VOID) {
52169d1999-12-21Henrik Grubbström (Grubba)  if (!low_pike_types_le(b_tmp, a_tmp, 0, flags)) {
8fea161999-12-31Henrik Grubbström (Grubba)  return 0;
52169d1999-12-21Henrik Grubbström (Grubba)  }
3d12931999-11-25Henrik Grubbström (Grubba)  }
93dd411999-11-23Henrik Grubbström (Grubba)  } /* check the 'many' type */ a++; b++;
69a9431999-12-21Henrik Grubbström (Grubba)  if ((EXTRACT_UCHAR(a) != T_VOID) && (EXTRACT_UCHAR(b) != T_VOID)) {
52169d1999-12-21Henrik Grubbström (Grubba)  if (!low_pike_types_le(b, a, 0, flags)) {
8fea161999-12-31Henrik Grubbström (Grubba)  return 0;
52169d1999-12-21Henrik Grubbström (Grubba)  }
3d12931999-11-25Henrik Grubbström (Grubba)  }
93dd411999-11-23Henrik Grubbström (Grubba)  a+=type_length(a); b+=type_length(b); /* check the returntype */
95a83d1999-12-26Henrik Grubbström (Grubba)  /* FIXME: Check array_cnt */ if ((EXTRACT_UCHAR(b) != T_VOID) && (EXTRACT_UCHAR(a) != T_VOID)) {
52169d1999-12-21Henrik Grubbström (Grubba)  if(!low_pike_types_le(a, b, array_cnt, flags)) return 0;
438d421999-11-26Henrik Grubbström (Grubba)  }
6134591999-12-15Henrik Grubbström (Grubba)  return 1; } if (array_cnt) return 0;
93dd411999-11-23Henrik Grubbström (Grubba) 
6134591999-12-15Henrik Grubbström (Grubba)  switch(EXTRACT_UCHAR(a)) {
93dd411999-11-23Henrik Grubbström (Grubba)  case T_MAPPING: /*
3ac0d11999-12-12Martin Stjernholm  * mapping(A:B) <= mapping(C:D) iff A <= C && B <= D.
93dd411999-11-23Henrik Grubbström (Grubba)  */
52169d1999-12-21Henrik Grubbström (Grubba)  if(!low_pike_types_le(++a, ++b, 0, flags)) return 0; return low_pike_types_le(a+type_length(a), b+type_length(b), 0, flags);
93dd411999-11-23Henrik Grubbström (Grubba)  case T_OBJECT: #if 0 if(extract_type_int(a+2) || extract_type_int(b+2)) { fprintf(stderr,"Type match1: "); stupid_describe_type(a,type_length(a));
18415a2001-02-27Martin Stjernholm  fprintf(stderr,"\nType match2: ");
93dd411999-11-23Henrik Grubbström (Grubba)  stupid_describe_type(b,type_length(b));
18415a2001-02-27Martin Stjernholm  fputc('\n', stderr);
93dd411999-11-23Henrik Grubbström (Grubba)  } #endif
fbafd01999-12-12Henrik Grubbström (Grubba)  /* * object(0|1 x) <= object(0|1 0) * object(0|1 0) <=! object(0|1 !0) * object(1 x) <= object(0|1 x)
6134591999-12-15Henrik Grubbström (Grubba)  * object(1 x) <= object(1 y) iff x == y
8fea161999-12-31Henrik Grubbström (Grubba)  * object(1 x) <= object(0 y) iff x implements y * Not WEAK_OBJECTS: * object(0 x) <= object(0 y) iff x implements y * WEAK_OBJECTS: * object(0 x) <= object(0 y) iff x is_compatible y
fbafd01999-12-12Henrik Grubbström (Grubba)  */
93dd411999-11-23Henrik Grubbström (Grubba)  /* object(* 0) matches any object */ if(!extract_type_int(b+2)) return 1; if(!extract_type_int(a+2)) return 0;
fbafd01999-12-12Henrik Grubbström (Grubba)  if ((EXTRACT_UCHAR(a+1) || !EXTRACT_UCHAR(b+1)) && (extract_type_int(a+2) == extract_type_int(b+2))) return 1;
93dd411999-11-23Henrik Grubbström (Grubba) 
fbafd01999-12-12Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(b+1)) {
6134591999-12-15Henrik Grubbström (Grubba)  return 0;
93dd411999-11-23Henrik Grubbström (Grubba)  } {
fbafd01999-12-12Henrik Grubbström (Grubba)  struct program *ap = id_to_program(extract_type_int(a+2)); struct program *bp = id_to_program(extract_type_int(b+2));
93dd411999-11-23Henrik Grubbström (Grubba) 
fbafd01999-12-12Henrik Grubbström (Grubba)  if (!ap || !bp) { /* Shouldn't happen... */ return 0; }
8fea161999-12-31Henrik Grubbström (Grubba)  if ((flags & LE_WEAK_OBJECTS) && (!EXTRACT_UCHAR(a+1))) { return is_compatible(implements_a=ap, implements_b=bp); }
20ea771999-12-15Fredrik Hübinette (Hubbe)  return implements(implements_a=ap, implements_b=bp);
93dd411999-11-23Henrik Grubbström (Grubba)  } break; case T_INT: { INT32 amin=extract_type_int(a+1); INT32 amax=extract_type_int(a+1+sizeof(INT32)); INT32 bmin=extract_type_int(b+1); INT32 bmax=extract_type_int(b+1+sizeof(INT32)); if(amin < bmin || amax > bmax) return 0; break; }
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE:
93dd411999-11-23Henrik Grubbström (Grubba)  case T_MULTISET: case T_ARRAY:
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM:
52169d1999-12-21Henrik Grubbström (Grubba)  if(!low_pike_types_le(++a, ++b, 0, flags)) return 0;
93dd411999-11-23Henrik Grubbström (Grubba)  case T_FLOAT: case T_STRING: case T_ZERO:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_VOID: case T_MIXED: break; default:
a4a1722000-12-05Per Hedbor  fatal("Error in type string.\n");
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
fbafd01999-12-12Henrik Grubbström (Grubba)  return 1; } /* * Check the function parameters. * Note: The difference between this function, and pike_types_le() * is the more lenient check for T_OR, and the handling of T_ARRAY. */
b8a6882001-02-26Henrik Grubbström (Grubba) static int low_strict_check_call(char *fun_type, char *arg_type)
fbafd01999-12-12Henrik Grubbström (Grubba) { while ((EXTRACT_UCHAR(fun_type) == T_OR) || (EXTRACT_UCHAR(fun_type) == T_ARRAY)) { if (EXTRACT_UCHAR(fun_type++) == T_OR) {
b8a6882001-02-26Henrik Grubbström (Grubba)  int res = low_strict_check_call(fun_type, arg_type);
fbafd01999-12-12Henrik Grubbström (Grubba)  if (res) return res; fun_type += type_length(fun_type); } }
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(fun_type, arg_type, 0, 0); }
b8a6882001-02-26Henrik Grubbström (Grubba) int strict_check_call(struct pike_type *fun_type, struct pike_type *arg_type) { return low_strict_check_call(fun_type->str, arg_type->str); }
52169d1999-12-21Henrik Grubbström (Grubba) /* * Check validity of soft-cast. * Note: This uses a weaker check of function arguments, since * people get confused otherwise. */
d68a072001-02-20Henrik Grubbström (Grubba) int check_soft_cast(struct pike_type *to, struct pike_type *from)
52169d1999-12-21Henrik Grubbström (Grubba) {
8fea161999-12-31Henrik Grubbström (Grubba)  return low_pike_types_le(to->str, from->str, 0, LE_WEAK_OBJECTS);
5267b71995-08-09Fredrik Hübinette (Hubbe) } /* * Return the return type from a function call. */ static int low_get_return_type(char *a,char *b) {
bce86c1996-02-25Fredrik Hübinette (Hubbe)  int tmp; switch(EXTRACT_UCHAR(a))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
bce86c1996-02-25Fredrik Hübinette (Hubbe)  case T_OR:
7260711996-06-21Fredrik Hübinette (Hubbe)  {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *o1, *o2;
7260711996-06-21Fredrik Hübinette (Hubbe)  a++; o1=o2=0; type_stack_mark(); if(low_get_return_type(a,b)) { o1=pop_unfinished_type(); type_stack_mark(); } if(low_get_return_type(a+type_length(a),b)) o2=pop_unfinished_type(); else pop_stack_mark();
a946c71998-03-02Fredrik Hübinette (Hubbe)  if(!o1 && !o2) return 0;
4d7b181999-12-07Fredrik Hübinette (Hubbe)  medium_or_pike_types(o1,o2, 0);
7260711996-06-21Fredrik Hübinette (Hubbe) 
d68a072001-02-20Henrik Grubbström (Grubba)  if(o1) free_type(o1); if(o2) free_type(o2);
7260711996-06-21Fredrik Hübinette (Hubbe)  return 1; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
bce86c1996-02-25Fredrik Hübinette (Hubbe)  case T_AND:
5267b71995-08-09Fredrik Hübinette (Hubbe)  a++;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  type_stack_mark();
5267b71995-08-09Fredrik Hübinette (Hubbe)  tmp=low_get_return_type(a,b);
bce86c1996-02-25Fredrik Hübinette (Hubbe)  type_stack_pop_to_mark(); if(!tmp) return 0; return low_get_return_type(a+type_length(a),b);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
bce86c1996-02-25Fredrik Hübinette (Hubbe)  case T_ARRAY:
5267b71995-08-09Fredrik Hübinette (Hubbe)  a++; tmp=low_get_return_type(a,b); if(!tmp) return 0; push_type(T_ARRAY); return 1; }
5ac7661998-04-28Fredrik Hübinette (Hubbe)  a=low_match_types(a,b,NO_SHORTCUTS);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(a) {
fc0ad41999-12-11Henrik Grubbström (Grubba) #if 0 if ((lex.pragmas & ID_STRICT_TYPES) &&
52169d1999-12-21Henrik Grubbström (Grubba)  !low_pike_types_le(a, b, 0, 0)) {
fc0ad41999-12-11Henrik Grubbström (Grubba)  yywarning("Type mismatch"); } #endif /* 0 */
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(EXTRACT_UCHAR(a)) { case T_FUNCTION: a++; while(EXTRACT_UCHAR(a)!=T_MANY) a+=type_length(a); a++; a+=type_length(a);
9e52381998-03-01Fredrik Hübinette (Hubbe)  push_unfinished_type_with_markers(a, a_markers );
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1;
d2c6081996-11-07Fredrik Hübinette (Hubbe)  case T_PROGRAM:
6d33d82001-03-28Henrik Grubbström (Grubba)  push_unfinished_type(a+1);
d2c6081996-11-07Fredrik Hübinette (Hubbe)  return 1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  default: push_type(T_MIXED); return 1; } } return 0; }
d68a072001-02-20Henrik Grubbström (Grubba) int match_types(struct pike_type *a, struct pike_type *b)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  check_type_string(a); check_type_string(b);
9e52381998-03-01Fredrik Hübinette (Hubbe)  clear_markers();
bce86c1996-02-25Fredrik Hübinette (Hubbe)  return 0!=low_match_types(a->str, b->str,0);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
d68a072001-02-20Henrik Grubbström (Grubba) int pike_types_le(struct pike_type *a, struct pike_type *b)
93dd411999-11-23Henrik Grubbström (Grubba) { check_type_string(a); check_type_string(b); clear_markers();
52169d1999-12-21Henrik Grubbström (Grubba)  return low_pike_types_le(a->str, b->str, 0, 0);
93dd411999-11-23Henrik Grubbström (Grubba) }
2a50961995-08-23Fredrik Hübinette (Hubbe) 
3c0c281998-01-26Fredrik Hübinette (Hubbe) #ifdef DEBUG_MALLOC
d68a072001-02-20Henrik Grubbström (Grubba) #define low_index_type(X,Y,Z) ((struct pike_type *)debug_malloc_pass(debug_low_index_type((X),(Y),(Z))))
3c0c281998-01-26Fredrik Hübinette (Hubbe) #else #define low_index_type debug_low_index_type #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  /* FIXME, add the index */
d68a072001-02-20Henrik Grubbström (Grubba) static struct pike_type *debug_low_index_type(char *t, char *index_type, node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *tmp;
8852cb1999-10-25Fredrik Hübinette (Hubbe)  struct program *p;
fc0ad41999-12-11Henrik Grubbström (Grubba) 
4d7b181999-12-07Fredrik Hübinette (Hubbe)  switch(low_check_indexing(t, index_type, n)) { case 0: return 0; case -1: reference_shared_string(zero_type_string); return zero_type_string; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(EXTRACT_UCHAR(t++)) {
b8cda21997-01-21Fredrik Hübinette (Hubbe)  case T_OBJECT: {
8852cb1999-10-25Fredrik Hübinette (Hubbe)  p=id_to_program(extract_type_int(t+1)); comefrom_int_index:
dcab7e1998-02-19Fredrik Hübinette (Hubbe)  if(p && n)
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
4d7b181999-12-07Fredrik Hübinette (Hubbe)  INT32 i;
b8cda21997-01-21Fredrik Hübinette (Hubbe)  if(n->token == F_ARROW) {
4d7b181999-12-07Fredrik Hübinette (Hubbe)  /* FIXME: make this stricter */
bc68521999-12-18Martin Stjernholm  if((i=FIND_LFUN(p,LFUN_ARROW))!=-1)
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
4d7b181999-12-07Fredrik Hübinette (Hubbe)  /* FIXME: function_type_string should be replaced with something * derived from type_string */
46aa641999-12-29Henrik Grubbström (Grubba)  if(i!=-1 && (tmp=check_call(function_type_string, ID_FROM_INT(p, i)->type, 0)))
4d7b181999-12-07Fredrik Hübinette (Hubbe)  return tmp;
b8cda21997-01-21Fredrik Hübinette (Hubbe)  reference_shared_string(mixed_type_string); return mixed_type_string; } }else{
bc68521999-12-18Martin Stjernholm  if((i=FIND_LFUN(p,LFUN_INDEX)) != -1)
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
4d7b181999-12-07Fredrik Hübinette (Hubbe)  /* FIXME: function_type_string should be replaced with something * derived from type_string */
46aa641999-12-29Henrik Grubbström (Grubba)  if(i!=-1 && (tmp=check_call(function_type_string, ID_FROM_INT(p, i)->type, 0)))
4d7b181999-12-07Fredrik Hübinette (Hubbe)  return tmp;
b8cda21997-01-21Fredrik Hübinette (Hubbe)  reference_shared_string(mixed_type_string); return mixed_type_string; } } if(CDR(n)->token == F_CONSTANT && CDR(n)->u.sval.type==T_STRING) { i=find_shared_string_identifier(CDR(n)->u.sval.u.string, p); if(i==-1) {
b8c29a1998-08-19Fredrik Hübinette (Hubbe)  reference_shared_string(mixed_type_string); return mixed_type_string;
b8cda21997-01-21Fredrik Hübinette (Hubbe)  }else{
da52b71999-11-23Fredrik Hübinette (Hubbe) #if 0
6bc9281998-04-10Fredrik Hübinette (Hubbe)  if(EXTRACT_UCHAR(t) || (p->identifier_references[i].id_flags & ID_NOMASK) || (ID_FROM_INT(p, i)->identifier_flags & IDENTIFIER_PROTOTYPED)) {
da52b71999-11-23Fredrik Hübinette (Hubbe) #endif
6bc9281998-04-10Fredrik Hübinette (Hubbe)  reference_shared_string(ID_FROM_INT(p, i)->type); return ID_FROM_INT(p, i)->type;
da52b71999-11-23Fredrik Hübinette (Hubbe) #if 0
6bc9281998-04-10Fredrik Hübinette (Hubbe)  }else{ reference_shared_string(mixed_type_string); return mixed_type_string; }
da52b71999-11-23Fredrik Hübinette (Hubbe) #endif
b8cda21997-01-21Fredrik Hübinette (Hubbe)  } } } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  default: reference_shared_string(mixed_type_string); return mixed_type_string;
fc0ad41999-12-11Henrik Grubbström (Grubba)  case T_MIXED: if (lex.pragmas & ID_STRICT_TYPES) { yywarning("Indexing mixed."); } reference_shared_string(mixed_type_string); return mixed_type_string;
8852cb1999-10-25Fredrik Hübinette (Hubbe)  case T_INT: #ifdef AUTO_BIGNUM /* Don't force Gmp.mpz to be loaded here since this function * is called long before the master object is compiled... * /Hubbe */ p=get_auto_bignum_program_or_zero(); goto comefrom_int_index; #endif
93dd411999-11-23Henrik Grubbström (Grubba)  case T_ZERO:
fc0ad41999-12-11Henrik Grubbström (Grubba)  case T_TYPE:
fb2f661998-11-05Fredrik Hübinette (Hubbe)  case T_VOID: case T_FLOAT:
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
fb2f661998-11-05Fredrik Hübinette (Hubbe)  return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_OR: {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *a, *b;
4d7b181999-12-07Fredrik Hübinette (Hubbe)  a=low_index_type(t,index_type,n);
5267b71995-08-09Fredrik Hübinette (Hubbe)  t+=type_length(t);
4d7b181999-12-07Fredrik Hübinette (Hubbe)  b=low_index_type(t,index_type,n);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!b) return a; if(!a) return b;
a946c71998-03-02Fredrik Hübinette (Hubbe)  type_stack_mark();
4d7b181999-12-07Fredrik Hübinette (Hubbe)  medium_or_pike_types(a,b,1);
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(a); free_type(b);
36feac1997-03-06Fredrik Hübinette (Hubbe)  return pop_unfinished_type();
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
bce86c1996-02-25Fredrik Hübinette (Hubbe)  case T_AND:
4d7b181999-12-07Fredrik Hübinette (Hubbe)  return low_index_type(t+type_length(t),index_type,n);
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_STRING: /* always int */
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET: /* always int */
5267b71995-08-09Fredrik Hübinette (Hubbe)  reference_shared_string(int_type_string); return int_type_string; case T_MAPPING: t+=type_length(t);
de2a581997-09-28Fredrik Hübinette (Hubbe)  return make_shared_binary_string(t, type_length(t));
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_ARRAY:
de2a581997-09-28Fredrik Hübinette (Hubbe)  {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *a;
04da272000-03-10Henrik Grubbström (Grubba)  if(low_pike_types_le(tString, index_type, 0, 0) && (a = low_index_type(t, tString, n))) { /* Possible to index the array with a string. */
fc42132000-03-10Henrik Grubbström (Grubba)  type_stack_mark(); push_finished_type(a);
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(a);
fc42132000-03-10Henrik Grubbström (Grubba)  push_type(T_ARRAY);
04da272000-03-10Henrik Grubbström (Grubba)  if (low_match_types(tInt, index_type, 0)) { /* Also possible to index the array with an int. */ push_unfinished_type(t); push_type(T_OR); }
fc42132000-03-10Henrik Grubbström (Grubba)  return pop_unfinished_type();
04da272000-03-10Henrik Grubbström (Grubba)  } if (low_match_types(tInt, index_type, 0)) { /* Possible to index the array with an int. */
de2a581997-09-28Fredrik Hübinette (Hubbe)  return make_shared_binary_string(t, type_length(t)); }
04da272000-03-10Henrik Grubbström (Grubba)  /* Bad index type. */ return 0;
de2a581997-09-28Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
d68a072001-02-20Henrik Grubbström (Grubba) struct pike_type *index_type(struct pike_type *type, struct pike_type *index_type, node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *t;
9e52381998-03-01Fredrik Hübinette (Hubbe)  clear_markers();
4d7b181999-12-07Fredrik Hübinette (Hubbe)  t=low_index_type(type->str,index_type->str,n);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!t) copy_shared_string(t,mixed_type_string); return t; }
1a3e1b1999-04-13Fredrik Hübinette (Hubbe) 
d68a072001-02-20Henrik Grubbström (Grubba) static struct pike_type *low_array_value_type(char *arr_t)
144ce31999-12-19Henrik Grubbström (Grubba) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *res = NULL; struct pike_type *sub_t;
144ce31999-12-19Henrik Grubbström (Grubba)  while (EXTRACT_UCHAR(arr_t) == T_OR) { arr_t++; sub_t = low_array_value_type(arr_t); arr_t += type_length(arr_t); if (sub_t) { if (res) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *new = or_pike_types(res, sub_t, 1); free_type(res); free_type(sub_t);
144ce31999-12-19Henrik Grubbström (Grubba)  res = new; } else { res = sub_t; } } } if (EXTRACT_UCHAR(arr_t) != T_ARRAY) return res; arr_t++; sub_t = make_shared_binary_string(arr_t, type_length(arr_t)); if (res) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *new = or_pike_types(res, sub_t, 1); free_type(res); free_type(sub_t);
144ce31999-12-19Henrik Grubbström (Grubba)  return new; } return sub_t; }
d68a072001-02-20Henrik Grubbström (Grubba) struct pike_type *array_value_type(struct pike_type *array_type)
144ce31999-12-19Henrik Grubbström (Grubba) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *t = low_array_value_type(array_type->str);
144ce31999-12-19Henrik Grubbström (Grubba)  if (!t) copy_shared_string(t, mixed_type_string); return t; }
1a3e1b1999-04-13Fredrik Hübinette (Hubbe) #ifdef DEBUG_MALLOC
d68a072001-02-20Henrik Grubbström (Grubba) #define low_key_type(X,Y) ((struct pike_type *)debug_malloc_pass(debug_low_key_type((X),(Y))))
1a3e1b1999-04-13Fredrik Hübinette (Hubbe) #else #define low_key_type debug_low_key_type #endif /* FIXME, add the index */
d68a072001-02-20Henrik Grubbström (Grubba) static struct pike_type *debug_low_key_type(char *t, node *n)
1a3e1b1999-04-13Fredrik Hübinette (Hubbe) { switch(EXTRACT_UCHAR(t++)) { case T_OBJECT: { struct program *p=id_to_program(extract_type_int(t+1)); if(p && n) { if(n->token == F_ARROW) { if(FIND_LFUN(p,LFUN_ARROW)!=-1 || FIND_LFUN(p,LFUN_ASSIGN_ARROW)!=-1) { reference_shared_string(mixed_type_string); return mixed_type_string; } }else{ if(FIND_LFUN(p,LFUN_INDEX) != -1 || FIND_LFUN(p,LFUN_ASSIGN_INDEX) != -1) { reference_shared_string(mixed_type_string); return mixed_type_string; } } } reference_shared_string(string_type_string); return string_type_string; } default: reference_shared_string(mixed_type_string); return mixed_type_string; case T_VOID:
93dd411999-11-23Henrik Grubbström (Grubba)  case T_ZERO:
fc0ad41999-12-11Henrik Grubbström (Grubba)  case T_TYPE:
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  case T_FLOAT: case T_INT:
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  return 0; case T_OR: {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *a, *b;
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  a=low_key_type(t,n); t+=type_length(t); b=low_key_type(t,n); if(!b) return a; if(!a) return b; type_stack_mark();
4d7b181999-12-07Fredrik Hübinette (Hubbe)  medium_or_pike_types(a,b,1);
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(a); free_type(b);
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  return pop_unfinished_type(); } case T_AND: return low_key_type(t+type_length(t),n); case T_ARRAY: case T_STRING: /* always int */ reference_shared_string(int_type_string); return int_type_string; case T_MAPPING: case T_MULTISET: return make_shared_binary_string(t, type_length(t)); } }
d68a072001-02-20Henrik Grubbström (Grubba) struct pike_type *key_type(struct pike_type *type, node *n)
1a3e1b1999-04-13Fredrik Hübinette (Hubbe) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *t;
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  clear_markers(); t=low_key_type(type->str,n); if(!t) copy_shared_string(t,mixed_type_string); return t; }
b8cda21997-01-21Fredrik Hübinette (Hubbe) static int low_check_indexing(char *type, char *index_type, node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) { switch(EXTRACT_UCHAR(type++)) { case T_OR:
b8cda21997-01-21Fredrik Hübinette (Hubbe)  return low_check_indexing(type,index_type,n) || low_check_indexing(type+type_length(type),index_type,n);
bce86c1996-02-25Fredrik Hübinette (Hubbe)  case T_AND:
b8cda21997-01-21Fredrik Hübinette (Hubbe)  return low_check_indexing(type,index_type,n) && low_check_indexing(type+type_length(type),index_type,n);
bce86c1996-02-25Fredrik Hübinette (Hubbe)  case T_NOT:
4d7b181999-12-07Fredrik Hübinette (Hubbe)  return low_check_indexing(type,index_type,n)!=1;
bce86c1996-02-25Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_ARRAY:
de2a581997-09-28Fredrik Hübinette (Hubbe)  if(low_match_types(string_type_string->str, index_type,0) && low_check_indexing(type, index_type,n)) return 1; case T_STRING:
bce86c1996-02-25Fredrik Hübinette (Hubbe)  return !!low_match_types(int_type_string->str, index_type,0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_OBJECT:
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
b660c81999-03-01Fredrik Hübinette (Hubbe)  struct program *p=id_to_program(extract_type_int(type+1));
b8cda21997-01-21Fredrik Hübinette (Hubbe)  if(p) { if(n->token == F_ARROW) {
6bc9281998-04-10Fredrik Hübinette (Hubbe)  if(FIND_LFUN(p,LFUN_ARROW)!=-1 || FIND_LFUN(p,LFUN_ASSIGN_ARROW)!=-1) return 1;
b8cda21997-01-21Fredrik Hübinette (Hubbe)  }else{
6bc9281998-04-10Fredrik Hübinette (Hubbe)  if(FIND_LFUN(p,LFUN_INDEX)!=-1 || FIND_LFUN(p,LFUN_ASSIGN_INDEX)!=-1) return 1;
b8cda21997-01-21Fredrik Hübinette (Hubbe)  } return !!low_match_types(string_type_string->str, index_type,0); }else{ return 1; } }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_MAPPING:
4d7b181999-12-07Fredrik Hübinette (Hubbe)  return low_match_types(type,index_type,0) ? 1 : -1;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
8852cb1999-10-25Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM case T_INT: #endif case T_PROGRAM: return !!low_match_types(string_type_string->str, index_type,0);
43f12e1998-09-29Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_MIXED: return 1; default: return 0; } }
d68a072001-02-20Henrik Grubbström (Grubba) int check_indexing(struct pike_type *type, struct pike_type *index_type,
b8cda21997-01-21Fredrik Hübinette (Hubbe)  node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  check_type_string(type); check_type_string(index_type);
b9e4ba1996-11-18Fredrik Hübinette (Hubbe) 
b8cda21997-01-21Fredrik Hübinette (Hubbe)  return low_check_indexing(type->str, index_type->str, n);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
5b4dd31998-02-23Fredrik Hübinette (Hubbe) static int low_count_arguments(char *q) { int num,num2;
d429a71998-02-24Fredrik Hübinette (Hubbe) 
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  switch(EXTRACT_UCHAR(q++)) { case T_OR: num=low_count_arguments(q); num2=low_count_arguments(q+type_length(q)); if(num<0 && num2>0) return num; if(num2<0 && num>0) return num2; if(num2<0 && num<0) return ~num>~num2?num:num2; return num>num2?num:num2; case T_AND: num=low_count_arguments(q); num2=low_count_arguments(q+type_length(q)); if(num<0 && num2>0) return num2; if(num2<0 && num>0) return num; if(num2<0 && num<0) return ~num<~num2?num:num2; return num<num2?num:num2;
d429a71998-02-24Fredrik Hübinette (Hubbe)  default: return 0x7fffffff;
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  case T_FUNCTION: num=0; while(EXTRACT_UCHAR(q)!=T_MANY) { num++; q+=type_length(q); } q++; if(EXTRACT_UCHAR(q)!=T_VOID) return ~num; return num; } }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* Count the number of arguments for a funciton type. * return -1-n if the function can take number of arguments * >= n (varargs) */
d68a072001-02-20Henrik Grubbström (Grubba) int count_arguments(struct pike_type *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  check_type_string(s);
b9e4ba1996-11-18Fredrik Hübinette (Hubbe) 
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  return low_count_arguments(s->str);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
3aa7831999-06-02Fredrik Hübinette (Hubbe)  static int low_minimum_arguments(char *q) { int num; switch(EXTRACT_UCHAR(q++)) { case T_OR: case T_AND: return MAXIMUM(low_count_arguments(q), low_count_arguments(q+type_length(q))); default: return 0; case T_FUNCTION: num=0; while(EXTRACT_UCHAR(q)!=T_MANY) { if(low_match_types(void_type_string->str, q, B_EXACT)) return num; num++; q+=type_length(q); } return num; } } /* Count the minimum number of arguments for a funciton type. */
d68a072001-02-20Henrik Grubbström (Grubba) int minimum_arguments(struct pike_type *s)
3aa7831999-06-02Fredrik Hübinette (Hubbe) { int ret; check_type_string(s); ret=low_minimum_arguments(s->str); #if 0 fprintf(stderr,"minimum_arguments("); simple_describe_type(s); fprintf(stderr," ) -> %d\n",ret); #endif return ret; }
d68a072001-02-20Henrik Grubbström (Grubba) struct pike_type *check_call(struct pike_type *args, struct pike_type *type, int strict)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  check_type_string(args); check_type_string(type);
9e52381998-03-01Fredrik Hübinette (Hubbe)  clear_markers();
36feac1997-03-06Fredrik Hübinette (Hubbe)  type_stack_mark();
1d53281996-11-25Fredrik Hübinette (Hubbe)  max_correct_args=0;
36feac1997-03-06Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(low_get_return_type(type->str,args->str)) {
46aa641999-12-29Henrik Grubbström (Grubba)  if (strict) {
b8a6882001-02-26Henrik Grubbström (Grubba)  if (!strict_check_call(type, args)) {
fbafd01999-12-12Henrik Grubbström (Grubba)  struct pike_string *type_t = describe_type(type);
6134591999-12-15Henrik Grubbström (Grubba) 
52169d1999-12-21Henrik Grubbström (Grubba)  if (!low_pike_types_le(type->str, tFuncV(tNone,tZero,tMix), 0, 0)) {
6134591999-12-15Henrik Grubbström (Grubba)  yywarning("Calling non-function value."); yywarning("Type called: %s", type_t->str); } else { struct pike_string *arg_t = describe_type(args); yywarning("Arguments not strictly compatible."); yywarning("Expected: %s", type_t->str); yywarning("Got : %s", arg_t->str); free_string(arg_t); }
fbafd01999-12-12Henrik Grubbström (Grubba)  free_string(type_t); } }
36feac1997-03-06Fredrik Hübinette (Hubbe)  return pop_unfinished_type();
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
36feac1997-03-06Fredrik Hübinette (Hubbe)  pop_stack_mark();
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; } }
d68a072001-02-20Henrik Grubbström (Grubba) INT32 get_max_args(struct pike_type *type)
5b4dd31998-02-23Fredrik Hübinette (Hubbe) { INT32 ret,tmp=max_correct_args;
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  check_type_string(type);
9e52381998-03-01Fredrik Hübinette (Hubbe)  clear_markers();
46aa641999-12-29Henrik Grubbström (Grubba)  type = check_call(function_type_string, type, 0);
d68a072001-02-20Henrik Grubbström (Grubba)  if(type) free_type(type);
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  ret=max_correct_args; max_correct_args=tmp; return tmp; }
b2d75f1999-10-25Fredrik Hübinette (Hubbe) 
d40fac2001-02-26Henrik Grubbström (Grubba) static struct pike_type *low_zzap_function_return(char *a, INT32 id)
b2d75f1999-10-25Fredrik Hübinette (Hubbe) { switch(EXTRACT_UCHAR(a)) { case T_OR: {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *ar, *br, *ret=0;
b2d75f1999-10-25Fredrik Hübinette (Hubbe)  a++;
d40fac2001-02-26Henrik Grubbström (Grubba)  ar = low_zzap_function_return(a,id); br = low_zzap_function_return(a+type_length(a),id);
4d7b181999-12-07Fredrik Hübinette (Hubbe)  if(ar && br) ret=or_pike_types(ar,br,0);
d68a072001-02-20Henrik Grubbström (Grubba)  if(ar) free_type(ar); if(br) free_type(br);
b2d75f1999-10-25Fredrik Hübinette (Hubbe)  return ret; } case T_FUNCTION: type_stack_mark(); push_type_int(id); push_type(1); push_type(T_OBJECT); type_stack_mark(); a++; while(EXTRACT_UCHAR(a)!=T_MANY) { type_stack_mark(); push_unfinished_type(a); type_stack_reverse(); a+=type_length(a); } a++; push_type(T_MANY); type_stack_mark(); push_unfinished_type(a); type_stack_reverse(); type_stack_reverse(); push_type(T_FUNCTION); return pop_unfinished_type();
a0b73f2000-01-03Martin Stjernholm  case T_ARRAY:
d40fac2001-02-26Henrik Grubbström (Grubba)  return low_zzap_function_return(a+1,id);
3002342000-02-29Henrik Grubbström (Grubba)  case T_MIXED: /* I wonder when this occurrs, but apparently it does... */
d40fac2001-02-26Henrik Grubbström (Grubba)  return low_zzap_function_return(tFuncV(tVoid,tOr(tMix,tVoid),tObj), id);
b2d75f1999-10-25Fredrik Hübinette (Hubbe)  }
a4a1722000-12-05Per Hedbor /* This error is bogus /Hubbe
d40fac2001-02-26Henrik Grubbström (Grubba)  fatal("low_zzap_function_return() called with unexpected value: %d\n",
6b4a2b1999-10-31Henrik Grubbström (Grubba)  EXTRACT_UCHAR(a));
2d47b91999-11-27Fredrik Hübinette (Hubbe) */
6b4a2b1999-10-31Henrik Grubbström (Grubba)  return NULL;
b2d75f1999-10-25Fredrik Hübinette (Hubbe) }
d40fac2001-02-26Henrik Grubbström (Grubba) struct pike_type *zzap_function_return(struct pike_type *t, INT32 id) { return low_zzap_function_return(t->str, id); }
d68a072001-02-20Henrik Grubbström (Grubba) struct pike_type *get_type_of_svalue(struct svalue *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *ret;
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(s->type) { case T_FUNCTION:
bdb5091996-09-25Fredrik Hübinette (Hubbe)  if(s->subtype == FUNCTION_BUILTIN)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(ret, s->u.efun->type);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{ struct program *p; p=s->u.object->prog; if(!p) {
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(ret, zero_type_string);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(ret, ID_FROM_INT(p,s->subtype)->type);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } return ret;
e5e0d91999-12-13Henrik Grubbström (Grubba)  case T_MULTISET:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_ARRAY:
e5e0d91999-12-13Henrik Grubbström (Grubba)  {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *arg_type;
e5e0d91999-12-13Henrik Grubbström (Grubba)  struct array *a; if (s->type == T_MULTISET) { a = s->u.multiset->ind; } else { a = s->u.array; }
502d851999-12-30Martin Stjernholm #if 0 int i;
e5e0d91999-12-13Henrik Grubbström (Grubba)  /* FIXME: Circular structures? */ copy_shared_string(arg_type, zero_type_string); for (i = 0; i < a->size; i++) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *tmp1 = get_type_of_svalue(a->item+i); struct pike_type *tmp2 = or_pike_types(arg_type, tmp1, 1); free_type(arg_type); free_type(tmp1);
e5e0d91999-12-13Henrik Grubbström (Grubba)  arg_type = tmp2; } #else /* !0 */
502d851999-12-30Martin Stjernholm  if (a->size)
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(arg_type, mixed_type_string);
502d851999-12-30Martin Stjernholm  else
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(arg_type, zero_type_string);
e5e0d91999-12-13Henrik Grubbström (Grubba) #endif /* 0 */ type_stack_mark();
d40fac2001-02-26Henrik Grubbström (Grubba)  push_finished_type(arg_type);
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(arg_type);
e5e0d91999-12-13Henrik Grubbström (Grubba)  push_type(s->type); return pop_unfinished_type(); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_MAPPING:
3db32a1997-03-04Fredrik Hübinette (Hubbe)  type_stack_mark();
57a4ab2000-01-27Fredrik Hübinette (Hubbe)  if (m_sizeof(s->u.mapping)) {
502d851999-12-30Martin Stjernholm  push_type(T_MIXED); push_type(T_MIXED); } else { push_type(T_ZERO); push_type(T_ZERO); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  push_type(T_MAPPING);
3db32a1997-03-04Fredrik Hübinette (Hubbe)  return pop_unfinished_type();
5267b71995-08-09Fredrik Hübinette (Hubbe) 
041a731996-11-12Mirar (Pontus Hagland)  case T_OBJECT:
3db32a1997-03-04Fredrik Hübinette (Hubbe)  type_stack_mark(); if(s->u.object->prog) {
b2d75f1999-10-25Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM if(is_bignum_object(s->u.object)) {
d40fac2001-02-26Henrik Grubbström (Grubba)  push_int_type(MIN_INT32, MAX_INT32);
b2d75f1999-10-25Fredrik Hübinette (Hubbe)  } else #endif { push_type_int(s->u.object->prog->id); push_type(1); push_type(T_OBJECT); }
3db32a1997-03-04Fredrik Hübinette (Hubbe)  }else{
e5e0d91999-12-13Henrik Grubbström (Grubba)  /* Destructed object */ push_type(T_ZERO);
3db32a1997-03-04Fredrik Hübinette (Hubbe)  } return pop_unfinished_type();
041a731996-11-12Mirar (Pontus Hagland) 
e82b301997-01-29Fredrik Hübinette (Hubbe)  case T_INT: if(s->u.integer) {
b660c81999-03-01Fredrik Hübinette (Hubbe)  type_stack_mark();
b2d75f1999-10-25Fredrik Hübinette (Hubbe)  /* Fixme, check that the integer is in range of MIN_INT32 .. MAX_INT32! */
d40fac2001-02-26Henrik Grubbström (Grubba)  push_int_type(s->u.integer, s->u.integer);
b660c81999-03-01Fredrik Hübinette (Hubbe)  return pop_unfinished_type();
e82b301997-01-29Fredrik Hübinette (Hubbe)  }else{
be6fec2001-04-01Henrik Grubbström (Grubba)  copy_pike_type(ret, zero_type_string);
e82b301997-01-29Fredrik Hübinette (Hubbe)  } return ret;
9f68471997-03-08Fredrik Hübinette (Hubbe)  case T_PROGRAM: {
6d33d82001-03-28Henrik Grubbström (Grubba)  /* FIXME: An alternative is to push PROGRAM(OBJECT(1, p->id)) */
d40fac2001-02-26Henrik Grubbström (Grubba)  struct pike_type *t;
993ba72000-02-15Fredrik Hübinette (Hubbe)  int id;
da77e22000-09-08Fredrik Hübinette (Hubbe)  if(s->u.program->identifiers)
993ba72000-02-15Fredrik Hübinette (Hubbe)  {
da77e22000-09-08Fredrik Hübinette (Hubbe)  id=FIND_LFUN(s->u.program,LFUN_CREATE); if(id>=0) {
d40fac2001-02-26Henrik Grubbström (Grubba)  struct pike_string *tmp; t = ID_FROM_INT(s->u.program, id)->type; if((t=zzap_function_return(t, s->u.program->id))) return t; tmp = describe_type(ID_FROM_INT(s->u.program, id)->type);
da77e22000-09-08Fredrik Hübinette (Hubbe)  /* yywarning("Failed to zzap function return for type: %s.", tmp->str);*/ free_string(tmp); }
81c8202000-09-10Henrik Grubbström (Grubba)  } else {
d40fac2001-02-26Henrik Grubbström (Grubba)  t = function_type_string; if((t = zzap_function_return(t, s->u.program->id))) return t;
9f68471997-03-08Fredrik Hübinette (Hubbe)  }
2d47b91999-11-27Fredrik Hübinette (Hubbe) 
d40fac2001-02-26Henrik Grubbström (Grubba)  type_stack_mark(); push_object_type(1, s->u.program->id); push_type(T_VOID); push_type(T_MANY); push_type(T_FUNCTION);
2d47b91999-11-27Fredrik Hübinette (Hubbe) 
d40fac2001-02-26Henrik Grubbström (Grubba)  return pop_unfinished_type();
9f68471997-03-08Fredrik Hübinette (Hubbe)  }
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE: type_stack_mark(); push_finished_type(s->u.type); push_type(T_TYPE); return pop_unfinished_type();
5267b71995-08-09Fredrik Hübinette (Hubbe)  default:
3db32a1997-03-04Fredrik Hübinette (Hubbe)  type_stack_mark();
5267b71995-08-09Fredrik Hübinette (Hubbe)  push_type(s->type);
3db32a1997-03-04Fredrik Hübinette (Hubbe)  return pop_unfinished_type();
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
d68a072001-02-20Henrik Grubbström (Grubba) static struct pike_type *low_object_type_to_program_type(char *obj_t)
6334d21999-12-22Henrik Grubbström (Grubba) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *res = NULL; struct pike_type *sub;
6334d21999-12-22Henrik Grubbström (Grubba)  struct svalue sval; int id; while(EXTRACT_UCHAR(obj_t) == T_OR) { obj_t++; sub = low_object_type_to_program_type(obj_t); if (!sub) { if (res) {
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(res);
6334d21999-12-22Henrik Grubbström (Grubba)  } return NULL; } if (res) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *tmp = or_pike_types(res, sub, 1); free_type(res); free_type(sub);
6334d21999-12-22Henrik Grubbström (Grubba)  res = tmp; } else { res = sub; } obj_t += type_length(obj_t); } sval.type = T_PROGRAM; if ((EXTRACT_UCHAR(obj_t) != T_OBJECT) || (!(id = extract_type_int(obj_t + 2))) || (!(sval.u.program = id_to_program(id))) || (!(sub = get_type_of_svalue(&sval)))) { if (res) {
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(res);
6334d21999-12-22Henrik Grubbström (Grubba)  } return NULL; }
0b57922000-03-23Henrik Grubbström (Grubba)  /* FIXME: obj_t + 1 should propagate to the return-type in sub. */
6334d21999-12-22Henrik Grubbström (Grubba)  if (res) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *tmp = or_pike_types(res, sub, 1); free_type(res); free_type(sub);
6334d21999-12-22Henrik Grubbström (Grubba)  return tmp; } return sub; } /* Used by fix_object_program_type() */
d68a072001-02-20Henrik Grubbström (Grubba) struct pike_type *object_type_to_program_type(struct pike_type *obj_t)
6334d21999-12-22Henrik Grubbström (Grubba) { return low_object_type_to_program_type(obj_t->str); }
d5b6742001-02-23Henrik Grubbström (Grubba) static int low_type_may_overload(char *type, int lfun)
b477901998-06-05Fredrik Hübinette (Hubbe) { switch(EXTRACT_UCHAR(type++)) { case T_ASSIGN:
71a9672001-03-03Henrik Grubbström (Grubba)  return low_type_may_overload(type+1, lfun);
b477901998-06-05Fredrik Hübinette (Hubbe)  case T_FUNCTION: case T_ARRAY: /* might want to check for `() */ default: return 0; case T_OR:
71a9672001-03-03Henrik Grubbström (Grubba)  return low_type_may_overload(type, lfun) || low_type_may_overload(type+type_length(type), lfun);
b477901998-06-05Fredrik Hübinette (Hubbe)  case T_AND:
71a9672001-03-03Henrik Grubbström (Grubba)  return low_type_may_overload(type, lfun) && low_type_may_overload(type+type_length(type), lfun);
b477901998-06-05Fredrik Hübinette (Hubbe)  case T_NOT:
71a9672001-03-03Henrik Grubbström (Grubba)  return !low_type_may_overload(type, lfun);
b477901998-06-05Fredrik Hübinette (Hubbe)  case T_MIXED: return 1; case T_OBJECT: {
b660c81999-03-01Fredrik Hübinette (Hubbe)  struct program *p=id_to_program(extract_type_int(type+1));
b477901998-06-05Fredrik Hübinette (Hubbe)  if(!p) return 1; return FIND_LFUN(p, lfun)!=-1; } } }
20ea771999-12-15Fredrik Hübinette (Hubbe) 
d5b6742001-02-23Henrik Grubbström (Grubba) int type_may_overload(struct pike_type *type, int lfun) { return low_type_may_overload(type->str, lfun); }
20ea771999-12-15Fredrik Hübinette (Hubbe) 
d68a072001-02-20Henrik Grubbström (Grubba) void yyexplain_nonmatching_types(struct pike_type *type_a, struct pike_type *type_b,
03318e2000-03-16Fredrik Hübinette (Hubbe)  int flags)
20ea771999-12-15Fredrik Hübinette (Hubbe) { implements_a=0; implements_b=0; match_types(type_a,type_b);
0b57922000-03-23Henrik Grubbström (Grubba) #if 0
20ea771999-12-15Fredrik Hübinette (Hubbe)  if(!(implements_a && implements_b && type_a->str[0]==T_OBJECT && type_b->str[0]==T_OBJECT))
0b57922000-03-23Henrik Grubbström (Grubba) #endif /* 0 */
20ea771999-12-15Fredrik Hübinette (Hubbe)  { struct pike_string *s1,*s2; s1=describe_type(type_a); s2=describe_type(type_b);
03318e2000-03-16Fredrik Hübinette (Hubbe)  if(flags & YYTE_IS_WARNING) { yywarning("Expected: %s",s1->str); yywarning("Got : %s",s2->str); }else{ my_yyerror("Expected: %s",s1->str); my_yyerror("Got : %s",s2->str); }
20ea771999-12-15Fredrik Hübinette (Hubbe)  free_string(s1); free_string(s2); } if(implements_a && implements_b)
03318e2000-03-16Fredrik Hübinette (Hubbe)  yyexplain_not_implements(implements_a,implements_b,flags);
20ea771999-12-15Fredrik Hübinette (Hubbe) }
95a83d1999-12-26Henrik Grubbström (Grubba) 
9b5a822001-03-29Henrik Grubbström (Grubba) struct pike_type *debug_make_pike_type(const char *t)
95a83d1999-12-26Henrik Grubbström (Grubba) { return make_shared_binary_string(t, type_length(t)); }
d4a1362001-02-09Fredrik Hübinette (Hubbe) 
d5b6742001-02-23Henrik Grubbström (Grubba) static int low_pike_type_allow_premature_toss(char *type)
d4a1362001-02-09Fredrik Hübinette (Hubbe) { again: switch(EXTRACT_UCHAR(type++)) { case T_NOT:
d5b6742001-02-23Henrik Grubbström (Grubba)  return !low_pike_type_allow_premature_toss(type);
d4a1362001-02-09Fredrik Hübinette (Hubbe)  case T_OBJECT: case T_MIXED: case T_FUNCTION: return 0;
ce88d62001-03-19Henrik Grubbström (Grubba)  case PIKE_T_RING:
d4a1362001-02-09Fredrik Hübinette (Hubbe)  case T_SCOPE: case T_ASSIGN: type++; goto again; case T_OR: case T_MAPPING:
d5b6742001-02-23Henrik Grubbström (Grubba)  if(!low_pike_type_allow_premature_toss(type)) return 0;
d4a1362001-02-09Fredrik Hübinette (Hubbe)  case T_AND: type+=type_length(type); case T_ARRAY: case T_MULTISET: goto again; case T_PROGRAM:
6d33d82001-03-28Henrik Grubbström (Grubba)  case T_TYPE:
d4a1362001-02-09Fredrik Hübinette (Hubbe)  case T_INT: case T_FLOAT: case T_STRING: return 1; }
d68a072001-02-20Henrik Grubbström (Grubba)  /* NOT_REACHED */ return 0;
d4a1362001-02-09Fredrik Hübinette (Hubbe) }
d5b6742001-02-23Henrik Grubbström (Grubba)  int pike_type_allow_premature_toss(struct pike_type *type) { return low_pike_type_allow_premature_toss(type->str); }
71a9672001-03-03Henrik Grubbström (Grubba)  #endif /* USE_PIKE_TYPE */
9e6f6f2001-03-18Henrik Grubbström (Grubba) struct pike_string *type_to_string(struct pike_type *t) { #ifdef USE_PIKE_TYPE init_buf(); low_type_to_string(t); return free_buf(); #else /* !USE_PIKE_TYPE */ add_ref(t); return t; #endif /* USE_PIKE_TYPE */ }
71a9672001-03-03Henrik Grubbström (Grubba) void init_types(void) { #ifdef USE_PIKE_TYPE /* Initialize hashtable here. */ pike_type_hash = (struct pike_type **)xalloc(sizeof(struct pike_type *) * PIKE_TYPE_HASH_SIZE); MEMSET(pike_type_hash, 0, sizeof(struct pike_type *) * PIKE_TYPE_HASH_SIZE); pike_type_hash_size = PIKE_TYPE_HASH_SIZE;
6d33d82001-03-28Henrik Grubbström (Grubba)  init_pike_type_blocks();
9b5a822001-03-29Henrik Grubbström (Grubba) #endif /* USE_PIKE_TYPE */
71a9672001-03-03Henrik Grubbström (Grubba)  string_type_string = CONSTTYPE(tString); int_type_string = CONSTTYPE(tInt); object_type_string = CONSTTYPE(tObj);
6d33d82001-03-28Henrik Grubbström (Grubba)  program_type_string = CONSTTYPE(tPrg(tObj));
71a9672001-03-03Henrik Grubbström (Grubba)  float_type_string = CONSTTYPE(tFloat); mixed_type_string = CONSTTYPE(tMix); array_type_string = CONSTTYPE(tArray); multiset_type_string = CONSTTYPE(tMultiset); mapping_type_string = CONSTTYPE(tMapping); function_type_string = CONSTTYPE(tFunction);
54f8ac2001-03-17Henrik Grubbström (Grubba)  type_type_string = CONSTTYPE(tType(tMix));
71a9672001-03-03Henrik Grubbström (Grubba)  void_type_string = CONSTTYPE(tVoid); zero_type_string = CONSTTYPE(tZero); any_type_string = CONSTTYPE(tOr(tVoid,tMix)); weak_type_string = CONSTTYPE(tOr4(tArray,tMultiset,tMapping, tFuncV(tNone,tZero,tOr(tMix,tVoid)))); } void cleanup_pike_types(void) {
94b2fb2001-03-28Henrik Grubbström (Grubba) #if defined(USE_PIKE_TYPE) && defined(DEBUG_MALLOC)
bd93582001-03-28Henrik Grubbström (Grubba)  struct pike_type_location *t = all_pike_type_locations;
94b2fb2001-03-28Henrik Grubbström (Grubba)  while(t) { free_type(t->t); t = t->next; } #endif /* USE_PIKE_TYPE && DEBUG_MALLOC */
71a9672001-03-03Henrik Grubbström (Grubba)  free_type(string_type_string); free_type(int_type_string); free_type(float_type_string); free_type(function_type_string); free_type(object_type_string); free_type(program_type_string); free_type(array_type_string); free_type(multiset_type_string); free_type(mapping_type_string); free_type(type_type_string); free_type(mixed_type_string); free_type(void_type_string); free_type(zero_type_string); free_type(any_type_string); free_type(weak_type_string);
9b5a822001-03-29Henrik Grubbström (Grubba) } void cleanup_pike_type_table(void) {
71a9672001-03-03Henrik Grubbström (Grubba) #ifdef USE_PIKE_TYPE /* Free the hashtable here. */ if (pike_type_hash) { free(pike_type_hash);
f62c412001-03-05Henrik Grubbström (Grubba)  /* Don't do this, it messes up stuff... */ /* pike_type_hash = NULL; */
71a9672001-03-03Henrik Grubbström (Grubba)  }
f62c412001-03-05Henrik Grubbström (Grubba)  /* Don't do this, it messes up stuff... */ /* pike_type_hash_size = 0; */
9b5a822001-03-29Henrik Grubbström (Grubba) #ifdef DEBUG_MALLOC free_all_pike_type_blocks(); #endif /* DEBUG_MALLOC */
71a9672001-03-03Henrik Grubbström (Grubba) #endif /* USE_PIKE_TYPE */ }