diff --git a/src/pike_types.c b/src/pike_types.c index 39e7a4c6b65613b5eac6a3fe5da5811ce7fd4762..a948df6dc1aa8e593378e3771de58bbb3788ba99 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: pike_types.c,v 1.95 1999/12/14 14:55:57 hubbe Exp $"); +RCSID("$Id: pike_types.c,v 1.96 1999/12/15 01:14:17 grubba Exp $"); #include <ctype.h> #include "svalue.h" #include "pike_types.h" @@ -32,7 +32,7 @@ int max_correct_args; static void internal_parse_type(char **s); static int type_length(char *t); -static int low_pike_types_le(char *a, char *b); +static int low_pike_types_le(char *a, char *b, int array_cnt); #define TWOT(X,Y) (((X) << 8)+(Y)) #define EXTRACT_TWOT(X,Y) TWOT(EXTRACT_UCHAR(X), EXTRACT_UCHAR(Y)) @@ -57,7 +57,7 @@ static int low_pike_types_le(char *a, char *b); * T_OBJECT <0/1> <program_id> * ^ * 0 means 'implements' - * 1 means 'inherits' + * 1 means 'is' (aka 'clone of') * Integers are encoded as: * T_INT <min> <max> * Everything except T_VOID matches T_ZERO. @@ -777,7 +777,7 @@ void stupid_describe_type(char *a,INT32 len) case T_PROGRAM: printf("program"); break; case T_OBJECT: printf("object(%s %ld)", - EXTRACT_UCHAR(a+e+1)?"inherits":"implements", + EXTRACT_UCHAR(a+e+1)?"is":"implements", (long)extract_type_int(a+e+2)); e+=sizeof(INT32)+1; break; @@ -866,7 +866,7 @@ char *low_describe_type(char *t) if(extract_type_int(t+1)) { char buffer[100]; - sprintf(buffer,"object(%s %ld)",*t?"inherits":"implements", + sprintf(buffer,"object(%s %ld)",*t?"is":"implements", (long)extract_type_int(t+1)); my_strcat(buffer); }else{ @@ -1354,11 +1354,11 @@ static void low_and_pike_types(char *t1, char *t2) { push_unfinished_type(t1); } - else if(low_pike_types_le(t1, t2)) + else if(low_pike_types_le(t1, t2, 0)) { push_unfinished_type(t1); } - else if(low_pike_types_le(t2, t1)) + else if(low_pike_types_le(t2, t1, 0)) { push_unfinished_type(t2); } @@ -1848,7 +1848,6 @@ static char *low_match_types2(char *a,char *b, int flags) if(EXTRACT_UCHAR(a+1)) { /* object(1 x) =? object(1 x) */ - /* FIXME: Ought to check if a inherits b or b inherits a. */ if(extract_type_int(a+2) != extract_type_int(b+2)) return 0; }else{ /* object(0 *) =? object(0 *) */ @@ -1932,13 +1931,14 @@ static char *low_match_types2(char *a,char *b, int flags) * with a mapping(int:int) won't change the type of the mapping after the * operation. */ -static int low_pike_types_le(char *a,char *b) +static int low_pike_types_le(char *a, char *b, int array_cnt) #ifdef PIKE_TYPE_DEBUG { int e; char *s; - static int low_pike_types_le2(char *a,char *b); + static int low_pike_types_le2(char *a, char *b, int array_cnt); int res; + char buf[50]; if (l_flag) { init_buf(); @@ -1955,13 +1955,23 @@ static int low_pike_types_le(char *a,char *b) my_strcat(", "); low_describe_type(b); } + 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); my_strcat(");\n"); fprintf(stderr,"%s",(s=simple_free_buf())); free(s); indent++; } - res=low_pike_types_le2(a,b); + res=low_pike_types_le2(a, b, array_cnt); if (l_flag) { indent--; @@ -1972,7 +1982,7 @@ static int low_pike_types_le(char *a,char *b) return res; } -static int low_pike_types_le2(char *a,char *b) +static int low_pike_types_le2(char *a, char *b, int array_cnt) #endif /* PIKE_TYPE_DEBUG */ { @@ -1985,30 +1995,33 @@ static int low_pike_types_le2(char *a,char *b) /* OK if either of the parts is a subset. */ /* FIXME: What if b also contains an AND? */ a++; - ret = low_pike_types_le(a,b); + ret = low_pike_types_le(a, b, array_cnt); if(ret) return ret; a += type_length(a); - return low_pike_types_le(a,b); + return low_pike_types_le(a, b, array_cnt); case T_OR: /* OK, if both of the parts are a subset */ a++; - ret=low_pike_types_le(a,b); + ret=low_pike_types_le(a, b, array_cnt); if (!ret) return 0; a+=type_length(a); - return low_pike_types_le(a,b); + return low_pike_types_le(a, b, array_cnt); case T_NOT: - return !low_pike_types_le(a+1,b); + return !low_pike_types_le(a+1, b, array_cnt); case T_ASSIGN: - ret=low_pike_types_le(a+2,b); + ret=low_pike_types_le(a+2, b, array_cnt); if(ret && EXTRACT_UCHAR(b)!=T_VOID) { int m=EXTRACT_UCHAR(a+1)-'0'; struct pike_string *tmp; + int i; type_stack_mark(); push_unfinished_type_with_markers(b, b_markers); + for(i=array_cnt; i > 0; i--) + push_type(T_ARRAY); tmp=pop_unfinished_type(); type_stack_mark(); @@ -2039,9 +2052,9 @@ static int low_pike_types_le2(char *a,char *b) { int m=EXTRACT_UCHAR(a)-'0'; if(a_markers[m]) - return low_pike_types_le(a_markers[m]->str, b); + return low_pike_types_le(a_markers[m]->str, b, array_cnt); else - return low_pike_types_le(mixed_type_string->str, b); + return low_pike_types_le(mixed_type_string->str, b, array_cnt); } } @@ -2050,30 +2063,33 @@ static int low_pike_types_le2(char *a,char *b) case T_AND: /* OK, if a is a subset of both parts. */ b++; - ret = low_pike_types_le(a,b); + ret = low_pike_types_le(a, b, array_cnt); if(!ret) return 0; b+=type_length(b); - return low_pike_types_le(a,b); + return low_pike_types_le(a, b, array_cnt); case T_OR: /* OK if a is a subset of either of the parts. */ b++; - ret=low_pike_types_le(a,b); + ret=low_pike_types_le(a, b, array_cnt); if (ret) return ret; b+=type_length(b); - return low_pike_types_le(a,b); + return low_pike_types_le(a, b, array_cnt); case T_NOT: - return !low_pike_types_le(a,b+1); + return !low_pike_types_le(a, b+1, array_cnt); case T_ASSIGN: - ret=low_pike_types_le(a,b+2); + ret=low_pike_types_le(a, b+2, array_cnt); if(ret && EXTRACT_UCHAR(a)!=T_VOID) { int m=EXTRACT_UCHAR(b+1)-'0'; struct pike_string *tmp; + int i; type_stack_mark(); push_unfinished_type_with_markers(a, a_markers); + for(i = array_cnt; i < 0; i++) + push_type(T_ARRAY); tmp=pop_unfinished_type(); type_stack_mark(); @@ -2104,36 +2120,69 @@ static int low_pike_types_le2(char *a,char *b) { int m=EXTRACT_UCHAR(b)-'0'; if(b_markers[m]) - return low_pike_types_le(a, b_markers[m]->str); + return low_pike_types_le(a, b_markers[m]->str, array_cnt); else - return low_pike_types_le(a, mixed_type_string->str); + return low_pike_types_le(a, mixed_type_string->str, array_cnt); } + } - case T_MIXED: + if ((array_cnt < 0) && (EXTRACT_UCHAR(b) == T_ARRAY)) { + while (EXTRACT_UCHAR(b) == T_ARRAY) { + b++; + if (!++array_cnt) break; + } + return low_pike_types_le(a, b, array_cnt); + } else if ((array_cnt > 0) && (EXTRACT_UCHAR(a) == T_ARRAY)) { + while (EXTRACT_UCHAR(a) == T_ARRAY) { + a++; + if (!--array_cnt) break; + } + return low_pike_types_le(a, b, array_cnt); + } + + if (EXTRACT_UCHAR(b) == T_MIXED) { /* any_type <= 'mixed' */ - return 1; + if (array_cnt <= 0) { + /* !array(mixed) */ + return 1; + } } if (EXTRACT_UCHAR(a) == T_MIXED) { - return 0; + if (array_cnt >= 0) { + /* !array(mixed) */ + return 0; + } } if (EXTRACT_UCHAR(a) == T_VOID) { /* void <= any_type */ - return 1; + if (array_cnt >= 0) { + /* !array(void) */ + return 1; + } } if (EXTRACT_UCHAR(b) == T_VOID) { - return 0; + if (array_cnt <= 0) { + /* !array(void) */ + return 0; + } } if (EXTRACT_UCHAR(a) == T_ZERO) { /* void <= zero <= any_type */ - return 1; + if (array_cnt >= 0) { + /* !array(zero) */ + return 1; + } } if (EXTRACT_UCHAR(b) == T_ZERO) { - return 0; + if (array_cnt <= 0) { + /* !array(zero) */ + return 0; + } } /* Special cases (tm) */ @@ -2148,7 +2197,7 @@ static int low_pike_types_le2(char *a,char *b) { struct pike_string *s; if((s=low_object_lfun_type(a, LFUN_CALL))) - return low_pike_types_le(s->str,b); + return low_pike_types_le(s->str, b, array_cnt); return 1; } @@ -2156,16 +2205,32 @@ static int low_pike_types_le2(char *a,char *b) { struct pike_string *s; if((s=low_object_lfun_type(b, LFUN_CALL))) - return low_pike_types_le(a,s->str); + return low_pike_types_le(a, s->str, array_cnt); return 1; } + + case TWOT(T_FUNCTION, T_ARRAY): + { + while (EXTRACT_UCHAR(b) == T_ARRAY) { + b++; + array_cnt++; + } + return low_pike_types_le(a, b, array_cnt); + } + + case TWOT(T_ARRAY, T_FUNCTION): + { + while (EXTRACT_UCHAR(a) == T_ARRAY) { + a++; + array_cnt--; + } + return low_pike_types_le(a, b, array_cnt); + } } if(EXTRACT_UCHAR(a) != EXTRACT_UCHAR(b)) return 0; - switch(EXTRACT_UCHAR(a)) - { - case T_FUNCTION: + if (EXTRACT_UCHAR(a) == T_FUNCTION) { /* * function(A...:B) <= function(C...:D) iff C <= A && B <= D */ @@ -2199,14 +2264,14 @@ static int low_pike_types_le2(char *a,char *b) if (EXTRACT_UCHAR(a_tmp) != T_VOID) { /* if (EXTRACT_UCHAR(b_tmp) == T_VOID) return 0; */ - if (!low_pike_types_le(b_tmp, a_tmp)) return 0; + if (!low_pike_types_le(b_tmp, a_tmp, 0)) return 0; } } /* check the 'many' type */ a++; b++; if (EXTRACT_UCHAR(a) != T_VOID) { - if (!low_pike_types_le(b, a)) + if (!low_pike_types_le(b, a, 0)) return 0; } @@ -2216,16 +2281,21 @@ static int low_pike_types_le2(char *a,char *b) /* check the returntype */ if (EXTRACT_UCHAR(b) != T_VOID) { /* FIXME: Check if a has type void here? */ - if(!low_pike_types_le(a,b)) return 0; + if(!low_pike_types_le(a, b, array_cnt)) return 0; } - break; + return 1; + } + + if (array_cnt) return 0; + switch(EXTRACT_UCHAR(a)) + { case T_MAPPING: /* * mapping(A:B) <= mapping(C:D) iff A <= C && B <= D. */ - if(!low_pike_types_le(++a, ++b)) return 0; - return low_pike_types_le(a+type_length(a),b+type_length(b)); + if(!low_pike_types_le(++a, ++b, 0)) return 0; + return low_pike_types_le(a+type_length(a), b+type_length(b), 0); case T_OBJECT: #if 0 @@ -2242,7 +2312,7 @@ static int low_pike_types_le2(char *a,char *b) * 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 inherits y + * object(1 x) <= object(1 y) iff x == y * object(0|1 x) <= object(0 y) iff x implements y */ @@ -2258,10 +2328,7 @@ static int low_pike_types_le2(char *a,char *b) return 1; if (EXTRACT_UCHAR(b+1)) { - if (!EXTRACT_UCHAR(a+1)) { - /* We can't guarantee the inherit relation. */ - return 0; - } + return 0; } { @@ -2272,12 +2339,7 @@ static int low_pike_types_le2(char *a,char *b) /* Shouldn't happen... */ return 0; } - if (EXTRACT_UCHAR(b+1)) { - /* FIXME: Should probably have a better test here. */ - return low_get_storage(ap, bp) != -1; - } else { - return implements(ap, bp); - } + return implements(ap, bp); } break; @@ -2296,7 +2358,7 @@ static int low_pike_types_le2(char *a,char *b) case T_MULTISET: case T_ARRAY: - if(!low_pike_types_le(++a,++b)) return 0; + if(!low_pike_types_le(++a, ++b, 0)) return 0; case T_FLOAT: case T_STRING: @@ -2328,7 +2390,7 @@ int strict_check_call(char *fun_type, char *arg_type) fun_type += type_length(fun_type); } } - return low_pike_types_le(fun_type, arg_type); + return low_pike_types_le(fun_type, arg_type, 0); } /* @@ -2388,7 +2450,7 @@ static int low_get_return_type(char *a,char *b) { #if 0 if ((lex.pragmas & ID_STRICT_TYPES) && - !low_pike_types_le(a, b)) { + !low_pike_types_le(a, b, 0)) { yywarning("Type mismatch"); } #endif /* 0 */ @@ -2430,7 +2492,7 @@ int pike_types_le(struct pike_string *a,struct pike_string *b) check_type_string(a); check_type_string(b); clear_markers(); - return low_pike_types_le(a->str, b->str); + return low_pike_types_le(a->str, b->str, 0); } @@ -2871,16 +2933,21 @@ struct pike_string *check_call(struct pike_string *args, if(low_get_return_type(type->str,args->str)) { if (lex.pragmas & ID_STRICT_TYPES) { - if (type == mixed_type_string) { - yywarning("Calling mixed."); - } else if (!strict_check_call(type->str, args->str)) { - struct pike_string *arg_t = describe_type(args); + if (!strict_check_call(type->str, args->str)) { struct pike_string *type_t = describe_type(type); - yywarning("Arguments not strictly compatible."); - yywarning("Expected: %s", type_t->str); - yywarning("Got : %s", arg_t->str); + + if (!low_pike_types_le(type->str, tFunction, 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_string(type_t); - free_string(arg_t); } } return pop_unfinished_type();