cb22561995-10-11Fredrik Hübinette (Hubbe) /*\
06983f1996-09-22Fredrik Hübinette (Hubbe) ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License)
cb22561995-10-11Fredrik Hübinette (Hubbe) ||| See the files COPYING and DISCLAIMER for more information. \*/
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "global.h"
1347171998-04-23Fredrik Hübinette (Hubbe) RCSID("$Id: pike_types.c,v 1.41 1998/04/24 00:08:42 hubbe 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"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "error.h"
b8cda21997-01-21Fredrik Hübinette (Hubbe) #include "las.h" #include "language.h"
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #include "pike_memory.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1d53281996-11-25Fredrik Hübinette (Hubbe) int max_correct_args;
bce86c1996-02-25Fredrik Hübinette (Hubbe) static void internal_parse_type(char **s);
b9e4ba1996-11-18Fredrik Hübinette (Hubbe) static int type_length(char *t);
bce86c1996-02-25Fredrik Hübinette (Hubbe) 
9f68471997-03-08Fredrik Hübinette (Hubbe) #define TWOT(X,Y) (((X) << 8)+(Y)) #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 * basic type are string, int, float, object and program * 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 * T_UNKNOWN only matches T_MIXED and T_UNKNOWN
6bc9281998-04-10Fredrik Hübinette (Hubbe)  * objects are coded thus: * T_OBJECT <0/1> <program_id> * ^ * 0 means 'inherits' * 1 means 'is'
5267b71995-08-09Fredrik Hübinette (Hubbe)  */
06983f1996-09-22Fredrik Hübinette (Hubbe) struct pike_string *string_type_string; struct pike_string *int_type_string; struct pike_string *float_type_string; struct pike_string *function_type_string; struct pike_string *object_type_string; struct pike_string *program_type_string; struct pike_string *array_type_string; struct pike_string *multiset_type_string; struct pike_string *mapping_type_string; struct pike_string *mixed_type_string; struct pike_string *void_type_string; struct pike_string *any_type_string;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a946c71998-03-02Fredrik Hübinette (Hubbe) static struct pike_string *a_markers[10],*b_markers[10];
9e52381998-03-01Fredrik Hübinette (Hubbe) 
22ca071998-04-08Fredrik Hübinette (Hubbe) static void clear_markers(void)
9e52381998-03-01Fredrik Hübinette (Hubbe) { unsigned int e;
a946c71998-03-02Fredrik Hübinette (Hubbe)  for(e=0;e<NELEM(a_markers);e++) { if(a_markers[e]) { free_string(a_markers[e]); a_markers[e]=0; } if(b_markers[e]) { free_string(b_markers[e]); b_markers[e]=0; } }
9e52381998-03-01Fredrik Hübinette (Hubbe) }
b9e4ba1996-11-18Fredrik Hübinette (Hubbe) #ifdef DEBUG static void CHECK_TYPE(struct pike_string *s) { if(debug_findstring(s) != s) fatal("Type string not shared.\n"); if(type_length(s->str) != s->len)
9e52381998-03-01Fredrik Hübinette (Hubbe)  { stupid_describe_type(s->str,s->len);
6bc9281998-04-10Fredrik Hübinette (Hubbe)  fatal("Length of type is wrong. (should be %d, is %d)\n",type_length(s->str),s->len);
9e52381998-03-01Fredrik Hübinette (Hubbe)  }
b9e4ba1996-11-18Fredrik Hübinette (Hubbe) } #else #define CHECK_TYPE(X) #endif
be478c1997-08-30Henrik Grubbström (Grubba) void init_types(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) { string_type_string=parse_type("string"); int_type_string=parse_type("int"); object_type_string=parse_type("object"); program_type_string=parse_type("program"); float_type_string=parse_type("float"); mixed_type_string=parse_type("mixed"); array_type_string=parse_type("array");
06983f1996-09-22Fredrik Hübinette (Hubbe)  multiset_type_string=parse_type("multiset");
5267b71995-08-09Fredrik Hübinette (Hubbe)  mapping_type_string=parse_type("mapping"); function_type_string=parse_type("function"); void_type_string=parse_type("void");
f6f02d1995-10-16Fredrik Hübinette (Hubbe)  any_type_string=parse_type("void|mixed");
5267b71995-08-09Fredrik Hübinette (Hubbe) } static int type_length(char *t) { 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: fatal("error in type string.\n"); /*NOTREACHED*/ break; 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++; case T_MAPPING: case T_OR: case T_AND: t+=type_length(t); case T_ARRAY: case T_MULTISET: case T_NOT:
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_INT: case T_FLOAT: case T_STRING: case T_PROGRAM: case T_MIXED: case T_VOID: case T_UNKNOWN: break; 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 *type_stackp=type_stack; unsigned char *pike_type_mark_stack[PIKE_TYPE_STACK_SIZE/4]; unsigned char **pike_type_mark_stackp=pike_type_mark_stack;
7260711996-06-21Fredrik Hübinette (Hubbe) 
be478c1997-08-30Henrik Grubbström (Grubba) INT32 pop_stack_mark(void)
7260711996-06-21Fredrik Hübinette (Hubbe) {
1347171998-04-23Fredrik Hübinette (Hubbe)  pike_type_mark_stackp--; if(pike_type_mark_stackp<pike_type_mark_stack)
7260711996-06-21Fredrik Hübinette (Hubbe)  fatal("Type mark stack underflow\n");
1347171998-04-23Fredrik Hübinette (Hubbe)  return type_stackp - *pike_type_mark_stackp;
7260711996-06-21Fredrik Hübinette (Hubbe) }
be478c1997-08-30Henrik Grubbström (Grubba) void pop_type_stack(void)
7260711996-06-21Fredrik Hübinette (Hubbe) { type_stackp--; if(type_stackp<type_stack) fatal("Type stack underflow\n"); }
be478c1997-08-30Henrik Grubbström (Grubba) void type_stack_pop_to_mark(void)
7260711996-06-21Fredrik Hübinette (Hubbe) {
36feac1997-03-06Fredrik Hübinette (Hubbe)  type_stackp-=pop_stack_mark(); #ifdef DEBUG if(type_stackp<type_stack) 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) {
36feac1997-03-06Fredrik Hübinette (Hubbe)  INT32 a; a=pop_stack_mark();
5425bb1997-05-30Henrik Grubbström (Grubba)  reverse((char *)(type_stackp-a),a,1);
7260711996-06-21Fredrik Hübinette (Hubbe) }
d2c6081996-11-07Fredrik Hübinette (Hubbe) void push_type_int(unsigned INT32 i) {
36feac1997-03-06Fredrik Hübinette (Hubbe)  int e; for(e=sizeof(i)-1;e>=0;e--) push_type(((unsigned char *)&i)[e]);
d2c6081996-11-07Fredrik Hübinette (Hubbe) }
7260711996-06-21Fredrik Hübinette (Hubbe) void push_unfinished_type(char *s) { int e; e=type_length(s); for(e--;e>=0;e--) push_type(s[e]); }
a946c71998-03-02Fredrik Hübinette (Hubbe) static void push_unfinished_type_with_markers(char *s, struct pike_string **am)
9e52381998-03-01Fredrik Hübinette (Hubbe) {
2a6d261998-03-25Fredrik Hübinette (Hubbe)  int e,c,len=type_length(s); 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{ push_type(T_MIXED); } break; #endif case T_OBJECT: push_type(c); push_type(EXTRACT_UCHAR(s+ ++e)); push_type(EXTRACT_UCHAR(s+ ++e)); push_type(EXTRACT_UCHAR(s+ ++e)); push_type(EXTRACT_UCHAR(s+ ++e));
6bc9281998-04-10Fredrik Hübinette (Hubbe)  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) }
06983f1996-09-22Fredrik Hübinette (Hubbe) void push_finished_type(struct pike_string *type)
7260711996-06-21Fredrik Hübinette (Hubbe) { int e;
b9e4ba1996-11-18Fredrik Hübinette (Hubbe)  CHECK_TYPE(type);
7260711996-06-21Fredrik Hübinette (Hubbe)  for(e=type->len-1;e>=0;e--) push_type(type->str[e]); }
2a6d261998-03-25Fredrik Hübinette (Hubbe) void push_finished_type_backwards(struct pike_string *type) { int e; CHECK_TYPE(type); MEMCPY(type_stackp, type->str, type->len); type_stackp+=type->len; }
61e9a01998-01-25Fredrik Hübinette (Hubbe) struct pike_string *debug_pop_unfinished_type(void)
7260711996-06-21Fredrik Hübinette (Hubbe) { int len,e;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *s;
36feac1997-03-06Fredrik Hübinette (Hubbe)  len=pop_stack_mark();
7260711996-06-21Fredrik Hübinette (Hubbe)  s=begin_shared_string(len);
36feac1997-03-06Fredrik Hübinette (Hubbe)  type_stackp-=len; MEMCPY(s->str, type_stackp, len); reverse(s->str, len, 1);
b9e4ba1996-11-18Fredrik Hübinette (Hubbe)  s=end_shared_string(s); CHECK_TYPE(s); return s;
7260711996-06-21Fredrik Hübinette (Hubbe) }
61e9a01998-01-25Fredrik Hübinette (Hubbe) struct pike_string *debug_pop_type(void)
7260711996-06-21Fredrik Hübinette (Hubbe) {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *s;
36feac1997-03-06Fredrik Hübinette (Hubbe)  s=pop_unfinished_type(); type_stack_mark();
7260711996-06-21Fredrik Hübinette (Hubbe)  return s; }
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)  { if(len>=sizeof(buf)) error("Buffer overflow in parse_type\n"); 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)  {
1347171998-04-23Fredrik Hübinette (Hubbe)  case 'i': if(!strcmp(buf,"int")) { push_type(T_INT); break; } 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; if(**s != ':') error("Missing ':' after ... in function type.\n"); break; } pop_stack_mark(); pop_stack_mark(); } ++*s; type_stack_mark(); internal_parse_type(_s); /* return type */ type_stack_reverse(); if(**s != ')') error("Missing ')' in function type.\n"); ++*s; type_stack_reverse(); }else{ push_type(T_MIXED); push_type(T_MIXED);
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")) { push_type_int(0); push_type(0); push_type(T_OBJECT); break; } goto bad_type; case 'p': if(!strcmp(buf,"program")) { push_type(T_PROGRAM); break; } 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 '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();
1347171998-04-23Fredrik Hübinette (Hubbe)  if(**s != ':') error("Expecting ':'.\n"); ++*s; type_stack_mark(); internal_parse_type(_s);
5267b71995-08-09Fredrik Hübinette (Hubbe)  type_stack_reverse();
1347171998-04-23Fredrik Hübinette (Hubbe)  if(**s != ')') error("Expecting ')'.\n"); ++*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); if(**s != ')') 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(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 != ')') 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_type(buf[0]); push_type(T_ASSIGN); }else{ push_type(buf[0]); } break; } default: bad_type: 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;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  if(**s != ')') error("Expecting ')'.\n"); 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. */
06983f1996-09-22Fredrik Hübinette (Hubbe) struct pike_string *parse_type(char *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
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");
36feac1997-03-06Fredrik Hübinette (Hubbe)  return pop_unfinished_type();
5267b71995-08-09Fredrik Hübinette (Hubbe) } #ifdef DEBUG void stupid_describe_type(char *a,INT32 len) { INT32 e; for(e=0;e<len;e++) { if(e) printf(" "); 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': printf("%c",EXTRACT_UCHAR(a+e)); break; case T_ASSIGN: printf("="); break; case T_INT: printf("int"); break; case T_FLOAT: printf("float"); break; case T_STRING: printf("string"); break; case T_PROGRAM: printf("program"); break; case T_OBJECT:
6bc9281998-04-10Fredrik Hübinette (Hubbe)  printf("object(%s %ld)",
1347171998-04-23Fredrik Hübinette (Hubbe)  EXTRACT_UCHAR(a+e+1)?"clone of":"inherits",
6bc9281998-04-10Fredrik Hübinette (Hubbe)  (long)EXTRACT_INT(a+e+2)); e+=sizeof(INT32)+1;
9e52381998-03-01Fredrik Hübinette (Hubbe)  break; case T_FUNCTION: printf("function"); break; case T_ARRAY: printf("array"); break; case T_MAPPING: printf("mapping"); break; case T_MULTISET: printf("multiset"); break; case T_UNKNOWN: printf("unknown"); break; case T_MANY: printf("many"); break; case T_OR: printf("or"); break; case T_AND: printf("and"); break; case T_NOT: printf("not"); break; case T_VOID: printf("void"); break; case T_MIXED: printf("mixed"); break; default: printf("%d",EXTRACT_UCHAR(a+e)); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } printf("\n"); }
0d202a1995-10-20Fredrik Hübinette (Hubbe) 
06983f1996-09-22Fredrik Hübinette (Hubbe) void simple_describe_type(struct pike_string *s)
0d202a1995-10-20Fredrik Hübinette (Hubbe) { stupid_describe_type(s->str,s->len); }
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif char *low_describe_type(char *t) { 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; case T_VOID: my_strcat("void"); break; case T_MIXED: my_strcat("mixed"); break; case T_UNKNOWN: my_strcat("unknown"); break; case T_INT: my_strcat("int"); break; case T_FLOAT: my_strcat("float"); break; case T_PROGRAM: my_strcat("program"); break; case T_OBJECT:
0ee27b1998-04-14Fredrik Hübinette (Hubbe)  if(EXTRACT_INT(t+1)) { char buffer[100]; sprintf(buffer,"object(%s %ld)",*t?"is":"implements",(long)EXTRACT_INT(t+1)); 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; case T_FUNCTION:
bce86c1996-02-25Fredrik Hübinette (Hubbe)  {
9e52381998-03-01Fredrik Hübinette (Hubbe)  int s; my_strcat("function("); s=0; while(EXTRACT_UCHAR(t) != T_MANY) { if(s++) my_strcat(", "); t=low_describe_type(t); }
bce86c1996-02-25Fredrik Hübinette (Hubbe)  t++;
9e52381998-03-01Fredrik Hübinette (Hubbe)  if(EXTRACT_UCHAR(t) == T_VOID) { t++; }else{ if(s++) my_strcat(", "); t=low_describe_type(t); my_strcat(" ..."); } my_strcat(" : ");
bce86c1996-02-25Fredrik Hübinette (Hubbe)  t=low_describe_type(t); my_strcat(")");
9e52381998-03-01Fredrik Hübinette (Hubbe)  break;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  }
9e52381998-03-01Fredrik Hübinette (Hubbe)  case T_ARRAY: if(EXTRACT_UCHAR(t)==T_MIXED) { my_strcat("array"); t++; }else{ t=low_describe_type(t); my_strcat("*"); } 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("!"); t=low_describe_type(t); break; case T_OR: t=low_describe_type(t); my_strcat(" | "); t=low_describe_type(t); break; case T_AND:
bce86c1996-02-25Fredrik Hübinette (Hubbe)  t=low_describe_type(t);
9e52381998-03-01Fredrik Hübinette (Hubbe)  my_strcat(" & "); t=low_describe_type(t); 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);
bce86c1996-02-25Fredrik Hübinette (Hubbe)  my_strcat(":"); t=low_describe_type(t); my_strcat(")"); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; } return t; }
06983f1996-09-22Fredrik Hübinette (Hubbe) struct pike_string *describe_type(struct pike_string *type)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
bce86c1996-02-25Fredrik Hübinette (Hubbe)  if(!type) return make_shared_string("mixed"); init_buf(); low_describe_type(type->str); 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;
9e52381998-03-01Fredrik Hübinette (Hubbe)  default: return T_MIXED;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
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: case T_INT: case T_FLOAT: return EXTRACT_UCHAR(t);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
06983f1996-09-22Fredrik Hübinette (Hubbe) TYPE_T compile_type_to_runtime_type(struct pike_string *s)
bce86c1996-02-25Fredrik Hübinette (Hubbe) { return low_compile_type_to_runtime_type(s->str); }
a946c71998-03-02Fredrik Hübinette (Hubbe)  static int low_find_exact_type_match(char *needle, char *haystack) { while(EXTRACT_UCHAR(haystack)==T_OR) { haystack++; if(low_find_exact_type_match(needle, haystack)) 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); } if(!low_find_exact_type_match(to_push, not_push)) { push_unfinished_type(to_push); push_type(T_OR); } } static void low_or_pike_types(char *t1, char *t2) { if(!t1) { if(!t2) push_type(T_VOID); else push_unfinished_type(t2); } else if(!t2) { push_unfinished_type(t1); } else if(EXTRACT_UCHAR(t1)==T_MIXED || EXTRACT_UCHAR(t2)==T_MIXED) { push_type(T_MIXED); } else { push_unfinished_type(t1); very_low_or_pike_types(t2,t1); } } static void medium_or_pike_types(struct pike_string *a, struct pike_string *b) { low_or_pike_types( a ? a->str : 0 , b ? b->str : 0 ); } static struct pike_string *or_pike_types(struct pike_string *a, struct pike_string *b) { type_stack_mark(); medium_or_pike_types(a,b); return pop_unfinished_type(); }
6bc9281998-04-10Fredrik Hübinette (Hubbe) static struct pike_string *low_object_lfun_type(char *t, short lfun) { struct program *p; int i; p=id_to_program(EXTRACT_INT(t+2)); 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) 
bce86c1996-02-25Fredrik Hübinette (Hubbe) #define A_EXACT 1 #define B_EXACT 2
5b4dd31998-02-23Fredrik Hübinette (Hubbe) #define NO_MAX_ARGS 4
bce86c1996-02-25Fredrik 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)
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);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(ret) return ret; a+=type_length(a);
bce86c1996-02-25Fredrik Hübinette (Hubbe)  return low_match_types(a,b,flags); 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';
a946c71998-03-02Fredrik Hübinette (Hubbe)  type_stack_mark(); low_or_pike_types(a_markers[m] ? a_markers[m]->str : 0,b); if(a_markers[m]) free_string(a_markers[m]); a_markers[m]=pop_unfinished_type();
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])
a946c71998-03-02Fredrik Hübinette (Hubbe)  return low_match_types(a_markers[m]->str, b, flags);
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);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(ret) return ret; b+=type_length(b);
bce86c1996-02-25Fredrik Hübinette (Hubbe)  return low_match_types(a,b,flags); 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';
a946c71998-03-02Fredrik Hübinette (Hubbe)  type_stack_mark(); low_or_pike_types(b_markers[m] ? b_markers[m]->str : 0,a); if(b_markers[m]) free_string(b_markers[m]); b_markers[m]=pop_unfinished_type();
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])
a946c71998-03-02Fredrik Hübinette (Hubbe)  return low_match_types(a, b_markers[m]->str, flags);
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 */
bce86c1996-02-25Fredrik Hübinette (Hubbe)  if(EXTRACT_UCHAR(a) == T_MIXED && !(flags & A_EXACT)) return a; if(EXTRACT_UCHAR(b) == T_MIXED && !(flags & B_EXACT)) return a;
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):
255d351997-01-26Fredrik Hübinette (Hubbe)  return a;
9f68471997-03-08Fredrik Hübinette (Hubbe)  case TWOT(T_OBJECT, T_FUNCTION):
d2c6081996-11-07Fredrik Hübinette (Hubbe)  {
6bc9281998-04-10Fredrik Hübinette (Hubbe)  struct pike_string *s; if((s=low_object_lfun_type(a, LFUN_CALL))) return low_match_types(s->str,b,flags);
d2c6081996-11-07Fredrik Hübinette (Hubbe)  return a; }
9f68471997-03-08Fredrik Hübinette (Hubbe)  case TWOT(T_FUNCTION, T_OBJECT): {
6bc9281998-04-10Fredrik Hübinette (Hubbe)  struct pike_string *s; if((s=low_object_lfun_type(b, LFUN_CALL))) return low_match_types(a,s->str,flags);
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); }
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  if(!low_match_types(a_tmp, b_tmp, flags | NO_MAX_ARGS)) 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{
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  if(!low_match_types(a,b,flags | NO_MAX_ARGS)) 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 */
bce86c1996-02-25Fredrik Hübinette (Hubbe)  if(!low_match_types(a,b,flags)) return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case T_MAPPING:
bce86c1996-02-25Fredrik Hübinette (Hubbe)  if(!low_match_types(++a,++b,flags)) return 0; if(!low_match_types(a+type_length(a),b+type_length(b),flags)) 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 if(EXTRACT_INT(a+2) || EXTRACT_INT(b+2)) { fprintf(stderr,"Type match1: "); stupid_describe_type(a,type_length(a)); fprintf(stderr,"Type match2: "); stupid_describe_type(b,type_length(b)); } #endif
6bc9281998-04-10Fredrik Hübinette (Hubbe)  /* object(* 0) matches any object */ if(!EXTRACT_INT(a+2) || !EXTRACT_INT(b+2)) break; /* 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) */ if(EXTRACT_INT(a+2) != EXTRACT_INT(b+2)) return 0; }else{ /* object(0 *) =? object(0 *) */ break; } } { struct program *ap,*bp;
636e471998-04-15Fredrik Hübinette (Hubbe)  ap=id_to_program(EXTRACT_INT(a+2)); bp=id_to_program(EXTRACT_INT(b+2));
6bc9281998-04-10Fredrik Hübinette (Hubbe)  if(!ap || !bp) break;
636e471998-04-15Fredrik Hübinette (Hubbe) 
6bc9281998-04-10Fredrik Hübinette (Hubbe)  if(EXTRACT_UCHAR(a+1)) {
0ee27b1998-04-14Fredrik Hübinette (Hubbe)  if(!implements(ap,bp))
6bc9281998-04-10Fredrik Hübinette (Hubbe)  return 0; }else{
0ee27b1998-04-14Fredrik Hübinette (Hubbe)  if(!implements(bp,ap))
6bc9281998-04-10Fredrik Hübinette (Hubbe)  return 0; } }
d2c6081996-11-07Fredrik Hübinette (Hubbe)  break;
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_ARRAY:
bce86c1996-02-25Fredrik Hübinette (Hubbe)  if(!low_match_types(++a,++b,flags)) return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_INT: case T_FLOAT: case T_STRING: case T_PROGRAM: case T_VOID: case T_MIXED: break; default: fatal("error in type string.\n"); } return ret; } /* * 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)  {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *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; medium_or_pike_types(o1,o2);
7260711996-06-21Fredrik Hübinette (Hubbe)  if(o1) free_string(o1); if(o2) free_string(o2); 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; }
bce86c1996-02-25Fredrik Hübinette (Hubbe)  a=low_match_types(a,b,0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(a) { 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: push_type_int(0);
6bc9281998-04-10Fredrik Hübinette (Hubbe)  push_type(0);
d2c6081996-11-07Fredrik Hübinette (Hubbe)  push_type(T_OBJECT); return 1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  default: push_type(T_MIXED); return 1; } } return 0; }
06983f1996-09-22Fredrik Hübinette (Hubbe) int match_types(struct pike_string *a,struct pike_string *b)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b9e4ba1996-11-18Fredrik Hübinette (Hubbe)  CHECK_TYPE(a); CHECK_TYPE(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) }
2a50961995-08-23Fredrik Hübinette (Hubbe) 
3c0c281998-01-26Fredrik Hübinette (Hubbe) #ifdef DEBUG_MALLOC #define low_index_type(X,Y) ((struct pike_string *)debug_malloc_touch(debug_low_index_type((X),(Y)))) #else #define low_index_type debug_low_index_type #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  /* FIXME, add the index */
3c0c281998-01-26Fredrik Hübinette (Hubbe) static struct pike_string *debug_low_index_type(char *t, node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) { switch(EXTRACT_UCHAR(t++)) {
b8cda21997-01-21Fredrik Hübinette (Hubbe)  case T_OBJECT: {
6bc9281998-04-10Fredrik Hübinette (Hubbe)  struct program *p=id_to_program(EXTRACT_INT(t+1));
dcab7e1998-02-19Fredrik Hübinette (Hubbe)  if(p && n)
b8cda21997-01-21Fredrik Hübinette (Hubbe)  { if(n->token == F_ARROW) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(FIND_LFUN(p,LFUN_ARROW)!=-1 || FIND_LFUN(p,LFUN_ASSIGN_ARROW)!=-1)
b8cda21997-01-21Fredrik Hübinette (Hubbe)  { reference_shared_string(mixed_type_string); return mixed_type_string; } }else{
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(FIND_LFUN(p,LFUN_INDEX) != -1 || FIND_LFUN(p,LFUN_ASSIGN_INDEX) != -1)
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) { INT32 i; i=find_shared_string_identifier(CDR(n)->u.sval.u.string, p); if(i==-1) { reference_shared_string(int_type_string); return int_type_string; }else{
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)) { reference_shared_string(ID_FROM_INT(p, i)->type); return ID_FROM_INT(p, i)->type; }else{ reference_shared_string(mixed_type_string); return mixed_type_string; }
b8cda21997-01-21Fredrik Hübinette (Hubbe)  } } } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  default: reference_shared_string(mixed_type_string); return mixed_type_string; case T_OR: {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *a,*b;
36feac1997-03-06Fredrik Hübinette (Hubbe)  type_stack_mark();
b8cda21997-01-21Fredrik Hübinette (Hubbe)  a=low_index_type(t,n);
5267b71995-08-09Fredrik Hübinette (Hubbe)  t+=type_length(t);
b8cda21997-01-21Fredrik Hübinette (Hubbe)  b=low_index_type(t,n);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!b) return a; if(!a) return b;
a946c71998-03-02Fredrik Hübinette (Hubbe)  type_stack_mark(); medium_or_pike_types(a,b);
3c0c281998-01-26Fredrik Hübinette (Hubbe)  free_string(a); free_string(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:
b8cda21997-01-21Fredrik Hübinette (Hubbe)  return low_index_type(t+type_length(t),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:
dcab7e1998-02-19Fredrik Hübinette (Hubbe)  if(n && low_match_types(string_type_string->str,CDR(n)->type->str,0))
de2a581997-09-28Fredrik Hübinette (Hubbe)  { struct pike_string *a=low_index_type(t,n); if(!a) return make_shared_binary_string(t, type_length(t)); type_stack_mark(); push_finished_type(a); free_string(a); push_type(T_ARRAY); if(low_match_types(int_type_string->str,CDR(n)->type->str,0)) { push_unfinished_type(t);
a946c71998-03-02Fredrik Hübinette (Hubbe)  push_type(T_OR);
de2a581997-09-28Fredrik Hübinette (Hubbe)  } return pop_unfinished_type(); }else{ return make_shared_binary_string(t, type_length(t)); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
b8cda21997-01-21Fredrik Hübinette (Hubbe) struct pike_string *index_type(struct pike_string *type, node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *t;
9e52381998-03-01Fredrik Hübinette (Hubbe)  clear_markers();
b8cda21997-01-21Fredrik Hübinette (Hubbe)  t=low_index_type(type->str,n);
5267b71995-08-09Fredrik Hübinette (Hubbe)  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:
b8cda21997-01-21Fredrik Hübinette (Hubbe)  return !low_check_indexing(type,index_type,n);
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)  {
6bc9281998-04-10Fredrik Hübinette (Hubbe)  struct program *p=id_to_program(EXTRACT_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:
bce86c1996-02-25Fredrik Hübinette (Hubbe)  return !!low_match_types(type,index_type,0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_MIXED: return 1; default: return 0; } }
06983f1996-09-22Fredrik Hübinette (Hubbe) int check_indexing(struct pike_string *type,
b8cda21997-01-21Fredrik Hübinette (Hubbe)  struct pike_string *index_type, node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b9e4ba1996-11-18Fredrik Hübinette (Hubbe)  CHECK_TYPE(type); CHECK_TYPE(index_type);
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) */
06983f1996-09-22Fredrik Hübinette (Hubbe) int count_arguments(struct pike_string *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b9e4ba1996-11-18Fredrik Hübinette (Hubbe)  CHECK_TYPE(s);
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  return low_count_arguments(s->str);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
06983f1996-09-22Fredrik Hübinette (Hubbe) struct pike_string *check_call(struct pike_string *args,
1d53281996-11-25Fredrik Hübinette (Hubbe)  struct pike_string *type)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b9e4ba1996-11-18Fredrik Hübinette (Hubbe)  CHECK_TYPE(args); CHECK_TYPE(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)) {
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; } }
5b4dd31998-02-23Fredrik Hübinette (Hubbe) INT32 get_max_args(struct pike_string *type) { INT32 ret,tmp=max_correct_args; CHECK_TYPE(type);
9e52381998-03-01Fredrik Hübinette (Hubbe)  clear_markers();
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  type=check_call(function_type_string, type); if(type) free_string(type); ret=max_correct_args; max_correct_args=tmp; return tmp; }
06983f1996-09-22Fredrik Hübinette (Hubbe) struct pike_string *get_type_of_svalue(struct svalue *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *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)  { ret=s->u.efun->type; }else{ struct program *p; p=s->u.object->prog; if(!p) { ret=int_type_string; }else{ ret=ID_FROM_INT(p,s->subtype)->type; } } reference_shared_string(ret); return ret; case T_ARRAY:
3db32a1997-03-04Fredrik Hübinette (Hubbe)  type_stack_mark(); push_type(T_MIXED);
5267b71995-08-09Fredrik Hübinette (Hubbe)  push_type(T_ARRAY);
3db32a1997-03-04Fredrik Hübinette (Hubbe)  return pop_unfinished_type();
5267b71995-08-09Fredrik Hübinette (Hubbe) 
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET:
3db32a1997-03-04Fredrik Hübinette (Hubbe)  type_stack_mark(); push_type(T_MIXED);
06983f1996-09-22Fredrik Hübinette (Hubbe)  push_type(T_MULTISET);
3db32a1997-03-04Fredrik Hübinette (Hubbe)  return pop_unfinished_type();
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_MAPPING:
3db32a1997-03-04Fredrik Hübinette (Hubbe)  type_stack_mark();
6557ff1996-06-09Fredrik Hübinette (Hubbe)  push_type(T_MIXED); push_type(T_MIXED);
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) { push_type_int(s->u.object->prog->id);
6bc9281998-04-10Fredrik Hübinette (Hubbe)  push_type(1);
3db32a1997-03-04Fredrik Hübinette (Hubbe)  }else{ push_type_int(0);
6bc9281998-04-10Fredrik Hübinette (Hubbe)  push_type(0);
3db32a1997-03-04Fredrik Hübinette (Hubbe)  }
041a731996-11-12Mirar (Pontus Hagland)  push_type(T_OBJECT);
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) { ret=int_type_string; }else{ ret=mixed_type_string; } reference_shared_string(ret); return ret;
9f68471997-03-08Fredrik Hübinette (Hubbe)  case T_PROGRAM: { char *a;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  int id=FIND_LFUN(s->u.program,LFUN_CREATE);
9f68471997-03-08Fredrik Hübinette (Hubbe)  if(id>=0) { a=ID_FROM_INT(s->u.program, id)->type->str; }else{ a=function_type_string->str; } if(EXTRACT_UCHAR(a)==T_FUNCTION) { type_stack_mark(); push_type_int(s->u.program->id);
6bc9281998-04-10Fredrik Hübinette (Hubbe)  push_type(1);
9f68471997-03-08Fredrik Hübinette (Hubbe)  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(); } }
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)  } } char *get_name_of_type(int t) { switch(t) { case T_ARRAY: return "array";
45c8971997-01-03Fredrik Hübinette (Hubbe)  case T_FLOAT: return "float"; case T_FUNCTION: return "function"; case T_INT: return "int"; case T_LVALUE: return "lvalue";
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_MAPPING: return "mapping";
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET: return "multiset";
45c8971997-01-03Fredrik Hübinette (Hubbe)  case T_OBJECT: return "object"; case T_PROGRAM: return "program"; case T_STRING: return "string";
3c04e81997-03-13Fredrik Hübinette (Hubbe)  case T_VOID: return "void";
5267b71995-08-09Fredrik Hübinette (Hubbe)  default: return "unknown"; } }
be478c1997-08-30Henrik Grubbström (Grubba) void cleanup_pike_types(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) { free_string(string_type_string); free_string(int_type_string); free_string(float_type_string); free_string(function_type_string); free_string(object_type_string); free_string(program_type_string); free_string(array_type_string);
06983f1996-09-22Fredrik Hübinette (Hubbe)  free_string(multiset_type_string);
5267b71995-08-09Fredrik Hübinette (Hubbe)  free_string(mapping_type_string); free_string(mixed_type_string); free_string(void_type_string);
f6f02d1995-10-16Fredrik Hübinette (Hubbe)  free_string(any_type_string);
5267b71995-08-09Fredrik Hübinette (Hubbe) }