From 1a8209aa2bc0030628660753dba2d7c3a9ee3d1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?= <grubba@grubba.org> Date: Tue, 17 Apr 2007 12:47:14 +0200 Subject: [PATCH] Improved the joining capabilities of or_pike_types() et al some more. Rev: src/pike_types.c:1.289 --- src/pike_types.c | 209 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 154 insertions(+), 55 deletions(-) diff --git a/src/pike_types.c b/src/pike_types.c index 357c2d7eae..1943a43b09 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: pike_types.c,v 1.288 2007/04/16 18:51:44 grubba Exp $ +|| $Id: pike_types.c,v 1.289 2007/04/17 10:47:14 grubba Exp $ */ #include "global.h" @@ -213,7 +213,7 @@ static void internal_parse_type(const char **s); * RING type type * TUPLE type type * MAPPING index type value type - * OR type type + * OR type (not OR) type * AND type type * ARRAY type - * MULTISET type - @@ -2276,8 +2276,12 @@ static void low_or_pike_types(struct pike_type *t1, */ static int lower_or_pike_types(struct pike_type *t1, struct pike_type *t2, - int zero_implied) + int zero_implied, + int elem_on_stack) { + int ret = 0; + struct pike_type *t = NULL; + struct pike_type *top = NULL; #if 0 fprintf(stderr, " lower_or_pike_types("); simple_describe_type(t1); @@ -2286,17 +2290,15 @@ static int lower_or_pike_types(struct pike_type *t1, fprintf(stderr, ")\n"); #endif if (t1 == t2) { - push_finished_type(t1); - return 0; + t = t1; } else if (zero_implied && (t1->type == T_MIXED || t2->type == T_MIXED)) { - push_type(T_MIXED); - return 0; + t = mixed_type_string; } else if (t1->type < t2->type) { - push_finished_type(t1); - return -1; + t = t1; + ret = -1; } else if (t1->type > t2->type) { - push_finished_type(t2); - return 1; + t = t2; + ret = 1; } else { #ifdef PIKE_DEBUG if (t1->type != t2->type) { @@ -2306,11 +2308,93 @@ static int lower_or_pike_types(struct pike_type *t1, #endif /* PIKE_DEBUG */ switch(t1->type) { case T_INT: + if (CAR_TO_INT(t1) < CAR_TO_INT(t2)) { + t = t1; + ret = -1; + } else { + t = t2; + ret = 1; + } + break; + case T_STRING: { - INT32 min1 = CAR_TO_INT(t1); - INT32 max1 = CDR_TO_INT(t1); - INT32 min2 = CAR_TO_INT(t2); - INT32 max2 = CDR_TO_INT(t2); + INT32 w1 = CAR_TO_INT(t1); + INT32 w2 = CAR_TO_INT(t2); + if (w1 >= w2) { + t = t1; + } else { + t = t2; + } + } + break; + case T_OBJECT: + if (!CDR_TO_INT(t1)) { + t = t1; + } else if (!CDR_TO_INT(t2)) { + t = t2; + } else if (CDR_TO_INT(t1) < CDR_TO_INT(t2)) { + t = t1; + ret = -1; + } else { + t = t2; + ret = 1; + } + break; + case T_MAPPING: + if (t1->car->type < t2->car->type) { + t = t1; + ret = -1; + break; + } + if (t1->car->type > t2->car->type) { + t = t2; + ret = 1; + break; + } + if (t1->cdr->type < t2->cdr->type) { + t = t1; + ret = -1; + break; + } + if (t1->cdr->type > t2->cdr->type) { + t = t2; + ret = 1; + break; + } + t = t1; + ret = -1; + break; + case T_ARRAY: + case T_MULTISET: + if (t1->car->type < t2->car->type) { + t = t1; + ret = -1; + break; + } else if (t1->car->type > t2->car->type) { + t = t2; + ret = 1; + break; + } + /* FALL_THOUGH */ + default: + t = t1; + ret = -1; + break; + } + } + if (!elem_on_stack || ((top = peek_type_stack())->type != t->type)) { + push_finished_type(t); + } else { + switch(t->type) { + case T_FLOAT: + /* There can only be one. */ + break; + case T_INT: + { + INT32 min1 = CAR_TO_INT(t); + INT32 max1 = CDR_TO_INT(t); + INT32 min2 = CAR_TO_INT(top); + INT32 max2 = CDR_TO_INT(top); if (zero_implied) { if (min1 == 1) min1 = 0; @@ -2319,67 +2403,80 @@ static int lower_or_pike_types(struct pike_type *t1, if (max2 == -1) max2 = 0; } - if ((max1 < min2) && (max1 + 1 < min2)) { + if ((min1 > max2) && (min1 > max2 + 1)) { /* No overlap. */ - push_finished_type(t1); - return -1; - } else if ((min1 > max2) && (min1 > max2 + 1)) { - /* No overlap. */ - push_finished_type(t2); - return 1; + push_finished_type(t); +#ifdef PIKE_DEBUG + } else if ((min2 > max1) && (min2 > max1 + 1)) { + /* No overlap and wrong order! */ + Pike_fatal("Bad integer ordering in lower_or_pike_types().\n"); +#endif } else { + Pike_compiler->type_stackp--; + free_type(top); /* Overlap */ min1 = MINIMUM(min1, min2); max1 = MAXIMUM(max1, max2); push_int_type(min1, max1); - return 0; } } break; case T_STRING: { - INT32 w1 = CAR_TO_INT(t1); - INT32 w2 = CAR_TO_INT(t2); + INT32 w1 = CAR_TO_INT(t); + INT32 w2 = CAR_TO_INT(top); if (w1 >= w2) { - push_finished_type(t1); - } else { - push_finished_type(t2); + Pike_compiler->type_stackp--; + free_type(top); + push_finished_type(t); } } - return 0; + break; + case T_OBJECT: + if (CDR_TO_INT(top)) { + push_finished_type(t); + } + break; case T_ARRAY: case T_MULTISET: - { - low_or_pike_types(t1->car, t2->car, zero_implied); - push_type(t1->type); - return 0; - } + Pike_compiler->type_stackp--; + low_or_pike_types(t->car, top->car, zero_implied); + push_type(t->type); + free_type(top); + break; case T_SCOPE: - low_or_pike_types(t1->cdr, t2->cdr, zero_implied); - if (CAR_TO_INT(t1) > CAR_TO_INT(t2)) - push_scope_type(CAR_TO_INT(t1)); + Pike_compiler->type_stackp--; + low_or_pike_types(t->cdr, top->cdr, zero_implied); + if (CAR_TO_INT(t) > CAR_TO_INT(top)) + push_scope_type(CAR_TO_INT(t)); else - push_scope_type(CAR_TO_INT(t2)); - return 0; + push_scope_type(CAR_TO_INT(top)); + free_type(top); + break; case T_MAPPING: - if (t1->car == t2->car) { - push_finished_type(t1->car); - low_or_pike_types(t1->cdr, t2->cdr, zero_implied); + if (t->car == top->car) { + Pike_compiler->type_stackp--; + push_finished_type(t->car); + low_or_pike_types(t->cdr, top->cdr, zero_implied); push_reverse_type(T_MAPPING); - return 0; - } else if (t1->cdr == t2->cdr) { - push_finished_type(t1->cdr); - low_or_pike_types(t1->car, t2->car, zero_implied); + free_type(top); + break; + } else if (t->cdr == top->cdr) { + Pike_compiler->type_stackp--; + push_finished_type(t->cdr); + low_or_pike_types(t->car, top->car, zero_implied); push_type(T_MAPPING); - return 0; + free_type(top); + break; } /* FALL_THROUGH */ default: - push_finished_type(t1); - return -1; + push_finished_type(t); + break; } } + return ret; } static void low_or_pike_types(struct pike_type *t1, @@ -2419,7 +2516,8 @@ static void low_or_pike_types(struct pike_type *t1, push_finished_type(t1); } else if (t1->type == T_OR) { - int type_cnt = 0; + int on_stack = 0; + type_stack_mark(); while (t1 || t2) { if (!t1) { if (t2->type == T_OR) { @@ -2465,22 +2563,23 @@ static void low_or_pike_types(struct pike_type *t1, Pike_fatal("Invalid type to lower_or_pike_types!\n"); } #endif - val = lower_or_pike_types(a, b, zero_implied); + val = lower_or_pike_types(a, b, zero_implied, on_stack); if (val <= 0) t1 = n1; if (val >= 0) t2 = n2; } - type_cnt++; + on_stack = 1; } - while (type_cnt > 1) { + on_stack = pop_stack_mark(); + while (on_stack > 1) { push_reverse_joiner_type(T_OR); - type_cnt--; + on_stack--; } } else if (t2->type == T_OR) { low_or_pike_types(t2, t1, zero_implied); } else { - int val = lower_or_pike_types(t1, t2, zero_implied); + int val = lower_or_pike_types(t1, t2, zero_implied, 0); if (val < 0) { push_finished_type(t2); push_reverse_joiner_type(T_OR); -- GitLab