diff --git a/src/interpret.c b/src/interpret.c index 6b1669d11f19005aa1f238fdbcaba22612cabaa9..5aba4fb120fe8d9736d79b5fff91c66d83ab61ff 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: interpret.c,v 1.125 1999/05/13 07:24:51 hubbe Exp $"); +RCSID("$Id: interpret.c,v 1.126 1999/06/03 01:39:33 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -993,7 +993,7 @@ void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2) /* adjust arguments on stack */ if(args < num_args) /* push zeros */ { - clear_svalues(sp, num_args-args); + clear_svalues_undefined(sp, num_args-args); sp += num_args-args; args += num_args-args; } diff --git a/src/las.c b/src/las.c index fa701e0361e5e65ddde5470556bf0f54c2339861..4017ffcd3237285c65c44a2c68f0aa366f05f2df 100644 --- a/src/las.c +++ b/src/las.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: las.c,v 1.80 1999/05/01 17:53:00 grubba Exp $"); +RCSID("$Id: las.c,v 1.81 1999/06/03 01:39:35 hubbe Exp $"); #include "language.h" #include "interpret.h" @@ -2409,7 +2409,8 @@ static int is_null_branch(node *n) static struct svalue *is_stupid_func(node *n, int args, - int vargs) + int vargs, + struct pike_string *type) { node *a,*b; int tmp; @@ -2445,10 +2446,13 @@ static struct svalue *is_stupid_func(node *n, n=CAR(n); if(!n || n->token != F_CONSTANT) return 0; - if((count_arguments(n->type) < 0) == !!vargs) - return &n->u.sval; + if((count_arguments(n->type) < 0) == !vargs) + return 0; + + if(minimum_arguments(type) < minimum_arguments(n->type)) + return 0; - return 0; + return &n->u.sval; } int dooptcode(struct pike_string *name, @@ -2488,7 +2492,7 @@ int dooptcode(struct pike_string *name, }else{ n=mknode(F_ARG_LIST,n,0); - if((foo=is_stupid_func(n, args, vargs))) + if((foo=is_stupid_func(n, args, vargs, type))) { if(foo->type == T_FUNCTION && foo->subtype==FUNCTION_BUILTIN) { diff --git a/src/pike_types.c b/src/pike_types.c index 68236c7f12bcb21029c5fcb16315e26107a3cf2e..4c1d357aa0ecda013094bc859569c2a3ed21667b 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.55 1999/04/13 20:10:09 hubbe Exp $"); +RCSID("$Id: pike_types.c,v 1.56 1999/06/03 01:39:36 hubbe Exp $"); #include <ctype.h> #include "svalue.h" #include "pike_types.h" @@ -1696,6 +1696,52 @@ int count_arguments(struct pike_string *s) return low_count_arguments(s->str); } + +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. + */ +int minimum_arguments(struct pike_string *s) +{ + 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; +} + struct pike_string *check_call(struct pike_string *args, struct pike_string *type) { diff --git a/src/pike_types.h b/src/pike_types.h index 42b74723a4cec5a0f599358315317f5dc77224d9..6ba0dd38c63ba092d89f20e59302b81d20d3b3a9 100644 --- a/src/pike_types.h +++ b/src/pike_types.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: pike_types.h,v 1.19 1999/04/13 20:10:10 hubbe Exp $ + * $Id: pike_types.h,v 1.20 1999/06/03 01:39:37 hubbe Exp $ */ #ifndef PIKE_TYPES_H #define PIKE_TYPES_H @@ -125,6 +125,7 @@ int check_indexing(struct pike_string *type, struct pike_string *index_type, node *n); int count_arguments(struct pike_string *s); +int minimum_arguments(struct pike_string *s); struct pike_string *check_call(struct pike_string *args, struct pike_string *type); INT32 get_max_args(struct pike_string *type); diff --git a/src/svalue.c b/src/svalue.c index 9d700a8e44ee6bee17650865b6647da94ac08831..f0a5a406c775ea5c9b350a34df5cc6826c199012 100644 --- a/src/svalue.c +++ b/src/svalue.c @@ -22,7 +22,7 @@ #include <ctype.h> #include "queue.h" -RCSID("$Id: svalue.c,v 1.41 1999/04/01 17:22:18 hubbe Exp $"); +RCSID("$Id: svalue.c,v 1.42 1999/06/03 01:39:38 hubbe Exp $"); struct svalue dest_ob_zero = { T_INT, 0 }; @@ -879,6 +879,16 @@ void clear_svalues(struct svalue *s, INT32 num) while(--num >= 0) *(s++)=dum; } +void clear_svalues_undefined(struct svalue *s, INT32 num) +{ + struct svalue dum; + dum.type=T_INT; + dum.subtype=NUMBER_UNDEFINED; + dum.u.refs=0; + dum.u.integer=0; + while(--num >= 0) *(s++)=dum; +} + void copy_svalues_recursively_no_free(struct svalue *to, struct svalue *from, INT32 num, diff --git a/src/svalue.h b/src/svalue.h index 5086d1402547e7a2c0b00abe4ace94d3c20836e1..ff14b2ba47d97f0c69bb66a17d5a872845cfd7c3 100644 --- a/src/svalue.h +++ b/src/svalue.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: svalue.h,v 1.26 1999/04/17 22:37:33 grubba Exp $ + * $Id: svalue.h,v 1.27 1999/06/03 01:39:39 hubbe Exp $ */ #ifndef SVALUE_H #define SVALUE_H @@ -294,6 +294,7 @@ int is_equal(struct svalue *a,struct svalue *b); int is_lt(struct svalue *a,struct svalue *b); void describe_svalue(struct svalue *s,int indent,struct processing *p); void clear_svalues(struct svalue *s, INT32 num); +void clear_svalues_undefined(struct svalue *s, INT32 num); void copy_svalues_recursively_no_free(struct svalue *to, struct svalue *from, INT32 num,