From a946c7dadca16dc50c7b20489d44993d82ca082a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Mon, 2 Mar 1998 08:06:59 -0800 Subject: [PATCH] better type checking Rev: src/builtin_functions.c:1.77 Rev: src/pike_types.c:1.35 --- src/builtin_functions.c | 6 +- src/pike_types.c | 144 ++++++++++++++++++++++++++++------------ 2 files changed, 106 insertions(+), 44 deletions(-) diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 0b28901cf9..cbdf3a5357 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.76 1998/03/01 11:40:46 hubbe Exp $"); +RCSID("$Id: builtin_functions.c,v 1.77 1998/03/02 16:06:58 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -262,7 +262,7 @@ void f_search(INT32 args) return; default: - error("Bad argument 2 to search()\n"); + error("Bad argument 1 to search()\n"); } } @@ -2387,7 +2387,7 @@ void init_builtin_efuns(void) add_efun("aggregate_multiset",f_aggregate_multiset,"function(0=mixed ...:multiset(0))",OPT_TRY_OPTIMIZE); add_efun("aggregate_mapping",f_aggregate_mapping,"function(0=mixed ...:mapping(0:0))",OPT_TRY_OPTIMIZE); add_efun("all_constants",f_all_constants,"function(:mapping(string:mixed))",OPT_EXTERNAL_DEPEND); - add_efun("allocate", f_allocate, "function(int,void|mixed:array)", 0); + add_efun("allocate", f_allocate, "function(int,void|0=mixed:array(0))", 0); add_efun("arrayp", f_arrayp, "function(mixed:int)",0); add_efun("backtrace",f_backtrace,"function(:array(array(function|int|string)))",OPT_EXTERNAL_DEPEND); diff --git a/src/pike_types.c b/src/pike_types.c index 287148ef40..a493100bdd 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: pike_types.c,v 1.34 1998/03/01 11:40:47 hubbe Exp $"); +RCSID("$Id: pike_types.c,v 1.35 1998/03/02 16:06:59 hubbe Exp $"); #include <ctype.h> #include "svalue.h" #include "pike_types.h" @@ -61,12 +61,24 @@ struct pike_string *mixed_type_string; struct pike_string *void_type_string; struct pike_string *any_type_string; -static char *a_markers[10],*b_markers[10]; +static struct pike_string *a_markers[10],*b_markers[10]; static void clear_markers() { unsigned int e; - for(e=0;e<NELEM(a_markers);e++) a_markers[e]=b_markers[e]=0; + 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; + } + } } #ifdef DEBUG @@ -233,7 +245,7 @@ void push_unfinished_type(char *s) for(e--;e>=0;e--) push_type(s[e]); } -static void push_unfinished_type_with_markers(char *s, char **am) +static void push_unfinished_type_with_markers(char *s, struct pike_string **am) { int e; e=type_length(s); @@ -243,7 +255,7 @@ static void push_unfinished_type_with_markers(char *s, char **am) { if(am[s[e]-'0']) { - push_unfinished_type(am[s[e]-'0']); + push_finished_type(am[s[e]-'0']); }else{ push_type(T_MIXED); } @@ -450,7 +462,7 @@ static void internal_parse_typeB(char **s) case '(': ++*s; - internal_parse_typeB(s); + internal_parse_type(s); while(ISSPACE(**((unsigned char **)s))) ++*s; if(**s != ')') error("Expecting ')'.\n"); break; @@ -736,6 +748,73 @@ TYPE_T compile_type_to_runtime_type(struct pike_string *s) return low_compile_type_to_runtime_type(s->str); } + +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(); +} + + #define A_EXACT 1 #define B_EXACT 2 #define NO_MAX_ARGS 4 @@ -773,13 +852,13 @@ static char *low_match_types(char *a,char *b, int flags) case T_ASSIGN: ret=low_match_types(a+2,b,flags); - if(ret) + if(ret && EXTRACT_UCHAR(b)!=T_VOID) { int m=EXTRACT_UCHAR(a+1)-'0'; - if(!a_markers[m]) - a_markers[m]=b; - else if(!low_is_same_type(a_markers[m], b)) - a_markers[m]=mixed_type_string->str; + 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(); } return ret; @@ -788,7 +867,7 @@ static char *low_match_types(char *a,char *b, int flags) { int m=EXTRACT_UCHAR(a)-'0'; if(a_markers[m]) - return low_match_types(a_markers[m], b, flags); + return low_match_types(a_markers[m]->str, b, flags); else return low_match_types(mixed_type_string->str, b, flags); } @@ -817,13 +896,13 @@ static char *low_match_types(char *a,char *b, int flags) case T_ASSIGN: ret=low_match_types(a,b+2,flags); - if(ret) + if(ret && EXTRACT_UCHAR(a)!=T_VOID) { int m=EXTRACT_UCHAR(b+1)-'0'; - if(!b_markers[m]) - b_markers[m]=a; - else if(!low_is_same_type(b_markers[m], a)) - b_markers[m]=mixed_type_string->str; + 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(); } return ret; @@ -832,7 +911,7 @@ static char *low_match_types(char *a,char *b, int flags) { int m=EXTRACT_UCHAR(b)-'0'; if(b_markers[m]) - return low_match_types(a, b_markers[m], flags); + return low_match_types(a, b_markers[m]->str, flags); else return low_match_types(a, mixed_type_string->str, flags); } @@ -978,25 +1057,9 @@ static int low_get_return_type(char *a,char *b) else pop_stack_mark(); - if(o1 == o2) - { - if(!o1) - { - return 0; - }else{ - push_finished_type(o1); - } - } - else if(o1 == mixed_type_string || o2 == mixed_type_string) - { - push_type(T_MIXED); - } - else - { - if(o1) push_finished_type(o1); - if(o2) push_finished_type(o2); - if(o1 && o2) push_type(T_OR); - } + if(!o1 && !o2) return 0; + + medium_or_pike_types(o1,o2); if(o1) free_string(o1); if(o2) free_string(o2); @@ -1114,11 +1177,10 @@ static struct pike_string *debug_low_index_type(char *t, node *n) b=low_index_type(t,n); if(!b) return a; if(!a) return b; - push_finished_type(b); - push_finished_type(a); + type_stack_mark(); + medium_or_pike_types(a,b); free_string(a); free_string(b); - push_type(T_OR); return pop_unfinished_type(); } @@ -1148,7 +1210,7 @@ static struct pike_string *debug_low_index_type(char *t, node *n) if(low_match_types(int_type_string->str,CDR(n)->type->str,0)) { push_unfinished_type(t); - push_type(T_OR); + push_type(T_OR); } return pop_unfinished_type(); }else{ -- GitLab