e576bb | 2002-10-11 | Martin Nilsson | | /*
|| 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.
*/
|
aedfb1 | 2002-10-09 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "global.h"
#include <ctype.h>
#include "svalue.h"
#include "stralloc.h"
|
4d404a | 2013-02-19 | Henrik Grubbström (Grubba) | | #include "pike_types.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "array.h"
#include "program.h"
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | #include "constants.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "object.h"
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | #include "multiset.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "mapping.h"
|
bb55f8 | 1997-03-16 | Fredrik Hübinette (Hubbe) | | #include "pike_macros.h"
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | #include "pike_error.h"
|
b8cda2 | 1997-01-21 | Fredrik Hübinette (Hubbe) | | #include "las.h"
|
93dd41 | 1999-11-23 | Henrik Grubbström (Grubba) | | #include "lex.h"
|
9aa6fa | 1997-05-19 | Fredrik Hübinette (Hubbe) | | #include "pike_memory.h"
|
6c3940 | 1999-10-28 | Fredrik Hübinette (Hubbe) | | #include "bignum.h"
|
fbafd0 | 1999-12-12 | Henrik Grubbström (Grubba) | | #include "main.h"
|
f76b4c | 2000-05-11 | Henrik Grubbström (Grubba) | | #include "opcodes.h"
|
e026a7 | 2004-03-10 | Henrik Grubbström (Grubba) | | #include "cyclic.h"
|
16c569 | 2007-03-31 | Henrik Grubbström (Grubba) | | #include "gc.h"
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | #include "pike_compiler.h"
|
d47659 | 2013-06-12 | Arne Goedeke | | #include "block_allocator.h"
|
8079a4 | 2014-01-11 | Tobias S. Josefowitz | | #include "bitvector.h"
|
c1835b | 2017-11-11 | Tobias S. Josefowitz | | #include "gc_header.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
552858 | 2000-12-01 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
f37a21 | 2002-08-14 | Henrik Grubbström (Grubba) | | #define PIKE_TYPE_DEBUG
|
552858 | 2000-12-01 | Henrik Grubbström (Grubba) | | #endif /* PIKE_DEBUG */
|
02f063 | 1999-11-24 | Fredrik Hübinette (Hubbe) | |
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* Number of entries in the struct pike_type hash-table. */
|
830d98 | 2015-12-10 | Per Hedbor | | /* 256Kb */
#define PIKE_TYPE_HASH_SIZE 32767
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
#ifdef PIKE_TYPE_DEBUG
static int indent=0;
#endif
|
1d5328 | 1996-11-25 | Fredrik Hübinette (Hubbe) | | int max_correct_args;
|
daea6d | 2007-03-20 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_type *string0_type_string;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_type *string_type_string;
PMOD_EXPORT struct pike_type *int_type_string;
|
218dba | 2020-01-08 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_type *int_pos_type_string;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_type *float_type_string;
PMOD_EXPORT struct pike_type *function_type_string;
|
6901f2 | 2020-09-25 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_type *void_function_type_string;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_type *object_type_string;
PMOD_EXPORT struct pike_type *program_type_string;
PMOD_EXPORT struct pike_type *array_type_string;
PMOD_EXPORT struct pike_type *multiset_type_string;
PMOD_EXPORT struct pike_type *mapping_type_string;
PMOD_EXPORT struct pike_type *type_type_string;
PMOD_EXPORT struct pike_type *mixed_type_string;
PMOD_EXPORT struct pike_type *void_type_string;
PMOD_EXPORT struct pike_type *zero_type_string;
|
38f931 | 2014-05-03 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_type *inheritable_type_string;
PMOD_EXPORT struct pike_type *typeable_type_string;
|
d6f6d6 | 2013-11-08 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_type *enumerable_type_string;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_type *any_type_string;
PMOD_EXPORT struct pike_type *weak_type_string; /* array|mapping|multiset|function */
|
6f16cb | 2008-05-18 | Henrik Grubbström (Grubba) | | struct pike_type *sscanf_type_string;
|
187405 | 2018-04-21 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_type *utf8_type_string;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
68ec3f | 2014-08-18 | Martin Nilsson | | PMOD_EXPORT struct pike_string *literal_string_string;
PMOD_EXPORT struct pike_string *literal_int_string;
PMOD_EXPORT struct pike_string *literal_float_string;
PMOD_EXPORT struct pike_string *literal_function_string;
PMOD_EXPORT struct pike_string *literal_object_string;
PMOD_EXPORT struct pike_string *literal_program_string;
PMOD_EXPORT struct pike_string *literal_array_string;
PMOD_EXPORT struct pike_string *literal_multiset_string;
PMOD_EXPORT struct pike_string *literal_mapping_string;
PMOD_EXPORT struct pike_string *literal_type_string;
PMOD_EXPORT struct pike_string *literal_mixed_string;
|
940501 | 2007-04-26 | Martin Stjernholm | | #ifdef DO_PIKE_CLEANUP
|
94b2fb | 2001-03-28 | Henrik Grubbström (Grubba) | | struct pike_type_location *all_pike_type_locations = NULL;
|
940501 | 2007-04-26 | Martin Stjernholm | | #endif /* DO_PIKE_CLEANUP */
|
94b2fb | 2001-03-28 | Henrik Grubbström (Grubba) | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | static struct pike_type *a_markers[10], *b_markers[10];
static struct program *implements_a;
static struct program *implements_b;
|
da371d | 2003-11-18 | Henrik Grubbström (Grubba) | | static int implements_mode;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
#ifdef PIKE_DEBUG
|
d4d96c | 2020-09-09 | Henrik Grubbström (Grubba) | | void TYPE_STACK_DEBUG(const char *fun)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
d4d96c | 2020-09-09 | Henrik Grubbström (Grubba) | | if (l_flag > 2) {
fprintf(stderr, "%25s(): stack_depth:%-3ld mark_stack_depth:%ld\n",
fun, (long)(Pike_compiler->type_stackp - type_stack),
(long)(Pike_compiler->pike_type_mark_stackp -
pike_type_mark_stack));
if (Pike_compiler->type_stackp != type_stack) {
fprintf(stderr, "%25s : top: ", "");
simple_describe_type(peek_type_stack());
fprintf(stderr, "\n");
}
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
static void clear_markers(void)
{
unsigned int e;
for(e=0;e<NELEM(a_markers);e++)
{
if(a_markers[e])
{
free_type(a_markers[e]);
a_markers[e]=0;
}
if(b_markers[e])
{
free_type(b_markers[e]);
b_markers[e]=0;
}
}
}
|
38a96a | 2020-01-04 | Henrik Grubbström (Grubba) | | void compiler_discard_top_type(void)
{
TYPE_STACK_DEBUG("discard_top_type");
#ifdef PIKE_DEBUG
|
1d54a1 | 2020-05-19 | Henrik Grubbström (Grubba) | | if (pike_type_mark_stack == Pike_compiler->pike_type_mark_stackp) {
/* Type mark stack empty. */
if (type_stack == Pike_compiler->type_stackp)
Pike_fatal("Type stack underflow.\n");
} else if (!peek_stack_mark())
|
38a96a | 2020-01-04 | Henrik Grubbström (Grubba) | | Pike_fatal("Type stack underflow.\n");
#endif
free_type(*(Pike_compiler->type_stackp--));
}
|
884b6f | 2008-06-17 | Martin Stjernholm | | void compiler_discard_type (void)
{
ptrdiff_t len = pop_stack_mark();
|
38a96a | 2020-01-04 | Henrik Grubbström (Grubba) | | TYPE_STACK_DEBUG("discard_type");
|
884b6f | 2008-06-17 | Martin Stjernholm | | for (;len > 0; len--) {
/* Get rid of excess junk. */
|
38a96a | 2020-01-04 | Henrik Grubbström (Grubba) | | compiler_discard_top_type();
|
884b6f | 2008-06-17 | Martin Stjernholm | | }
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | struct pike_type *debug_pop_type(void)
{
struct pike_type *t = pop_unfinished_type();
TYPE_STACK_DEBUG("pop_type");
type_stack_mark();
return t;
}
struct pike_type *debug_compiler_pop_type(void)
{
TYPE_STACK_DEBUG("compiler_pop_type");
if(Pike_compiler->num_parse_error)
{
|
526100 | 2004-03-12 | Henrik Grubbström (Grubba) | | struct pike_type *res;
|
884b6f | 2008-06-17 | Martin Stjernholm | | compiler_discard_type();
add_ref(res = mixed_type_string);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | type_stack_mark();
|
526100 | 2004-03-12 | Henrik Grubbström (Grubba) | | return res;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }else{
return debug_pop_type();
}
}
|
e68c78 | 2006-07-05 | Martin Stjernholm | | PMOD_EXPORT char *get_name_of_type(TYPE_T t)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(t & PIKE_T_MASK)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
97a733 | 2008-03-30 | Martin Stjernholm | | case T_ARRAY: return "array";
case T_MAPPING: return "mapping";
case T_MULTISET: return "multiset";
case T_OBJECT: return "object";
case T_FUNCTION: return "function";
case T_PROGRAM: return "program";
case T_STRING: return "string";
case T_TYPE: return "type";
case T_INT: return "int";
case T_FLOAT: return "float";
case T_ZERO: return "zero";
case T_VOID: return "void";
case T_MIXED: return "mixed";
default: return "unknown";
#ifdef PIKE_DEBUG
/* Let's make it able to describe any type constant in debug mode. */
case T_UNFINISHED: return "T_UNFINISHED";
case T_MANY: return "T_MANY";
case PIKE_T_INT_UNTYPED: return "PIKE_T_INT_UNTYPED";
case PIKE_T_GET_SET: return "PIKE_T_GET_SET";
case PIKE_T_FREE: return "PIKE_T_FREE";
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | case PIKE_T_FUNCTION_ARG: return "PIKE_T_FUNCTION_ARG";
|
0a3d9f | 2020-07-18 | Henrik Grubbström (Grubba) | |
case PIKE_T_FIND_LFUN: return "PIKE_T_FIND_LFUN";
|
97a733 | 2008-03-30 | Martin Stjernholm | | case PIKE_T_ATTRIBUTE: return "PIKE_T_ATTRIBUTE";
case PIKE_T_NSTRING: return "PIKE_T_NSTRING";
|
d78593 | 2020-01-14 | Henrik Grubbström (Grubba) | | case PIKE_T_LSTRING: return "PIKE_T_LSTRING";
case PIKE_T_LARRAY: return "PIKE_T_LARRAY";
|
97a733 | 2008-03-30 | Martin Stjernholm | | case PIKE_T_RING: return "PIKE_T_RING";
case PIKE_T_NAME: return "PIKE_T_NAME";
case PIKE_T_SCOPE: return "PIKE_T_SCOPE";
case PIKE_T_TUPLE: return "PIKE_T_TUPLE";
case T_ASSIGN: return "T_ASSIGN";
case T_DELETED: return "T_DELETED";
case PIKE_T_UNKNOWN: return "PIKE_T_UNKNOWN";
case T_OBJ_INDEX: return "T_OBJ_INDEX";
case T_SVALUE_PTR: return "T_SVALUE_PTR";
case T_ARRAY_LVALUE: return "T_ARRAY_LVALUE";
case T_NOT: return "T_NOT";
case T_AND: return "T_AND";
case T_OR: return "T_OR";
case T_STORAGE: return "object storage";
case T_MAPPING_DATA: return "mapping_data";
case T_PIKE_FRAME: return "pike_frame";
case T_MULTISET_DATA: return "multiset_data";
case T_STRUCT_CALLABLE: return "callable";
#endif
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
#define TWOT(X,Y) (((X) << 8)+(Y))
static int low_pike_types_le(struct pike_type *a, struct pike_type *b,
int array_cnt, unsigned int flags);
static int low_check_indexing(struct pike_type *type,
struct pike_type *index_type,
node *n);
|
0929a0 | 2002-09-12 | Marcus Comstedt | | static void internal_parse_type(const char **s);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
/*
* New and improved type representation system.
*
* This representation is new in Pike 7.3.
*
* Node: Car: Cdr:
* ---------------------------------------------
* SCOPE num vars (int) type
* ASSIGN variable (int) type
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | * NAME name (string) type
|
64ac75 | 2007-11-03 | Henrik Grubbström (Grubba) | | * ATTRIBUTE name (string) type Added in 7.7.
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | * FUNCTION type FUNCTION|MANY
* MANY many type return type
|
64ac75 | 2007-11-03 | Henrik Grubbström (Grubba) | | * RING type type Reserved.
* TUPLE type type Reserved.
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | * MAPPING index type value type
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | * OR type (not OR) type
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | * AND type type
|
16edb9 | 2020-01-03 | Henrik Grubbström (Grubba) | | * ARRAY len type type len added in 8.1
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | * MULTISET type -
* NOT type -
* '0'-'9' - -
* FLOAT - -
|
16edb9 | 2020-01-03 | Henrik Grubbström (Grubba) | | * STRING len type ZERO, INT or OR len:8.1, Range:7.7
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | * TYPE type -
|
6d33d8 | 2001-03-28 | Henrik Grubbström (Grubba) | | * PROGRAM type -
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | * MIXED - -
* VOID - -
* ZERO - -
* UNKNOWN - -
* INT min (int) max (int)
* OBJECT implements/is object id(int)
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | * OPERATOR type Depends on bit #15. Added in 8.1
|
0a3d9f | 2020-07-18 | Henrik Grubbström (Grubba) | | * FIND_LFUN object type lfun (int) Added in 8.1
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | * TRANSITIVE fun_type fun_type Added in 8.1
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | *
* Note that the cdr of a FUNCTION is a valid FUNCTION for the rest of
* the arguments.
*
* Note also that functions that don't take any arguments, or just
* a many argument just have a MANY node, and no FUNCTION node.
*
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | * TRANSITIVE has a car with the current state, and a cdr with the
* function type to apply.
*
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | */
|
d47659 | 2013-06-12 | Arne Goedeke | | static struct block_allocator type_allocator = BA_INIT(sizeof(struct pike_type), 128);
PMOD_EXPORT void really_free_pike_type(struct pike_type * t) {
ba_free(&type_allocator, t);
}
ATTRIBUTE((malloc))
|
3b54e5 | 2014-08-21 | Martin Nilsson | | PMOD_EXPORT struct pike_type * alloc_pike_type(void) {
|
c1835b | 2017-11-11 | Tobias S. Josefowitz | | struct pike_type *t = ba_alloc(&type_allocator);
|
abe64b | 2018-05-19 | Tobias S. Josefowitz | | gc_init_marker(t);
|
c1835b | 2017-11-11 | Tobias S. Josefowitz | | return t;
|
d47659 | 2013-06-12 | Arne Goedeke | | }
PMOD_EXPORT void count_memory_in_pike_types(size_t *n, size_t *s) {
ba_count_all(&type_allocator, n, s);
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
23db45 | 2003-08-20 | Martin Stjernholm | | struct pike_type **pike_type_hash = NULL;
size_t pike_type_hash_size = 0;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | void debug_free_type(struct pike_type *t)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
6c633b | 2019-12-15 | Henrik Grubbström (Grubba) | | if (!t) return;
|
f588b4 | 2003-03-15 | Henrik Grubbström (Grubba) | | #ifdef DEBUG_MALLOC
if (t == (struct pike_type *)(size_t)0x55555555) {
Pike_fatal("Freeing dead type.\n");
}
#endif /* DEBUG_MALLOC */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | loop:
|
50ea68 | 2003-03-14 | Henrik Grubbström (Grubba) | | if (!sub_ref(t)) {
|
64017e | 2013-05-31 | Per Hedbor | | unsigned INT32 hash = t->hash & pike_type_hash_size;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | struct pike_type **t2 = pike_type_hash + hash;
struct pike_type *car, *cdr;
unsigned INT32 type;
|
64017e | 2013-05-31 | Per Hedbor | | #ifdef PIKE_DEBUG
|
878cad | 2005-02-02 | Henrik Grubbström (Grubba) | | /* PIKE_DEBUG code */
|
64017e | 2013-05-31 | Per Hedbor | | if (hash > pike_type_hash_size) {
|
878cad | 2005-02-02 | Henrik Grubbström (Grubba) | | Pike_fatal("Modulo operation failed for hash:%u, index:%u, size:%u.\n",
t->hash, hash, pike_type_hash_size);
}
/* End PIKE_DEBUG code */
|
64017e | 2013-05-31 | Per Hedbor | | #endif
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | while (*t2) {
if (*t2 == t) {
*t2 = t->next;
break;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | t2 = &((*t2)->next);
}
car = t->car;
cdr = t->cdr;
type = t->type;
|
d47659 | 2013-06-12 | Arne Goedeke | | really_free_pike_type((struct pike_type*)debug_malloc_pass(t));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
/* FIXME: Recursion: Should we use a stack? */
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(type & PIKE_T_MASK) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
case T_MANY:
case T_TUPLE:
case T_MAPPING:
case T_OR:
case T_AND:
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_RING:
|
16edb9 | 2020-01-03 | Henrik Grubbström (Grubba) | | case T_ARRAY:
case T_STRING:
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* Free car & cdr */
free_type(car);
|
97a733 | 2008-03-30 | Martin Stjernholm | | t = (struct pike_type *) cdr;
debug_free_type_preamble (t);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | goto loop;
|
5e06a8 | 2016-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_AUTO:
if (!car)
break;
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_MULTISET:
case T_NOT:
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | case T_TYPE:
case T_PROGRAM:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* Free car */
|
97a733 | 2008-03-30 | Martin Stjernholm | | t = (struct pike_type *) car;
debug_free_type_preamble (t);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | goto loop;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_SCOPE:
case T_ASSIGN:
/* Free cdr */
|
97a733 | 2008-03-30 | Martin Stjernholm | | t = (struct pike_type *) cdr;
debug_free_type_preamble (t);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | goto loop;
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | |
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
free_string((struct pike_string *)car);
|
97a733 | 2008-03-30 | Martin Stjernholm | | t = (struct pike_type *) cdr;
debug_free_type_preamble (t);
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | goto loop;
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | |
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | case PIKE_T_OPERATOR:
/* Free car and maybe cdr. */
if (type & 0x8000) {
/* Free cdr. */
free_type(cdr);
}
t = car;
debug_free_type_preamble(t);
goto loop;
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case T_FLOAT:
case T_MIXED:
case T_VOID:
case T_ZERO:
case PIKE_T_UNKNOWN:
case T_INT:
case T_OBJECT:
break;
default:
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("free_type(): Unhandled type-node: %d\n", type);
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | break;
#endif /* PIKE_DEBUG */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
}
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | static inline struct pike_type *debug_mk_type(unsigned INT32 type,
struct pike_type *car,
struct pike_type *cdr,
int flag_method)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | /* FIXME: The hash ought to be based on the tree contents, regardless
* of what the adresses of the type nodes are.
*/
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | struct pike_type *t;
|
13670c | 2015-05-25 | Martin Nilsson | | unsigned INT32 index,
|
bd6739 | 2015-10-14 | Martin Nilsson | | hash = (unsigned INT32)
((ptrdiff_t)type*0x10204081)^
(0x8003*PTR_TO_INT(car))^
~(0x10001*PTR_TO_INT(cdr));
|
64017e | 2013-05-31 | Per Hedbor | |
hash ^= (hash >> 20) ^ (hash >> 12);
hash ^= (hash >> 7) ^ (hash >> 4);
index = hash & pike_type_hash_size;
|
a07104 | 2005-06-03 | Henrik Grubbström (Grubba) | | #ifdef PIKE_EXTRA_DEBUG
static unsigned INT32 extra_debug_index = (unsigned INT32)~0;
#endif /* PIKE_EXTRA_DEBUG */
|
64017e | 2013-05-31 | Per Hedbor | | #ifdef PIKE_DEBUG
|
e87c52 | 2004-03-11 | Henrik Grubbström (Grubba) | | /* PIKE_DEBUG code */
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | if ((type & ~PIKE_T_MASK) && ((type & PIKE_T_MASK) != PIKE_T_OPERATOR)) {
|
2148b0 | 2005-02-05 | Henrik Grubbström (Grubba) | | /* The bad type node on OSF/1 seems to be:
*
* type: 0xffff
* car: valid pointer.
* cdr: 0x400000000
* next: 0x100000000
*/
Pike_fatal("Attempt to create an invalid type node: %d(%s)\n"
" car: %p\n"
" cdr: %p\n",
type, get_name_of_type(type),
car, cdr);
}
|
64017e | 2013-05-31 | Per Hedbor | | if (index > pike_type_hash_size) {
|
2d76f2 | 2005-05-20 | Martin Stjernholm | | Pike_fatal("Modulo operation failed for hash:%u, index:%u, "
"size:%"PRINTSIZET"d.\n",
|
e87c52 | 2004-03-11 | Henrik Grubbström (Grubba) | | hash, index, pike_type_hash_size);
}
/* End PIKE_DEBUG code */
|
64017e | 2013-05-31 | Per Hedbor | | #endif
|
a07104 | 2005-06-03 | Henrik Grubbström (Grubba) | | #ifdef PIKE_EXTRA_DEBUG
if ((!~extra_debug_index) &&
(type == T_FUNCTION) &&
(car->type == T_STRING) &&
(cdr->type == T_FUNCTION) &&
(cdr->car->type == T_STRING) &&
(cdr->cdr->type == T_MANY) &&
(cdr->cdr->car->type == T_VOID) &&
(cdr->cdr->cdr->type == T_STRING)) {
/* Attempt to detect why we get a core-dump on OSF/1
* when loading Unicode.so from test_resolv.
*
* The problem triggs when the type for normalize() is created.
* function(string,string:string)
* /grubba 2005-02-04
*
* Load order:
* Module Hashtable status Note
* Nettle.so OK
* ___Oracle.so - load_module() fails.
* Image.so - loads ok.
* Unicode.so FAIL
*
* pike_type node:
* Field Before After
* t 1404b5020 1404b5020
* t->type 4 (function) 65535 (unknown)
* t->car 1404863f8 (1404863f8) 140557560 (1404863f8)
* t->cdr 1404b43d8 (1404b43d8) 400000000 (1404b43d8)
* t->next 0 100000000
* /grubba 2005-06-03
*/
extra_debug_index = index;
}
#endif /* PIKE_EXTRA_DEBUG */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | for(t = pike_type_hash[index]; t; t = t->next) {
|
3841f3 | 2005-02-04 | Henrik Grubbström (Grubba) | | #ifdef PIKE_EXTRA_DEBUG
|
a07104 | 2005-06-03 | Henrik Grubbström (Grubba) | | if (index == extra_debug_index) {
|
2148b0 | 2005-02-05 | Henrik Grubbström (Grubba) | | fprintf(stderr,
" %s:%d:PIKE_EXTRA_DEBUG:\n"
" t: %p\n",
|
3841f3 | 2005-02-04 | Henrik Grubbström (Grubba) | | __FILE__, __LINE__,
t);
|
2148b0 | 2005-02-05 | Henrik Grubbström (Grubba) | | fprintf(stderr,
" t->type:%d (%s)\n"
" t->car: %p (%p)\n"
" t->cdr: %p (%p)\n"
" t->next:%p\n",
|
3841f3 | 2005-02-04 | Henrik Grubbström (Grubba) | | t->type, get_name_of_type(t->type),
t->car, car,
|
2148b0 | 2005-02-05 | Henrik Grubbström (Grubba) | | t->cdr, cdr,
t->next);
|
3841f3 | 2005-02-04 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_EXTRA_DEBUG */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if ((t->hash == hash) && (t->type == type) &&
(t->car == car) && (t->cdr == cdr)) {
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | /* Free car & cdr as appropriate. */
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(type & PIKE_T_MASK) {
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
case T_MANY:
case T_TUPLE:
case T_MAPPING:
case T_OR:
case T_AND:
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_RING:
|
16edb9 | 2020-01-03 | Henrik Grubbström (Grubba) | | case T_ARRAY:
case T_STRING:
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | /* Free car & cdr */
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | free_type((struct pike_type *)debug_malloc_pass(car));
free_type((struct pike_type *)debug_malloc_pass(cdr));
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | break;
case T_MULTISET:
case T_NOT:
|
6d33d8 | 2001-03-28 | Henrik Grubbström (Grubba) | | case T_TYPE:
case T_PROGRAM:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | /* Free car */
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | free_type((struct pike_type *)debug_malloc_pass(car));
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | break;
|
6e0fce | 2013-05-28 | Per Hedbor | | case PIKE_T_AUTO:
if( car )
free_type((struct pike_type *)debug_malloc_pass(car));
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case T_SCOPE:
case T_ASSIGN:
/* Free cdr */
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | free_type((struct pike_type *)debug_malloc_pass(cdr));
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | break;
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | free_string((struct pike_string *)debug_malloc_pass(car));
free_type((struct pike_type *)debug_malloc_pass(cdr));
break;
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | |
case PIKE_T_OPERATOR:
if (type & 0x8000) {
free_type((struct pike_type *)debug_malloc_pass(cdr));
}
free_type((struct pike_type *)debug_malloc_pass(car));
break;
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case T_FLOAT:
case T_MIXED:
case T_VOID:
case T_ZERO:
case PIKE_T_UNKNOWN:
case T_INT:
case T_OBJECT:
break;
default:
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("mk_type(): Unhandled type-node: %d\n", type);
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | break;
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | #endif /* PIKE_DEBUG */
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | }
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | add_ref((struct pike_type *)debug_malloc_pass(t));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return t;
}
}
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | |
#ifdef PIKE_DEBUG
if ((type == T_OR) && (car->type == T_OR)) {
Pike_fatal("Invalid CAR to OR node.\n");
}
#endif
|
13670c | 2015-05-25 | Martin Nilsson | |
|
d47659 | 2013-06-12 | Arne Goedeke | | debug_malloc_pass(t = ba_alloc(&type_allocator));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
50ea68 | 2003-03-14 | Henrik Grubbström (Grubba) | | t->refs = 0;
|
abe64b | 2018-05-19 | Tobias S. Josefowitz | | gc_init_marker(t);
|
50ea68 | 2003-03-14 | Henrik Grubbström (Grubba) | | add_ref(t); /* For DMALLOC... */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | t->type = type;
t->flags = 0;
t->car = car;
t->cdr = cdr;
t->hash = hash;
t->next = pike_type_hash[index];
pike_type_hash[index] = t;
if (flag_method) {
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | if (flag_method == PT_IS_MARKER) {
t->flags = PT_FLAG_MARKER_0 << (type-'0');
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | } else if (type == PIKE_T_SCOPE) {
/* The scope blocks propagation of markers. */
t->flags = cdr->flags & ~(PT_FLAG_MARKER|PT_FLAG_ASSIGN);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
if (car && (flag_method & PT_COPY_CAR)) {
|
ba6fd4 | 2007-05-01 | Henrik Grubbström (Grubba) | | t->flags |= car->flags;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
if (cdr && (flag_method & PT_COPY_CDR)) {
|
ba6fd4 | 2007-05-01 | Henrik Grubbström (Grubba) | | t->flags |= cdr->flags;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
}
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | #ifdef DEBUG_MALLOC
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(type & PIKE_T_MASK) {
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
case T_MANY:
case T_TUPLE:
case T_MAPPING:
case T_OR:
case T_AND:
case PIKE_T_RING:
|
16edb9 | 2020-01-03 | Henrik Grubbström (Grubba) | | case T_ARRAY:
case T_STRING:
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | debug_malloc_pass(car);
debug_malloc_pass(cdr);
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | case T_MULTISET:
case T_NOT:
case T_TYPE:
case T_PROGRAM:
|
5e06a8 | 2016-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_AUTO:
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | debug_malloc_pass(car);
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | case T_ASSIGN:
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | t->flags |= PT_FLAG_ASSIGN_0 << PTR_TO_INT(car);
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | case T_SCOPE:
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | debug_malloc_pass(cdr);
break;
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
debug_malloc_pass(car);
debug_malloc_pass(cdr);
break;
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | case PIKE_T_OPERATOR:
if (type & 0x8000) {
debug_malloc_pass(cdr);
}
debug_malloc_pass(car);
break;
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | case T_FLOAT:
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | case T_MIXED:
case T_VOID:
case T_ZERO:
case PIKE_T_UNKNOWN:
case T_INT:
case T_OBJECT:
break;
default:
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("mk_type(): Unhandled type-node: %d\n", type);
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | break;
}
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | #else /* !DEBUG_MALLOC */
if (type == T_ASSIGN) {
t->flags |= PT_FLAG_ASSIGN_0 << PTR_TO_INT(car);
}
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | #endif /* DEBUG_MALLOC */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return t;
}
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | #ifdef DEBUG_MALLOC
#define mk_type(T,CAR,CDR,FLAG) ((struct pike_type *)debug_malloc_pass(debug_mk_type(T,CAR,CDR,FLAG)))
#else /* !DEBUG_MALLOC */
#define mk_type debug_mk_type
#endif /* DEBUG_MALLOC */
|
18cec0 | 2014-05-22 | Per Hedbor | | struct pike_type **type_stack;
struct pike_type ***pike_type_mark_stack;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
b08494 | 2019-10-17 | Henrik Grubbström (Grubba) | | ptrdiff_t peek_stack_mark(void)
{
if(Pike_compiler->pike_type_mark_stackp-1 < pike_type_mark_stack)
Pike_fatal("Type mark stack underflow\n");
TYPE_STACK_DEBUG("peek_stack_mark");
return Pike_compiler->type_stackp - Pike_compiler->pike_type_mark_stackp[-1];
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | ptrdiff_t pop_stack_mark(void)
|
13670c | 2015-05-25 | Martin Nilsson | | {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | Pike_compiler->pike_type_mark_stackp--;
if(Pike_compiler->pike_type_mark_stackp<pike_type_mark_stack)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Type mark stack underflow\n");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
TYPE_STACK_DEBUG("pop_stack_mark");
return Pike_compiler->type_stackp - *Pike_compiler->pike_type_mark_stackp;
}
void type_stack_pop_to_mark(void)
{
pop_stack_mark();
|
5b368e | 2001-03-31 | Henrik Grubbström (Grubba) | | while(Pike_compiler->type_stackp > *Pike_compiler->pike_type_mark_stackp) {
free_type(*(Pike_compiler->type_stackp--));
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
TYPE_STACK_DEBUG("type_stack_pop_to_mark");
}
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | struct pike_type *debug_peek_type_stack(void)
{
return *(Pike_compiler->type_stackp);
}
|
69aa4b | 2003-01-26 | Mirar (Pontus Hagland) | | void debug_push_int_type(INT_TYPE min, INT_TYPE max)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
271080 | 2003-01-26 | Mirar (Pontus Hagland) | | #if SIZEOF_INT_TYPE > 4
/* a bit kludgy: should maybe really allow 64 bit INT_TYPE */
/* see also extract_type_int */
if (min<MIN_INT32) min=MIN_INT32;
else if (min>MAX_INT32) min=MAX_INT32;
if (max<MIN_INT32) max=MIN_INT32;
else if (max>MAX_INT32) max=MAX_INT32;
#endif
|
483c2f | 2003-11-24 | Henrik Grubbström (Grubba) | |
|
12efe2 | 2014-09-04 | Stephen R. van den Berg | | #ifdef PIKE_DEBUG /* FIXME: Kludge to support 2^32-1 */
|
ce3d2f | 2014-10-01 | Martin Nilsson | | if (((min>0 && max>0) || (min<0 && max<0)) && min > max)
|
483c2f | 2003-11-24 | Henrik Grubbström (Grubba) | | Pike_fatal("push_int_type(): Bad integer range:"
" min:%"PRINTPIKEINT"d, max:%"PRINTPIKEINT"d.\n",
min, max);
#endif /* PIKE_DEBUG */
|
ed0e4d | 2007-04-17 | Henrik Grubbström (Grubba) | |
|
48f1db | 2007-11-03 | Henrik Grubbström (Grubba) | | if (!min && !max) {
/* Special case... */
push_type(T_ZERO);
} else {
*(++Pike_compiler->type_stackp) = mk_type(T_INT,
(void *)(ptrdiff_t)min,
(void *)(ptrdiff_t)max, 0);
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | TYPE_STACK_DEBUG("push_int_type");
}
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | /**
* Used with arrays and strings.
*
* On entry the type stack contains the value type.
*
* Generates an array or string type with no length limits.
*/
void debug_push_unlimited_array_type(enum PIKE_TYPE t)
{
struct compilation * c = MAYBE_THIS_COMPILATION;
#ifdef PIKE_DEBUG
if ((t != PIKE_T_ARRAY) && (t != PIKE_T_STRING)) {
|
908a34 | 2020-01-12 | Henrik Grubbström (Grubba) | | Pike_fatal("Invalid type for push_unlimited_array_type(): %s (%d)\n",
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | get_name_of_type(t), t);
}
#endif
|
ff76fd | 2020-01-21 | Henrik Grubbström (Grubba) | | if (peek_type_stack()->type == PIKE_T_ZERO) {
push_type(PIKE_T_ZERO);
} else {
push_int_type(0, MAX_INT32);
}
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_type(t);
|
087e50 | 2020-08-28 | Henrik Grubbström (Grubba) | |
TYPE_STACK_DEBUG("push_array_type");
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | }
|
007961 | 2014-09-30 | Per Hedbor | | static int (*program_id_to_id)(int) = NULL;
PMOD_EXPORT void set_program_id_to_id( int (*to)(int) )
{
program_id_to_id = to;
}
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | void debug_push_object_type(int flag, INT32 id)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
007961 | 2014-09-30 | Per Hedbor | | if( program_id_to_id )
id = program_id_to_id(id);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | *(++Pike_compiler->type_stackp) = mk_type(T_OBJECT,
(void *)(ptrdiff_t)flag,
(void *)(ptrdiff_t)id, 0);
TYPE_STACK_DEBUG("push_object_type");
}
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | void debug_push_object_type_backwards(int flag, INT32 id)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
push_object_type(flag, id);
}
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | void debug_push_scope_type(int level)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
*Pike_compiler->type_stackp = mk_type(T_SCOPE,
(void *)(ptrdiff_t)level,
*Pike_compiler->type_stackp,
PT_COPY_CDR);
TYPE_STACK_DEBUG("push_scope_type");
}
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | void debug_push_assign_type(int marker)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
9e6f6f | 2001-03-18 | Henrik Grubbström (Grubba) | | marker -= '0';
|
13670c | 2015-05-25 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
9e6f6f | 2001-03-18 | Henrik Grubbström (Grubba) | | if ((marker < 0) || (marker > 9)) {
|
ecdbac | 2003-01-17 | Johan Sundström | | Pike_fatal("Bad assign marker: %d\n", marker);
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
|
9e6f6f | 2001-03-18 | Henrik Grubbström (Grubba) | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | *Pike_compiler->type_stackp = mk_type(T_ASSIGN,
(void *)(ptrdiff_t)marker,
*Pike_compiler->type_stackp,
PT_COPY_CDR);
TYPE_STACK_DEBUG("push_assign_type");
}
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | void debug_push_type_attribute(struct pike_string *attr)
{
/* fprintf(stderr, "push_type_attribute(\"%s\")\n", attr->str); */
add_ref(attr);
*Pike_compiler->type_stackp = mk_type(PIKE_T_ATTRIBUTE,
(void *)attr,
*Pike_compiler->type_stackp,
PT_COPY_CDR);
|
087e50 | 2020-08-28 | Henrik Grubbström (Grubba) | | TYPE_STACK_DEBUG("push_type_attribute");
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | }
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | void debug_push_type_name(struct pike_string *name)
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | {
/* fprintf(stderr, "push_type_name(\"%s\")\n", name->str); */
add_ref(name);
*Pike_compiler->type_stackp = mk_type(PIKE_T_NAME,
(void *)name,
*Pike_compiler->type_stackp,
PT_COPY_CDR);
TYPE_STACK_DEBUG("push_type_name");
}
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | static struct pike_type *apply_type_operator(enum PIKE_TYPE op,
struct pike_type *arg1,
struct pike_type *arg2);
void debug_push_type_operator(enum PIKE_TYPE op, struct pike_type *arg)
{
struct pike_type *t = *Pike_compiler->type_stackp;
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | struct pike_type *tmp;
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | int free_arg = 0;
#ifdef PIKE_DEBUG
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | if ((op & PIKE_T_MASK) != 0x80) {
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | Pike_fatal("Invalid operator for push_operator: 0x%04x\n", op);
}
#endif
if (op & 0x8000) {
if (!arg) {
Pike_compiler->type_stackp--;
arg = *Pike_compiler->type_stackp;
free_arg = 1;
*Pike_compiler->type_stackp = t;
}
}
/* Attempt to propagate the operator towards the leaf nodes. */
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(t->type & PIKE_T_MASK) {
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case T_ASSIGN:
case PIKE_T_OPERATOR:
case PIKE_T_SCOPE:
/* Deferred evaluation. */
if (op & 0x8000) {
*Pike_compiler->type_stackp = mk_type(op,
*Pike_compiler->type_stackp,
arg,
PT_COPY_BOTH);
} else {
*Pike_compiler->type_stackp = mk_type(op,
*Pike_compiler->type_stackp,
arg,
PT_COPY_CAR);
}
break;
case PIKE_T_NAME:
case PIKE_T_ATTRIBUTE:
{
Pike_compiler->type_stackp--;
push_finished_type(t->cdr);
push_type_operator(op, arg);
if (t->type == PIKE_T_NAME) {
push_type_name((struct pike_string *)t->car);
} else {
push_type_attribute((struct pike_string *)t->car);
}
free_type(t);
break;
}
case T_NOT:
{
/* Unary propagate. */
int unop = t->type;
pop_type_stack(t->type);
push_type_operator(op, arg);
push_type(unop);
break;
}
case T_AND:
case T_OR:
{
struct pike_type *tmp;
int binop = t->type;
/* Propagate. */
pop_type_stack(t->type);
tmp = *Pike_compiler->type_stackp;
Pike_compiler->type_stackp--;
push_type_operator(op, arg);
Pike_compiler->type_stackp++;
*Pike_compiler->type_stackp = tmp;
push_type_operator(op, arg);
push_type(binop);
break;
}
default:
*Pike_compiler->type_stackp = apply_type_operator(op, t, arg);
free_type(t);
break;
}
if (free_arg) {
free_type(arg);
}
|
087e50 | 2020-08-28 | Henrik Grubbström (Grubba) | | TYPE_STACK_DEBUG("push_type_operator");
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | }
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | | void debug_push_finished_type(struct pike_type *t)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
be6fec | 2001-04-01 | Henrik Grubbström (Grubba) | | copy_pike_type(*(++Pike_compiler->type_stackp), t);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
TYPE_STACK_DEBUG("push_finished_type");
}
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | static void push_reverse_joiner_type(unsigned int type)
{
/* fprintf(stderr, "push_reverse_joiner_type(%d)\n", type); */
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(type & PIKE_T_MASK) {
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | case T_OR:
case T_AND:
/* Special case: Check if the two top elements are equal. */
if (Pike_compiler->type_stackp[-1] == Pike_compiler->type_stackp[0]) {
free_type(*(Pike_compiler->type_stackp--));
return;
}
/* Make a new type of the top two types. */
--Pike_compiler->type_stackp;
#ifdef PIKE_DEBUG
if ((*Pike_compiler->type_stackp)->type == type) {
Pike_fatal("Invalid CAR to push_reverse_joiner_type().\n");
}
#endif /* PIKE_DEBUG */
*Pike_compiler->type_stackp = mk_type(type,
*Pike_compiler->type_stackp,
*(Pike_compiler->type_stackp+1),
PT_COPY_BOTH);
break;
default:
Pike_fatal("Illegal reverse joiner type: %d\n", type);
}
}
static void low_or_pike_types(struct pike_type *t1,
struct pike_type *t2,
int zero_implied);
|
7e877a | 2003-04-02 | Martin Stjernholm | | void debug_push_type(unsigned int type)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
/* fprintf(stderr, "push_type(%d)\n", type); */
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(type & PIKE_T_MASK) {
|
5a3fd8 | 2005-03-21 | Henrik Grubbström (Grubba) | | case T_OR:
case T_AND:
/* Special case: Check if the two top elements are equal. */
if (Pike_compiler->type_stackp[-1] == Pike_compiler->type_stackp[0]) {
free_type(*(Pike_compiler->type_stackp--));
return;
}
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | if (Pike_compiler->type_stackp[0]->type == type) {
/* The top type is the same as our type.
* Split it and join the parts with the other type.
*/
struct pike_type *top = *(Pike_compiler->type_stackp--);
push_finished_type(top->cdr);
push_type(type);
push_finished_type(top->car);
push_type(type);
free_type(top);
return;
}
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | if (type == T_OR) {
struct pike_type *t1 = *(Pike_compiler->type_stackp--);
struct pike_type *t2 = *(Pike_compiler->type_stackp--);
low_or_pike_types(t1, t2, 0);
free_type(t2);
free_type(t1);
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | return;
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
case T_MANY:
case T_TUPLE:
case T_MAPPING:
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_RING:
|
d2edc3 | 2020-01-07 | Henrik Grubbström (Grubba) | | case T_ARRAY:
case T_STRING:
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* Make a new type of the top two types. */
--Pike_compiler->type_stackp;
*Pike_compiler->type_stackp = mk_type(type,
*(Pike_compiler->type_stackp+1),
*Pike_compiler->type_stackp,
PT_COPY_BOTH);
break;
|
651326 | 2014-02-16 | Henrik Grubbström (Grubba) | | case T_PROGRAM:
if ((*Pike_compiler->type_stackp)->type != T_OBJECT) {
|
90582b | 2014-02-16 | Henrik Grubbström (Grubba) | | struct pike_type *t = (*Pike_compiler->type_stackp);
while ((t->type == PIKE_T_NAME) || (t->type == PIKE_T_ATTRIBUTE)) {
t = t->cdr;
}
if (t->type != T_OBJECT) {
/* Not a program type, convert it to a type type. */
type = T_TYPE;
}
|
651326 | 2014-02-16 | Henrik Grubbström (Grubba) | | }
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_MULTISET:
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | case T_TYPE:
|
ec9bc1 | 2016-05-01 | Henrik Grubbström (Grubba) | | case PIKE_T_AUTO:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* Make a new type of the top type, and put it in car. */
*Pike_compiler->type_stackp = mk_type(type,
*Pike_compiler->type_stackp, NULL,
PT_COPY_CAR);
break;
|
f8b104 | 2020-10-02 | Henrik Grubbström (Grubba) | | case T_NOT:
/* Make a new type of the top type, and put it in car.
*
* Special case: Remove double inversions.
*/
{
struct pike_type *t = *Pike_compiler->type_stackp;
if (t->type == T_NOT) {
*Pike_compiler->type_stackp = t->car;
add_ref(t->car);
free_type(t);
break;
}
*Pike_compiler->type_stackp = mk_type(type, t, NULL, PT_COPY_CAR);
}
break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_SCOPE:
case T_ASSIGN:
case T_INT:
case T_OBJECT:
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | default:
|
408a1e | 2004-10-30 | Martin Stjernholm | | /* Should not occur. */
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | Pike_fatal("Unsupported argument to push_type(): %d\n", type);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | case T_FLOAT:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_MIXED:
case T_VOID:
case T_ZERO:
case PIKE_T_UNKNOWN:
/* Leaf type. */
*(++Pike_compiler->type_stackp) = mk_type(type, NULL, NULL, 0);
break;
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | case PIKE_T_OPERATOR:
push_type_operator(type, NULL);
break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
/* Marker. */
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | *(++Pike_compiler->type_stackp) = mk_type(type, NULL, NULL, PT_IS_MARKER);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
}
TYPE_STACK_DEBUG("push_type");
}
/* Pop one level of types. This is the inverse of push_type() */
|
7e877a | 2003-04-02 | Martin Stjernholm | | void debug_pop_type_stack(unsigned int expected)
|
13670c | 2015-05-25 | Martin Nilsson | | {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | struct pike_type *top;
if(Pike_compiler->type_stackp<type_stack)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Type stack underflow\n");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
2be1db | 2001-04-18 | Henrik Grubbström (Grubba) | | top = *(Pike_compiler->type_stackp);
/* Special case... */
if (top->type == T_MIXED) return; /* Probably due to an earlier error */
Pike_compiler->type_stackp--;
|
5b368e | 2001-03-31 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | if ((top->type != expected) &&
(top->type != PIKE_T_NAME) &&
(top->type != PIKE_T_ATTRIBUTE)) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Unexpected type on stack: %d (expected %d)\n", top->type, expected);
|
5b368e | 2001-03-31 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
/* OPTIMIZE: It looks like this function is always called with
* expected == T_ARRAY.
*/
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(top->type & PIKE_T_MASK) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
case T_MANY:
case T_TUPLE:
case T_MAPPING:
case T_OR:
case T_AND:
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_RING:
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* Both car & cdr. */
push_finished_type(top->cdr);
push_finished_type(top->car);
break;
case T_MULTISET:
case T_NOT:
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | case T_TYPE:
|
6d33d8 | 2001-03-28 | Henrik Grubbström (Grubba) | | case T_PROGRAM:
|
ec9bc1 | 2016-05-01 | Henrik Grubbström (Grubba) | | case PIKE_T_AUTO:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* car */
push_finished_type(top->car);
break;
case T_SCOPE:
case T_ASSIGN:
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | case T_ARRAY:
case T_STRING:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* cdr */
push_finished_type(top->cdr);
break;
case T_INT:
case T_OBJECT:
case T_FLOAT:
case T_MIXED:
case T_VOID:
case T_ZERO:
case PIKE_T_UNKNOWN:
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
/* Leaf */
break;
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
/* Pop the name and recurse. */
push_finished_type(top->cdr);
|
5b368e | 2001-03-31 | Henrik Grubbström (Grubba) | | pop_type_stack(expected);
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | break;
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | |
case PIKE_T_OPERATOR:
if (top->type & 0x8000) {
push_finished_type(top->cdr);
}
push_finished_type(top->car);
break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | default:
Pike_error("pop_type_stack(): Unhandled node type: %d\n", top->type);
}
free_type(top);
TYPE_STACK_DEBUG("pop_type_stack");
}
|
7e877a | 2003-04-02 | Martin Stjernholm | | void debug_push_reverse_type(unsigned int type)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
/* fprintf(stderr, "push_reverse_type(%d)\n", type); */
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | switch(type & 0x80ff) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
case T_MANY:
case T_TUPLE:
case T_MAPPING:
case T_OR:
case T_AND:
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_RING:
|
d2edc3 | 2020-01-07 | Henrik Grubbström (Grubba) | | case PIKE_T_ARRAY:
case PIKE_T_STRING:
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | case PIKE_T_OPERATOR | 0x8000:
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
/* Binary type-node. -- swap the types. */
struct pike_type *tmp = Pike_compiler->type_stackp[0];
Pike_compiler->type_stackp[0] = Pike_compiler->type_stackp[-1];
Pike_compiler->type_stackp[-1] = tmp;
break;
}
}
push_type(type);
TYPE_STACK_DEBUG("push_reverse_type");
}
|
77f0d6 | 2013-12-12 | Henrik Grubbström (Grubba) | | static int is_int_type(struct pike_type *t)
{
loop:
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(t->type & PIKE_T_MASK) {
|
77f0d6 | 2013-12-12 | Henrik Grubbström (Grubba) | | case T_INT:
case T_ZERO:
case T_VOID:
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | case PIKE_T_OPERATOR:
|
77f0d6 | 2013-12-12 | Henrik Grubbström (Grubba) | | return 1;
case T_OR:
case T_AND:
return is_int_type(t->car) && is_int_type(t->cdr);
case PIKE_T_NAME:
case PIKE_T_ATTRIBUTE:
case PIKE_T_SCOPE:
case T_ASSIGN:
t = t->cdr;
goto loop;
default:
return 0;
}
}
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | /* The marker_set is used as follows:
*
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | * PT_FLAG_MARKER_n Indicates that marker #n should be kept after
* expansion.
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | *
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | * PT_FLAG_ASSIGN_n Indicates that the assign to marker #n should
* NOT be removed.
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | */
static void debug_push_finished_type_with_markers(struct pike_type *type,
struct pike_type **markers,
INT32 marker_set)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | INT32 car_set, cdr_set;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | recurse:
|
c585d5 | 2007-04-26 | Henrik Grubbström (Grubba) | | #ifdef PIKE_TYPE_DEBUG
if (l_flag > 2) {
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "push_finished_type_with_markers((");
simple_describe_type(type);
fprintf(stderr, "),..., 0x%08x)...\n", marker_set);
|
c585d5 | 2007-04-26 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_TYPE_DEBUG */
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | /* We need to replace if there are any markers, or if there's a
* non-masked assign.
*/
if (!(type->flags & (~marker_set | PT_FLAG_MARKER) & PT_FLAG_MARK_ASSIGN)) {
/* Nothing to replace in this subtree. */
|
c585d5 | 2007-04-26 | Henrik Grubbström (Grubba) | | #ifdef PIKE_TYPE_DEBUG
if (l_flag > 2) {
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "Nothing to replace in this subtree.\n");
|
c585d5 | 2007-04-26 | Henrik Grubbström (Grubba) | | simple_describe_type(type);
fprintf(stderr, "\n");
}
#endif /* PIKE_TYPE_DEBUG */
|
77f0d6 | 2013-12-12 | Henrik Grubbström (Grubba) | | if ((marker_set & PT_FLAG_INT_ONLY) && !is_int_type(type)) {
push_finished_type(int_type_string);
} else {
push_finished_type(type);
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return;
}
if ((type->type >= '0') && (type->type <= '9')) {
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | /* Marker. */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | unsigned int m = type->type - '0';
|
c585d5 | 2007-04-26 | Henrik Grubbström (Grubba) | | #ifdef PIKE_TYPE_DEBUG
if ((l_flag > 2) && m) {
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | fprintf(stderr, "Marker %d: %p.\n", m, markers[m]);
}
|
c585d5 | 2007-04-26 | Henrik Grubbström (Grubba) | | #endif /* PIKE_TYPE_DEBUG */
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | if (markers[m]) {
/* The marker has a value. */
struct pike_type *type = dmalloc_touch(struct pike_type *, markers[m]);
|
c585d5 | 2007-04-26 | Henrik Grubbström (Grubba) | | #ifdef PIKE_TYPE_DEBUG
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | if (l_flag > 2) {
fprintf(stderr, "Marker value.\n");
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | }
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | #endif
/* FIXME: We probably ought to switch to the other marker set here. */
markers[m] = NULL;
|
77f0d6 | 2013-12-12 | Henrik Grubbström (Grubba) | | push_finished_type_with_markers(type, markers,
marker_set & PT_FLAG_INT_ONLY);
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | if (type->flags & (PT_FLAG_MARKER|PT_FLAG_ASSIGN)) {
push_scope_type(0);
}
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | if (markers[m]) free_type(markers[m]);
markers[m] = dmalloc_touch(struct pike_type *, type);
} else {
/* The marker has not been set. */
|
c585d5 | 2007-04-26 | Henrik Grubbström (Grubba) | | #ifdef PIKE_TYPE_DEBUG
if (l_flag > 2) {
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "No marker value.\n");
|
c585d5 | 2007-04-26 | Henrik Grubbström (Grubba) | | }
#endif
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | }
if (marker_set & (PT_FLAG_MARKER_0 << m)) {
/* The marker should be kept. */
|
c585d5 | 2007-04-26 | Henrik Grubbström (Grubba) | | #ifdef PIKE_TYPE_DEBUG
if (l_flag > 2) {
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "Keep marker.\n");
|
c585d5 | 2007-04-26 | Henrik Grubbström (Grubba) | | }
#endif
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | push_type(type->type);
if (markers[m]) push_type(T_OR);
} else if (!markers[m]) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | push_type(T_ZERO);
}
TYPE_STACK_DEBUG("push_finished_type_with_markers");
return;
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | } else if (type->type == T_ASSIGN) {
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | /* Assign. */
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | int marker = PTR_TO_INT(type->car);
|
c585d5 | 2007-04-26 | Henrik Grubbström (Grubba) | | #ifdef PIKE_TYPE_DEBUG
if (l_flag > 2) {
fprintf(stderr, "Assign to marker %"PRINTPTRDIFFT"d.\n",
CAR_TO_INT(type));
}
#endif /* PIKE_TYPE_DEBUG */
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | if (marker_set & (PT_FLAG_ASSIGN_0 << marker)) {
/* The assignment should be kept as-is. */
#ifdef PIKE_TYPE_DEBUG
if (l_flag > 2) {
fprintf(stderr, "Keep assignment.\n");
}
#endif /* PIKE_TYPE_DEBUG */
/* Clear the flag. */
push_finished_type_with_markers(type->cdr, markers,
marker_set &
~(PT_FLAG_ASSIGN_0 << marker));
push_assign_type('0' + marker);
TYPE_STACK_DEBUG("push_finished_type_with_markers");
return;
} else {
#ifdef PIKE_TYPE_DEBUG
if (l_flag > 2) {
fprintf(stderr, "Strip assignment.\n");
}
#endif /* PIKE_TYPE_DEBUG */
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | type = type->cdr;
goto recurse;
}
} else if (type->type == PIKE_T_NAME) {
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | /* Strip the name, since it won't be correct anymore. */
type = type->cdr;
goto recurse;
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | } else if (type->type == PIKE_T_ATTRIBUTE) {
/* Keep the attribute. */
push_finished_type_with_markers(type->cdr, markers, marker_set);
push_type_attribute((struct pike_string *)type->car);
|
65367f | 2013-12-10 | Henrik Grubbström (Grubba) | | goto done;
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | } else if ((type->type & PIKE_T_MASK) == PIKE_T_OPERATOR) {
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | push_finished_type_with_markers(type->car, markers, marker_set);
push_type_operator(type->type, type->cdr);
goto done;
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | } else if (type->type == PIKE_T_TRANSITIVE) {
push_finished_type(type->cdr);
push_finished_type_with_markers(type->car, markers, marker_set);
push_type(PIKE_T_TRANSITIVE);
goto done;
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* FIXME: T_SCOPE */
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | |
if (type->car) {
/* Keep markers for assigns in the car. */
cdr_set = marker_set |
((type->car->flags & PT_FLAG_ASSIGN)>>PT_ASSIGN_SHIFT);
} else {
cdr_set = marker_set;
}
if (type->cdr) {
/* Keep assigns for markers in the cdr. */
car_set = marker_set |
((type->cdr->flags & PT_FLAG_MARKER)<<PT_ASSIGN_SHIFT);
} else {
car_set = marker_set;
}
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | if ((type->type == T_OR) || (type->type == T_AND)) {
/* Special case handling for implicit zero. */
/* FIXME: Probably ought to use {or,and}_pike_types() here.
* Problem is that they may mess with the markers...
*/
|
9f194c | 2007-04-01 | Henrik Grubbström (Grubba) | |
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | type_stack_mark();
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | /* We want to keep markers that have assigns in the car. */
push_finished_type_with_markers(type->cdr, markers, cdr_set);
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | if (type->type == T_OR) {
|
9f194c | 2007-04-01 | Henrik Grubbström (Grubba) | | struct pike_type *first = pop_type();
struct pike_type *second;
struct pike_type *res;
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | push_finished_type_with_markers(type->car, markers, car_set);
|
9f194c | 2007-04-01 | Henrik Grubbström (Grubba) | | second = pop_unfinished_type();
push_finished_type(res = or_pike_types(first, second, 1));
free_type(second);
free_type(first);
free_type(res);
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | } else if (peek_type_stack() == zero_type_string) {
pop_stack_mark();
} else {
type_stack_mark();
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | push_finished_type_with_markers(type->car, markers, car_set);
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | if (peek_type_stack() == zero_type_string) {
free_type(pop_unfinished_type());
free_type(pop_unfinished_type());
push_finished_type(zero_type_string);
} else {
pop_stack_mark();
pop_stack_mark();
push_type(T_AND);
}
}
} else {
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | /* Make sure to filter invalid nodes from the marker in case
* it is a string type.
*/
if (type->type == PIKE_T_STRING) cdr_set |= PT_FLAG_INT_ONLY;
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | if (type->cdr) {
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | /* In all other cases type->cdr will be a valid node if is not NULL. */
push_finished_type_with_markers(type->cdr, markers, cdr_set);
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | }
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | if (type->car) {
/* In all other cases type->car will be a valid node if it is not NULL. */
push_finished_type_with_markers(type->car, markers, car_set);
}
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | /* push_type has sufficient magic to recreate the type. */
push_type(type->type);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
65367f | 2013-12-10 | Henrik Grubbström (Grubba) | | done:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | TYPE_STACK_DEBUG("push_finished_type_with_markers");
}
|
2adac4 | 2003-03-07 | Henrik Grubbström (Grubba) | | static void push_type_field(TYPE_FIELD field)
{
field &= (BIT_BASIC|BIT_COMPLEX);
if (!field) {
/* No values. */
push_type(T_ZERO);
} else if (field == (BIT_BASIC|BIT_COMPLEX)) {
/* All values. */
push_type(T_MIXED);
} else {
/* Check the bits... */
push_type(T_ZERO);
if (field & BIT_COMPLEX) {
if (field & BIT_ARRAY) {
push_type(T_MIXED);
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_ARRAY);
|
2adac4 | 2003-03-07 | Henrik Grubbström (Grubba) | | push_type(T_OR);
}
if (field & BIT_MAPPING) {
push_type(T_MIXED);
push_type(T_MIXED);
push_type(T_MAPPING);
push_type(T_OR);
}
if (field & BIT_MULTISET) {
push_type(T_MIXED);
push_type(T_MULTISET);
push_type(T_OR);
}
if (field & BIT_OBJECT) {
push_object_type(0, 0);
push_type(T_OR);
}
if (field & BIT_FUNCTION) {
push_type(T_ZERO);
push_type(T_ZERO);
push_type(T_MIXED);
push_type(T_OR);
push_type(T_MANY);
push_type(T_OR);
}
if (field & BIT_PROGRAM) {
push_object_type(0, 0);
push_type(T_PROGRAM);
push_type(T_OR);
}
}
if (field & BIT_BASIC) {
if (field & BIT_STRING) {
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | push_int_type(MIN_INT32, MAX_INT32);
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_STRING);
|
2adac4 | 2003-03-07 | Henrik Grubbström (Grubba) | | push_type(T_OR);
}
if (field & BIT_TYPE) {
push_type(T_MIXED);
push_type(T_TYPE);
push_type(T_OR);
}
if (field & BIT_INT) {
push_int_type(MIN_INT32, MAX_INT32);
push_type(T_OR);
}
if (field & BIT_FLOAT) {
push_type(T_FLOAT);
push_type(T_OR);
}
}
}
|
087e50 | 2020-08-28 | Henrik Grubbström (Grubba) | | TYPE_STACK_DEBUG("push_type_field");
|
2adac4 | 2003-03-07 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | INT32 extract_type_int(char *p)
{
|
8079a4 | 2014-01-11 | Tobias S. Josefowitz | | return get_unaligned_be32(p);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
0841e7 | 2020-10-12 | Henrik Grubbström (Grubba) | | static struct pike_type *low_pop_type(void)
{
TYPE_STACK_DEBUG("low_pop_type");
return *(Pike_compiler->type_stackp--);
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | struct pike_type *debug_pop_unfinished_type(void)
{
ptrdiff_t len;
len = pop_stack_mark();
if (len != 1) {
|
2d76f2 | 2005-05-20 | Martin Stjernholm | | Pike_fatal("pop_unfinished_type(): Unexpected len: %"PRINTPTRDIFFT"d\n", len);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
TYPE_STACK_DEBUG("pop_unfinished_type");
return *(Pike_compiler->type_stackp--);
}
/******/
|
d26598 | 2011-01-15 | Henrik Grubbström (Grubba) | | static struct pike_string *internal_parse_type_string(const char **_s)
{
const unsigned char **s = (const unsigned char **)_s;
const unsigned char *p;
struct string_builder tmp;
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
d26598 | 2011-01-15 | Henrik Grubbström (Grubba) | | if(**s != '\"') yyerror("Expected '\"'.");
else
++*s;
init_string_builder(&tmp, 0);
p = *s;
while(1) {
int c;
do {
c = *p++;
} while ((c > '\\') || ((c != '\"') && (c != '\\') && (c != '\n')));
string_builder_binary_strcat(&tmp, *_s, p - (1 + *s));
if (c == '"') {
*s = ++p;
break;
} else if (c == '\\') {
p_wchar2 buf;
ptrdiff_t len = 0;
if (!parse_esc_seq0((p_wchar0 *)p, &buf, &len)) {
string_builder_putchar(&tmp, buf);
p += len;
} else {
yyerror("Invalid \\-escape.");
}
} else {
yyerror("Expected '\"'.");
break;
}
*s = p;
}
return finish_string_builder(&tmp);
}
|
0929a0 | 2002-09-12 | Marcus Comstedt | | static void internal_parse_typeA(const char **_s)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
char buf[80];
unsigned int len;
|
0929a0 | 2002-09-12 | Marcus Comstedt | | const unsigned char **s = (const unsigned char **)_s;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
5e6dc2 | 2017-01-10 | Martin Nilsson | | for(len=0;isidchar(EXTRACT_UCHAR(s[0]+len));len++)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
6e878a | 2007-01-10 | Henrik Grubbström (Grubba) | | if(len>=sizeof(buf)-1) {
|
2d76f2 | 2005-05-20 | Martin Stjernholm | | my_yyerror("Buffer overflow in parse_type(\"%s\") (limit %"PRINTSIZET"d).",
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | *s, sizeof(buf));
push_type(T_MIXED);
return;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | buf[len] = s[0][len];
}
buf[len]=0;
*s += len;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | switch(buf[0])
{
case 'z':
if(!strcmp(buf,"zero")) { push_type(T_ZERO); break; }
goto bad_type;
case 'i':
if(!strcmp(buf,"int"))
{
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(**s=='(')
{
INT32 min,max;
++*s;
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
1f1c67 | 2003-11-24 | Henrik Grubbström (Grubba) | | if (**s != '.') {
|
2ae97e | 2014-09-03 | Martin Nilsson | | min=strtol((const char *)*s,(char **)s,0);
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
1f1c67 | 2003-11-24 | Henrik Grubbström (Grubba) | | } else {
|
1abbfb | 2006-07-05 | Martin Stjernholm | | min = MIN_INT32;
|
1f1c67 | 2003-11-24 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(s[0][0]=='.' && s[0][1]=='.')
s[0]+=2;
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | else {
yyerror("Missing .. in integer type.");
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
1f1c67 | 2003-11-24 | Henrik Grubbström (Grubba) | | if (**s != ')') {
|
2ae97e | 2014-09-03 | Martin Nilsson | | max=strtol((const char *)*s,(char **)s,0);
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
1f1c67 | 2003-11-24 | Henrik Grubbström (Grubba) | | } else {
|
1abbfb | 2006-07-05 | Martin Stjernholm | | max = MAX_INT32;
|
1f1c67 | 2003-11-24 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | if(**s != ')') yyerror("Missing ')' in integer range.");
else
++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | push_int_type(min, max);
}else{
push_int_type(MIN_INT32, MAX_INT32);
}
break;
}
goto bad_type;
case 'f':
if(!strcmp(buf,"function"))
{
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(**s == '(')
{
int nargs = 0;
++*s;
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | while(1)
{
if(**s == ':')
{
push_type(T_VOID);
break;
}
internal_parse_type(_s);
if(**s==',')
{
nargs++;
++*s;
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
else if(s[0][0]=='.' && s[0][1]=='.' && s[0][2]=='.')
{
*s+=3;
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | if(**s != ':') {
yyerror("Missing ':' after ... in function type.");
|
adb7ea | 2008-01-13 | Henrik Grubbström (Grubba) | | --*s;
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
} else {
nargs++;
}
}
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | /* Skip the colon. */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | ++*s;
internal_parse_type(_s); /* return type */
push_reverse_type(T_MANY);
while (nargs-- > 0) {
push_reverse_type(T_FUNCTION);
}
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | if(**s != ')') yyerror("Missing ')' in function type.");
else
++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }else{
push_type(T_VOID);
push_type(T_MIXED);
push_type(T_OR);
push_type(T_VOID);
push_type(T_ZERO);
push_type(T_OR);
push_type(T_MANY);
}
break;
}
if(!strcmp(buf,"float")) { push_type(T_FLOAT); break; }
goto bad_type;
case 'o':
if(!strcmp(buf,"object"))
{
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
f37a21 | 2002-08-14 | Henrik Grubbström (Grubba) | | if(**s == '(') /* object({,is,implements} {id,this_program}) */
|
c02ce6 | 2001-03-18 | Per Hedbor | | {
|
f37a21 | 2002-08-14 | Henrik Grubbström (Grubba) | | int is = 0, id;
|
c02ce6 | 2001-03-18 | Per Hedbor | | ++*s;
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
c02ce6 | 2001-03-18 | Per Hedbor | | if( **s != 'i' )
|
f37a21 | 2002-08-14 | Henrik Grubbström (Grubba) | | goto no_is_implements;
|
c02ce6 | 2001-03-18 | Per Hedbor | | ++*s;
|
f37a21 | 2002-08-14 | Henrik Grubbström (Grubba) | | if( **s == 's' ) {
++*s;
if (**s != ' ') {
goto bad_type;
}
is = 1;
++*s;
} else {
|
d41606 | 2006-07-06 | Marcus Comstedt | | if (strncmp((const char *)*s, "mplements ", 10)) {
|
f37a21 | 2002-08-14 | Henrik Grubbström (Grubba) | | goto bad_type;
}
*s += 10;
}
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
f37a21 | 2002-08-14 | Henrik Grubbström (Grubba) | | no_is_implements:
|
c02ce6 | 2001-03-18 | Per Hedbor | | if( !**s )
goto bad_type;
|
d41606 | 2006-07-06 | Marcus Comstedt | | if (!strncmp((const char *)*s, "this_program", 12)) {
|
f37a21 | 2002-08-14 | Henrik Grubbström (Grubba) | | id = Pike_compiler->new_program->id;
*s += 12;
} else {
|
13670c | 2015-05-25 | Martin Nilsson | | id = atoi( (const char *)*s );
|
f37a21 | 2002-08-14 | Henrik Grubbström (Grubba) | | while( **s >= '0' && **s <= '9' )
++*s;
}
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
c02ce6 | 2001-03-18 | Per Hedbor | | if( !**s || **s != ')' )
goto bad_type;
++*s;
push_object_type(is, id);
}
else
push_object_type(0, 0);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
}
goto bad_type;
case 'p':
|
6d33d8 | 2001-03-28 | Henrik Grubbström (Grubba) | | if(!strcmp(buf,"program")) {
push_object_type(0, 0);
push_type(T_PROGRAM);
break;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | goto bad_type;
case 's':
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | if(!strcmp(buf,"string")) {
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | if(**s == '(')
{
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | INT32 min,max;
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | ++*s;
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | if (**s != '.') {
|
2ae97e | 2014-09-03 | Martin Nilsson | | min=strtol((const char *)*s,(char **)s,0);
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | } else {
min = MIN_INT32;
}
if(s[0][0]=='.' && s[0][1]=='.')
s[0]+=2;
else {
yyerror("Missing .. in integer type.");
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | if (**s != ')') {
|
2ae97e | 2014-09-03 | Martin Nilsson | | max=strtol((const char *)*s,(char **)s,0);
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | } else {
max = MAX_INT32;
}
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | if(**s != ')') yyerror("Missing ')' in string width.");
else
++*s;
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | push_int_type(min, max);
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | } else {
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | push_finished_type(int_type_string);
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | }
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_STRING);
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | break;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | goto bad_type;
case 'v':
if(!strcmp(buf,"void")) { push_type(T_VOID); break; }
goto bad_type;
case 't':
if (!strcmp(buf,"tuple"))
{
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(**s == '(')
{
++*s;
internal_parse_type(_s);
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | if(**s != ',') yyerror("Expected ','.");
else
++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | internal_parse_type(_s);
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | if(**s != ')') yyerror("Expected ')'.");
else
++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }else{
push_type(T_MIXED);
push_type(T_MIXED);
}
push_reverse_type(T_TUPLE);
break;
}
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | /* FIXME: Handle type(T) */
if(!strcmp(buf,"type")) { push_type(T_MIXED); push_type(T_TYPE); break; }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | goto bad_type;
case 'm':
if(!strcmp(buf,"mixed")) { push_type(T_MIXED); break; }
if(!strcmp(buf,"mapping"))
{
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(**s == '(')
{
++*s;
internal_parse_type(_s);
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | if(**s != ':') yyerror("Expected ':'.");
else
++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | internal_parse_type(_s);
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | if(**s != ')') yyerror("Expected ')'.");
else
++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }else{
push_type(T_MIXED);
push_type(T_MIXED);
}
push_reverse_type(T_MAPPING);
break;
}
if(!strcmp(buf,"multiset"))
{
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(**s == '(')
{
++*s;
internal_parse_type(_s);
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | if(**s != ')') yyerror("Expected ')'.");
else
++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }else{
push_type(T_MIXED);
}
push_type(T_MULTISET);
break;
}
goto bad_type;
case 'u':
if(!strcmp(buf,"unknown")) { push_type(PIKE_T_UNKNOWN); break; }
goto bad_type;
case 'a':
if(!strcmp(buf,"array"))
{
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(**s == '(')
{
++*s;
internal_parse_type(_s);
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | if(**s != ')') yyerror("Expected ')'.");
else
++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }else{
push_type(T_MIXED);
}
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_ARRAY);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
}
goto bad_type;
|
d26598 | 2011-01-15 | Henrik Grubbström (Grubba) | | case '_':
if (!strcmp(buf, "__attribute__")) {
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
d26598 | 2011-01-15 | Henrik Grubbström (Grubba) | | if(**s == '(')
{
struct pike_string *attr;
++*s;
attr = internal_parse_type_string(_s);
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
d26598 | 2011-01-15 | Henrik Grubbström (Grubba) | | if(**s != ',') yyerror("Expected ','.");
else
++*s;
internal_parse_type(_s);
if(**s != ')') yyerror("Expected ')'.");
else
++*s;
push_type_attribute(attr);
free_string(attr);
}else{
push_type(T_MIXED);
}
break;
} else if (!strcmp(buf, "__deprecated__")) {
struct pike_string *deprecated_string;
MAKE_CONST_STRING(deprecated_string, "deprecated");
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
d26598 | 2011-01-15 | Henrik Grubbström (Grubba) | | if(**s == '(')
{
++*s;
internal_parse_type(_s);
if(**s != ')') yyerror("Expected ')'.");
else
++*s;
}else{
push_type(T_MIXED);
}
push_type_attribute(deprecated_string);
break;
}
goto bad_type;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if(atoi(buf)<10)
{
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(**s=='=')
{
++*s;
internal_parse_type(_s);
push_assign_type(buf[0]);
}else{
push_type(buf[0]);
}
break;
}
|
3595ea | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
default:
bad_type:
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | push_type(T_MIXED);
my_yyerror("Couldn't parse type. (%s).", buf);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(**s)) ++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
0929a0 | 2002-09-12 | Marcus Comstedt | | static void internal_parse_typeB(const char **s)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(EXTRACT_UCHAR(*s))) ++*s;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | switch(**s)
{
case '!':
++*s;
internal_parse_typeB(s);
push_type(T_NOT);
break;
case '(':
++*s;
internal_parse_type(s);
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(EXTRACT_UCHAR(*s))) ++*s;
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | if(**s != ')') {
yyerror("Expected ')' in type.");
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | ++*s;
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | default:
internal_parse_typeA(s);
}
}
|
0929a0 | 2002-09-12 | Marcus Comstedt | | static void internal_parse_typeCC(const char **s)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
internal_parse_typeB(s);
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(EXTRACT_UCHAR(*s))) ++*s;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | while(**s == '*')
{
++*s;
|
e045b2 | 2014-09-03 | Martin Nilsson | | while(isspace(EXTRACT_UCHAR(*s))) ++*s;
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_ARRAY);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
|
0929a0 | 2002-09-12 | Marcus Comstedt | | static void internal_parse_typeC(const char **s)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
internal_parse_typeCC(s);
if(**s == '&')
{
++*s;
internal_parse_typeC(s);
push_reverse_type(T_AND);
}
}
|
0929a0 | 2002-09-12 | Marcus Comstedt | | static void internal_parse_type(const char **s)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
internal_parse_typeC(s);
while(**s == '|')
{
++*s;
internal_parse_typeC(s);
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.
* It takes a string on the exact same format as Pike and returns a type
* struct.
*/
|
0929a0 | 2002-09-12 | Marcus Comstedt | | struct pike_type *parse_type(const char *s)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
struct pike_type *ret;
#ifdef PIKE_DEBUG
struct pike_type **ts=Pike_compiler->type_stackp;
struct pike_type ***ptms=Pike_compiler->pike_type_mark_stackp;
#endif
/* fprintf(stderr, "parse_type(\"%s\")...\n", s); */
TYPE_STACK_DEBUG("parse_type");
type_stack_mark();
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | internal_parse_type(&s);
if( *s )
|
be9b02 | 2003-06-06 | Henrik Grubbström (Grubba) | | yyerror("Extra junk at end of type definition.");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
ret=pop_unfinished_type();
#ifdef PIKE_DEBUG
if(ts!=Pike_compiler->type_stackp || ptms!=Pike_compiler->pike_type_mark_stackp)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Type stack whacked in parse_type.\n");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | #endif
return ret;
}
#ifdef PIKE_DEBUG
/* FIXME: */
void stupid_describe_type_string(char *a, ptrdiff_t len)
{
ptrdiff_t e;
for(e=0;e<len;e++)
{
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | if(e) fprintf(stderr, " ");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | switch(EXTRACT_UCHAR(a+e))
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "%c",EXTRACT_UCHAR(a+e));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | case T_SCOPE: fprintf(stderr, "scope"); break;
case T_TUPLE: fprintf(stderr, "tuple"); break;
case T_ASSIGN: fprintf(stderr, "="); break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_INT:
{
INT32 min=extract_type_int(a+e+1);
INT32 max=extract_type_int(a+e+1+sizeof(INT32));
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "int");
|
2bda50 | 2013-12-16 | Henrik Grubbström (Grubba) | | if(min!=MIN_INT32 || max!=MAX_INT32) {
if (!min && max && !(max & (max+1))) {
int j = 0;
while (max) {
max >>= 1;
j++;
}
fprintf(stderr, "(%dbit)", j);
|
6f6590 | 2019-12-22 | Henrik Grubbström (Grubba) | | } else if (min == max) {
fprintf(stderr, "(%ld)", (long)min);
|
2bda50 | 2013-12-16 | Henrik Grubbström (Grubba) | | } else {
fprintf(stderr, "(%ld..%ld)",(long)min,(long)max);
}
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | e+=sizeof(INT32)*2;
break;
}
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | case T_FLOAT: fprintf(stderr, "float"); break;
case T_STRING: fprintf(stderr, "string"); break;
case T_TYPE: fprintf(stderr, "type"); break;
case T_PROGRAM: fprintf(stderr, "program"); break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_OBJECT:
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "object(%s %ld)",
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | EXTRACT_UCHAR(a+e+1)?"is":"implements",
(long)extract_type_int(a+e+2));
e+=sizeof(INT32)+1;
break;
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | case T_FUNCTION: fprintf(stderr, "function"); break;
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | case PIKE_T_FUNCTION_ARG: fprintf(stderr, "function_arg"); break;
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | case T_ARRAY: fprintf(stderr, "array"); break;
case T_MAPPING: fprintf(stderr, "mapping"); break;
case T_MULTISET: fprintf(stderr, "multiset"); break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | case PIKE_T_UNKNOWN: fprintf(stderr, "unknown"); break;
case T_MANY: fprintf(stderr, "many"); break;
case T_OR: fprintf(stderr, "or"); break;
case T_AND: fprintf(stderr, "and"); break;
case T_NOT: fprintf(stderr, "not"); break;
case T_VOID: fprintf(stderr, "void"); break;
case T_ZERO: fprintf(stderr, "zero"); break;
case T_MIXED: fprintf(stderr, "mixed"); break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | case PIKE_T_OPERATOR:
fprintf(stderr, "operator ");
e++;
switch(EXTRACT_UCHAR(a+e)<<8 | PIKE_T_OPERATOR) {
|
0a3d9f | 2020-07-18 | Henrik Grubbström (Grubba) | | case PIKE_T_FIND_LFUN: fprintf(stderr, "find_lfun"); break;
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | default:
fprintf(stderr, "unknown<0x%04x>",
EXTRACT_UCHAR(a+e)<<8 | PIKE_T_OPERATOR);
break;
}
break;
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
fprintf(stderr, "transitive");
break;
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | default: fprintf(stderr, "%d",EXTRACT_UCHAR(a+e)); break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "\n");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
203e41 | 2007-04-05 | Henrik Grubbström (Grubba) | | #endif
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
void simple_describe_type(struct pike_type *s)
{
if (s) {
|
491ab0 | 2007-03-31 | Henrik Grubbström (Grubba) | | /* fprintf(stderr, "[[[%p]]]", s); */
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(s->type & PIKE_T_MASK) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "%d", s->type-'0');
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "{ %s = ", ((struct pike_string *)s->car)->str);
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | simple_describe_type(s->cdr);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, " }");
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | break;
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | {
struct pike_string *deprecated;
MAKE_CONST_STRING(deprecated, "deprecated");
if (((struct pike_string *)s->car) == deprecated) {
fprintf(stderr, "__deprecated__(");
} else {
fprintf(stderr, "__attribute__(\"%s\", ",
((struct pike_string *)s->car)->str);
}
simple_describe_type(s->cdr);
fprintf(stderr, ")");
}
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_SCOPE:
|
6fd069 | 2003-07-01 | Martin Stjernholm | | fprintf(stderr, "scope(%"PRINTPTRDIFFT"d, ", CAR_TO_INT(s));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | simple_describe_type(s->cdr);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, ")");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_TUPLE:
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "tuple(");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | simple_describe_type(s->car);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, ", ");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | simple_describe_type(s->cdr);
|
13670c | 2015-05-25 | Martin Nilsson | | fprintf(stderr, ")");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_ASSIGN:
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | fprintf(stderr, "(%"PRINTPTRDIFFT"d = ", CAR_TO_INT(s));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | simple_describe_type(s->cdr);
|
13670c | 2015-05-25 | Martin Nilsson | | fprintf(stderr, ")");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_INT:
{
|
d2361e | 2003-06-30 | Martin Stjernholm | | INT32 min = CAR_TO_INT(s);
INT32 max = CDR_TO_INT(s);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "int");
|
2bda50 | 2013-12-16 | Henrik Grubbström (Grubba) | | if(min!=MIN_INT32 || max!=MAX_INT32) {
if (!min && max && !(max & (max+1))) {
int j = 0;
while (max) {
max >>= 1;
j++;
}
fprintf(stderr, "(%dbit)", j);
|
6f6590 | 2019-12-22 | Henrik Grubbström (Grubba) | | } else if (min == max) {
fprintf(stderr, "(%ld)", (long)min);
|
2bda50 | 2013-12-16 | Henrik Grubbström (Grubba) | | } else {
fprintf(stderr, "(%ld..%ld)",(long)min,(long)max);
}
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
}
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | case T_FLOAT: fprintf(stderr, "float"); break;
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | case T_STRING:
{
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | INT32 min;
INT32 max;
fprintf(stderr, "string");
|
ce56eb | 2020-01-11 | Henrik Grubbström (Grubba) | | if ((s->car == int_pos_type_string) && (s->cdr == int_type_string)) {
break;
}
fprintf(stderr, "(");
if (s->car != int_pos_type_string) {
simple_describe_type(s->car);
fprintf(stderr, ": ");
}
s = s->cdr;
|
b90857 | 2008-09-08 | Henrik Grubbström (Grubba) | | if (s != int_type_string) {
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | while (s->type == T_OR) {
|
8151ac | 2008-06-18 | Henrik Grubbström (Grubba) | | struct pike_type *char_type = s->car;
while(char_type->type == T_ASSIGN) {
char_type = char_type->cdr;
}
|
b90857 | 2008-09-08 | Henrik Grubbström (Grubba) | | if (char_type->type == T_ZERO) {
fprintf(stderr, "zero | ");
s = s->cdr;
continue;
}
|
0551da | 2013-12-13 | Henrik Grubbström (Grubba) | | if ((char_type->type >= '0') && (char_type->type <= '9')) {
fprintf(stderr, "$%c | ", char_type->type);
s = s->cdr;
continue;
}
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
8151ac | 2008-06-18 | Henrik Grubbström (Grubba) | | if (char_type->type != T_INT) {
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | Pike_fatal("Invalid node type (%d:%s) in string type.\n",
|
8151ac | 2008-06-18 | Henrik Grubbström (Grubba) | | char_type->type, get_name_of_type(char_type->type));
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
|
8151ac | 2008-06-18 | Henrik Grubbström (Grubba) | | min = CAR_TO_INT(char_type);
max = CDR_TO_INT(char_type);
|
a776c9 | 2014-01-11 | Arne Goedeke | | if (!min && max && max != MAX_INT32 && !(max & (max+1))) {
|
2bda50 | 2013-12-16 | Henrik Grubbström (Grubba) | | int j = 0;
while (max) {
max >>= 1;
j++;
}
fprintf(stderr, "%dbit", j);
} else {
|
6f6590 | 2019-12-22 | Henrik Grubbström (Grubba) | | if ((min != MIN_INT32) || (max == min)) {
|
2bda50 | 2013-12-16 | Henrik Grubbström (Grubba) | | fprintf(stderr, "%d", min);
}
|
6f6590 | 2019-12-22 | Henrik Grubbström (Grubba) | | if (max != min) {
fprintf(stderr, "..");
if (max != MAX_INT32) {
fprintf(stderr, "%d", max);
}
|
2bda50 | 2013-12-16 | Henrik Grubbström (Grubba) | | }
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | }
fprintf(stderr, " | ");
s = s->cdr;
}
|
8151ac | 2008-06-18 | Henrik Grubbström (Grubba) | | while(s->type == T_ASSIGN) {
s = s->cdr;
}
|
b90857 | 2008-09-08 | Henrik Grubbström (Grubba) | | if (s->type == T_ZERO) {
fprintf(stderr, "zero");
|
0551da | 2013-12-13 | Henrik Grubbström (Grubba) | | } else if ((s->type >= '0') && (s->type <= '9')) {
fprintf(stderr, "$%c", s->type);
|
b90857 | 2008-09-08 | Henrik Grubbström (Grubba) | | } else {
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
b90857 | 2008-09-08 | Henrik Grubbström (Grubba) | | if (s->type != T_INT) {
Pike_fatal("Invalid node type (%d:%s) in string type.\n",
s->type, get_name_of_type(s->type));
}
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | #endif /* PIKE_DEBUG */
|
b90857 | 2008-09-08 | Henrik Grubbström (Grubba) | | min = CAR_TO_INT(s);
max = CDR_TO_INT(s);
|
a776c9 | 2014-01-11 | Arne Goedeke | | if (!min && max && max != MAX_INT32 && !(max & (max+1))) {
|
2bda50 | 2013-12-16 | Henrik Grubbström (Grubba) | | int j = 0;
while (max) {
max >>= 1;
j++;
}
fprintf(stderr, "%dbit", j);
} else {
|
6f6590 | 2019-12-22 | Henrik Grubbström (Grubba) | | if ((min != MIN_INT32) || (min == max)) {
|
2bda50 | 2013-12-16 | Henrik Grubbström (Grubba) | | fprintf(stderr, "%d", min);
}
|
6f6590 | 2019-12-22 | Henrik Grubbström (Grubba) | | if (min != max) {
fprintf(stderr, "..");
if (max != MAX_INT32) {
fprintf(stderr, "%d", max);
}
|
2bda50 | 2013-12-16 | Henrik Grubbström (Grubba) | | }
|
b90857 | 2008-09-08 | Henrik Grubbström (Grubba) | | }
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | }
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | }
|
ce56eb | 2020-01-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, ")");
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | break;
}
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | case T_TYPE:
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "type(");
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | simple_describe_type(s->car);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, ")");
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | break;
|
6d33d8 | 2001-03-28 | Henrik Grubbström (Grubba) | | case T_PROGRAM:
fprintf(stderr, "program(");
simple_describe_type(s->car);
fprintf(stderr, ")");
break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_OBJECT:
|
6fd069 | 2003-07-01 | Martin Stjernholm | | fprintf(stderr, "object(%s %"PRINTPTRDIFFT"d)",
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | s->car?"is":"implements",
|
d2361e | 2003-06-30 | Martin Stjernholm | | CDR_TO_INT(s));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_FUNCTION:
case T_MANY:
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "function(");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | while(s->type == T_FUNCTION) {
simple_describe_type(s->car);
s = s->cdr;
if ((s->type == T_FUNCTION) ||
|
fb013e | 2020-08-19 | Henrik Grubbström (Grubba) | | ((s->type == T_MANY) && (s->car->type != T_VOID))) {
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, ", ");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | if (s->type != T_MANY) {
fprintf(stderr, ", @");
simple_describe_type(s);
fprintf(stderr, ")");
} else {
if (s->car->type != T_VOID) {
simple_describe_type(s->car);
fprintf(stderr, "...");
}
fprintf(stderr, ":");
simple_describe_type(s->cdr);
fprintf(stderr, ")");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
break;
|
502670 | 2020-05-18 | Henrik Grubbström (Grubba) | | case T_ARRAY: /* FIXME: cdr */
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "array(");
|
ce56eb | 2020-01-11 | Henrik Grubbström (Grubba) | | if (s->car != int_pos_type_string) {
simple_describe_type(s->car);
fprintf(stderr, ":");
}
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | simple_describe_type(s->cdr);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, ")");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_MAPPING:
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "mapping(");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | simple_describe_type(s->car);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, ":");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | simple_describe_type(s->cdr);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, ")");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_MULTISET:
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "multiset(");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | simple_describe_type(s->car);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, ")");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | case PIKE_T_UNKNOWN: fprintf(stderr, "unknown"); break;
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_RING:
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "ring(");
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | simple_describe_type(s->car);
|
158853 | 2012-12-29 | Jonas Walldén | | fprintf(stderr, "\260");
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | simple_describe_type(s->cdr);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, ")");
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_OR:
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "or(");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | simple_describe_type(s->car);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "|");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | simple_describe_type(s->cdr);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, ")");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_AND:
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "and(");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | simple_describe_type(s->car);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "&");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | simple_describe_type(s->cdr);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, ")");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_NOT:
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "not(");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | simple_describe_type(s->car);
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, ")");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | case T_VOID: fprintf(stderr, "void"); break;
case T_ZERO: fprintf(stderr, "zero"); break;
case T_MIXED: fprintf(stderr, "mixed"); break;
|
ec9bc1 | 2016-05-01 | Henrik Grubbström (Grubba) | | case PIKE_T_AUTO:
fprintf(stderr, "auto");
if (s->car && (s->car->type != T_ZERO)) {
fprintf(stderr, "(");
simple_describe_type(s->car);
fprintf(stderr, ")");
}
break;
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | |
case PIKE_T_OPERATOR:
fprintf(stderr, "operator<0x%04x>(", s->type);
simple_describe_type(s->car);
if (s->type & 0x8000) {
fprintf(stderr, ",");
simple_describe_type(s->cdr);
} else {
switch(s->type) {
|
0a3d9f | 2020-07-18 | Henrik Grubbström (Grubba) | | case PIKE_T_FIND_LFUN:
fprintf(stderr, ",\"%s\")", STR0(lfun_strings[CDR_TO_INT(s)]));
break;
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | default:
if (s->cdr) {
fprintf(stderr, ",0x%08lx)", CDR_TO_INT(s));
} else {
fprintf(stderr, ")");
}
break;
}
}
break;
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
fprintf(stderr, "transitive(");
simple_describe_type(s->car);
fprintf(stderr, ", ");
simple_describe_type(s->cdr);
fprintf(stderr, ")");
break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | default:
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "Unknown type node: %d, %p:%p",
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | s->type, s->car, s->cdr);
|
491ab0 | 2007-03-31 | Henrik Grubbström (Grubba) | | #ifdef DEBUG_MALLOC
debug_malloc_dump_references(s, 0, 2, 0);
#endif
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
}
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | | if (s->flags) {
fprintf(stderr, "[%06x]", s->flags);
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
|
35ce41 | 2001-03-27 | Henrik Grubbström (Grubba) | | fprintf(stderr, "NULL");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
|
9b5a82 | 2001-03-29 | Henrik Grubbström (Grubba) | |
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | | static void low_describe_int_range(struct string_builder *s,
struct pike_type *t)
{
if (!t || (t == int_type_string)) return;
loop:
switch(t->type) {
case T_ZERO:
string_builder_strcat(s, "zero");
break;
case T_INT:
{
INT32 min=CAR_TO_INT(t);
INT32 max=CDR_TO_INT(t);
if (min == max) {
string_builder_sprintf(s, "%ld", (long) min);
} else if (!min && (max != MAX_INT32) && !(max & (max + 1))) {
int j = 0;
while (max) {
max >>= 1;
j++;
}
string_builder_sprintf(s, "%dbit", j);
} else {
if (min != MIN_INT32) {
string_builder_sprintf(s, "%ld..", (long)min);
} else {
string_builder_strcat(s, "..");
}
if (max != MAX_INT32) {
string_builder_sprintf(s, "%ld", (long)max);
}
}
}
break;
case T_ASSIGN:
|
a13129 | 2020-09-30 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "%ld = (", CAR_TO_INT(t));
low_describe_int_range(s, t->cdr);
string_builder_strcat(s, ")");
break;
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | | case T_OR:
low_describe_int_range(s, t->car);
string_builder_strcat(s, " | ");
t = t->cdr;
goto loop;
default:
low_describe_type(s, t);
break;
}
}
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | void low_describe_type(struct string_builder *s, struct pike_type *t)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
a6dfba | 2005-09-09 | Henrik Grubbström (Grubba) | | check_c_stack(1024);
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | switch(t->type) /* NB: No masking here! */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_putchar(s, t->type);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_ASSIGN:
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "(%c=%T)", '0' + CAR_TO_INT(t), t->cdr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_SCOPE:
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "scope(%c,%T)", '0' + CAR_TO_INT(t), t->cdr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_TUPLE:
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "[%T,%T]", t->car, t->cdr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | case T_VOID: string_builder_strcat(s, "void"); break;
case T_ZERO: string_builder_strcat(s, "zero"); break;
case T_MIXED: string_builder_strcat(s, "mixed"); break;
case PIKE_T_UNKNOWN: string_builder_strcat(s, "unknown"); break;
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_INT:
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | | string_builder_strcat(s, "int");
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | | if (t == int_type_string) break;
string_builder_putchar(s, '(');
low_describe_int_range(s, t);
string_builder_putchar(s, ')');
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | |
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | case T_FLOAT: string_builder_strcat(s, "float"); break;
|
6d33d8 | 2001-03-28 | Henrik Grubbström (Grubba) | | case T_PROGRAM:
|
a9b2da | 2002-07-03 | Henrik Grubbström (Grubba) | | if ((t->car->type == T_OBJECT) &&
(!t->car->cdr)) {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_strcat(s, "program");
|
a9b2da | 2002-07-03 | Henrik Grubbström (Grubba) | | } else {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "program(%T)", t->car);
|
a9b2da | 2002-07-03 | Henrik Grubbström (Grubba) | | }
|
6d33d8 | 2001-03-28 | Henrik Grubbström (Grubba) | | break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_OBJECT:
if (t->cdr)
{
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | struct svalue sval;
|
71868e | 2007-03-30 | Henrik Grubbström (Grubba) | | if (t->car) {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_strcat(s, "object(is ");
|
71868e | 2007-03-30 | Henrik Grubbström (Grubba) | | } else {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_strcat(s, "object(implements ");
|
71868e | 2007-03-30 | Henrik Grubbström (Grubba) | | }
|
1cba5d | 2011-02-05 | Henrik Grubbström (Grubba) | | /* We need to save the global buffer, in case id_to_program()
* starts running Pike code. */
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | sval.u.program = id_to_program(CDR_TO_INT(t));
if (sval.u.program) {
SET_SVAL_TYPE(sval, T_PROGRAM);
SET_SVAL_SUBTYPE(sval, 0);
string_builder_sprintf(s, "%O)", &sval);
|
71868e | 2007-03-30 | Henrik Grubbström (Grubba) | | } else {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "%"PRINTPTRDIFFT"d)", CDR_TO_INT(t));
|
71868e | 2007-03-30 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }else{
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_strcat(s, "object");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
break;
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | case T_STRING:
{
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | | string_builder_strcat(s, "string");
|
ce56eb | 2020-01-11 | Henrik Grubbström (Grubba) | | if ((t->cdr == int_type_string) && (t->car == int_pos_type_string)) {
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | | break;
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | }
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | | string_builder_putchar(s, '(');
|
53257b | 2020-01-16 | Henrik Grubbström (Grubba) | | if (t->car == zero_type_string) {
/* Zero-length string. */
string_builder_strcat(s, "zero");
} else {
if (t->car != int_pos_type_string) {
low_describe_int_range(s, t->car);
|
a13129 | 2020-09-30 | Henrik Grubbström (Grubba) | | string_builder_strcat(s, ":");
|
53257b | 2020-01-16 | Henrik Grubbström (Grubba) | | }
low_describe_int_range(s, t->cdr);
|
ce56eb | 2020-01-11 | Henrik Grubbström (Grubba) | | }
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | | string_builder_putchar(s, ')');
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | break;
}
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | case T_TYPE:
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "type(%T)", t->car);
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | break;
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | |
case PIKE_T_NAME:
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "{ %S = %T }",
(struct pike_string *)t->car, t->cdr);
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | {
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct pike_string *deprecated;
MAKE_CONST_STRING(deprecated, "deprecated");
if (((struct pike_string *)t->car) == deprecated) {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "__deprecated__(%T)", t->cdr);
|
187405 | 2018-04-21 | Henrik Grubbström (Grubba) | | } else if (t == utf8_type_string) {
string_builder_sprintf(s, "utf8_string");
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | } else {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | struct svalue sval;
SET_SVAL(sval, PIKE_T_STRING, 0, string,
(struct pike_string *)t->car);
string_builder_sprintf(s, "__attribute__(%O, %T)", &sval, t->cdr);
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | }
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | }
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
case T_MANY:
{
if(t->type == T_MANY &&
t->cdr->type == T_OR &&
((t->cdr->car->type == T_MIXED && t->cdr->cdr->type == T_VOID) ||
(t->cdr->cdr->type == T_MIXED && t->cdr->car->type == T_VOID)) &&
(t->car->type == T_ZERO ||
(t->car->type == T_OR &&
((t->car->car->type == T_ZERO && t->car->cdr->type == T_VOID) ||
(t->car->cdr->type == T_ZERO && t->car->car->type == T_VOID)))))
{
/* function == function(zero...:mixed|void) or
* function(zero|void...:mixed|void)
*/
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_strcat(s, "function");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* done */
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | int arg = 0;
string_builder_strcat(s, "function(");
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | while(t->type == T_FUNCTION)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | if(arg++) string_builder_strcat(s, ", ");
low_describe_type(s, t->car);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | t = t->cdr;
}
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | if (t->type != T_MANY) {
|
1b0a06 | 2020-08-27 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, ", @%T)", t);
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | } else {
if(t->car->type != T_VOID)
{
if(arg++) string_builder_strcat(s, ", ");
low_describe_type(s, t->car);
string_builder_strcat(s, " ...");
}
t = t->cdr;
string_builder_sprintf(s, " : %T)", t);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
break;
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_ARRAY:
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | | string_builder_strcat(s, "array");
|
440487 | 2020-01-13 | Henrik Grubbström (Grubba) | | if((t->cdr->type == T_MIXED) && (t->car == int_pos_type_string)) {
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | | break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | | string_builder_putchar(s, '(');
|
53257b | 2020-01-16 | Henrik Grubbström (Grubba) | | if (t->car == zero_type_string) {
/* Zero-length array. */
string_builder_strcat(s, "zero");
} else {
if (t->car != int_pos_type_string) {
low_describe_int_range(s, t->car);
string_builder_putchar(s, ':');
if (t->cdr->type != T_MIXED) {
string_builder_putchar(s, ' ');
}
|
ce56eb | 2020-01-11 | Henrik Grubbström (Grubba) | | }
}
if (t->cdr->type != T_MIXED) {
string_builder_sprintf(s, "%T", t->cdr);
}
|
5ee03f | 2020-01-10 | Henrik Grubbström (Grubba) | | string_builder_putchar(s, ')');
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_MULTISET:
if(t->car->type != T_MIXED) {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "multiset(%T)", t->car);
} else {
string_builder_strcat(s, "multiset");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_NOT:
if (t->car->type > T_NOT) {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "!(%T)", t->car);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "!%T", t->car);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
break;
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | |
case PIKE_T_RING:
/* FIXME: Should be renumbered for correct parenthesing. */
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "(%T)\260(%T)", t->car, t->cdr);
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_OR:
if (t->car->type > T_OR) {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "(%T)", t->car);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | low_describe_type(s, t->car);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_strcat(s, " | ");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if (t->cdr->type > T_OR) {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "(%T)", t->cdr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | low_describe_type(s, t->cdr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_AND:
if (t->car->type > T_AND) {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "(%T)", t->car);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | low_describe_type(s, t->car);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_strcat(s, " & ");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if (t->cdr->type > T_AND) {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "(%T)", t->cdr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | low_describe_type(s, t->cdr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_MAPPING:
if(t->car->type != T_MIXED || t->cdr->type != T_MIXED) {
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "mapping(%T:%T)", t->car, t->cdr);
} else {
string_builder_strcat(s, "mapping");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
break;
|
ec9bc1 | 2016-05-01 | Henrik Grubbström (Grubba) | | case PIKE_T_AUTO:
if (t->car->type != T_ZERO) {
string_builder_sprintf(s, "auto(%T)", t->car);
} else {
string_builder_strcat(s, "auto");
}
break;
|
0a3d9f | 2020-07-18 | Henrik Grubbström (Grubba) | |
case PIKE_T_FIND_LFUN:
string_builder_sprintf(s, "find_lfun(%T, \"%S\")",
t->car, lfun_strings[CDR_TO_INT(t)]);
break;
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
string_builder_sprintf(s, "transitive(%T, %T)", t->car, t->cdr);
break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | default:
{
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | if ((t->type & PIKE_T_MASK) == PIKE_T_OPERATOR) {
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | string_builder_sprintf(s, "operator(0x%04x)(%T", t->type, t->car);
if (t->type & 0x8000) {
string_builder_sprintf(s, ",%T)", t->cdr);
} else if (t->cdr) {
string_builder_sprintf(s, ",0x%08lx)", CDR_TO_INT(t));
} else {
string_builder_strcat(s, ")");
}
} else {
string_builder_sprintf(s, "unknown code(%d)", t->type);
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
}
}
}
struct pike_string *describe_type(struct pike_type *type)
{
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | struct string_builder s;
ONERROR err;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(!type) return make_shared_string("mixed");
|
b10e41 | 2015-10-11 | Henrik Grubbström (Grubba) | | init_string_builder(&s, 0);
SET_ONERROR(err, free_string_builder, &s);
low_describe_type(&s, type);
UNSET_ONERROR(err);
return finish_string_builder(&s);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
/******/
TYPE_T compile_type_to_runtime_type(struct pike_type *t)
{
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | switch(t->type) /* Note: No masking here. */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_RING:
return compile_type_to_runtime_type(t->car);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_OR:
{
TYPE_T tmp = compile_type_to_runtime_type(t->car);
if(tmp == compile_type_to_runtime_type(t->cdr))
return tmp;
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_TUPLE:
/* FIXME: Shouldn't occur/should be converted to array? */
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | default:
return T_MIXED;
case T_ZERO:
return T_INT;
case T_SCOPE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return compile_type_to_runtime_type(t->cdr);
case T_MANY:
|
0a3d9f | 2020-07-18 | Henrik Grubbström (Grubba) | | case PIKE_T_FIND_LFUN:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return T_FUNCTION;
case T_ARRAY:
case T_MAPPING:
case T_MULTISET:
case T_OBJECT:
case T_PROGRAM:
case T_FUNCTION:
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_STRING:
case T_TYPE:
case T_INT:
case T_FLOAT:
return t->type;
}
}
|
fe607e | 2019-04-09 | Henrik Grubbström (Grubba) | | /**
* Check whether a type is for a __deprecated__ value.
*
* @param t
* Type to check.
*/
int deprecated_typep(struct pike_type *t)
{
struct pike_string *deprecated_string;
MAKE_CONST_STRING(deprecated_string, "deprecated");
while (t) {
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(t->type & PIKE_T_MASK) {
|
fe607e | 2019-04-09 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
if (((struct pike_string*)t->car) == deprecated_string) {
return 1;
}
/* FALLTHRU */
case PIKE_T_SCOPE:
case T_ASSIGN:
case PIKE_T_NAME:
t = t->cdr;
continue;
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | case PIKE_T_OPERATOR:
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | t = t->car;
continue;
|
fe607e | 2019-04-09 | Henrik Grubbström (Grubba) | | }
break;
}
return 0;
}
|
a570c5 | 2016-06-13 | Henrik Grubbström (Grubba) | | int get_int_type_range(struct pike_type *t, INT_TYPE *range)
{
int ret = 0;
loop:
switch(t->type) {
case T_INT:
{
INT_TYPE min = CAR_TO_INT(t);
INT_TYPE max = CDR_TO_INT(t);
if (range[0] > min) range[0] = min;
if (range[1] < max) range[1] = max;
return 1;
}
break;
case T_ZERO:
case T_VOID:
if (range[0] > 0) range[0] = 0;
if (range[1] < 0) range[1] = 0;
return 1;
case T_SCOPE:
case T_ASSIGN:
case PIKE_T_NAME:
case PIKE_T_ATTRIBUTE:
t = t->cdr;
goto loop;
case T_OR:
case T_AND:
ret = get_int_type_range(t->car, range);
t = t->cdr;
goto loop;
default:
break;
}
return ret;
}
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | static void low_or_pike_types(struct pike_type *t1,
struct pike_type *t2,
int zero_implied);
/* Push either t1, t2 or the OR of t1 and t2.
* Returns -1 if t1 was pushed.
* 0 if the OR was pushed. (Successful join)
* 1 if t2 was pushed.
|
2a61e8 | 2011-03-24 | Henrik Grubbström (Grubba) | | *
* zero_implied: One of:
* 0 the zero type (if any) must be explicit in the result.
* 1 the zero type is implicit.
* 3 zero is implicit and integers are regarded as masks (cf enums).
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | */
static int lower_or_pike_types(struct pike_type *t1,
struct pike_type *t2,
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | int zero_implied,
int elem_on_stack)
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | {
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | int ret = 0;
struct pike_type *t = NULL;
struct pike_type *top = NULL;
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | #if 0
fprintf(stderr, " lower_or_pike_types(");
simple_describe_type(t1);
fprintf(stderr, ", ");
simple_describe_type(t2);
fprintf(stderr, ")\n");
#endif
if (t1 == t2) {
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | t = t1;
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | } else if (!t1) {
t = t2;
ret = 1;
} else if (!t2) {
t = t1;
ret = -1;
|
2631f8 | 2007-05-07 | Henrik Grubbström (Grubba) | | } else if (zero_implied && (t1->type == T_ZERO)) {
t = t2;
} else if (zero_implied && (t2->type == T_ZERO)) {
t = t1;
|
739c8b | 2020-07-15 | Henrik Grubbström (Grubba) | | } else if ((t1->type == T_NOT) && pike_types_le(t1->car, t2)) {
t = mixed_type_string;
} else if ((t2->type == T_NOT) && pike_types_le(t2->car, t1)) {
t = mixed_type_string;
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | } else if ((t1->type ^ '0') < (t2->type ^ '0')) {
/* Note: Adjusted order to get markers first. */
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | t = t1;
ret = -1;
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | } else if ((t1->type ^ '0') > (t2->type ^ '0')) {
/* Note: Adjusted order to get markers first. */
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | t = t2;
ret = 1;
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | } else {
#ifdef PIKE_DEBUG
if (t1->type != t2->type) {
Pike_fatal("Lost track of types t1->type: %d, t2->type: %d\n",
t1->type, t2->type);
}
#endif /* PIKE_DEBUG */
switch(t1->type) {
case T_INT:
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | if (CAR_TO_INT(t1) < CAR_TO_INT(t2)) {
t = t1;
ret = -1;
} else {
t = t2;
ret = 1;
}
break;
case T_STRING:
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | {
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | low_or_pike_types(t1->cdr, t2->cdr, 1);
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_STRING);
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | return 0;
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | }
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:
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | if (t1->cdr->type < t2->cdr->type) {
t = t1;
ret = -1;
break;
} else if (t1->cdr->type > t2->cdr->type) {
t = t2;
ret = 1;
break;
}
if (t1 < t2) {
t = t1;
ret = -1;
} else {
t = t2;
ret = 1;
}
break;
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | 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;
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | default:
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | #if 0
if (pike_types_le(t1, t2)) {
t = t2;
} else if (pike_types_le(t2, t1)) {
t = t1;
} else
#endif /* 0 */
if (t1 < t2) {
t = t1;
ret = -1;
} else {
t = t2;
ret = 1;
}
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | break;
}
}
|
2631f8 | 2007-05-07 | Henrik Grubbström (Grubba) | | if (!elem_on_stack) {
|
efd38b | 2016-02-24 | Henrik Grubbström (Grubba) | | if (t) {
push_finished_type(t);
} else {
push_type(T_ZERO);
}
} else if (!t) {
/* No need to do anything. */
|
2631f8 | 2007-05-07 | Henrik Grubbström (Grubba) | | } else if ((top = peek_type_stack())->type != t->type) {
if (zero_implied && (top->type == T_ZERO)) {
Pike_compiler->type_stackp--;
free_type(top);
push_finished_type(t);
} else if (zero_implied && (t->type == T_ZERO)) {
/* The zero is implied. */
} else {
push_finished_type(t);
}
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | } else if (t == top) {
/* No need to do anything. */
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | } else {
switch(t->type) {
case T_FLOAT:
|
9e6638 | 2007-04-18 | Henrik Grubbström (Grubba) | | case T_MIXED:
case T_VOID:
case T_ZERO:
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | /* 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);
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | |
if (zero_implied) {
if (min1 == 1) min1 = 0;
if (min2 == 1) min2 = 0;
if (max1 == -1) max1 = 0;
if (max2 == -1) max2 = 0;
|
2a61e8 | 2011-03-24 | Henrik Grubbström (Grubba) | |
if (zero_implied == 3) {
/* Or between integer masks.
* This is a bit more lenient than the default further below,
* and is used for generating the type for enums.
*/
|
160954 | 2011-03-25 | Henrik Grubbström (Grubba) | |
/* Ensure that zero is always in the range.
* This also ensures that there'll be an overlap.
*/
if (max1 < 0) max1 = 0;
|
2a61e8 | 2011-03-24 | Henrik Grubbström (Grubba) | | if (max2 < 0) max2 = 0;
|
160954 | 2011-03-25 | Henrik Grubbström (Grubba) | | if (min1 > 0) min1 = 0;
|
2a61e8 | 2011-03-24 | Henrik Grubbström (Grubba) | | if (min2 > 0) min2 = 0;
|
160954 | 2011-03-25 | Henrik Grubbström (Grubba) | |
/* Both max values are now >= 0, so this or is safe. */
max1 |= max2;
if ((min1 < 0) && (min2 < 0)) {
min1 &= min2;
}
|
2a61e8 | 2011-03-24 | Henrik Grubbström (Grubba) | | }
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | }
|
2a61e8 | 2011-03-24 | Henrik Grubbström (Grubba) | |
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | if ((min1 > max2) && (min1 > max2 + 1)) {
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | /* No overlap. */
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | 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
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | } else {
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | Pike_compiler->type_stackp--;
free_type(top);
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | /* Overlap */
min1 = MINIMUM(min1, min2);
max1 = MAXIMUM(max1, max2);
push_int_type(min1, max1);
}
}
break;
case T_STRING:
{
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | Pike_compiler->type_stackp--;
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | low_or_pike_types(t->cdr, top->cdr, 1);
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_STRING);
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | free_type(top);
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | }
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | break;
case T_OBJECT:
if (CDR_TO_INT(top)) {
push_finished_type(t);
}
break;
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | case T_ARRAY:
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | Pike_compiler->type_stackp--;
low_or_pike_types(t->cdr, top->cdr, zero_implied);
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(t->type);
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | free_type(top);
break;
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | case T_MULTISET:
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | Pike_compiler->type_stackp--;
low_or_pike_types(t->car, top->car, zero_implied);
push_type(t->type);
free_type(top);
break;
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | case T_MAPPING:
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | if (t->car == top->car) {
Pike_compiler->type_stackp--;
push_finished_type(t->car);
low_or_pike_types(t->cdr, top->cdr, zero_implied);
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | push_reverse_type(T_MAPPING);
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | 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);
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | push_type(T_MAPPING);
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | free_type(top);
break;
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | }
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | default:
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | if (t < top) {
Pike_compiler->type_stackp--;
push_finished_type(t);
push_finished_type(top);
free_type(top);
} else {
push_finished_type(t);
}
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | break;
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | }
}
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | return ret;
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | static void low_or_pike_types(struct pike_type *t1,
struct pike_type *t2,
int zero_implied)
{
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
struct pike_type *arg1 = t1;
struct pike_type *arg2 = t2;
#endif
#if 0
fprintf(stderr, " low_or_pike_types(");
simple_describe_type(t1);
fprintf(stderr, ", ");
simple_describe_type(t2);
fprintf(stderr, ")\n");
#endif
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(!t1)
{
if(!t2)
push_type(T_VOID);
else
push_finished_type(t2);
}
else if((!t2)
|| (t2->type == T_ZERO && zero_implied)
)
{
push_finished_type(t1);
}
else if (t1->type == T_ZERO && zero_implied)
{
push_finished_type(t2);
}
|
9f194c | 2007-04-01 | Henrik Grubbström (Grubba) | | else if (t1 == t2) {
push_finished_type(t1);
}
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | else if ((t1->type == T_OR) || (t2->type == T_OR)) {
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | int on_stack = 0;
type_stack_mark();
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | while (t1 || t2) {
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | struct pike_type *a = t1;
struct pike_type *b = t2;
struct pike_type *n1 = NULL;
struct pike_type *n2 = NULL;
int val;
if (t1 && t1->type == T_OR) {
a = t1->car;
n1 = t1->cdr;
}
if (t2 && t2->type == T_OR) {
b = t2->car;
n2 = t2->cdr;
}
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | if (a && b && ((a->type == T_OR) || (b->type == T_OR))) {
fprintf(stderr, " low_or_pike_types(");
simple_describe_type(arg1);
fprintf(stderr, ", ");
simple_describe_type(arg2);
fprintf(stderr, ")\n a:");
simple_describe_type(a);
fprintf(stderr, "\n b:");
simple_describe_type(b);
fprintf(stderr, ")\n");
Pike_fatal("Invalid type to lower_or_pike_types!\n");
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | }
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | #endif
val = lower_or_pike_types(a, b, zero_implied, on_stack);
if (val <= 0) t1 = n1;
if (val >= 0) t2 = n2;
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | on_stack = 1;
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | }
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | on_stack = pop_stack_mark();
while (on_stack > 1) {
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | push_reverse_joiner_type(T_OR);
|
1a8209 | 2007-04-17 | Henrik Grubbström (Grubba) | | on_stack--;
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | }
|
9f194c | 2007-04-01 | Henrik Grubbström (Grubba) | | }
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | else {
|
64ac75 | 2007-11-03 | Henrik Grubbström (Grubba) | | int val;
type_stack_mark();
val = lower_or_pike_types(t1, t2, zero_implied, 0);
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | if (val < 0) {
|
64ac75 | 2007-11-03 | Henrik Grubbström (Grubba) | | lower_or_pike_types(NULL, t2, zero_implied, 1);
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | } else if (val > 0) {
|
64ac75 | 2007-11-03 | Henrik Grubbström (Grubba) | | lower_or_pike_types(t1, NULL, zero_implied, 1);
} else {
pop_stack_mark();
return;
}
for (val = pop_stack_mark(); val > 1; val--) {
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | push_reverse_joiner_type(T_OR);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
}
struct pike_type *or_pike_types(struct pike_type *a,
struct pike_type *b,
int zero_implied)
{
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | struct pike_type *res;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | type_stack_mark();
|
a60941 | 2011-03-24 | Henrik Grubbström (Grubba) | | low_or_pike_types(a,b,1|zero_implied);
|
641a3f | 2007-04-16 | Henrik Grubbström (Grubba) | | res = pop_unfinished_type();
#if 0
fprintf(stderr, " ==> ");
simple_describe_type(res);
fprintf(stderr, "\n");
#endif
return res;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
static void even_lower_and_pike_types(struct pike_type *t1,
struct pike_type *t2)
{
while(t2->type == T_OR)
{
even_lower_and_pike_types(t1, t2->car);
t2 = t2->cdr;
}
if (t1->type == t2->type) {
if (t1->type == T_INT) {
INT32 i1, i2;
INT32 upper_bound, lower_bound;
|
d2361e | 2003-06-30 | Martin Stjernholm | | i1 = CDR_TO_INT(t1);
i2 = CDR_TO_INT(t2);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | upper_bound = MINIMUM(i1,i2);
|
d2361e | 2003-06-30 | Martin Stjernholm | | i1 = CAR_TO_INT(t1);
i2 = CAR_TO_INT(t2);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | lower_bound = MAXIMUM(i1,i2);
if (upper_bound >= lower_bound) {
push_int_type(lower_bound, upper_bound);
push_type(T_OR);
}
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | } else if (t1->type == T_STRING) {
push_type(T_ZERO);
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | even_lower_and_pike_types(t1->cdr, t2->cdr);
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_STRING);
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | push_type(T_OR);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
push_finished_type(t1);
push_type(T_OR);
}
}
}
static int lower_and_pike_types(struct pike_type *t1, struct pike_type *t2)
{
int is_complex = 0;
while(t1->type == T_OR)
{
is_complex |= lower_and_pike_types(t1->car, t2);
t1 = t1->cdr;
}
switch(t1->type) {
case T_ZERO:
case T_VOID:
break;
case T_STRING:
case T_FLOAT:
case T_INT:
even_lower_and_pike_types(t1, t2);
break;
default:
return 1;
}
return is_complex;
}
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | /* FIXME: T_STRING! */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | static int low_and_push_complex_pike_type(struct pike_type *type)
{
int is_complex = 0;
while(type->type == T_OR)
{
int new_complex;
new_complex = low_and_push_complex_pike_type(type->car);
if (new_complex) {
if (is_complex) {
push_type(T_OR);
} else {
is_complex = 1;
}
}
type = type->cdr;
}
switch(type->type) {
case T_VOID:
case T_ZERO:
case T_STRING:
case T_FLOAT:
case T_INT:
/* Simple type. Already handled. */
break;
default:
push_finished_type(type);
if (is_complex) {
push_type(T_OR);
}
return 1;
}
return is_complex;
}
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | /* FIXME: T_STRING! */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | static void low_and_pike_types(struct pike_type *t1,
struct pike_type *t2)
{
if(!t1 || t1->type == T_VOID ||
!t2 || t2->type == T_VOID)
{
push_type(T_VOID);
}
else if(t1->type == T_ZERO ||
t2->type == T_ZERO)
{
push_type(T_ZERO);
}
else if(t1->type == T_MIXED)
{
push_finished_type(t2);
}
else if(t2->type == T_MIXED)
{
push_finished_type(t1);
}
else if(t1->type == T_INT && t2->type == T_INT)
{
INT32 i1,i2;
INT32 upper_bound, lower_bound;
|
d2361e | 2003-06-30 | Martin Stjernholm | | i1 = CDR_TO_INT(t1);
i2 = CDR_TO_INT(t2);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | upper_bound = MINIMUM(i1,i2);
|
d2361e | 2003-06-30 | Martin Stjernholm | | i1 = CAR_TO_INT(t1);
i2 = CAR_TO_INT(t2);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | lower_bound = MAXIMUM(i1,i2);
if (upper_bound >= lower_bound) {
push_int_type(lower_bound, upper_bound);
} else {
/* No overlap! */
/* FIXME: Warn? */
push_type(T_VOID);
}
}
else if (t1->type == T_SCOPE)
{
if (t2->type == T_SCOPE) {
low_and_pike_types(t1->cdr, t2->cdr);
if (t1->car > t2->car)
|
d2361e | 2003-06-30 | Martin Stjernholm | | push_scope_type(CAR_TO_INT(t1));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | else
|
d2361e | 2003-06-30 | Martin Stjernholm | | push_scope_type(CAR_TO_INT(t2));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
low_and_pike_types(t1->cdr, t2);
|
d2361e | 2003-06-30 | Martin Stjernholm | | push_scope_type(CAR_TO_INT(t1));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
else if (t2->type == T_SCOPE)
{
low_and_pike_types(t1, t2->cdr);
|
d2361e | 2003-06-30 | Martin Stjernholm | | push_scope_type(CAR_TO_INT(t2));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | else if ((t1->type == T_STRING) && (t2->type == T_STRING)) {
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | low_and_pike_types(t1->cdr, t2->cdr);
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_STRING);
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | }
else if((t1->type == T_FLOAT) && (t2->type == T_FLOAT))
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
push_finished_type(t1);
}
else if(low_pike_types_le(t1, t2, 0, 0))
{
push_finished_type(t1);
}
else if(low_pike_types_le(t2, t1, 0, 0))
{
push_finished_type(t2);
}
else
{
push_type(T_ZERO);
if (lower_and_pike_types(t1, t2)) {
/* t1 contains complex types. */
if (low_and_push_complex_pike_type(t2)) {
/* t2 also contains complex types. */
low_and_push_complex_pike_type(t1);
|
eccb9d | 2020-09-11 | Henrik Grubbström (Grubba) | | push_reverse_joiner_type(T_AND);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | push_type(T_OR);
}
}
/* push_finished_type(t1); */
/* very_low_and_pike_types(t2,t1); */
}
}
struct pike_type *and_pike_types(struct pike_type *a,
struct pike_type *b)
{
type_stack_mark();
low_and_pike_types(a, b);
return pop_unfinished_type();
}
static struct pike_type *low_object_lfun_type(struct pike_type *t, short lfun)
{
struct program *p;
int i;
|
ff7275 | 2007-11-15 | Henrik Grubbström (Grubba) | | while ((t->type == PIKE_T_NAME) || (t->type == PIKE_T_ATTRIBUTE)) {
t = t->cdr;
}
#ifdef PIKE_DEBUG
if (t->type != T_OBJECT) {
fprintf(stderr, "Invalid type to low_object_lfun_type(");
simple_describe_type(t);
fprintf(stderr, ", \"%s\")\n", lfun_names[lfun]);
Pike_fatal("Invalid type to low_object_lfun_type: %d (expected OBJECT).\n",
t->type);
}
#endif /* PIKE_DEBUG */
|
d2361e | 2003-06-30 | Martin Stjernholm | | p = id_to_program(CDR_TO_INT(t));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(!p) return 0;
i=FIND_LFUN(p, lfun);
if(i==-1) return 0;
return ID_FROM_INT(p, i)->type;
}
|
0a3d9f | 2020-07-18 | Henrik Grubbström (Grubba) | | /**
* This function differs from low_object_lfun_type() above in
* that it handles more cases, falls back to the default lfun
* type (with a warning), and adds a reference to the returned
* type.
*/
static struct pike_type *find_lfun_type(struct pike_type *t, int lfun)
{
struct pike_type *ret = NULL;
struct svalue *s;
if (!t) return NULL;
loop:
switch(t->type) {
case PIKE_T_NAME:
case PIKE_T_ATTRIBUTE:
t = t->cdr;
goto loop;
case T_OBJECT:
{
struct program *p = NULL;
if (t->cdr) {
p = id_to_program(CDR_TO_INT(t));
}
if (p) {
int f = FIND_LFUN(p, lfun);
if (f != -1) {
struct identifier *id = ID_FROM_INT(p, f);
ret = id->type;
add_ref(ret);
return ret;
}
ref_push_string(lfun_strings[lfun]);
yytype_report(REPORT_WARNING, NULL, 0, NULL,
NULL, 0, t,
|
1247b7 | 2020-08-15 | Henrik Grubbström (Grubba) | | 1, "Expected object implementing lfun::%s().");
|
0a3d9f | 2020-07-18 | Henrik Grubbström (Grubba) | | }
break;
}
case T_PROGRAM:
t = t->car;
goto loop;
case T_FUNCTION:
case T_MANY:
t = t->cdr;
goto loop;
case T_OR:
case T_AND:
type_stack_mark();
push_finished_type(find_lfun_type(t->car, lfun));
push_finished_type(find_lfun_type(t->cdr, lfun));
push_type(t->type);
return pop_unfinished_type();
case T_MIXED:
case T_ZERO:
case T_VOID:
break;
default:
ref_push_string(lfun_strings[lfun]);
yytype_report(REPORT_WARNING, NULL, 0, NULL,
NULL, 0, t,
|
1247b7 | 2020-08-15 | Henrik Grubbström (Grubba) | | 1, "Expected object implementing lfun::%s().");
|
0a3d9f | 2020-07-18 | Henrik Grubbström (Grubba) | | break;
}
#if 0
/* FIXME: This does not work, as lfun_types contains narrow types
* (zero for arguments, etc), while we here want the wide type
* (mixed for arguments, etc).
*/
s = low_mapping_string_lookup(lfun_types, lfun_strings[lfun]);
#ifdef PIKE_DEBUG
if (!s) {
Pike_fatal("Unknown lfun: %s\n", STR0(lfun_strings[lfun]));
}
#endif
if (TYPEOF(*s) == PIKE_T_TYPE) {
ret = s->u.type;
add_ref(ret);
return ret;
}
return NULL;
#else
add_ref(function_type_string);
return function_type_string;
#endif
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
/******/
|
bdaf7f | 2020-09-18 | Henrik Grubbström (Grubba) | | struct remap_state {
unsigned char map[0x20];
unsigned INT32 allocated;
};
|
eaf18d | 2020-09-26 | Henrik Grubbström (Grubba) | | static int alloc_remap_marker(struct remap_state *remap, int marker,
enum pt_remap_flags flags)
|
bdaf7f | 2020-09-18 | Henrik Grubbström (Grubba) | | {
int ret;
|
0240eb | 2020-09-29 | Henrik Grubbström (Grubba) | | marker = marker & 0x0f;
|
bdaf7f | 2020-09-18 | Henrik Grubbström (Grubba) | |
|
0240eb | 2020-09-29 | Henrik Grubbström (Grubba) | | if (!remap) return '0' | marker;
|
3eb891 | 2020-09-21 | Henrik Grubbström (Grubba) | |
|
0240eb | 2020-09-29 | Henrik Grubbström (Grubba) | | if (flags & PT_FLAG_REMAP_SWAP_MARKERS) marker |= 0x10;
if ((ret = remap->map[marker])) return ret;
|
bdaf7f | 2020-09-18 | Henrik Grubbström (Grubba) | |
|
3eb891 | 2020-09-21 | Henrik Grubbström (Grubba) | | for (ret = 0; ret < 10; ret++) {
if (!(remap->allocated & (1 << ret))) {
remap->allocated |= (1 << ret);
ret |= '0';
|
0240eb | 2020-09-29 | Henrik Grubbström (Grubba) | | remap->map[marker] = ret;
|
3eb891 | 2020-09-21 | Henrik Grubbström (Grubba) | | return ret;
}
}
return 0;
}
|
eaf18d | 2020-09-26 | Henrik Grubbström (Grubba) | | static int remap_marker(struct remap_state *remap, int marker,
enum pt_remap_flags flags)
|
3eb891 | 2020-09-21 | Henrik Grubbström (Grubba) | | {
int ret;
|
0240eb | 2020-09-29 | Henrik Grubbström (Grubba) | | marker = marker & 0x0f;
if (!remap) return '0' | marker;
|
3eb891 | 2020-09-21 | Henrik Grubbström (Grubba) | |
|
0240eb | 2020-09-29 | Henrik Grubbström (Grubba) | | if (flags & PT_FLAG_REMAP_SWAP_MARKERS) marker |= 0x10;
|
3eb891 | 2020-09-21 | Henrik Grubbström (Grubba) | |
|
0240eb | 2020-09-29 | Henrik Grubbström (Grubba) | | if ((ret = remap->map[marker])) return ret;
|
bdaf7f | 2020-09-18 | Henrik Grubbström (Grubba) | |
for (ret = 0; ret < 10; ret++) {
if (!(remap->allocated & (1 << ret))) {
remap->allocated |= (1 << ret);
ret |= '0';
|
0240eb | 2020-09-29 | Henrik Grubbström (Grubba) | | remap->map[marker] = ret;
|
bdaf7f | 2020-09-18 | Henrik Grubbström (Grubba) | | return ret;
}
}
return 0;
}
|
eaf18d | 2020-09-26 | Henrik Grubbström (Grubba) | | static void free_marker(struct remap_state *remap, int marker,
enum pt_remap_flags flags)
|
bdaf7f | 2020-09-18 | Henrik Grubbström (Grubba) | | {
int m;
if (!remap) return;
|
0240eb | 2020-09-29 | Henrik Grubbström (Grubba) | | marker &= 0x0f;
if (flags & PT_FLAG_REMAP_SWAP_MARKERS) marker |= 0x10;
|
eaf18d | 2020-09-26 | Henrik Grubbström (Grubba) | |
|
0240eb | 2020-09-29 | Henrik Grubbström (Grubba) | | if (!(m = remap->map[marker])) return;
|
bdaf7f | 2020-09-18 | Henrik Grubbström (Grubba) | |
|
0240eb | 2020-09-29 | Henrik Grubbström (Grubba) | | remap->map[marker] = 0;
|
bdaf7f | 2020-09-18 | Henrik Grubbström (Grubba) | | remap->allocated &= ~(1 << (m & 0x0f));
}
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | static struct pike_type *lookup_marker(struct mapping *markers, int marker)
{
struct svalue key, *val;
if (!markers || !marker) return NULL;
SET_SVAL(key, T_INT, NUMBER_NUMBER, integer, marker);
val = low_mapping_lookup(markers, &key);
if (!val) return NULL;
if (TYPEOF(*val) == PIKE_T_TYPE) {
return val->u.type;
}
return NULL;
}
static void store_marker(struct mapping *markers, int marker,
struct pike_type *value)
{
struct svalue key, val;
if (!markers || !marker) return;
SET_SVAL(key, T_INT, NUMBER_NUMBER, integer, marker);
SET_SVAL(val, T_TYPE, 0, type, value);
mapping_insert(markers, &key, &val);
}
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | static void push_remap_markers(struct pike_type *t,
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | struct mapping *markers,
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | struct remap_state *remap,
|
eaf18d | 2020-09-26 | Henrik Grubbström (Grubba) | | enum pt_remap_flags flags)
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | {
if (!remap) {
push_finished_type(t);
return;
}
/* FIXME: Use the type flags to detect whether we can just push
* the type verbatim.
*/
switch(t->type & PIKE_T_MASK) {
case T_ASSIGN:
{
|
957a00 | 2020-09-22 | Henrik Grubbström (Grubba) | | int marker = alloc_remap_marker(remap, CAR_TO_INT(t), flags);
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | |
if (!markers || !(flags & PT_FLAG_REMAP_EVAL_MARKERS)) {
push_remap_markers(t->cdr, markers, remap, flags);
push_assign_type(marker);
} else {
struct pike_type *old = lookup_marker(markers, marker);
struct pike_type *new = t->cdr;
if (old) {
new = or_pike_types(old, new, 0);
} else {
add_ref(new);
}
store_marker(markers, marker, new);
free_pike_type(new);
push_remap_markers(t->cdr, markers, remap, flags);
}
if (flags & PT_FLAG_REMAP_BOTH_MARKERS) {
marker = alloc_remap_marker(remap, CAR_TO_INT(t),
flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
if (!markers || !(flags & PT_FLAG_REMAP_EVAL_MARKERS)) {
push_assign_type(marker);
} else {
struct pike_type *old = lookup_marker(markers, marker);
struct pike_type *new = t->cdr;
if (old) {
new = or_pike_types(old, new, 0);
} else {
add_ref(new);
}
store_marker(markers, marker, new);
free_pike_type(new);
push_remap_markers(t->cdr, markers, remap, flags);
switch(flags & PT_FLAG_REMAP_BOTH_MARKERS_MASK) {
case PT_FLAG_REMAP_BOTH_MARKERS_AND:
push_type(T_AND);
break;
case PT_FLAG_REMAP_BOTH_MARKERS_OR:
push_type(T_OR);
break;
default:
Pike_fatal("Unsupported marker joining method.\n");
break;
}
}
}
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | break;
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
|
957a00 | 2020-09-22 | Henrik Grubbström (Grubba) | | int marker = remap_marker(remap, t->type, flags);
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | struct pike_type *value = lookup_marker(markers, marker);
if (value) {
push_remap_markers(value, markers, remap, flags);
} else if ((markers) && (flags & PT_FLAG_REMAP_EVAL_MARKERS)) {
/* Marker without matching assign. */
/* FIXME: Report error? */
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | push_type(T_MIXED);
} else {
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | |
/* Remap the marker. */
if (!marker) {
/* FIXME: Improve error handling here. */
push_type(T_MIXED);
} else {
push_type(marker);
}
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | }
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | |
|
eaf18d | 2020-09-26 | Henrik Grubbström (Grubba) | | if (flags & PT_FLAG_REMAP_BOTH_MARKERS) {
marker = remap_marker(remap, t->type,
flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | value = lookup_marker(markers, marker);
if (value) {
push_remap_markers(value, markers, remap, flags);
} else if ((markers) && (flags & PT_FLAG_REMAP_EVAL_MARKERS)) {
/* Marker without matching assign. */
/* FIXME: Report error? */
|
a01d93 | 2020-09-24 | Henrik Grubbström (Grubba) | | push_type(T_MIXED);
} else {
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | |
/* Remap the marker. */
if (!marker) {
/* FIXME: Improve error handling here. */
push_type(T_MIXED);
} else {
push_type(marker);
}
|
a01d93 | 2020-09-24 | Henrik Grubbström (Grubba) | | }
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | |
|
eaf18d | 2020-09-26 | Henrik Grubbström (Grubba) | | switch(flags & PT_FLAG_REMAP_BOTH_MARKERS_MASK) {
case PT_FLAG_REMAP_BOTH_MARKERS_AND:
|
a01d93 | 2020-09-24 | Henrik Grubbström (Grubba) | | push_type(T_AND);
break;
|
eaf18d | 2020-09-26 | Henrik Grubbström (Grubba) | | case PT_FLAG_REMAP_BOTH_MARKERS_OR:
|
a01d93 | 2020-09-24 | Henrik Grubbström (Grubba) | | push_type(T_OR);
break;
default:
Pike_fatal("Unsupported marker joining method.\n");
break;
}
}
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | break;
}
|
674bb6 | 2020-09-22 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(t->cdr, markers, remap, flags);
|
90dca5 | 2020-09-23 | Henrik Grubbström (Grubba) | | push_type_name((struct pike_string *)(t->car));
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | break;
|
674bb6 | 2020-09-22 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(t->cdr, markers, remap, flags);
|
90dca5 | 2020-09-23 | Henrik Grubbström (Grubba) | | push_type_attribute((struct pike_string *)(t->car));
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | break;
case T_SCOPE:
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(t->cdr, markers, remap, flags);
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | push_scope_type(CAR_TO_INT(t));
break;
case PIKE_T_OPERATOR:
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(t->car, markers, remap, flags);
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | |
if (t->type & 0x8000) {
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(t->cdr, markers, remap, flags);
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | push_reverse_type(t->type);
} else {
switch(t->type) {
case PIKE_T_FIND_LFUN:
push_type_operator(t->type, t->cdr);
break;
default:
Pike_fatal("Unsupported operator %d in push_remap_markers().\n",
t->type);
break;
}
}
break;
/* Verbatim */
case T_OBJECT:
case T_VOID:
case T_ZERO:
case T_INT:
case T_FLOAT:
case PIKE_T_MIXED:
push_finished_type(t);
break;
/* Unary */
case T_PROGRAM:
case T_MULTISET:
case T_NOT:
case T_TYPE:
case PIKE_T_AUTO:
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(t->car, markers, remap, flags);
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | push_type(t->type);
break;
/* Binary */
case T_OR:
case T_AND:
case T_FUNCTION:
case T_MANY:
case T_TUPLE:
case T_MAPPING:
case PIKE_T_RING:
case T_ARRAY:
case T_STRING:
case PIKE_T_TRANSITIVE:
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(t->car, markers, remap, flags);
push_remap_markers(t->cdr, markers, remap, flags);
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | push_reverse_type(t->type);
break;
}
}
/**
* Remap markers (if any) in the type.
*/
static struct pike_type *remap_markers(struct pike_type *t,
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | struct mapping *markers,
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | struct remap_state *remap,
|
eaf18d | 2020-09-26 | Henrik Grubbström (Grubba) | | enum pt_remap_flags flags)
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | {
type_stack_mark();
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(t, markers, remap, flags);
|
6494d1 | 2020-09-20 | Henrik Grubbström (Grubba) | | return pop_unfinished_type();
}
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | static struct pike_type *low_intersect_types(struct pike_type *a,
struct pike_type *b,
struct remap_state *remap,
enum pt_cmp_flags aflags,
enum pt_cmp_flags bflags,
enum pt_remap_flags remap_flags);
|
b98ea3 | 2020-10-10 | Henrik Grubbström (Grubba) | |
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | static struct pike_type *expand_transitive(struct pike_type *fun,
struct pike_type **markers,
int flags);
|
456578 | 2020-10-11 | Henrik Grubbström (Grubba) | | static void push_binop(enum pt_binop op)
{
struct pike_type *a, *b;
switch(op) {
case PT_BINOP_AND:
push_type(T_AND);
break;
case PT_BINOP_OR:
push_type(T_OR);
break;
case PT_BINOP_B:
a = low_pop_type();
b = low_pop_type();
push_finished_type(b);
free_type(a);
free_type(b);
break;
case PT_BINOP_A:
a = low_pop_type();
b = low_pop_type();
push_finished_type(a);
free_type(a);
free_type(b);
break;
case PT_BINOP_ALL:
a = low_pop_type();
b = low_pop_type();
push_type(T_MIXED);
free_type(a);
free_type(b);
break;
case PT_BINOP_NONE:
Pike_fatal("Unsupported binop.\n");
case PT_BINOP_MINUS:
case PT_BINOP_INVERSE_MINUS:
/* One of the minterms. */
if (op & PT_BINOP_NOT_B) {
a = low_pop_type();
push_type(T_NOT);
push_finished_type(a);
free_type(a);
}
if (op & PT_BINOP_NOT_A) {
push_type(T_NOT);
}
push_type(T_AND);
break;
case PT_BINOP_NOR:
push_type(T_OR);
push_type(T_NOT);
break;
default:
{
enum pt_binop inv_op = (~op) & PT_BINOP_ALL;
if (!(inv_op & (inv_op - 1))) {
/* An inverted minterm. */
if (inv_op & PT_BINOP_NOT_B) {
a = low_pop_type();
push_type(T_NOT);
push_finished_type(a);
push_type(T_NOT);
free_type(a);
}
if (inv_op & PT_BINOP_NOT_A) {
push_type(T_NOT);
}
push_type(T_OR);
break;
}
/* FIXME: XOR, NXOR */
Pike_fatal("Unsupported binary type operation: 0x%02x\n", op);
}
}
}
static void push_reverse_binop(enum pt_binop op)
{
/* Swap bits 1 & 2 in op to reverse the meanings of the arguments. */
push_binop((op & PT_BINOP_XNOR) |
((op & PT_BINOP_MINUS) ? PT_BINOP_INVERSE_MINUS : 0) |
((op & PT_BINOP_INVERSE_MINUS) ? PT_BINOP_MINUS : 0));
}
|
b98ea3 | 2020-10-10 | Henrik Grubbström (Grubba) | | /**
* Low-level intersection (aka And) of two types.
*
* Note:
* There are two major operating modes; the external, where
* the two types have unrelated markers, which then need to
* be remapped in the result, and the internal, where the
* two types have related markers (this mode is used mainly
* when evaluating a type).
*
* The internal mode is indicated via the remap state being NULL.
*/
static struct pike_type *low_type_binop(enum pt_binop op,
struct pike_type *a,
struct pike_type *b,
struct remap_state *remap,
enum pt_cmp_flags aflags,
enum pt_cmp_flags bflags,
enum pt_remap_flags remap_flags)
{
struct pike_type *tmp, *tmp2, *ret;
struct pike_type *aret = NULL, *bret = NULL;
enum pt_cmp_flags avoidable;
enum pt_cmp_flags bvoidable;
switch(op) {
case PT_BINOP_AND:
case PT_BINOP_MINUS:
break;
case PT_BINOP_INVERSE_MINUS:
tmp = a;
a = b;
b = tmp;
avoidable = aflags;
aflags = bflags;
bflags = avoidable;
remap_flags ^= PT_FLAG_REMAP_SWAP_MARKERS;
op = PT_BINOP_MINUS;
break;
case PT_BINOP_NOR:
type_stack_mark();
push_remap_markers(a, NULL, remap, remap_flags);
push_remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
push_type(T_OR);
push_type(T_NOT);
return pop_unfinished_type();
case PT_BINOP_OR:
type_stack_mark();
push_remap_markers(a, NULL, remap, remap_flags);
push_remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
push_type(T_OR);
return pop_unfinished_type();
#ifdef PIKE_DEBUG
default:
Pike_fatal("Unsupported binary type operation: 0x%02x\n", op);
#endif
}
if (!a || !b) return NULL;
if (a == b) {
if (op & PT_BINOP_AND) {
/* FIXME: Perform masking of remap_flags here. */
return remap_markers(a, NULL, remap,
remap_flags | PT_FLAG_REMAP_BOTH_MARKERS_AND);
} else {
return NULL;
}
}
/* First check for markers. */
switch(a->type) {
case T_ASSIGN:
{
int marker = alloc_remap_marker(remap, CAR_TO_INT(a), remap_flags);
tmp = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags);
if (tmp) {
type_stack_mark();
push_finished_type(tmp);
push_assign_type(marker);
free_type(tmp);
return pop_unfinished_type();
}
free_marker(remap, CAR_TO_INT(a), remap_flags);
return NULL;
}
}
switch(b->type) {
case T_ASSIGN:
{
int marker = alloc_remap_marker(remap, CAR_TO_INT(b),
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
tmp = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags);
if (tmp) {
type_stack_mark();
push_finished_type(tmp);
push_assign_type(marker);
free_type(tmp);
return pop_unfinished_type();
}
free_marker(remap, CAR_TO_INT(b),
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
return NULL;
}
}
/* Attributes and names. */
switch(a->type) {
case PIKE_T_NAME:
tmp = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type_name((struct pike_string *)(a->car));
free_type(tmp);
return pop_unfinished_type();
case PIKE_T_ATTRIBUTE:
tmp = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type_attribute((struct pike_string *)(a->car));
free_type(tmp);
return pop_unfinished_type();
case T_SCOPE:
tmp = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_scope_type(CAR_TO_INT(a));
free_type(tmp);
return pop_unfinished_type();
}
switch(b->type) {
case PIKE_T_NAME:
tmp = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type_name((struct pike_string *)(b->car));
free_type(tmp);
return pop_unfinished_type();
case PIKE_T_ATTRIBUTE:
tmp = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type_attribute((struct pike_string *)(b->car));
free_type(tmp);
return pop_unfinished_type();
case T_SCOPE:
tmp = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_scope_type(CAR_TO_INT(b));
free_type(tmp);
return pop_unfinished_type();
}
/* Check consolidated types. */
switch(a->type) {
case T_OR:
/* (a1 | a2) op b <==> (a1 op b) | (a2 op b) */
tmp = low_type_binop(op, a->car, b, remap, aflags, bflags, remap_flags);
tmp2 = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp2) return tmp;
if (!tmp) return tmp2;
type_stack_mark();
push_finished_type(tmp);
push_finished_type(tmp2);
push_reverse_type(T_OR);
free_type(tmp);
free_type(tmp2);
return pop_unfinished_type();
case T_AND:
tmp = low_type_binop(op, a->car, b, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
tmp2 = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp2) {
free_type(tmp);
return NULL;
}
switch(op) {
case PT_BINOP_AND:
/* NB: Attempt to avoid keeping the result from inverted types,
* in order to reduce type expansion.
*/
if (a->car->type == T_NOT) {
/* (!a1 & a2) & b <==> (a2 & b) & !a1 */
free_type(tmp);
tmp = remap_markers(a->car, NULL, remap, remap_flags);
} else if (a->cdr->type == T_NOT) {
/* (a1 & !a2) & b <==> (a1 & b) & !a2 */
free_type(tmp2);
tmp2 = remap_markers(a->cdr, NULL, remap, remap_flags);
}
break;
}
type_stack_mark();
push_finished_type(tmp);
push_finished_type(tmp2);
push_reverse_type(T_AND);
free_type(tmp);
free_type(tmp2);
return pop_unfinished_type();
case T_NOT:
/* Rotate the opcode 2 bits.
*
* This converts A to ~A and vice versa.
*/
op = ((op << 2) | (op >> 2)) & PT_BINOP_ALL;
return low_type_binop(op, a->car, b,
remap, aflags, bflags, remap_flags);
}
switch(b->type) {
case T_OR:
tmp = low_type_binop(op, a, b->car, remap, aflags, bflags, remap_flags);
tmp2 = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags);
if (!tmp2) return tmp;
if (!tmp) return tmp2;
type_stack_mark();
push_finished_type(tmp);
push_finished_type(tmp2);
push_reverse_type(T_OR);
free_type(tmp);
free_type(tmp2);
return pop_unfinished_type();
case T_AND:
tmp = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
tmp2 = low_type_binop(op, a, b->car, remap, aflags, bflags, remap_flags);
if (!tmp2) {
free_type(tmp2);
return NULL;
}
switch(op) {
case PT_BINOP_AND:
/* NB: Attempt to avoid keeping the result from inverted types,
* in order to reduce type expansion.
*/
if (b->car->type == T_NOT) {
free_type(tmp);
tmp = remap_markers(b->car, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
} else if (b->cdr->type == T_NOT) {
free_type(tmp2);
tmp2 = remap_markers(b->cdr, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
}
break;
}
type_stack_mark();
push_finished_type(tmp);
push_finished_type(tmp2);
push_reverse_type(T_AND);
free_type(tmp);
free_type(tmp2);
return pop_unfinished_type();
case T_NOT:
/* Swap the bits of the opcode pairwise.
*
* This converts B to ~B and vice versa.
*/
op = (((op & PT_BINOP_B) << 1) | ((op >> 1) & PT_BINOP_B)) & PT_BINOP_ALL;
return low_type_binop(op, a, b->car,
remap, aflags, bflags, remap_flags);
}
/* NB: Complex types from this point onwards are containers,
* and the voidable property does not propagate into them.
*/
avoidable = aflags & PT_FLAG_CMP_VOIDABLE;
aflags &= ~PT_FLAG_CMP_VOIDABLE;
bvoidable = bflags & PT_FLAG_CMP_VOIDABLE;
bflags &= ~PT_FLAG_CMP_VOIDABLE;
/* Check implicit casting. */
loop:
switch(TWOT(a->type & PIKE_T_MASK, b->type & PIKE_T_MASK)) {
case TWOT(T_PROGRAM, T_FUNCTION):
case TWOT(T_PROGRAM, T_MANY):
aret = a->car;
a = low_object_lfun_type(aret, LFUN_CREATE);
if (!a) {
a = void_function_type_string;
}
goto loop;
case TWOT(T_FUNCTION, T_PROGRAM):
case TWOT(T_MANY, T_PROGRAM):
bret = b->car;
b = low_object_lfun_type(bret, LFUN_CREATE);
if (!b) {
b = void_function_type_string;
}
goto loop;
case TWOT(T_OBJECT, T_FUNCTION):
case TWOT(T_OBJECT, T_MANY):
case TWOT(T_OBJECT, T_PROGRAM):
case TWOT(T_OBJECT, PIKE_T_TRANSITIVE):
a = low_object_lfun_type(a, LFUN_CALL);
if (!a) return NULL;
goto loop;
case TWOT(T_FUNCTION, T_OBJECT):
case TWOT(T_MANY, T_OBJECT):
case TWOT(T_PROGRAM, T_OBJECT):
case TWOT(PIKE_T_TRANSITIVE, T_OBJECT):
b = low_object_lfun_type(b, LFUN_CALL);
if (!b) return NULL;
goto loop;
case TWOT(PIKE_T_TRANSITIVE, T_FUNCTION):
case TWOT(PIKE_T_TRANSITIVE, T_MANY):
case TWOT(PIKE_T_TRANSITIVE, T_PROGRAM):
case TWOT(PIKE_T_TRANSITIVE, PIKE_T_TRANSITIVE):
tmp = expand_transitive(a, NULL, 0);
ret = low_type_binop(op, tmp, b, remap, aflags, bflags, remap_flags);
free_type(tmp);
return ret;
case TWOT(T_FUNCTION, PIKE_T_TRANSITIVE):
case TWOT(T_MANY, PIKE_T_TRANSITIVE):
case TWOT(T_PROGRAM, PIKE_T_TRANSITIVE):
tmp = expand_transitive(b, NULL, 0);
ret = low_type_binop(op, a, tmp, remap, aflags, bflags, remap_flags);
free_type(tmp);
return ret;
case TWOT(T_FUNCTION, PIKE_T_OPERATOR):
case TWOT(PIKE_T_OPERATOR, T_FUNCTION):
type_stack_mark();
push_finished_type(a);
push_finished_type(b);
switch(op) {
case PT_BINOP_AND:
push_reverse_type(T_AND);
break;
case PT_BINOP_OR:
push_reverse_type(T_OR);
break;
case PT_BINOP_MINUS:
push_type(T_NOT);
push_reverse_type(T_AND);
break;
default:
Pike_fatal("Unsupported.\n");
}
return pop_unfinished_type();
case TWOT(T_FUNCTION, T_FUNCTION):
case TWOT(T_FUNCTION, T_MANY):
case TWOT(T_MANY, T_FUNCTION):
case TWOT(T_MANY, T_MANY):
/* NB: For simplicity in the (common case)
* many(assign(m, mixed), m),
* we expand the many node (as required) to
* function(assign(m, mixed), many(assign(m, mixed), m)),
* and leave it to the evaluator to join the multiple
* assignments with or. The alternative (and stricter) would
* be to allocate a new marker for each step of the expansion
* and to have explicit or nodes:
* function(assign(m1, mixed), many(assign(m2, mixed), or(m1, m2))).
*/
{
int nargs;
struct pike_type *ai = a;
struct pike_type *bi = b;
int got_empty = 0;
int got_full = 0;
type_stack_mark();
type_stack_mark(); /* To keep track of the number of args. */
while(1) {
/* Invariant:
* a->type and b->type are either T_FUNCTION or T_MANY.
*/
enum pt_cmp_flags avoidable = 0;
enum pt_cmp_flags bvoidable = 0;
/* Check the argument. */
/* NB: The MANY argument is always voidable. */
if (ai->type == T_MANY) avoidable |= PT_FLAG_CMP_VOIDABLE;
if (bi->type == T_MANY) bvoidable |= PT_FLAG_CMP_VOIDABLE;
tmp = low_type_binop(op, ai->car, bi->car, remap,
aflags | avoidable,
bflags | bvoidable,
remap_flags);
switch(op) {
case PT_BINOP_AND:
if (!tmp) {
if (avoidable && bvoidable) {
/* NB: The VOIDABLE flag only affects comparisons with
* explicit void. If both arguments have implicit void,
* and nothing other in common, we arrive here.
*/
push_type(T_VOID);
} else {
goto function_fail;
}
}
push_finished_type(tmp);
free_type(tmp);
if (avoidable && bvoidable) {
/* Time to check the return types. */
if (!aret) aret = ai->cdr;
if (!bret) bret = bi->cdr;
tmp = low_type_binop(op, aret, bret, remap,
aflags, bflags, remap_flags);
if (!tmp) goto function_fail;
nargs = pop_stack_mark();
push_finished_type(tmp);
free_type(tmp);
nargs--;
push_reverse_type(T_MANY);
while (nargs--) {
push_reverse_type(T_FUNCTION);
}
return pop_unfinished_type();
}
break;
case PT_BINOP_MINUS:
if (!tmp) {
if (got_full) goto function_next;
got_empty = 1;
} else {
if (tmp == ai) {
got_full = 1;
} else {
free_type(tmp);
break;
}
free_type(tmp);
if (got_empty) goto function_next;
}
if (avoidable && bvoidable) {
/* Time to check the return types. */
if (!aret) aret = ai->cdr;
if (!bret) bret = bi->cdr;
tmp = low_type_binop(op, aret, bret, NULL, aflags, bflags,
remap_flags);
if (!tmp) {
if (got_full) goto function_next;
got_empty = 1;
} else {
if (tmp == aret) {
got_full = 1;
} else {
free_type(tmp);
goto function_next;
}
free_type(tmp);
if (got_empty) goto function_next;
}
if (!got_full) {
return NULL;
}
type_stack_mark();
push_remap_markers(a, NULL, remap, remap_flags);
return pop_unfinished_type();
}
break;
default:
Pike_fatal("Unsupported.\n");
}
function_next:
/* Advance to the next argument. */
if (ai->type == T_FUNCTION) {
ai = ai->cdr;
}
if (bi->type == T_FUNCTION) {
bi = bi->cdr;
}
if ((ai->type != T_FUNCTION) && (ai->type != T_MANY)) {
if (aret) {
Pike_fatal("Unsupported type operation.\n");
}
break;
}
if ((bi->type != T_FUNCTION) && (bi->type != T_MANY)) {
if (bret) {
Pike_fatal("Unsupported type operation.\n");
}
break;
}
}
nargs = pop_stack_mark();
if (op & PT_BINOP_NOT_B) {
nargs = 0;
ai = a;
bi = b;
}
/* Either of a and/or b is a complex type. */
push_remap_markers(ai, NULL, remap, remap_flags);
push_remap_markers(bi, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
switch(op) {
case PT_BINOP_AND:
push_reverse_type(T_AND);
break;
case PT_BINOP_OR:
push_reverse_type(T_OR);
break;
case PT_BINOP_MINUS:
push_type(T_NOT);
push_reverse_type(T_AND);
break;
default:
Pike_fatal("Unsupported.\n");
}
while (nargs--) {
push_reverse_type(T_FUNCTION);
}
return pop_unfinished_type();
function_fail:
compiler_discard_type();
pop_stack_mark();
return NULL;
}
case TWOT(T_VOID, T_ZERO):
if (op & PT_BINOP_AND) {
/* Return zero. */
add_ref(b);
return b;
}
return NULL;
case TWOT(T_ZERO, T_VOID):
if (op & PT_BINOP_AND) {
/* Return zero. */
add_ref(a);
return a;
}
return NULL;
case TWOT(T_ZERO, T_INT):
if ((CAR_TO_INT(b) <= 0) && (CDR_TO_INT(b) >= 0)) {
if (op == PT_BINOP_AND) {
add_ref(a);
return a;
} else if (op == PT_BINOP_MINUS) {
return NULL;
}
}
if (op == PT_BINOP_AND) {
return NULL;
} else if (op == PT_BINOP_MINUS) {
add_ref(a);
return a;
}
break;
case TWOT(T_INT, T_ZERO):
if ((CAR_TO_INT(a) <= 0) && (CDR_TO_INT(a) >= 0)) {
if (op == PT_BINOP_AND) {
add_ref(b);
return b;
} else if (op == PT_BINOP_MINUS) {
return NULL;
}
}
if (op == PT_BINOP_AND) {
return NULL;
} else if (op == PT_BINOP_MINUS) {
type_stack_mark();
if (CAR_TO_INT(a) < 0) {
push_int_type(CAR_TO_INT(a), -1);
}
if (CDR_TO_INT(a) > 0) {
push_int_type(1, CDR_TO_INT(a));
if (CAR_TO_INT(a) < 0) {
push_reverse_type(T_OR);
}
}
return pop_unfinished_type();
}
break;
/* T_TYPE and T_PROGRAM are essentially the same thing. */
case TWOT(T_TYPE, T_TYPE):
case TWOT(T_TYPE, T_PROGRAM):
case TWOT(T_PROGRAM, T_TYPE):
case TWOT(T_PROGRAM, T_PROGRAM):
tmp = low_type_binop(op, a->car, b->car, remap,
aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
if (a->type == b->type) {
push_type(a->type);
} else {
push_type(T_TYPE);
}
free_type(tmp);
return pop_unfinished_type();
case TWOT(T_TYPE, T_FUNCTION):
case TWOT(T_TYPE, T_MANY):
case TWOT(T_TYPE, PIKE_T_TRANSITIVE):
type_stack_mark();
push_finished_type(a->car);
push_type(T_VOID);
push_type(T_MANY);
push_type(T_MIXED);
push_type(T_FUNCTION);
tmp = pop_unfinished_type();
ret = low_type_binop(op, tmp, b, remap, aflags, bflags, remap_flags);
free_type(tmp);
return ret;
case TWOT(T_FUNCTION, T_TYPE):
case TWOT(T_MANY, T_TYPE):
case TWOT(PIKE_T_TRANSITIVE, T_TYPE):
type_stack_mark();
push_finished_type(b->car);
push_type(T_VOID);
push_type(T_MANY);
push_type(T_MIXED);
push_type(T_FUNCTION);
tmp = pop_unfinished_type();
ret = low_type_binop(op, a, tmp, remap, aflags, bflags, remap_flags);
free_type(tmp);
return ret;
#if 0
/* FIXME: */
case PIKE_T_RING:
#endif
}
if (a->type == T_VOID) {
if (bvoidable) {
if (op & PT_BINOP_AND) {
add_ref(a);
return a;
} else {
return NULL;
}
}
if (op == PT_BINOP_MINUS) {
add_ref(a);
return a;
}
return NULL;
}
if (b->type == T_VOID) {
if (op == PT_BINOP_MINUS) {
add_ref(a);
return a;
}
if (avoidable) {
add_ref(b);
return b;
}
return NULL;
}
if (b->type == T_MIXED) {
/* NB: a being void has been handled above. */
if (op == PT_BINOP_MINUS) return NULL;
return remap_markers(a, NULL, remap, remap_flags);
}
if (a->type == T_MIXED) {
type_stack_mark();
push_remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
if (op == PT_BINOP_MINUS) {
push_type(T_NOT);
}
return pop_unfinished_type();
}
switch(a->type) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int marker = remap_marker(remap, a->type, remap_flags);
if (!marker) return NULL;
tmp = remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
if (op == PT_BINOP_MINUS) {
push_type(T_NOT);
}
push_type(marker);
push_reverse_type(T_AND);
free_type(tmp);
return pop_unfinished_type();
}
}
switch(b->type) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int marker = remap_marker(remap, b->type,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
if (!marker) return NULL;
tmp = remap_markers(a, NULL, remap, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type(marker);
if (op == PT_BINOP_MINUS) {
push_type(T_NOT);
}
push_reverse_type(T_AND);
free_type(tmp);
return pop_unfinished_type();
}
}
if (a->type != b->type) {
if (((a->type & PIKE_T_MASK) == PIKE_T_OPERATOR) ||
((b->type & PIKE_T_MASK) == PIKE_T_OPERATOR)) {
type_stack_mark();
push_remap_markers(a, NULL, remap, remap_flags);
push_remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
if (op == PT_BINOP_MINUS) {
push_type(T_NOT);
}
push_reverse_type(T_AND);
return pop_unfinished_type();
}
return NULL;
}
switch(a->type) {
case T_VOID:
case T_ZERO:
case T_FLOAT:
/* Not reached. Should be handled by the a == b test at
* the beginning of the function.
*/
Pike_fatal("Type hashing has duplicates.\n");
return NULL;
case T_INT:
{
INT32 bounds[6] = { MIN_INT32, };
int ab[6] = { 0, 0, };
int i;
int nbounds = 1;
INT32 bound;
INT32 other;
/* NB: The bits in ab are selected so that they match
* the shifts for the minterms in enum pt_binop.
*/
bound = CAR_TO_INT(a);
for (i = nbounds; i-- && bounds[i] > bound;) {
ab[i] |= 2;
}
if (bounds[i] < bound) {
/* We need to insert a bound. */
i++;
memmove(bounds + i + 1, bounds + i,
sizeof(bounds[i]) * (nbounds - i));
nbounds++;
bounds[i] = bound;
} else if (bounds[i] == bound) {
ab[i] |= 2;
}
bound = CDR_TO_INT(a);
if (bound < MAX_INT32) {
bound++;
for (i = nbounds; i-- && bounds[i] > bound;) {
ab[i] &= ~2;
}
if (bounds[i] < bound) {
/* We need to insert a bound. */
i++;
memmove(bounds + i + 1, bounds + i,
sizeof(bounds[i]) * (nbounds - i));
nbounds++;
bounds[i] = bound;
} else if (bounds[i] == bound) {
ab[i] &= ~2;
}
}
bound = CAR_TO_INT(b);
for (i = nbounds; i-- && bounds[i] > bound;) {
ab[i] |= 1;
}
if (bounds[i] < bound) {
/* We need to insert a bound. */
i++;
memmove(bounds + i + 1,
bounds + i, sizeof(bounds[i]) * (nbounds - i));
nbounds++;
bounds[i] = bound;
} else if (bounds[i] == bound) {
ab[i] |= 1;
}
bound = CDR_TO_INT(b);
if (bound < MAX_INT32) {
bound++;
for (i = nbounds; i-- && bounds[i] > bound;) {
ab[i] &= ~1;
}
if (bounds[i] < bound) {
/* We need to insert a bound. */
i++;
memmove(bounds + i + 1, bounds + i,
sizeof(bounds[i]) * (nbounds - i));
nbounds++;
bounds[i] = bound;
} else if (bounds[i] == bound) {
ab[i] &= ~1;
}
}
type_stack_mark();
for (i = 0; i < nbounds;) {
bound = MAX_INT32;
for (i = 0; i < nbounds; i++) {
if ((PT_BINOP_NOR >> ab[i]) & op) {
/* Found start of range. */
bound = bounds[i];
}
}
if (i == nbounds) break;
for (; i < nbounds; i++) {
if (!((PT_BINOP_NOR >> ab[i]) & op)) {
/* Found end of range. */
break;
}
}
if (i < nbounds) {
push_int_type(bound, bounds[i]-1);
} else {
push_int_type(bound, MAX_INT32);
}
}
nbounds = peek_stack_mark();
if (!nbounds) {
pop_stack_mark();
return NULL;
}
/* NB: Loop starts at 1! */
for (i = 1; i < nbounds; i++) {
push_type(T_OR);
}
return pop_unfinished_type();
}
case T_ARRAY:
case T_MAPPING:
case T_STRING:
tmp = low_type_binop(op, a->car, b->car, remap,
aflags, bflags, remap_flags);
if (!tmp && (op == PT_BINOP_AND)) return NULL;
tmp2 = low_type_binop(op, a->cdr, b->cdr, remap,
aflags, bflags, remap_flags);
if (!tmp2) {
if (op == PT_BINOP_AND) {
free_type(tmp);
return NULL;
} else if (!tmp) {
return NULL;
}
}
type_stack_mark();
if (op == PT_BINOP_MINUS) {
if (tmp) {
push_finished_type(a->cdr);
push_finished_type(tmp);
push_reverse_type(a->type);
free_type(tmp);
}
if (tmp2) {
push_finished_type(tmp2);
push_finished_type(a->car);
push_reverse_type(a->type);
free_type(tmp2);
}
if (peek_stack_mark() == 2) push_type(T_OR);
} else {
/* PT_BINOP_AND */
push_finished_type(tmp);
push_finished_type(tmp2);
push_reverse_type(a->type);
free_type(tmp);
free_type(tmp2);
}
return pop_unfinished_type();
case T_MULTISET:
case T_PROGRAM:
case T_TYPE:
tmp = low_type_binop(op, a->car, b->car, remap,
aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type(a->type);
return pop_unfinished_type();
/* FIXME: AND only from this point on. ======================= */
case T_OBJECT:
if (!a->cdr) {
add_ref(b);
return b;
}
if (!b->cdr) {
add_ref(a);
return a;
}
if (a->cdr == b->cdr) {
/* We know that they differ due to the a == b test at
* the befinning of the function. The only way they
* can differ is that car differs. There are only two
* valid values for car, so select the stricter (ie 'is-a')
*/
type_stack_mark();
push_object_type(1, CDR_TO_INT(a));
return pop_unfinished_type();
}
if (a->car && b->car) {
/* This is only possible if a->cdr == b->cdr, but that is
* handled above.
*/
return NULL;
}
{
struct program *ap = id_to_program(CDR_TO_INT(a));
struct program *bp = id_to_program(CDR_TO_INT(b));
if (!b->car && implements(ap, bp)) {
add_ref(a);
return a;
}
if (!a->car && implements(bp, ap)) {
add_ref(b);
return b;
}
if ((a->car == b->car) && is_compatible(ap, bp)) {
/* Both car must be 0 due to test above.
* It is possible to implement a class that
* implements both of the classes.
*/
type_stack_mark();
push_finished_type(a);
push_finished_type(b);
push_reverse_type(T_AND);
return pop_unfinished_type();
}
return NULL;
}
}
/* Leaf type. */
add_ref(a);
return a;
}
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | /**
* Low-level subtraction (aka And-not) of two types.
*
* Note:
* There are two major operating modes; the external, where
* the two types have unrelated markers, which then need to
* be remapped in the result, and the internal, where the
* two types have related markers (this mode is used mainly
* when evaluating a type).
*
* The internal mode is indicated via the remap state being NULL.
*/
static struct pike_type *low_subtract_types(struct pike_type *a,
struct pike_type *b,
struct remap_state *remap,
enum pt_cmp_flags aflags,
enum pt_cmp_flags bflags,
enum pt_remap_flags remap_flags)
{
struct pike_type *tmp, *tmp2, *ret;
struct pike_type *aret = NULL, *bret = NULL;
enum pt_cmp_flags avoidable;
enum pt_cmp_flags bvoidable;
if (!a || !b) return NULL;
if (a == b) {
return NULL;
}
/* First check for markers. */
switch(a->type) {
case T_ASSIGN:
{
int marker = alloc_remap_marker(remap, CAR_TO_INT(a), remap_flags);
tmp = low_subtract_types(a->cdr, b, remap, aflags, bflags, remap_flags);
if (tmp) {
type_stack_mark();
push_finished_type(tmp);
push_assign_type(marker);
free_type(tmp);
return pop_unfinished_type();
}
free_marker(remap, CAR_TO_INT(a), remap_flags);
return NULL;
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int marker = remap_marker(remap, a->type, remap_flags);
if (!marker) return NULL;
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | tmp = remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type(T_NOT);
push_type(marker);
push_reverse_type(T_AND);
free_type(tmp);
return pop_unfinished_type();
}
}
switch(b->type) {
case T_ASSIGN:
{
int marker = alloc_remap_marker(remap, CAR_TO_INT(b),
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
tmp = low_subtract_types(a, b->cdr, remap, aflags, bflags, remap_flags);
if (tmp) {
type_stack_mark();
push_finished_type(tmp);
push_assign_type(marker);
free_type(tmp);
return pop_unfinished_type();
}
free_marker(remap, CAR_TO_INT(b),
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
return NULL;
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int marker = remap_marker(remap, b->type,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
if (!marker) return NULL;
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | tmp = remap_markers(a, NULL, remap, remap_flags);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type(marker);
push_type(T_NOT);
push_reverse_type(T_AND);
free_type(tmp);
return pop_unfinished_type();
}
}
/* Attributes and names. */
switch(a->type) {
case PIKE_T_NAME:
tmp = low_subtract_types(a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type_name((struct pike_string *)(a->car));
free_type(tmp);
return pop_unfinished_type();
case PIKE_T_ATTRIBUTE:
tmp = low_subtract_types(a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type_attribute((struct pike_string *)(a->car));
free_type(tmp);
return pop_unfinished_type();
case T_SCOPE:
tmp = low_subtract_types(a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_scope_type(CAR_TO_INT(a));
free_type(tmp);
return pop_unfinished_type();
}
switch(b->type) {
case PIKE_T_NAME:
tmp = low_subtract_types(a, b->cdr, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
|
d10bc9 | 2020-10-08 | Henrik Grubbström (Grubba) | | /* FIXME: Is this a good idea? */
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | push_type_name((struct pike_string *)(b->car));
free_type(tmp);
return pop_unfinished_type();
case PIKE_T_ATTRIBUTE:
tmp = low_subtract_types(a, b->cdr, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
|
d10bc9 | 2020-10-08 | Henrik Grubbström (Grubba) | | /* FIXME: Is this a good idea? */
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | push_type_attribute((struct pike_string *)(b->car));
free_type(tmp);
return pop_unfinished_type();
case T_SCOPE:
tmp = low_subtract_types(a, b->cdr, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_scope_type(CAR_TO_INT(b));
free_type(tmp);
return pop_unfinished_type();
}
/* Check consolidated types. */
switch(a->type) {
case T_OR:
case T_AND:
tmp = low_subtract_types(a->car, b, remap, aflags, bflags, remap_flags);
if (!tmp && (a->type == T_AND)) return NULL;
tmp2 = low_subtract_types(a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp2) {
if (a->type == T_OR) return tmp;
free_type(tmp);
return NULL;
}
|
5bafbd | 2020-09-28 | Henrik Grubbström (Grubba) | | if (!tmp) {
return tmp2;
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | }
|
5bafbd | 2020-09-28 | Henrik Grubbström (Grubba) | | type_stack_mark();
push_finished_type(tmp);
push_finished_type(tmp2);
push_reverse_type(a->type);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | free_type(tmp);
free_type(tmp2);
|
5bafbd | 2020-09-28 | Henrik Grubbström (Grubba) | | return pop_unfinished_type();
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | }
switch(b->type) {
case T_OR:
/* DeMorgan
*
* a & ~(b1 | b2) <==> a & ~b1 & ~b2
*/
tmp = low_subtract_types(a, b->car, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
|
504814 | 2020-10-01 | Henrik Grubbström (Grubba) | | /* NB: We need to remap b->cdr separately to avoid remapping
* markers in a and b->car twice.
*/
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | tmp2 = remap_markers(b->cdr, NULL, remap,
|
504814 | 2020-10-01 | Henrik Grubbström (Grubba) | | remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
ret = low_subtract_types(tmp, tmp2, NULL, aflags, bflags, 0);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | free_type(tmp);
|
504814 | 2020-10-01 | Henrik Grubbström (Grubba) | | free_type(tmp2);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | return ret;
case T_AND:
/* DeMorgan
*
* a & ~(b1 & b2) <==> a & (~b1 | ~b2) <==> (a & ~b1) | (a & ~b2)
*/
tmp = low_subtract_types(a, b->car, remap, aflags, bflags, remap_flags);
|
504814 | 2020-10-01 | Henrik Grubbström (Grubba) | | tmp2 = low_subtract_types(a, b->cdr, remap, aflags, bflags, remap_flags);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | if (!tmp2) return tmp;
ret = or_pike_types(tmp, tmp2, 0);
free_type(tmp);
free_type(tmp2);
return ret;
}
/* NB: Complex types from this point onwards are containers,
* and the voidable property does not propagate into them.
*/
avoidable = aflags & PT_FLAG_CMP_VOIDABLE;
aflags &= ~PT_FLAG_CMP_VOIDABLE;
bvoidable = bflags & PT_FLAG_CMP_VOIDABLE;
bflags &= ~PT_FLAG_CMP_VOIDABLE;
/* Check implicit casting. */
loop:
switch(TWOT(a->type & PIKE_T_MASK, b->type & PIKE_T_MASK)) {
case TWOT(T_PROGRAM, T_FUNCTION):
case TWOT(T_PROGRAM, T_MANY):
aret = a->car;
a = low_object_lfun_type(aret, LFUN_CREATE);
if (!a) {
a = void_function_type_string;
}
goto loop;
case TWOT(T_FUNCTION, T_PROGRAM):
case TWOT(T_MANY, T_PROGRAM):
bret = b->car;
b = low_object_lfun_type(bret, LFUN_CREATE);
if (!b) {
b = void_function_type_string;
}
goto loop;
case TWOT(T_OBJECT, T_FUNCTION):
case TWOT(T_OBJECT, T_MANY):
case TWOT(T_OBJECT, T_PROGRAM):
case TWOT(T_OBJECT, PIKE_T_TRANSITIVE):
a = low_object_lfun_type(a, LFUN_CALL);
if (!a) return NULL;
goto loop;
case TWOT(T_FUNCTION, T_OBJECT):
case TWOT(T_MANY, T_OBJECT):
case TWOT(T_PROGRAM, T_OBJECT):
case TWOT(PIKE_T_TRANSITIVE, T_OBJECT):
b = low_object_lfun_type(b, LFUN_CALL);
if (!b) return NULL;
goto loop;
case TWOT(PIKE_T_TRANSITIVE, T_FUNCTION):
case TWOT(PIKE_T_TRANSITIVE, T_MANY):
case TWOT(PIKE_T_TRANSITIVE, T_PROGRAM):
case TWOT(PIKE_T_TRANSITIVE, PIKE_T_TRANSITIVE):
tmp = expand_transitive(a, NULL, 0);
ret = low_subtract_types(tmp, b, remap, aflags, bflags, remap_flags);
free_type(tmp);
return ret;
case TWOT(T_FUNCTION, PIKE_T_TRANSITIVE):
case TWOT(T_MANY, PIKE_T_TRANSITIVE):
case TWOT(T_PROGRAM, PIKE_T_TRANSITIVE):
tmp = expand_transitive(b, NULL, 0);
ret = low_subtract_types(a, tmp, remap, aflags, bflags, remap_flags);
free_type(tmp);
return ret;
case TWOT(T_FUNCTION, PIKE_T_OPERATOR):
case TWOT(PIKE_T_OPERATOR, T_FUNCTION):
type_stack_mark();
push_finished_type(a);
push_finished_type(b);
push_type(T_NOT);
push_reverse_type(T_AND);
return pop_unfinished_type();
case TWOT(T_FUNCTION, T_FUNCTION):
case TWOT(T_FUNCTION, T_MANY):
case TWOT(T_MANY, T_FUNCTION):
case TWOT(T_MANY, T_MANY):
/*
* function(a1, a2, a3...:aa) & ~function(b1, b2, b3...:bb)
*
* <==>
*
* If
* All ai & ~bi == ai
* Then
* function(a1, a2, a3...:aa)
*
* If
* All ai & ~bi == Ø
* Then
* Ø
*
* Otherwise
* Keep for later evaluation.
*/
{
int nargs;
struct pike_type *ai = a;
struct pike_type *bi = b;
int got_empty = 0;
int got_full = 0;
while(1) {
/* Invariant:
* a->type and b->type are either T_FUNCTION or T_MANY.
*/
enum pt_cmp_flags avoidable = 0;
enum pt_cmp_flags bvoidable = 0;
/* Check the argument. */
/* NB: The MANY argument is always voidable. */
if (ai->type == T_MANY) avoidable |= PT_FLAG_CMP_VOIDABLE;
if (bi->type == T_MANY) bvoidable |= PT_FLAG_CMP_VOIDABLE;
tmp = low_subtract_types(ai->car, bi->car, NULL,
aflags | avoidable, bflags | bvoidable,
remap_flags);
if (!tmp) {
if (got_full) break;
got_empty = 1;
} else {
if (tmp == ai) {
got_full = 1;
} else {
|
504814 | 2020-10-01 | Henrik Grubbström (Grubba) | | free_type(tmp);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | break;
}
free_type(tmp);
if (got_empty) break;
}
if (avoidable && bvoidable) {
/* Time to check the return types. */
if (!aret) aret = ai->cdr;
if (!bret) bret = bi->cdr;
tmp = low_subtract_types(aret, bret, NULL, aflags, bflags,
remap_flags);
if (!tmp) {
if (got_full) break;
got_empty = 1;
} else {
if (tmp == aret) {
got_full = 1;
} else {
|
504814 | 2020-10-01 | Henrik Grubbström (Grubba) | | free_type(tmp);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | break;
}
free_type(tmp);
if (got_empty) break;
}
if (!got_full) {
return NULL;
}
type_stack_mark();
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(a, NULL, remap, remap_flags);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | return pop_unfinished_type();
}
/* Advance to the next argument. */
if (ai->type == T_FUNCTION) {
ai = ai->cdr;
}
if (bi->type == T_FUNCTION) {
bi = bi->cdr;
}
if ((ai->type != T_FUNCTION) && (ai->type != T_MANY)) {
break;
}
if ((bi->type != T_FUNCTION) && (bi->type != T_MANY)) {
break;
}
}
/* Either of a and/or b is a complex type, or a partial overlap. */
type_stack_mark();
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(a, NULL, remap, remap_flags);
push_remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | push_type(T_NOT);
push_reverse_type(T_AND);
return pop_unfinished_type();
}
case TWOT(T_ZERO, T_INT):
if ((CAR_TO_INT(b) <= 0) && (CDR_TO_INT(b) >= 0)) {
return NULL;
}
add_ref(a);
return a;
case TWOT(T_INT, T_ZERO):
if ((CAR_TO_INT(a) > 0) || (CDR_TO_INT(a) < 0)) {
add_ref(a);
return a;
}
type_stack_mark();
if (CAR_TO_INT(a) < 0) {
push_int_type(CAR_TO_INT(a), -1);
}
if (CDR_TO_INT(a) > 0) {
push_int_type(1, CDR_TO_INT(a));
if (CAR_TO_INT(a) < 0) {
push_reverse_type(T_OR);
}
}
return pop_unfinished_type();
/* T_TYPE and T_PROGRAM are essentially the same thing. */
case TWOT(T_TYPE, T_TYPE):
case TWOT(T_TYPE, T_PROGRAM):
case TWOT(T_PROGRAM, T_TYPE):
case TWOT(T_PROGRAM, T_PROGRAM):
tmp = low_subtract_types(a->car, b->car, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
if (a->type == b->type) {
push_type(a->type);
} else {
push_type(T_TYPE);
}
free_type(tmp);
return pop_unfinished_type();
case TWOT(T_TYPE, T_FUNCTION):
case TWOT(T_TYPE, T_MANY):
case TWOT(T_TYPE, PIKE_T_TRANSITIVE):
type_stack_mark();
push_finished_type(a->car);
push_type(T_VOID);
push_type(T_MANY);
push_type(T_MIXED);
push_type(T_FUNCTION);
tmp = pop_unfinished_type();
ret = low_subtract_types(tmp, b, remap, aflags, bflags, remap_flags);
free_type(tmp);
return ret;
case TWOT(T_FUNCTION, T_TYPE):
case TWOT(T_MANY, T_TYPE):
case TWOT(PIKE_T_TRANSITIVE, T_TYPE):
type_stack_mark();
push_finished_type(b->car);
push_type(T_VOID);
push_type(T_MANY);
push_type(T_MIXED);
push_type(T_FUNCTION);
tmp = pop_unfinished_type();
ret = low_subtract_types(a, tmp, remap, aflags, bflags, remap_flags);
free_type(tmp);
return ret;
#if 0
/* FIXME: */
case PIKE_T_RING:
#endif
}
if (a->type == T_VOID) {
if (bvoidable) {
return NULL;
}
add_ref(a);
return a;
}
if (b->type == T_VOID) {
add_ref(a);
return a;
}
if (b->type == T_MIXED) {
/* NB: a being void has been handled above. */
return NULL;
}
if (a->type == T_MIXED) {
type_stack_mark();
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | push_type(T_NOT);
return pop_unfinished_type();
}
if (b->type == T_NOT) {
return low_intersect_types(a, b->car, remap, aflags, bflags, remap_flags);
}
if (a->type == T_NOT) {
/* DeMorgan and(not(a), not(b)) <==> not(or(a, b)) */
type_stack_mark();
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(a->car, NULL, remap, remap_flags);
push_remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | push_type(T_OR);
push_type(T_NOT);
return pop_unfinished_type();
}
if (a->type != b->type) {
if (((a->type & PIKE_T_MASK) == PIKE_T_OPERATOR) ||
((b->type & PIKE_T_MASK) == PIKE_T_OPERATOR)) {
type_stack_mark();
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(a, NULL, remap, remap_flags);
push_remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | push_type(T_NOT);
push_reverse_type(T_AND);
return pop_unfinished_type();
}
add_ref(a);
return a;
}
switch(a->type) {
case T_VOID:
case T_ZERO:
case T_FLOAT:
/* Not reached. Should be handled by the a == b test at
* the beginning of the function.
*/
Pike_fatal("Type hashing has duplicates.\n");
return NULL;
case T_INT:
{
INT32 alow,blow;
INT32 ahigh,bhigh;
alow = CAR_TO_INT(a);
blow = CAR_TO_INT(b);
ahigh = CDR_TO_INT(a);
bhigh = CDR_TO_INT(b);
if ((blow > ahigh) || (bhigh < alow)) {
/* No Overlap */
add_ref(a);
return a;
}
type_stack_mark();
if (blow > alow) {
push_int_type(alow, blow - 1);
}
if (bhigh < ahigh) {
push_int_type(bhigh + 1, ahigh);
}
switch(peek_stack_mark()) {
case 2:
push_type(T_OR);
break;
case 1:
break;
case 0:
return NULL;
}
return pop_unfinished_type();
}
case T_ARRAY:
case T_MAPPING:
case T_STRING:
tmp = low_subtract_types(a->car, b->car, remap,
aflags, bflags, remap_flags);
tmp2 = low_subtract_types(a->cdr, b->cdr, remap,
aflags, bflags, remap_flags);
if (!tmp && !tmp2) return NULL;
type_stack_mark();
if (tmp) {
push_finished_type(a->cdr);
push_finished_type(tmp);
push_reverse_type(a->type);
free_type(tmp);
}
if (tmp2) {
push_finished_type(tmp2);
push_finished_type(a->car);
push_reverse_type(a->type);
free_type(tmp2);
}
if (peek_stack_mark() == 2) push_type(T_OR);
return pop_unfinished_type();
case T_MULTISET:
case T_PROGRAM:
case T_TYPE:
tmp = low_subtract_types(a->car, b->car, remap,
aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type(a->type);
return pop_unfinished_type();
case T_OBJECT:
if (!b->cdr) {
return NULL;
}
if (a->cdr) {
if (a->cdr == b->cdr) {
return NULL;
}
if (a->car && b->car) {
/* This is only possible if a->cdr == b->cdr, but that is
* handled above.
*/
add_ref(a);
return a;
}
{
struct program *ap = id_to_program(CDR_TO_INT(a));
struct program *bp = id_to_program(CDR_TO_INT(b));
if (!b->car && implements(ap, bp)) {
return NULL;
}
if (!is_compatible(ap, bp)) {
add_ref(a);
return a;
}
}
}
type_stack_mark();
push_finished_type(a);
push_finished_type(b);
push_type(T_NOT);
push_reverse_type(T_AND);
return pop_unfinished_type();
}
/* Leaf type. */
return NULL;
}
struct pike_type *subtract_types(struct pike_type *a,
struct pike_type *b,
enum pt_cmp_flags aflags,
enum pt_cmp_flags bflags,
enum pt_remap_flags remap_flags)
{
struct remap_state remap;
memset(&remap, 0, sizeof(remap));
return low_subtract_types(a, b, &remap, aflags, bflags, remap_flags);
}
/**
* Low-level intersection (aka And) of two types.
*
* Note:
* There are two major operating modes; the external, where
* the two types have unrelated markers, which then need to
* be remapped in the result, and the internal, where the
* two types have related markers (this mode is used mainly
* when evaluating a type).
*
* The internal mode is indicated via the remap state being NULL.
*/
static struct pike_type *low_intersect_types(struct pike_type *a,
struct pike_type *b,
struct remap_state *remap,
enum pt_cmp_flags aflags,
enum pt_cmp_flags bflags,
enum pt_remap_flags remap_flags)
{
struct pike_type *tmp, *tmp2, *ret;
struct pike_type *aret = NULL, *bret = NULL;
enum pt_cmp_flags avoidable;
enum pt_cmp_flags bvoidable;
if (!a || !b) return NULL;
if (a == b) {
/* FIXME: Perform masking of remap_flags here. */
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | return remap_markers(a, NULL, remap,
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | remap_flags | PT_FLAG_REMAP_BOTH_MARKERS_AND);
}
/* First check for markers. */
switch(a->type) {
case T_ASSIGN:
{
int marker = alloc_remap_marker(remap, CAR_TO_INT(a), remap_flags);
tmp = low_intersect_types(a->cdr, b, remap, aflags, bflags, remap_flags);
if (tmp) {
type_stack_mark();
push_finished_type(tmp);
push_assign_type(marker);
free_type(tmp);
return pop_unfinished_type();
}
free_marker(remap, CAR_TO_INT(a), remap_flags);
return NULL;
}
}
switch(b->type) {
case T_ASSIGN:
{
int marker = alloc_remap_marker(remap, CAR_TO_INT(b),
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
tmp = low_intersect_types(a, b->cdr, remap, aflags, bflags, remap_flags);
if (tmp) {
type_stack_mark();
push_finished_type(tmp);
push_assign_type(marker);
free_type(tmp);
return pop_unfinished_type();
}
free_marker(remap, CAR_TO_INT(b),
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
return NULL;
}
}
/* Attributes and names. */
switch(a->type) {
case PIKE_T_NAME:
tmp = low_intersect_types(a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type_name((struct pike_string *)(a->car));
free_type(tmp);
return pop_unfinished_type();
case PIKE_T_ATTRIBUTE:
tmp = low_intersect_types(a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type_attribute((struct pike_string *)(a->car));
free_type(tmp);
return pop_unfinished_type();
case T_SCOPE:
tmp = low_intersect_types(a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_scope_type(CAR_TO_INT(a));
free_type(tmp);
return pop_unfinished_type();
}
switch(b->type) {
case PIKE_T_NAME:
tmp = low_intersect_types(a, b->cdr, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type_name((struct pike_string *)(b->car));
free_type(tmp);
return pop_unfinished_type();
case PIKE_T_ATTRIBUTE:
tmp = low_intersect_types(a, b->cdr, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type_attribute((struct pike_string *)(b->car));
free_type(tmp);
return pop_unfinished_type();
case T_SCOPE:
tmp = low_intersect_types(a, b->cdr, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_scope_type(CAR_TO_INT(b));
free_type(tmp);
return pop_unfinished_type();
}
/* Check consolidated types. */
switch(a->type) {
case T_OR:
tmp = low_intersect_types(a->car, b, remap, aflags, bflags, remap_flags);
tmp2 = low_intersect_types(a->cdr, b, remap, aflags, bflags, remap_flags);
|
1af963 | 2020-10-03 | Henrik Grubbström (Grubba) | | if (!tmp2) return tmp;
if (!tmp) return tmp2;
type_stack_mark();
push_finished_type(tmp);
push_finished_type(tmp2);
push_reverse_type(T_OR);
free_type(tmp);
free_type(tmp2);
return pop_unfinished_type();
case T_AND:
/* NB: Attempt to avoid keeping the result from inverted types,
* in order to reduce type expansion.
*/
if (a->car->type == T_NOT) {
tmp2 = low_intersect_types(a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp2) return NULL;
tmp = low_intersect_types(a->car, b, remap, aflags, bflags, remap_flags);
if (!tmp) {
free_type(tmp2);
return NULL;
}
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | free_type(tmp);
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | tmp = remap_markers(a->car, NULL, remap, remap_flags);
|
1af963 | 2020-10-03 | Henrik Grubbström (Grubba) | | } else {
tmp = low_intersect_types(a->car, b, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
tmp2 = low_intersect_types(a->cdr, b, remap, aflags, bflags, remap_flags);
if (!tmp2) {
free_type(tmp);
return NULL;
}
if (a->cdr->type == T_NOT) {
free_type(tmp2);
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | tmp2 = remap_markers(a->cdr, NULL, remap, remap_flags);
|
1af963 | 2020-10-03 | Henrik Grubbström (Grubba) | | }
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | }
|
1af963 | 2020-10-03 | Henrik Grubbström (Grubba) | |
|
5bafbd | 2020-09-28 | Henrik Grubbström (Grubba) | | type_stack_mark();
push_finished_type(tmp);
push_finished_type(tmp2);
|
1af963 | 2020-10-03 | Henrik Grubbström (Grubba) | | push_reverse_type(T_AND);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | free_type(tmp);
free_type(tmp2);
|
5bafbd | 2020-09-28 | Henrik Grubbström (Grubba) | | return pop_unfinished_type();
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | }
switch(b->type) {
case T_OR:
tmp = low_intersect_types(a, b->car, remap, aflags, bflags, remap_flags);
tmp2 = low_intersect_types(a, b->cdr, remap, aflags, bflags, remap_flags);
|
1af963 | 2020-10-03 | Henrik Grubbström (Grubba) | | if (!tmp2) return tmp;
if (!tmp) return tmp2;
type_stack_mark();
push_finished_type(tmp);
push_finished_type(tmp2);
push_reverse_type(T_OR);
free_type(tmp);
free_type(tmp2);
return pop_unfinished_type();
case T_AND:
/* NB: Attempt to avoid keeping the result from inverted types,
* in order to reduce type expansion.
*/
if (b->car->type == T_NOT) {
tmp = low_intersect_types(a, b->cdr, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
tmp2 = low_intersect_types(a, b->car, remap, aflags, bflags, remap_flags);
if (tmp2) {
free_type(tmp2);
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | tmp2 = remap_markers(b->car, NULL, remap,
|
1af963 | 2020-10-03 | Henrik Grubbström (Grubba) | | remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
}
} else {
tmp = low_intersect_types(a, b->car, remap, aflags, bflags, remap_flags);
if (!tmp) return NULL;
tmp2 = low_intersect_types(a, b->cdr, remap, aflags, bflags, remap_flags);
if (tmp2 && (b->cdr->type == T_NOT)) {
free_type(tmp2);
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | tmp2 = remap_markers(b->cdr, NULL, remap,
|
1af963 | 2020-10-03 | Henrik Grubbström (Grubba) | | remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
}
}
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | if (!tmp2) {
free_type(tmp);
return NULL;
}
|
1af963 | 2020-10-03 | Henrik Grubbström (Grubba) | |
|
5bafbd | 2020-09-28 | Henrik Grubbström (Grubba) | | type_stack_mark();
push_finished_type(tmp);
push_finished_type(tmp2);
|
1af963 | 2020-10-03 | Henrik Grubbström (Grubba) | | push_reverse_type(T_AND);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | free_type(tmp);
free_type(tmp2);
|
5bafbd | 2020-09-28 | Henrik Grubbström (Grubba) | | return pop_unfinished_type();
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | }
/* NB: Complex types from this point onwards are containers,
* and the voidable property does not propagate into them.
*/
avoidable = aflags & PT_FLAG_CMP_VOIDABLE;
aflags &= ~PT_FLAG_CMP_VOIDABLE;
bvoidable = bflags & PT_FLAG_CMP_VOIDABLE;
bflags &= ~PT_FLAG_CMP_VOIDABLE;
/* Check implicit casting. */
loop:
switch(TWOT(a->type & PIKE_T_MASK, b->type & PIKE_T_MASK)) {
case TWOT(T_PROGRAM, T_FUNCTION):
case TWOT(T_PROGRAM, T_MANY):
aret = a->car;
a = low_object_lfun_type(aret, LFUN_CREATE);
if (!a) {
a = void_function_type_string;
}
goto loop;
case TWOT(T_FUNCTION, T_PROGRAM):
case TWOT(T_MANY, T_PROGRAM):
bret = b->car;
b = low_object_lfun_type(bret, LFUN_CREATE);
if (!b) {
b = void_function_type_string;
}
goto loop;
case TWOT(T_OBJECT, T_FUNCTION):
case TWOT(T_OBJECT, T_MANY):
case TWOT(T_OBJECT, T_PROGRAM):
case TWOT(T_OBJECT, PIKE_T_TRANSITIVE):
a = low_object_lfun_type(a, LFUN_CALL);
if (!a) return NULL;
goto loop;
case TWOT(T_FUNCTION, T_OBJECT):
case TWOT(T_MANY, T_OBJECT):
case TWOT(T_PROGRAM, T_OBJECT):
case TWOT(PIKE_T_TRANSITIVE, T_OBJECT):
b = low_object_lfun_type(b, LFUN_CALL);
if (!b) return NULL;
goto loop;
case TWOT(PIKE_T_TRANSITIVE, T_FUNCTION):
case TWOT(PIKE_T_TRANSITIVE, T_MANY):
case TWOT(PIKE_T_TRANSITIVE, T_PROGRAM):
case TWOT(PIKE_T_TRANSITIVE, PIKE_T_TRANSITIVE):
tmp = expand_transitive(a, NULL, 0);
ret = low_intersect_types(tmp, b, remap, aflags, bflags, remap_flags);
free_type(tmp);
return ret;
case TWOT(T_FUNCTION, PIKE_T_TRANSITIVE):
case TWOT(T_MANY, PIKE_T_TRANSITIVE):
case TWOT(T_PROGRAM, PIKE_T_TRANSITIVE):
tmp = expand_transitive(b, NULL, 0);
ret = low_intersect_types(a, tmp, remap, aflags, bflags, remap_flags);
free_type(tmp);
return ret;
case TWOT(T_FUNCTION, PIKE_T_OPERATOR):
case TWOT(PIKE_T_OPERATOR, T_FUNCTION):
type_stack_mark();
push_finished_type(a);
push_finished_type(b);
push_reverse_type(T_AND);
return pop_unfinished_type();
case TWOT(T_FUNCTION, T_FUNCTION):
case TWOT(T_FUNCTION, T_MANY):
case TWOT(T_MANY, T_FUNCTION):
case TWOT(T_MANY, T_MANY):
/* NB: For simplicity in the (common case)
* many(assign(m, mixed), m),
* we expand the many node (as required) to
* function(assign(m, mixed), many(assign(m, mixed), m)),
* and leave it to the evaluator to join the multiple
* assignments with or. The alternative (and stricter) would
* be to allocate a new marker for each step of the expansion
* and to have explicit or nodes:
* function(assign(m1, mixed), many(assign(m2, mixed), or(m1, m2))).
*/
{
int nargs;
type_stack_mark();
type_stack_mark(); /* To keep track of the number of args. */
while(1) {
/* Invariant:
* a->type and b->type are either T_FUNCTION or T_MANY.
*/
enum pt_cmp_flags avoidable = 0;
enum pt_cmp_flags bvoidable = 0;
/* Check the argument. */
/* NB: The MANY argument is always voidable. */
if (a->type == T_MANY) avoidable |= PT_FLAG_CMP_VOIDABLE;
if (b->type == T_MANY) bvoidable |= PT_FLAG_CMP_VOIDABLE;
tmp = low_intersect_types(a->car, b->car, remap,
aflags | avoidable,
bflags | bvoidable,
remap_flags);
if (!tmp) {
if (avoidable && bvoidable) {
/* NB: The VOIDABLE flag only affects comparisons with
* explicit void. If both arguments have implicit void,
* and nothing other in common, we arrive here.
*/
push_type(T_VOID);
} else {
goto function_fail;
}
}
push_finished_type(tmp);
free_type(tmp);
if (avoidable && bvoidable) {
/* Time to check the return types. */
if (!aret) aret = a->cdr;
if (!bret) bret = b->cdr;
tmp = low_intersect_types(aret, bret, remap,
aflags, bflags, remap_flags);
if (!tmp) goto function_fail;
nargs = pop_stack_mark();
push_finished_type(tmp);
free_type(tmp);
nargs--;
push_reverse_type(T_MANY);
while (nargs--) {
push_reverse_type(T_FUNCTION);
}
return pop_unfinished_type();
}
/* Advance to the next argument. */
if (a->type == T_FUNCTION) {
a = a->cdr;
}
if (b->type == T_FUNCTION) {
b = b->cdr;
}
if ((a->type != T_FUNCTION) && (a->type != T_MANY)) {
if (aret) {
Pike_fatal("Unsupported type operation.\n");
}
break;
}
if ((b->type != T_FUNCTION) && (b->type != T_MANY)) {
if (bret) {
Pike_fatal("Unsupported type operation.\n");
}
break;
}
}
nargs = pop_stack_mark();
/* Either of a and/or b is a complex type. */
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | tmp = remap_markers(a, NULL, remap, remap_flags);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | push_finished_type(tmp);
free_type(tmp);
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | tmp = remap_markers(b, NULL, remap, remap_flags);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | push_finished_type(tmp);
free_type(tmp);
push_reverse_type(T_AND);
while (nargs--) {
push_reverse_type(T_FUNCTION);
}
return pop_unfinished_type();
function_fail:
compiler_discard_type();
pop_stack_mark();
return NULL;
}
case TWOT(T_VOID, T_ZERO):
/* Return zero. */
add_ref(b);
return b;
case TWOT(T_ZERO, T_VOID):
/* Return zero. */
add_ref(a);
return a;
case TWOT(T_ZERO, T_INT):
if ((CAR_TO_INT(b) <= 0) && (CDR_TO_INT(b) >= 0)) {
add_ref(a);
return a;
}
return NULL;
case TWOT(T_INT, T_ZERO):
if ((CAR_TO_INT(a) <= 0) && (CDR_TO_INT(a) >= 0)) {
add_ref(b);
return b;
}
return NULL;
/* T_TYPE and T_PROGRAM are essentially the same thing. */
case TWOT(T_TYPE, T_TYPE):
case TWOT(T_TYPE, T_PROGRAM):
case TWOT(T_PROGRAM, T_TYPE):
case TWOT(T_PROGRAM, T_PROGRAM):
tmp = low_intersect_types(a->car, b->car, remap,
aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
if (a->type == b->type) {
push_type(a->type);
} else {
push_type(T_TYPE);
}
free_type(tmp);
return pop_unfinished_type();
case TWOT(T_TYPE, T_FUNCTION):
case TWOT(T_TYPE, T_MANY):
case TWOT(T_TYPE, PIKE_T_TRANSITIVE):
type_stack_mark();
push_finished_type(a->car);
push_type(T_VOID);
push_type(T_MANY);
push_type(T_MIXED);
push_type(T_FUNCTION);
tmp = pop_unfinished_type();
ret = low_intersect_types(tmp, b, remap, aflags, bflags, remap_flags);
free_type(tmp);
return ret;
case TWOT(T_FUNCTION, T_TYPE):
case TWOT(T_MANY, T_TYPE):
case TWOT(PIKE_T_TRANSITIVE, T_TYPE):
type_stack_mark();
push_finished_type(b->car);
push_type(T_VOID);
push_type(T_MANY);
push_type(T_MIXED);
push_type(T_FUNCTION);
tmp = pop_unfinished_type();
ret = low_intersect_types(a, tmp, remap, aflags, bflags, remap_flags);
free_type(tmp);
return ret;
#if 0
/* FIXME: */
case PIKE_T_RING:
#endif
}
if (a->type == T_VOID) {
if (bvoidable) {
add_ref(a);
return a;
}
return NULL;
}
if (b->type == T_VOID) {
if (avoidable) {
add_ref(b);
return b;
}
return NULL;
}
if (a->type == T_MIXED) {
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | return remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | }
if (b->type == T_MIXED) {
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | return remap_markers(a, NULL, remap, remap_flags);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | }
if (a->type == T_NOT) {
if (b->type == T_NOT) {
/* DeMorgan and(not(a), not(b)) <==> not(or(a, b)) */
type_stack_mark();
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(a->car, NULL, remap, remap_flags);
push_remap_markers(b->car, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | push_type(T_OR);
push_type(T_NOT);
return pop_unfinished_type();
}
/* NB: Swapped argument order! */
return low_subtract_types(b, a->car, remap, bflags, aflags,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
}
if (b->type == T_NOT) {
return low_subtract_types(a, b->car, remap, aflags, bflags, remap_flags);
}
|
9b9e7c | 2020-10-06 | Henrik Grubbström (Grubba) | | switch(a->type) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int marker = remap_marker(remap, a->type, remap_flags);
if (!marker) return NULL;
tmp = remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type(marker);
push_reverse_type(T_AND);
free_type(tmp);
return pop_unfinished_type();
}
}
switch(b->type) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int marker = remap_marker(remap, b->type,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
if (!marker) return NULL;
tmp = remap_markers(a, NULL, remap, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type(marker);
push_reverse_type(T_AND);
free_type(tmp);
return pop_unfinished_type();
}
}
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | if (a->type != b->type) {
if (((a->type & PIKE_T_MASK) == PIKE_T_OPERATOR) ||
((b->type & PIKE_T_MASK) == PIKE_T_OPERATOR)) {
type_stack_mark();
|
003e12 | 2020-10-05 | Henrik Grubbström (Grubba) | | push_remap_markers(a, NULL, remap, remap_flags);
push_remap_markers(b, NULL, remap,
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
|
d41c19 | 2020-09-27 | Henrik Grubbström (Grubba) | | push_reverse_type(T_AND);
return pop_unfinished_type();
}
return NULL;
}
switch(a->type) {
case T_VOID:
case T_ZERO:
case T_FLOAT:
/* Not reached. Should be handled by the a == b test at
* the beginning of the function.
*/
Pike_fatal("Type hashing has duplicates.\n");
return NULL;
case T_INT:
{
INT32 i1,i2;
INT32 upper_bound, lower_bound;
i1 = CDR_TO_INT(a);
i2 = CDR_TO_INT(b);
upper_bound = MINIMUM(i1,i2);
i1 = CAR_TO_INT(a);
i2 = CAR_TO_INT(b);
lower_bound = MAXIMUM(i1,i2);
if (upper_bound < lower_bound) {
/* No overlap! */
return NULL;
}
type_stack_mark();
push_int_type(lower_bound, upper_bound);
return pop_unfinished_type();
}
case T_ARRAY:
case T_MAPPING:
case T_STRING:
tmp = low_intersect_types(a->car, b->car, remap,
aflags, bflags, remap_flags);
if (!tmp) return NULL;
tmp2 = low_intersect_types(a->cdr, b->cdr, remap,
aflags, bflags, remap_flags);
if (!tmp2) {
free_type(tmp);
return NULL;
}
type_stack_mark();
push_finished_type(tmp);
push_finished_type(tmp2);
push_reverse_type(a->type);
free_type(tmp);
free_type(tmp2);
return pop_unfinished_type();
case T_MULTISET:
case T_PROGRAM:
case T_TYPE:
tmp = low_intersect_types(a->car, b->car, remap,
aflags, bflags, remap_flags);
if (!tmp) return NULL;
type_stack_mark();
push_finished_type(tmp);
push_type(a->type);
return pop_unfinished_type();
case T_OBJECT:
if (!a->cdr) {
add_ref(b);
return b;
}
if (!b->cdr) {
add_ref(a);
return a;
}
if (a->cdr == b->cdr) {
/* We know that they differ due to the a == b test at
* the befinning of the function. The only way they
* can differ is that car differs. There are only two
* valid values for car, so select the stricter (ie 'is-a')
*/
type_stack_mark();
push_object_type(1, CDR_TO_INT(a));
return pop_unfinished_type();
}
if (a->car && b->car) {
/* This is only possible if a->cdr == b->cdr, but that is
* handled above.
*/
return NULL;
}
{
struct program *ap = id_to_program(CDR_TO_INT(a));
struct program *bp = id_to_program(CDR_TO_INT(b));
if (!b->car && implements(ap, bp)) {
add_ref(a);
return a;
}
if (!a->car && implements(bp, ap)) {
add_ref(b);
return b;
}
if ((a->car == b->car) && is_compatible(ap, bp)) {
/* Both car must be 0 due to test above.
* It is possible to implement a class that
* implements both of the classes.
*/
type_stack_mark();
push_finished_type(a);
push_finished_type(b);
push_reverse_type(T_AND);
return pop_unfinished_type();
}
return NULL;
}
}
/* Leaf type. */
add_ref(a);
return a;
}
struct pike_type *intersect_types(struct pike_type *a,
struct pike_type *b,
enum pt_cmp_flags aflags,
enum pt_cmp_flags bflags,
enum pt_remap_flags remap_flags)
{
struct remap_state remap;
memset(&remap, 0, sizeof(remap));
return low_intersect_types(a, b, &remap, aflags, bflags, remap_flags);
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /*
* match two type strings, return zero if they don't match, and return
* the part of 'a' that _did_ match if it did.
*/
|
2fad8e | 2005-11-08 | Henrik Grubbström (Grubba) | | static struct pike_type *low_match_types2(struct pike_type *a,
struct pike_type *b,
int flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | static struct pike_type *low_match_types(struct pike_type *a,
struct pike_type *b,
int flags)
{
|
72ef9c | 2020-08-19 | Henrik Grubbström (Grubba) | | struct pike_type *ret = NULL;
DECLARE_CYCLIC();
#ifdef PIKE_TYPE_DEBUG
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | int e;
char *s;
if (l_flag>2) {
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, "%*slow_match_types(", indent*2, "");
simple_describe_type(a);
fprintf(stderr, ",\n");
fprintf(stderr, "%*s%s", indent*2, "", " ");
simple_describe_type(b);
fprintf(stderr, ",\n");
fprintf(stderr, "%*s%s", indent*2, "", " ");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
if (flags) {
int f = 0;
if (flags & A_EXACT) {
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, "A_EXACT");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | f = 1;
}
if (flags & B_EXACT) {
if (f) {
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, " | ");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, "B_EXACT");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | f = 1;
}
if (flags & NO_MAX_ARGS) {
if (f) {
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr," | ");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, "NO_MAX_ARGS");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | f = 1;
}
if (flags & NO_SHORTCUTS) {
if (f) {
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, " | ");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, "NO_SHORTCUTS");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | f = 1;
}
} else {
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fputc('0', stderr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, ");\n");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | indent++;
}
|
72ef9c | 2020-08-19 | Henrik Grubbström (Grubba) | | #endif
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
72ef9c | 2020-08-19 | Henrik Grubbström (Grubba) | | if ((a == b) || (!a)) {
ret = a;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | if (ret) add_ref(ret);
|
72ef9c | 2020-08-19 | Henrik Grubbström (Grubba) | | } else {
ret = BEGIN_CYCLIC(a, b);
if (!ret) {
SET_CYCLIC_RET(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
72ef9c | 2020-08-19 | Henrik Grubbström (Grubba) | | ret = low_match_types2(a, b, flags);
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | } else {
add_ref(ret);
|
72ef9c | 2020-08-19 | Henrik Grubbström (Grubba) | | }
END_CYCLIC();
}
#ifdef PIKE_TYPE_DEBUG
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if (l_flag>2) {
indent--;
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, "%*s= ", indent*2, "");
|
72ef9c | 2020-08-19 | Henrik Grubbström (Grubba) | | if(ret)
simple_describe_type(ret);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | else
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, "NULL");
fputc('\n', stderr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
72ef9c | 2020-08-19 | Henrik Grubbström (Grubba) | | #endif
return ret;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
474d9e | 2020-08-29 | Henrik Grubbström (Grubba) | | static void push_expand_transitive_type(struct pike_type *cont,
struct pike_type *trans,
struct pike_type **markers,
int num_args)
{
struct pike_type *tmp;
TYPE_STACK_DEBUG("expand_transitive");
switch(cont->type) {
case T_OR: case T_AND:
push_expand_transitive_type(cont->cdr, trans, markers, num_args);
push_expand_transitive_type(cont->car, trans, markers, num_args);
push_type(cont->type);
break;
case PIKE_T_FUNCTION:
/*
* transitive(function(a, b, ...:c), X)
*
* ==>
*
* function(a, @transitive(function(b, ...:c), X)
*/
push_expand_transitive_type(cont->cdr, trans, markers, num_args + 1);
push_finished_type(cont->car);
push_type(cont->type);
break;
case T_MANY:
if (num_args) {
/* No need to expand futher for now. */
push_finished_type(trans);
push_finished_type(cont);
push_type(PIKE_T_TRANSITIVE);
} else {
/* Two cases:
*
* transitive(function(:x), function(x, a, b, ...: c))
*
* ==>
*
* function(:x) | expand(transitive(function(a, b, ...: c),
* function(x, a, b, ...:c)))
*
* And
*
* transitive(function(t...:x), function(x, a, b, ...: c))
*
* ==>
*
* function(t...:x) |
* function(t, @transitive(function(t...:x),
* function(x, a, b, c, ...:c)))) |
* expand(transitive(function(a, b, ...: c),
* function(x, a, b, ...:c)))
*/
DECLARE_CYCLIC();
|
eccb9d | 2020-09-11 | Henrik Grubbström (Grubba) | | push_finished_type_with_markers(cont, markers, 0);
|
474d9e | 2020-08-29 | Henrik Grubbström (Grubba) | |
if (!BEGIN_CYCLIC(cont, trans)) {
SET_CYCLIC_RET(1);
/* Check many arg. */
push_finished_type_with_markers(cont->car, markers, 0);
if (peek_type_stack()->type != T_VOID) {
push_finished_type(trans);
push_finished_type(cont);
push_type(PIKE_T_TRANSITIVE);
push_reverse_type(PIKE_T_FUNCTION);
push_type(T_OR);
} else {
compiler_discard_top_type();
}
push_finished_type_with_markers(cont->cdr, markers, 0);
tmp = low_new_check_call(trans, peek_type_stack(), 0, NULL);
compiler_discard_top_type();
if (tmp) {
/* Valid recursion. */
push_expand_transitive_type(tmp, trans, markers, 0);
free_type(tmp);
push_type(T_OR);
}
}
END_CYCLIC();
}
break;
case PIKE_T_MIXED:
push_type(PIKE_T_MIXED);
break;
default:
/* Unsupported. */
fprintf(stderr, "Attempting to expand unsupported type: ");
simple_describe_type(cont);
fprintf(stderr, "\n");
push_finished_type(function_type_string);
Pike_fatal("Attempt to expand unsupported type: %d\n", cont->type);
break;
}
}
/* Partially expand transitive types, so that eg matching
* against function types works as expected.
*/
static struct pike_type *expand_transitive(struct pike_type *fun,
struct pike_type **markers,
int flags)
{
struct pike_type *ret_type;
struct pike_type *cont_type;
assert(fun->type == PIKE_T_TRANSITIVE);
type_stack_mark();
push_expand_transitive_type(fun->car, fun->cdr, markers, 0);
return pop_unfinished_type();
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | static struct pike_type *low_match_types2(struct pike_type *a,
struct pike_type *b,
int flags)
{
int correct_args;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | struct pike_type *ret = NULL;
struct pike_type *tmp;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
dd29f4 | 2008-05-06 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
203e41 | 2007-04-05 | Henrik Grubbström (Grubba) | | fatal_check_c_stack(1024);
|
dd29f4 | 2008-05-06 | Henrik Grubbström (Grubba) | | #endif
|
203e41 | 2007-04-05 | Henrik Grubbström (Grubba) | |
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(a->type & PIKE_T_MASK)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
case T_AND:
ret = low_match_types(a->car, b, flags);
if(!ret) return 0;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | free_type(ret);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return low_match_types(a->cdr, b, flags);
case T_OR:
ret = low_match_types(a->car, b, flags);
if(ret && !(flags & NO_SHORTCUTS)) return ret;
if(ret)
{
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | struct pike_type *t = low_match_types(a->cdr, b, flags);
if (t) {
|
042e0a | 2020-08-24 | Henrik Grubbström (Grubba) | | type_stack_mark();
push_finished_type(ret);
push_finished_type(t);
push_type(T_OR);
free_type(ret);
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | free_type(t);
|
042e0a | 2020-08-24 | Henrik Grubbström (Grubba) | | ret = pop_unfinished_type();
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return ret;
}else{
return low_match_types(a->cdr, b, flags);
}
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_RING:
return low_match_types(a->car, b, flags);
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | case PIKE_T_SCOPE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | return low_match_types(a->cdr, b, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_NOT:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = low_match_types(a->car, b, (flags ^ B_EXACT ) | NO_MAX_ARGS);
if (ret) {
free_type(ret);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 0;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
add_ref(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return a;
|
3360ff | 2009-03-04 | Henrik Grubbström (Grubba) | | case T_ASSIGN:
{
int m = CAR_TO_INT(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | ret = low_match_types(a->cdr, b, flags);
|
3360ff | 2009-03-04 | Henrik Grubbström (Grubba) | | if(ret && (!a_markers[m] || b->type != T_VOID))
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
9e6f6f | 2001-03-18 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
if ((m < 0) || (m > 9)) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("marker out of range: %d\n", m);
|
9e6f6f | 2001-03-18 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | type_stack_mark();
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | push_finished_type_with_markers(b, b_markers, 0);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | tmp = pop_unfinished_type();
type_stack_mark();
low_or_pike_types(a_markers[m], tmp, 0);
if(a_markers[m]) free_type(a_markers[m]);
free_type(tmp);
a_markers[m] = pop_unfinished_type();
#ifdef PIKE_TYPE_DEBUG
if (l_flag>2) {
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, "%*sa_markers[%d]=",
indent*2, "", m);
simple_describe_type(a_markers[m]);
fputc('\n', stderr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
#endif
#ifdef PIKE_DEBUG
|
6fd069 | 2003-07-01 | Martin Stjernholm | | if(a_markers[m]->type == m+'0')
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Cyclic type!\n");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | #endif
}
return ret;
|
3360ff | 2009-03-04 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int m = a->type - '0';
if(a_markers[m])
{
|
203e41 | 2007-04-05 | Henrik Grubbström (Grubba) | | struct pike_type *t = a_markers[m];
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
if(a_markers[m]->type == a->type)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Cyclic type!\n");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(a_markers[m]->type == T_OR &&
a_markers[m]->car->type == a->type)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Cyclic type!\n");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | #endif
|
203e41 | 2007-04-05 | Henrik Grubbström (Grubba) | | a_markers[m] = NULL;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = low_match_types(t, b, flags);
|
64d8a6 | 2007-04-06 | Henrik Grubbström (Grubba) | | if (a_markers[m]) {
a_markers[m] = or_pike_types(tmp = a_markers[m], t, 0);
free_type(tmp);
free_type(t);
} else {
a_markers[m] = t;
}
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | return ret;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | else {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return low_match_types(mixed_type_string, b, flags);
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | |
case PIKE_T_OPERATOR:
{
|
1247b7 | 2020-08-15 | Henrik Grubbström (Grubba) | | struct pike_type *t = a->car;
if ((t->type >= '0') && (t->type <= '9')) {
t = a_markers[t->type - '0'];
if (!t) t = zero_type_string;
}
t = apply_type_operator(a->type, t, a->cdr);
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | ret = low_match_types(t, b, flags);
free_type(t);
return ret;
}
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | |
case PIKE_T_TRANSITIVE:
{
|
474d9e | 2020-08-29 | Henrik Grubbström (Grubba) | | #if 1
struct pike_type *t = expand_transitive(a, a_markers, flags);
ret = low_match_types(t, b, flags);
free_type(t);
return ret;
#else
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | /* FIXME */
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | add_ref(a);
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | return a;
|
474d9e | 2020-08-29 | Henrik Grubbström (Grubba) | | #endif
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(b->type & PIKE_T_MASK)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
case T_AND:
ret = low_match_types(a, b->car, flags);
if(!ret) return 0;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | free_type(ret);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return low_match_types(a, b->cdr, flags);
case T_OR:
ret = low_match_types(a, b->car, flags);
if(ret && !(flags & NO_SHORTCUTS)) return ret;
if(ret)
{
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | struct pike_type *t = low_match_types(a, b->cdr, flags);
if (t) {
|
042e0a | 2020-08-24 | Henrik Grubbström (Grubba) | | type_stack_mark();
push_finished_type(ret);
push_finished_type(t);
push_type(T_OR);
free_type(ret);
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | free_type(t);
|
042e0a | 2020-08-24 | Henrik Grubbström (Grubba) | | ret = pop_unfinished_type();
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return ret;
}else{
return low_match_types(a, b->cdr, flags);
}
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_RING:
return low_match_types(a, b->car, flags);
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | case PIKE_T_SCOPE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | return low_match_types(a, b->cdr, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_NOT:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = low_match_types(a, b->car, (flags ^ A_EXACT ) | NO_MAX_ARGS);
if (ret) {
free_type(ret);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 0;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
add_ref(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return a;
|
3360ff | 2009-03-04 | Henrik Grubbström (Grubba) | | case T_ASSIGN:
{
int m = CAR_TO_INT(b);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | ret = low_match_types(a, b->cdr, flags);
|
3360ff | 2009-03-04 | Henrik Grubbström (Grubba) | | if(ret && (!b_markers[m] || a->type != T_VOID))
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
type_stack_mark();
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | push_finished_type_with_markers(a, a_markers, 0);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | tmp=pop_unfinished_type();
type_stack_mark();
low_or_pike_types(b_markers[m], tmp, 0);
if(b_markers[m]) free_type(b_markers[m]);
free_type(tmp);
b_markers[m] = pop_unfinished_type();
#ifdef PIKE_TYPE_DEBUG
if (l_flag>2) {
|
128398 | 2015-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr, "%*sb_markers[%d]=",
indent*2, "", m);
simple_describe_type(b_markers[m]);
fputc('\n', stderr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
#endif
#ifdef PIKE_DEBUG
|
6fd069 | 2003-07-01 | Martin Stjernholm | | if(b_markers[m]->type == m+'0')
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Cyclic type!\n");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | #endif
}
return ret;
|
3360ff | 2009-03-04 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
|
339b7c | 2001-06-05 | Henrik Grubbström (Grubba) | | int m = b->type - '0';
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(b_markers[m])
{
|
203e41 | 2007-04-05 | Henrik Grubbström (Grubba) | | struct pike_type *t = b_markers[m];
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
if(b_markers[m]->type == b->type)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Cyclic type!\n");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | #endif
|
203e41 | 2007-04-05 | Henrik Grubbström (Grubba) | | b_markers[m] = NULL;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = low_match_types(a, t, flags);
|
64d8a6 | 2007-04-06 | Henrik Grubbström (Grubba) | | if (b_markers[m]) {
b_markers[m] = or_pike_types(tmp = b_markers[m], t, 0);
free_type(tmp);
free_type(t);
} else {
b_markers[m] = t;
}
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | return ret;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | else {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return low_match_types(a, mixed_type_string, flags);
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | |
case PIKE_T_OPERATOR:
{
|
1247b7 | 2020-08-15 | Henrik Grubbström (Grubba) | | struct pike_type *t = b->car;
if ((t->type >= '0') && (t->type <= '9')) {
t = b_markers[t->type - '0'];
if (!t) t = zero_type_string;
}
t = apply_type_operator(b->type, t, b->cdr);
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | ret = low_match_types(a, t, flags);
free_type(t);
return ret;
}
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | |
case PIKE_T_TRANSITIVE:
{
|
474d9e | 2020-08-29 | Henrik Grubbström (Grubba) | | #if 1
struct pike_type *t = expand_transitive(b, b_markers, flags);
ret = low_match_types(a, t, flags);
free_type(t);
return ret;
#else
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | /* FIXME */
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | add_ref(a);
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | return a;
|
474d9e | 2020-08-29 | Henrik Grubbström (Grubba) | | #endif
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
/* 'mixed' matches anything */
if((a->type == T_ZERO || a->type == T_MIXED) &&
!(flags & (A_EXACT|B_EXACT)) &&
(b->type != T_VOID))
{
#if 1
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = NULL;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | switch(b->type)
{
/* These types can contain sub-types */
case T_ARRAY:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = low_match_types(array_type_string, b, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_MAPPING:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = low_match_types(mapping_type_string, b, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_FUNCTION:
case T_MANY:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = low_match_types(function_type_string, b, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_MULTISET:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = low_match_types(multiset_type_string, b, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
}
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | if (ret) free_type(ret);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | #endif
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | add_ref(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return a;
}
if((b->type == T_ZERO || b->type == T_MIXED) &&
!(flags & (A_EXACT|B_EXACT)) &&
(a->type != T_VOID))
{
#if 1
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = NULL;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | switch(a->type)
{
/* These types can contain sub-types */
case T_ARRAY:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = low_match_types(a, array_type_string, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_MAPPING:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = low_match_types(a, mapping_type_string, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_FUNCTION:
case T_MANY:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = low_match_types(a, function_type_string, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_MULTISET:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | ret = low_match_types(a, multiset_type_string, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
}
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | if (ret) free_type(ret);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | #endif
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | add_ref(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return a;
}
/* Special cases (tm) */
switch(TWOT(a->type, b->type))
{
case TWOT(T_PROGRAM, T_FUNCTION):
case TWOT(T_FUNCTION, T_PROGRAM):
case TWOT(T_PROGRAM, T_MANY):
case TWOT(T_MANY, T_PROGRAM):
|
6d33d8 | 2001-03-28 | Henrik Grubbström (Grubba) | | /* FIXME: Should look at the sub-type of the program
* to determine the prototype to use.
*/
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | add_ref(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return a;
|
34b26e | 2008-05-10 | Henrik Grubbström (Grubba) | | case TWOT(PIKE_T_TYPE, T_FUNCTION):
case TWOT(PIKE_T_TYPE, T_MANY):
/* Convert the type to a casting function. */
type_stack_mark();
push_finished_type(a->car);
push_type(T_VOID);
push_type(T_MANY);
push_type(T_MIXED);
push_type(T_FUNCTION);
ret = a;
a = pop_unfinished_type();
if (low_match_types(a, b, flags)) {
free_type(a);
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | add_ref(ret);
|
34b26e | 2008-05-10 | Henrik Grubbström (Grubba) | | return ret;
}
free_type(a);
return NULL;
case TWOT(T_FUNCTION, PIKE_T_TYPE):
case TWOT(T_MANY, PIKE_T_TYPE):
/* Convert the type to a casting function. */
type_stack_mark();
push_finished_type(b->car);
push_type(T_VOID);
push_type(T_MANY);
push_type(T_MIXED);
push_type(T_FUNCTION);
b = pop_unfinished_type();
ret = low_match_types(a, b, flags);
free_type(b);
return ret;
case TWOT(PIKE_T_TYPE, T_PROGRAM):
case TWOT(T_PROGRAM, PIKE_T_TYPE):
return low_match_types(a->car, b->car, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case TWOT(T_OBJECT, T_FUNCTION):
case TWOT(T_OBJECT, T_MANY):
{
struct pike_type *s;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | if((s = low_object_lfun_type(a, LFUN_CALL))) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return low_match_types(s, b, flags);
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if (flags & B_EXACT) {
/* A function isn't an object */
return 0;
}
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | add_ref(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return a;
}
case TWOT(T_FUNCTION, T_OBJECT):
case TWOT(T_MANY, T_OBJECT):
{
struct pike_type *s;
if((s=low_object_lfun_type(b, LFUN_CALL)))
return low_match_types(a, s, flags);
if (flags & A_EXACT) {
/* A function isn't an object */
return 0;
}
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | add_ref(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return a;
}
case TWOT(T_INT, T_ZERO):
{
|
d2361e | 2003-06-30 | Martin Stjernholm | | if ((CAR_TO_INT(a) > 0) || (CDR_TO_INT(a) < 0)) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 0;
}
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | add_ref(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return a;
}
case TWOT(T_ZERO, T_INT):
{
|
d2361e | 2003-06-30 | Martin Stjernholm | | if ((CAR_TO_INT(b) > 0) || (CDR_TO_INT(b) < 0)) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 0;
}
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | add_ref(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return a;
}
case TWOT(T_FUNCTION, T_FUNCTION):
case TWOT(T_FUNCTION, T_MANY):
case TWOT(T_MANY, T_FUNCTION):
case TWOT(T_MANY, T_MANY):
ret = a;
correct_args=0;
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | while ((a->type == T_FUNCTION) || (b->type == T_FUNCTION))
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
struct pike_type *a_tmp, *b_tmp;
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | if ((a->type != T_FUNCTION) && (a->type != T_MANY)) break;
if ((b->type != T_FUNCTION) && (b->type != T_MANY)) break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | a_tmp = a->car;
if (a->type == T_FUNCTION)
{
a = a->cdr;
}
b_tmp = b->car;
if (b->type == T_FUNCTION)
{
b = b->cdr;
}
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | if(!(tmp = low_match_types(a_tmp, b_tmp,
(flags | NO_MAX_ARGS) & ~(A_EXACT|B_EXACT)))) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 0;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
free_type(tmp);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(++correct_args > max_correct_args)
if(!(flags & NO_MAX_ARGS))
max_correct_args=correct_args;
}
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | |
if ((a->type != T_MANY) || (b->type != T_MANY)) {
/* Handle the generic case. */
return low_match_types(a, b, flags);
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* check the 'many' type */
if(b->car->type != T_VOID &&
a->car->type != T_VOID)
{
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | if(!(tmp = low_match_types(a->car, b->car,
(flags | NO_MAX_ARGS) & ~(A_EXACT|B_EXACT)))) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 0;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
free_type(tmp);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
if(!(flags & NO_MAX_ARGS))
|
477550 | 2008-06-29 | Martin Stjernholm | | max_correct_args=MAX_INT32;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* check the returntype */
a = a->cdr;
b = b->cdr;
if ((b->type == T_VOID) && (a->type != T_VOID)) {
/* Promote b to a function returning zero. */
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | if (!(tmp = low_match_types(a, zero_type_string,
flags & ~(A_EXACT|B_EXACT)))) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 0;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
free_type(tmp);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else if ((a->type == T_VOID) && (b->type != T_VOID)) {
/* Promote a to a function returning zero. */
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | if(!(tmp = low_match_types(zero_type_string, b,
flags & ~(A_EXACT|B_EXACT)))) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 0;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
free_type(tmp);
} else {
if(!(tmp = low_match_types(a, b, flags & ~(A_EXACT|B_EXACT)))) {
return 0;
}
free_type(tmp);
}
add_ref(ret);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return ret;
}
if(a->type != b->type) return 0;
ret=a;
switch(a->type)
{
case T_MAPPING:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | if(!(tmp = low_match_types(a->car, b->car,
flags & ~(A_EXACT|B_EXACT)))) {
return 0;
}
free_type(tmp);
if(!(tmp = low_match_types(a->cdr, b->cdr,
flags & ~(A_EXACT|B_EXACT)))) {
return 0;
}
free_type(tmp);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | break;
case T_OBJECT:
#if 0
if(a->cdr || b->cdr)
{
fprintf(stderr,"Type match1: ");
stupid_describe_type(a,type_length(a));
fprintf(stderr,"Type match2: ");
stupid_describe_type(b,type_length(b));
}
#endif
/* object(* 0) matches any object */
if(!a->cdr || !b->cdr) break;
|
51922b | 2004-08-16 | Henrik Grubbström (Grubba) | | /* object(* x) =? object(* x) */
if (a->cdr == b->cdr) break;
/* Note: In Pike 7.4 and earlier the following was only done
* when a->car != b->car.
*/
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
struct program *ap,*bp;
|
d2361e | 2003-06-30 | Martin Stjernholm | | ap = id_to_program(CDR_TO_INT(a));
bp = id_to_program(CDR_TO_INT(b));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
if(!ap || !bp) break;
|
da371d | 2003-11-18 | Henrik Grubbström (Grubba) | | implements_mode = 0;
|
5223aa | 2004-08-16 | Martin Stjernholm | |
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | if (!is_compatible(implements_a=ap,implements_b=bp)) {
|
51922b | 2004-08-16 | Henrik Grubbström (Grubba) | | return 0;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
break;
case T_INT:
{
|
d2361e | 2003-06-30 | Martin Stjernholm | | INT32 amin = CAR_TO_INT(a);
INT32 amax = CDR_TO_INT(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
d2361e | 2003-06-30 | Martin Stjernholm | | INT32 bmin = CAR_TO_INT(b);
INT32 bmax = CDR_TO_INT(b);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(amin > bmax || bmin > amax) return 0;
break;
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | case T_ARRAY:
case T_STRING:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | if(!(tmp = low_match_types(a->cdr, b->cdr,
flags & ~(A_EXACT|B_EXACT)))) {
return 0;
}
free_type(tmp);
|
e9aa7d | 2020-01-19 | Henrik Grubbström (Grubba) | | /* FALLTHRU */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
6d33d8 | 2001-03-28 | Henrik Grubbström (Grubba) | | case T_PROGRAM:
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | case T_TYPE:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_MULTISET:
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | if(!(tmp = low_match_types(a->car, b->car,
flags & ~(A_EXACT|B_EXACT)))) {
return 0;
}
free_type(tmp);
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
case T_FLOAT:
case T_ZERO:
case T_VOID:
case T_MIXED:
break;
|
dd29f4 | 2008-05-06 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | default:
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Error in type string.\n");
|
dd29f4 | 2008-05-06 | Henrik Grubbström (Grubba) | | #endif
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | |
if (ret) add_ref(ret);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return ret;
}
/*
* Check the partial ordering relation.
*
* mixed
*
* int float string program function object
*
* zero
*
* void
*
* Note that non-destructive operations are assumed.
* ie it's assumed that calling a function(mapping(string|int:string|int):void)
* with a mapping(int:int) won't change the type of the mapping after the
* operation.
*/
|
2fad8e | 2005-11-08 | Henrik Grubbström (Grubba) | | static int low_pike_types_le2(struct pike_type *a, struct pike_type *b,
int array_cnt, unsigned int flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | static int low_pike_types_le(struct pike_type *a, struct pike_type *b,
int array_cnt, unsigned int flags)
{
int res;
|
41bee5 | 2020-08-30 | Henrik Grubbström (Grubba) | | DECLARE_CYCLIC();
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
41bee5 | 2020-08-30 | Henrik Grubbström (Grubba) | | #ifdef PIKE_TYPE_DEBUG
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if (l_flag>2) {
|
86b6ca | 2008-09-09 | Martin Stjernholm | | #if 0
struct compilation *c = MAYBE_THIS_COMPILATION;
if (c && c->lex.current_file)
fprintf (stderr, "%*s%s:%d:\n", indent * 2, "",
c->lex.current_file->str, c->lex.current_line);
#endif
|
571a13 | 2007-04-21 | Henrik Grubbström (Grubba) | | fprintf(stderr, "%*slow_pike_types_le(", indent*2, "");
simple_describe_type(a);
fprintf(stderr, ",\n%*s", indent*2 + 18, "");
simple_describe_type(b);
fprintf(stderr, ",\n%*s%d, 0x%08x);\n",
indent*2 + 18, "", array_cnt, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | indent++;
}
|
41bee5 | 2020-08-30 | Henrik Grubbström (Grubba) | | #endif /* PIKE_TYPE_DEBUG */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
41bee5 | 2020-08-30 | Henrik Grubbström (Grubba) | | if (!(res = (int)(ptrdiff_t)BEGIN_CYCLIC(a, b))) {
SET_CYCLIC_RET(1);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
41bee5 | 2020-08-30 | Henrik Grubbström (Grubba) | | res = low_pike_types_le2(a, b, array_cnt, flags);
}
END_CYCLIC();
#ifdef PIKE_TYPE_DEBUG
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if (l_flag>2) {
indent--;
|
571a13 | 2007-04-21 | Henrik Grubbström (Grubba) | | fprintf(stderr, "%*s= %d\n", indent*2, "", res);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
41bee5 | 2020-08-30 | Henrik Grubbström (Grubba) | | #endif /* PIKE_TYPE_DEBUG */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return res;
}
static int low_pike_types_le2(struct pike_type *a, struct pike_type *b,
int array_cnt, unsigned int flags)
{
|
08e866 | 2008-05-03 | Henrik Grubbström (Grubba) | | struct compilation *c = MAYBE_THIS_COMPILATION;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | int ret;
recurse:
#if 0
fprintf(stderr, "low_pike_types_le(%d, %d, %d, 0x%08x)\n",
a->type, b->type, array_cnt, flags);
#endif /* 0 */
if(a == b) return 1;
|
082c9b | 2020-07-19 | Henrik Grubbström (Grubba) | | #ifdef TYPE_GROUPING
if (b->type != T_OR) {
flags &= ~LE_B_GROUPED;
}
#endif
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(b->type & PIKE_T_MASK)
|
082c9b | 2020-07-19 | Henrik Grubbström (Grubba) | | {
case T_AND:
/* OK, if a is a subset of both parts. */
ret = low_pike_types_le(a, b->car, array_cnt, flags);
if(!ret) return 0;
b = b->cdr;
goto recurse;
case T_OR:
/* OK if a is a subset of either of the parts,
* unless we are grouped, in which case both
* parts need to be a subset.
*/
ret = low_pike_types_le(a, b->car, array_cnt, flags);
#ifdef TYPE_GROUPING
if (!ret != !(flags & LE_B_GROUPED)) {
if ((a->flags | b->flags) & PT_FLAG_ASSIGN) {
/* Note: Needed for side effects... */
low_pike_types_le(a, b->cdr, array_cnt, flags);
}
return ret;
}
#else
if (ret) return ret;
#endif
b = b->cdr;
goto recurse;
case PIKE_T_RING:
b = b->car;
goto recurse;
case PIKE_T_ATTRIBUTE:
if (!c) {
b = b->cdr;
goto recurse;
}
if (!low_pike_types_le(a, b->cdr, array_cnt, flags)) return 0;
ref_push_string((struct pike_string *)b->car);
ref_push_type_value(a);
ref_push_type_value(b->cdr);
safe_apply_current2(PC_PUSH_TYPE_ATTRIBUTE_FUN_NUM, 3,
"push_type_attribute");
if ((TYPEOF(Pike_sp[-1]) == T_INT) &&
(SUBTYPEOF(Pike_sp[-1]) == NUMBER_NUMBER) &&
(!Pike_sp[-1].u.integer)) {
pop_stack();
return 0;
}
pop_stack();
return 1;
case PIKE_T_SCOPE:
#ifdef TYPE_GROUPING
flags |= LE_B_GROUPED;
#endif
/* FALLTHRU */
case PIKE_T_NAME:
b = b->cdr;
goto recurse;
case T_NOT:
/* Some common cases. */
switch(b->car->type) {
case T_NOT:
b = b->car->car;
goto recurse;
case T_MIXED:
b = zero_type_string;
goto recurse;
case T_ZERO:
case T_VOID:
b = mixed_type_string;
goto recurse;
}
if (low_pike_types_le(a, b->car, array_cnt, flags)) {
return 0;
}
flags ^= LE_A_B_SWAPPED;
#ifdef TYPE_GROUPING
if (flags & LE_A_B_GROUPED) {
if ((flags & LE_A_B_GROUPED) == LE_A_B_GROUPED) {
flags ^= LE_A_B_GROUPED;
}
} else {
flags |= LE_A_B_GROUPED;
}
#endif
/* FIXME: This is wrong... */
return !low_pike_types_le(b->car, a, -array_cnt, flags);
case T_ASSIGN: {
struct pike_type **aa_markers = a_markers;
struct pike_type **bb_markers = b_markers;
int m = CAR_TO_INT(b);
ret = low_pike_types_le(a, b->cdr, array_cnt, flags);
if (flags & LE_A_B_SWAPPED) {
aa_markers = b_markers;
bb_markers = a_markers;
}
if(ret && (!bb_markers[m] || a->type != T_VOID))
{
int m = CAR_TO_INT(b);
struct pike_type *tmp;
int i;
type_stack_mark();
push_finished_type_with_markers(a, aa_markers, 0);
for(i = array_cnt; i < 0; i++)
push_unlimited_array_type(T_ARRAY);
tmp=pop_unfinished_type();
type_stack_mark();
low_or_pike_types(bb_markers[m], tmp, 0);
if(bb_markers[m]) free_type(bb_markers[m]);
free_type(tmp);
bb_markers[m] = pop_unfinished_type();
#ifdef PIKE_TYPE_DEBUG
if (l_flag>2) {
if (flags & LE_A_B_SWAPPED) {
fprintf(stderr, "%*sa_markers[%c]=",
indent * 2, "", (char)(m+'0'));
simple_describe_type(a_markers[m]);
} else {
fprintf(stderr, "%*sb_markers[%c]=",
indent * 2, "", (char)(m+'0'));
simple_describe_type(b_markers[m]);
}
fprintf(stderr, "\n");
}
#endif
}
return ret;
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int m = b->type - '0';
if (flags & LE_A_B_SWAPPED) {
if(a_markers[m]) {
b = a_markers[m];
} else {
b = mixed_type_string;
}
} else {
if(b_markers[m]) {
b = b_markers[m];
} else {
b = mixed_type_string;
}
}
goto recurse;
}
case PIKE_T_OPERATOR:
{
|
1247b7 | 2020-08-15 | Henrik Grubbström (Grubba) | | struct pike_type *t = b->car;
if ((t->type >= '0') && (t->type <= '9')) {
t = ((flags & LE_A_B_SWAPPED)?a_markers:b_markers)[t->type - '0'];
if (!t) t = zero_type_string;
}
t = apply_type_operator(b->type, t, b->cdr);
|
082c9b | 2020-07-19 | Henrik Grubbström (Grubba) | | ret = low_pike_types_le(a, t, array_cnt, flags);
free_type(t);
return ret;
}
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | |
case PIKE_T_TRANSITIVE:
{
|
41bee5 | 2020-08-30 | Henrik Grubbström (Grubba) | | struct pike_type *t =
expand_transitive(b, ((flags & LE_A_B_SWAPPED)?a_markers:b_markers), 0);
ret = low_pike_types_le(a, t, array_cnt, flags);
free_type(t);
return ret;
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | }
|
082c9b | 2020-07-19 | Henrik Grubbström (Grubba) | | }
|
50fd19 | 2008-08-11 | Henrik Grubbström (Grubba) | | #ifdef TYPE_GROUPING
if (a->type != T_OR) {
flags &= ~LE_A_GROUPED;
}
#endif
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(a->type & PIKE_T_MASK)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
case T_AND:
/* OK if either of the parts is a subset. */
/* FIXME: What if b also contains an AND? */
ret = low_pike_types_le(a->car, b, array_cnt, flags);
|
50fd19 | 2008-08-11 | Henrik Grubbström (Grubba) | | if(!ret) {
a = a->cdr;
goto recurse;
}
|
03344d | 2008-09-11 | Henrik Grubbström (Grubba) | | if ((a->flags | b->flags) & PT_FLAG_ASSIGN) {
/* Note that we need to recurse, since there are T_ASSIGN nodes
* in the cdr that need to be executed.
*/
low_pike_types_le(a->cdr, b, array_cnt, flags);
}
|
50fd19 | 2008-08-11 | Henrik Grubbström (Grubba) | | return 1;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
case T_OR:
|
80f7aa | 2007-06-29 | Henrik Grubbström (Grubba) | | /* OK, if both of the parts are a subset,
* unless we are grouped, in which case
* only one part needs to be a subset.
*/
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if (a->car->type == T_VOID) {
/* Special case for T_VOID */
/* FIXME: Should probably be handled as T_ZERO. */
|
42d56e | 2007-07-02 | Henrik Grubbström (Grubba) | | #ifdef TYPE_GROUPING
|
80f7aa | 2007-06-29 | Henrik Grubbström (Grubba) | | if (flags & LE_A_GROUPED) return 1;
|
42d56e | 2007-07-02 | Henrik Grubbström (Grubba) | | #endif
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | a = a->cdr;
goto recurse;
} else {
ret = low_pike_types_le(a->car, b, array_cnt, flags);
|
42d56e | 2007-07-02 | Henrik Grubbström (Grubba) | | #ifdef TYPE_GROUPING
|
ab83e8 | 2008-08-11 | Henrik Grubbström (Grubba) | | if (!ret == !(flags & LE_A_GROUPED)) {
|
03344d | 2008-09-11 | Henrik Grubbström (Grubba) | | if ((a->flags | b->flags) & PT_FLAG_ASSIGN) {
/* Note: Needed for side effects... */
low_pike_types_le(a->cdr, b, array_cnt, flags);
}
|
ab83e8 | 2008-08-11 | Henrik Grubbström (Grubba) | | return ret;
}
|
42d56e | 2007-07-02 | Henrik Grubbström (Grubba) | | #else
if (!ret) return 0;
#endif
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if (a->cdr->type == T_VOID) {
/* Special case for T_VOID */
/* FIXME: Should probably be handled as T_ZERO. */
return 1;
} else {
a = a->cdr;
goto recurse;
}
}
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_RING:
a = a->car;
goto recurse;
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | case PIKE_T_SCOPE:
|
42d56e | 2007-07-02 | Henrik Grubbström (Grubba) | | #ifdef TYPE_GROUPING
|
80f7aa | 2007-06-29 | Henrik Grubbström (Grubba) | | flags |= LE_A_GROUPED;
|
42d56e | 2007-07-02 | Henrik Grubbström (Grubba) | | #endif
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
a = a->cdr;
goto recurse;
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
if ((b->type == PIKE_T_ATTRIBUTE) && (a->car == b->car)) {
a = a->cdr;
b = b->cdr;
goto recurse;
}
|
08e866 | 2008-05-03 | Henrik Grubbström (Grubba) | | if (!c) {
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | a = a->cdr;
goto recurse;
}
if (!low_pike_types_le(a->cdr, b, array_cnt, flags)) return 0;
ref_push_string((struct pike_string *)a->car);
ref_push_type_value(a->cdr);
ref_push_type_value(b);
|
08e866 | 2008-05-03 | Henrik Grubbström (Grubba) | | safe_apply_current2(PC_POP_TYPE_ATTRIBUTE_FUN_NUM, 3,
"pop_type_attribute");
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(Pike_sp[-1]) == T_INT) &&
(SUBTYPEOF(Pike_sp[-1]) == NUMBER_NUMBER) &&
|
08e866 | 2008-05-03 | Henrik Grubbström (Grubba) | | (!Pike_sp[-1].u.integer)) {
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | pop_stack();
|
08e866 | 2008-05-03 | Henrik Grubbström (Grubba) | | return 0;
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | }
|
08e866 | 2008-05-03 | Henrik Grubbström (Grubba) | | pop_stack();
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | return 1;
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_NOT:
if (b->type == T_NOT) {
struct pike_type *tmp = a->car;
a = b->car;
b = tmp;
array_cnt = -array_cnt;
|
50fd19 | 2008-08-11 | Henrik Grubbström (Grubba) | | flags ^= LE_A_B_SWAPPED;
#if 0
|
42d56e | 2007-07-02 | Henrik Grubbström (Grubba) | | #ifdef TYPE_GROUPING
|
50fd19 | 2008-08-11 | Henrik Grubbström (Grubba) | | if (flags & LE_A_B_GROUPED) {
if ((flags & LE_A_B_GROUPED) == LE_A_B_GROUPED) {
flags ^= LE_A_B_GROUPED;
}
} else {
flags |= LE_A_B_GROUPED;
}
#endif
|
42d56e | 2007-07-02 | Henrik Grubbström (Grubba) | | #endif
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | goto recurse;
}
|
571a13 | 2007-04-21 | Henrik Grubbström (Grubba) | | /* Some common cases. */
switch(a->car->type) {
case T_NOT:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | a = a->car->car;
goto recurse;
|
571a13 | 2007-04-21 | Henrik Grubbström (Grubba) | | case T_MIXED:
a = zero_type_string;
goto recurse;
case T_ZERO:
case T_VOID:
a = mixed_type_string;
goto recurse;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
if (low_pike_types_le(a->car, b, array_cnt, flags)) {
return 0;
}
|
50fd19 | 2008-08-11 | Henrik Grubbström (Grubba) | | flags ^= LE_A_B_SWAPPED;
#if 0
|
42d56e | 2007-07-02 | Henrik Grubbström (Grubba) | | #ifdef TYPE_GROUPING
|
50fd19 | 2008-08-11 | Henrik Grubbström (Grubba) | | if (flags & LE_A_B_GROUPED) {
if ((flags & LE_A_B_GROUPED) == LE_A_B_GROUPED) {
flags ^= LE_A_B_GROUPED;
}
} else {
flags |= LE_A_B_GROUPED;
}
|
42d56e | 2007-07-02 | Henrik Grubbström (Grubba) | | #endif
|
50fd19 | 2008-08-11 | Henrik Grubbström (Grubba) | | #endif
/* FIXME: This is wrong... */
return !low_pike_types_le(b, a->car, -array_cnt, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
3360ff | 2009-03-04 | Henrik Grubbström (Grubba) | | case T_ASSIGN: {
struct pike_type **aa_markers = a_markers;
struct pike_type **bb_markers = b_markers;
int m = CAR_TO_INT(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | ret = low_pike_types_le(a->cdr, b, array_cnt, flags);
|
3360ff | 2009-03-04 | Henrik Grubbström (Grubba) | |
if (flags & LE_A_B_SWAPPED) {
aa_markers = b_markers;
bb_markers = a_markers;
}
if(ret && (!aa_markers[m] || (b->type != T_VOID)))
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
struct pike_type *tmp;
int i;
|
7926bf | 2007-03-26 | Henrik Grubbström (Grubba) | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | type_stack_mark();
|
3360ff | 2009-03-04 | Henrik Grubbström (Grubba) | | push_finished_type_with_markers(b, bb_markers, 0);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | for(i=array_cnt; i > 0; i--)
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_ARRAY);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | tmp=pop_unfinished_type();
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | type_stack_mark();
|
3360ff | 2009-03-04 | Henrik Grubbström (Grubba) | | low_or_pike_types(aa_markers[m], tmp, 0);
if(aa_markers[m]) free_type(aa_markers[m]);
free_type(tmp);
aa_markers[m] = pop_unfinished_type();
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | #ifdef PIKE_TYPE_DEBUG
if (l_flag>2) {
|
571a13 | 2007-04-21 | Henrik Grubbström (Grubba) | | if (flags & LE_A_B_SWAPPED) {
fprintf(stderr, "%*sb_markers[%c]=",
indent * 2, "", (char)(m+'0'));
simple_describe_type(b_markers[m]);
} else {
fprintf(stderr, "%*sa_markers[%c]=",
indent * 2, "", (char)(m+'0'));
simple_describe_type(a_markers[m]);
}
fprintf(stderr, "\n");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
#endif
}
return ret;
|
3360ff | 2009-03-04 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
|
ff3630 | 2001-03-31 | Henrik Grubbström (Grubba) | | int m = a->type - '0';
|
571a13 | 2007-04-21 | Henrik Grubbström (Grubba) | | if (flags & LE_A_B_SWAPPED) {
if(b_markers[m]) {
a = b_markers[m];
} else {
a = mixed_type_string;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
|
571a13 | 2007-04-21 | Henrik Grubbström (Grubba) | | if(a_markers[m]) {
a = a_markers[m];
} else {
a = mixed_type_string;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
goto recurse;
}
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | |
case PIKE_T_OPERATOR:
{
|
1247b7 | 2020-08-15 | Henrik Grubbström (Grubba) | | struct pike_type *t = a->car;
if ((t->type >= '0') && (t->type <= '9')) {
t = ((flags & LE_A_B_SWAPPED)?b_markers:a_markers)[t->type - '0'];
if (!t) t = zero_type_string;
}
t = apply_type_operator(a->type, t, a->cdr);
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | ret = low_pike_types_le(t, b, array_cnt, flags);
free_type(t);
return ret;
}
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | |
case PIKE_T_TRANSITIVE:
{
|
41bee5 | 2020-08-30 | Henrik Grubbström (Grubba) | | struct pike_type *t =
expand_transitive(a, ((flags & LE_A_B_SWAPPED)?b_markers:a_markers), 0);
ret = low_pike_types_le(t, b, array_cnt, flags);
free_type(t);
return ret;
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
if ((array_cnt < 0) && (b->type == T_ARRAY)) {
while (b->type == T_ARRAY) {
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | b = b->cdr;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if (!++array_cnt) break;
}
goto recurse;
} else if ((array_cnt > 0) && (a->type == T_ARRAY)) {
while (a->type == T_ARRAY) {
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | a = a->cdr;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if (!--array_cnt) break;
}
goto recurse;
}
/* NOTE: void only matches void. */
if (a->type == T_VOID) {
/* void <= any_type */
if (array_cnt >= 0) {
/* !array(void) */
if (!array_cnt && (b->type == T_VOID)) {
return 1;
}
return 0;
}
}
if (b->type == T_VOID) {
if (array_cnt <= 0) {
/* !array(void) */
return 0;
}
}
if (b->type == T_MIXED) {
/* any_type <= 'mixed' */
if (array_cnt <= 0) {
/* !array(mixed) */
return 1;
}
}
if (a->type == T_MIXED) {
if (array_cnt >= 0) {
/* !array(mixed) */
return 0;
}
}
if (a->type == T_ZERO) {
/* void <= zero <= any_type */
if (array_cnt >= 0) {
/* !array(zero) */
|
614c50 | 2012-02-17 | Henrik Grubbström (Grubba) | | if (!(flags & LE_EXPLICIT_ZERO) ||
((b->type == T_INT) && !array_cnt)) {
return 1;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
if (b->type == T_ZERO) {
if (array_cnt <= 0) {
/* !array(zero) */
return 0;
}
}
/* Special cases (tm) */
switch(TWOT(a->type, b->type))
{
case TWOT(T_PROGRAM, T_FUNCTION):
case TWOT(T_FUNCTION, T_PROGRAM):
case TWOT(T_PROGRAM, T_MANY):
case TWOT(T_MANY, T_PROGRAM):
/* FIXME: Not really... Should check the return value. */
|
6d33d8 | 2001-03-28 | Henrik Grubbström (Grubba) | | /* FIXME: Should also look at the subtype of the program. */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 1;
|
34b26e | 2008-05-10 | Henrik Grubbström (Grubba) | | case TWOT(PIKE_T_TYPE, T_FUNCTION):
case TWOT(PIKE_T_TYPE, T_MANY):
/* Convert the type to a casting function. */
type_stack_mark();
push_finished_type(a->car);
push_type(T_VOID);
push_type(T_MANY);
push_type(T_MIXED);
push_type(T_FUNCTION);
a = pop_unfinished_type();
if (low_pike_types_le(a, b, array_cnt, flags)) {
free_type(a);
return 1;
}
free_type(a);
return 0;
case TWOT(T_FUNCTION, PIKE_T_TYPE):
case TWOT(T_MANY, PIKE_T_TYPE):
/* Convert the type to a casting function. */
type_stack_mark();
push_finished_type(b->car);
push_type(T_VOID);
push_type(T_MANY);
push_type(T_MIXED);
push_type(T_FUNCTION);
b = pop_unfinished_type();
if (low_pike_types_le(a, b, array_cnt, flags)) {
free_type(b);
return 1;
}
free_type(b);
return 0;
case TWOT(PIKE_T_TYPE, T_PROGRAM):
case TWOT(T_PROGRAM, PIKE_T_TYPE):
return low_pike_types_le(a->car, b->car, array_cnt, flags);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case TWOT(T_OBJECT, T_FUNCTION):
case TWOT(T_OBJECT, T_MANY):
{
if((a = low_object_lfun_type(a, LFUN_CALL))) {
goto recurse;
}
return 1;
}
case TWOT(T_FUNCTION, T_OBJECT):
case TWOT(T_MANY, T_OBJECT):
{
if((b=low_object_lfun_type(b, LFUN_CALL))) {
goto recurse;
}
return 1;
}
case TWOT(T_FUNCTION, T_ARRAY):
case TWOT(T_MANY, T_ARRAY):
{
while (b->type == T_ARRAY) {
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | b = b->cdr;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | array_cnt++;
}
goto recurse;
}
case TWOT(T_ARRAY, T_FUNCTION):
case TWOT(T_ARRAY, T_MANY):
{
while (a->type == T_ARRAY) {
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | a = a->cdr;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | array_cnt--;
}
goto recurse;
}
case TWOT(T_FUNCTION, T_FUNCTION):
case TWOT(T_FUNCTION, T_MANY):
case TWOT(T_MANY, T_FUNCTION):
/*
* function(A...:B) <= function(C...:D) iff C <= A && B <= D
*/
/*
* function(:int) <= function(int:int)
* function(int|string:int) <= function(int:int)
* function(:int) <= function(:void)
* function(string:int) != function(int:int)
* function(int:int) != function(:int)
*
* FIXME: Enforcing of all required arguments?
*/
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | while((a->type == T_FUNCTION) || (b->type == T_FUNCTION))
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
struct pike_type *a_tmp, *b_tmp;
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | if ((a->type != T_FUNCTION) && (a->type != T_MANY)) break;
if ((b->type != T_FUNCTION) && (b->type != T_MANY)) break;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | a_tmp = a->car;
if (a->type == T_FUNCTION)
{
a = a->cdr;
}
b_tmp = b->car;
if (b->type == T_FUNCTION)
{
b = b->cdr;
}
if (a_tmp->type != T_VOID) {
|
50fd19 | 2008-08-11 | Henrik Grubbström (Grubba) | | /* Note: flags never has grouping at this point. */
if (!low_pike_types_le(b_tmp, a_tmp, 0, flags ^ LE_A_B_SWAPPED)) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 0;
}
|
b681db | 2016-10-31 | Henrik Grubbström (Grubba) | | } else if (flags & LE_TYPE_SVALUE) {
/* Note: flags never has grouping at this point. */
if (!low_pike_types_le(b_tmp, zero_type_string, 0,
flags ^ LE_A_B_SWAPPED)) {
return 0;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | |
if ((a->type != T_MANY) || (b->type != T_MANY)) {
/* Handle the generic case. */
return low_pike_types_le(a, b, array_cnt, flags);
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case TWOT(T_MANY, T_MANY):
/* check the 'many' type */
if ((a->car->type != T_VOID) && (b->car->type != T_VOID)) {
|
50fd19 | 2008-08-11 | Henrik Grubbström (Grubba) | | /* Note: flags never has grouping at this point. */
if (!low_pike_types_le(b->car, a->car, 0, flags ^ LE_A_B_SWAPPED)) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 0;
}
|
b681db | 2016-10-31 | Henrik Grubbström (Grubba) | | } else if ((flags & LE_TYPE_SVALUE) && (a->car->type != b->car->type)) {
if (a->car->type == T_VOID) {
/* Note: flags never has grouping at this point. */
if (!low_pike_types_le(b->car, zero_type_string, 0,
flags ^ LE_A_B_SWAPPED)) {
return 0;
}
} else {
/* Note: flags never has grouping at this point. */
if (!low_pike_types_le(zero_type_string, a->car, 0,
flags ^ LE_A_B_SWAPPED)) {
return 0;
}
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
a = a->cdr;
b = b->cdr;
/* check the returntype */
|
8ec3c6 | 2016-10-30 | Henrik Grubbström (Grubba) | | if (flags & LE_TYPE_SVALUE) return 1;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* FIXME: Check array_cnt */
if ((b->type != T_VOID) && (a->type != T_VOID)) {
if(!low_pike_types_le(a, b, array_cnt, flags)) return 0;
}
return 1;
}
if(a->type != b->type) return 0;
if (array_cnt) return 0;
switch(a->type)
{
case T_MAPPING:
|
8ec3c6 | 2016-10-30 | Henrik Grubbström (Grubba) | | if (flags & LE_TYPE_SVALUE) return 1;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /*
* mapping(A:B) <= mapping(C:D) iff A <= C && B <= D.
*/
if(!low_pike_types_le(a->car, b->car, 0, flags)) return 0;
array_cnt = 0;
a = a->cdr;
b = b->cdr;
goto recurse;
case T_OBJECT:
#if 0
if(a->cdr || b->cdr)
{
fprintf(stderr,"Type match1: ");
stupid_describe_type(a,type_length(a));
fprintf(stderr,"Type match2: ");
stupid_describe_type(b,type_length(b));
}
#endif
/*
* 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 == y
* object(1 x) <= object(0 y) iff x implements y
* Not WEAK_OBJECTS:
* object(0 x) <= object(0 y) iff x implements y
* WEAK_OBJECTS:
* object(0 x) <= object(0 y) iff x is_compatible y
*/
/* object(* 0) matches any object */
if(!b->cdr)
return 1;
if(!a->cdr)
return 0;
|
b78532 | 2003-11-11 | Henrik Grubbström (Grubba) | |
/* The 'is' flag is now ignored.
* /grubba 2003-11-11
*/
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
abe9fe | 2014-09-18 | Martin Nilsson | | if (a->cdr == b->cdr)
return 1;
|
5223aa | 2004-08-16 | Martin Stjernholm | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
d2361e | 2003-06-30 | Martin Stjernholm | | struct program *ap = id_to_program(CDR_TO_INT(a));
struct program *bp = id_to_program(CDR_TO_INT(b));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
2f0918 | 2006-01-20 | Henrik Grubbström (Grubba) | | #if 0
fprintf(stderr,
"id_to_program(%d) ==> %p\n"
"id_to_program(%d) ==> %p\n",
CDR_TO_INT(a), ap,
CDR_TO_INT(b), bp);
#endif /* 0 */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if (!ap || !bp) {
/* Shouldn't happen... */
|
382da2 | 2004-12-30 | Henrik Grubbström (Grubba) | | /* fprintf(stderr, "ap:%p bp:%p\n", ap, bp); */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 0;
}
|
abe9fe | 2014-09-18 | Martin Nilsson | | if ((flags & LE_WEAK_OBJECTS) && !a->car) {
|
da371d | 2003-11-18 | Henrik Grubbström (Grubba) | | implements_mode = 0;
|
2f0918 | 2006-01-20 | Henrik Grubbström (Grubba) | | #if 0
fprintf(stderr, " is_compat(%p(%d), %p(%d))\n",
ap, ap->id, bp, bp->id);
#endif /* 0 */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return is_compatible(implements_a=ap, implements_b=bp);
}
|
da371d | 2003-11-18 | Henrik Grubbström (Grubba) | | implements_mode = 1;
|
2f0918 | 2006-01-20 | Henrik Grubbström (Grubba) | | #if 0
fprintf(stderr, " implements(%p(%d), %p(%d))\n",
ap, ap->id, bp, bp->id);
#endif /* 0 */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return implements(implements_a=ap, implements_b=bp);
}
break;
case T_INT:
{
|
d2361e | 2003-06-30 | Martin Stjernholm | | INT32 amin = CAR_TO_INT(a);
INT32 amax = CDR_TO_INT(a);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
d2361e | 2003-06-30 | Martin Stjernholm | | INT32 bmin = CAR_TO_INT(b);
INT32 bmax = CDR_TO_INT(b);
|
dd29f4 | 2008-05-06 | Henrik Grubbström (Grubba) | |
/* Handle implicit zero... */
if (amin == 1) amin = 0;
if (bmin == 1) bmin = 0;
if (amax == -1) amax = 0;
if (bmax == -1) bmax = 0;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(amin < bmin || amax > bmax) return 0;
break;
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | case T_TYPE:
|
6d33d8 | 2001-03-28 | Henrik Grubbström (Grubba) | | case T_PROGRAM:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_MULTISET:
|
8ec3c6 | 2016-10-30 | Henrik Grubbström (Grubba) | | if (flags & LE_TYPE_SVALUE) return 1;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | a = a->car;
b = b->car;
array_cnt = 0;
goto recurse;
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | case T_ARRAY:
case T_STRING:
if (flags & LE_TYPE_SVALUE) return 1;
|
e9aa7d | 2020-01-19 | Henrik Grubbström (Grubba) | | if (!low_pike_types_le(a->car, b->car, 0, flags)) return 0;
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | a = a->cdr;
b = b->cdr;
array_cnt = 0;
goto recurse;
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | case T_FLOAT:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_ZERO:
case T_VOID:
case T_MIXED:
break;
|
dd29f4 | 2008-05-06 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | default:
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Error in type string.\n");
|
dd29f4 | 2008-05-06 | Henrik Grubbström (Grubba) | | #endif
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
return 1;
}
/*
* Check the function parameters.
* Note: The difference between this function, and pike_types_le()
* is the more lenient check for T_OR, and the handling of T_ARRAY.
*/
int strict_check_call(struct pike_type *fun_type,
struct pike_type *arg_type)
{
while ((fun_type->type == T_OR) ||
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | (fun_type->type == T_ARRAY) ||
(fun_type->type == PIKE_T_SCOPE)) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if (fun_type->type == T_OR) {
int res = strict_check_call(fun_type->car, arg_type);
if (res) return res;
fun_type = fun_type->cdr;
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | } else if (fun_type->type == PIKE_T_SCOPE) {
fun_type = fun_type->cdr;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | fun_type = fun_type->cdr;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
return low_pike_types_le(fun_type, arg_type, 0, 0);
}
/*
* Check validity of soft-cast.
* Note: This uses a weaker check of function arguments, since
* people get confused otherwise.
*/
int check_soft_cast(struct pike_type *to, struct pike_type *from)
{
return low_pike_types_le(to, from, 0, LE_WEAK_OBJECTS);
}
/*
* Return the return type from a function call.
*/
static int low_get_return_type(struct pike_type *a, struct pike_type *b)
{
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | struct pike_type *t;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | int tmp;
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | CHECK_COMPILER();
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(a->type & PIKE_T_MASK)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
case T_OR:
{
struct pike_type *o1, *o2;
o1=o2=0;
type_stack_mark();
|
13670c | 2015-05-25 | Martin Nilsson | | if(low_get_return_type(a->car, b))
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
o1=pop_unfinished_type();
type_stack_mark();
}
if(low_get_return_type(a->cdr, b))
o2=pop_unfinished_type();
else
pop_stack_mark();
if(!o1 && !o2) return 0;
low_or_pike_types(o1, o2, 0);
if(o1) free_type(o1);
if(o2) free_type(o2);
return 1;
}
case T_AND:
type_stack_mark();
tmp = low_get_return_type(a->car, b);
type_stack_pop_to_mark();
if(!tmp) return 0;
return low_get_return_type(a->cdr, b);
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_RING:
return low_get_return_type(a->car, b);
|
790d03 | 2007-05-09 | Henrik Grubbström (Grubba) | | case PIKE_T_SCOPE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
return low_get_return_type(a->cdr, b);
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
if (low_get_return_type(a->cdr, b)) {
push_type_attribute((struct pike_string *)a->car);
return 1;
}
return 0;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_ARRAY:
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | tmp = low_get_return_type(a->cdr, b);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(!tmp) return 0;
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_ARRAY);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 1;
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | |
case PIKE_T_OPERATOR:
{
struct pike_type *t = apply_type_operator(a->type, a->car, a->cdr);
tmp = low_get_return_type(t, b);
free_type(t);
return tmp;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | t = low_match_types(a, b, NO_SHORTCUTS);
if(t)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | a = t;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | #if 0
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | if ((c->lex.pragmas & ID_STRICT_TYPES) &&
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | !low_pike_types_le(a, b, 0, 0)) {
|
94d66b | 2008-05-24 | Henrik Grubbström (Grubba) | | yyreport_type(REPORT_WARNING, NULL, 0, b, NULL, 0, a, 0, "Type mismatch");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
#endif /* 0 */
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(a->type & PIKE_T_MASK)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
a = a->car;
if (a->type != T_FUNCTION) {
if (a->type == T_MANY) {
a = a->cdr;
push_finished_type_with_markers(a, a_markers, 0);
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | free_type(t);
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | return 1;
}
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | tmp = low_get_return_type(a, mixed_type_string);
free_type(t);
return tmp;
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | }
/* FALLTHRU */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
a = a->cdr;
while(a->type == T_FUNCTION) {
a = a->cdr;
}
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | if (a->type != T_MANY) {
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | tmp = low_get_return_type(a, mixed_type_string);
free_type(t);
return tmp;
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | }
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_MANY:
a = a->cdr;
|
838c21 | 2007-04-27 | Henrik Grubbström (Grubba) | | push_finished_type_with_markers(a, a_markers, 0);
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | free_type(t);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 1;
|
34b26e | 2008-05-10 | Henrik Grubbström (Grubba) | | case T_TYPE:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_PROGRAM:
|
6d33d8 | 2001-03-28 | Henrik Grubbström (Grubba) | | push_finished_type(a->car);
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | free_type(t);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 1;
default:
push_type(T_MIXED);
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | free_type(t);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 1;
}
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | free_type(t);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
return 0;
}
int match_types(struct pike_type *a, struct pike_type *b)
{
clear_markers();
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | a = low_match_types(a, b, 0);
free_type(a);
return !!a;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
int pike_types_le(struct pike_type *a,struct pike_type *b)
{
clear_markers();
return low_pike_types_le(a, b, 0, 0);
}
|
8ec3c6 | 2016-10-30 | Henrik Grubbström (Grubba) | | int check_variant_overload(struct pike_type *a, struct pike_type *b)
{
clear_markers();
return !low_pike_types_le(b, a, 0, LE_TYPE_SVALUE);
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
#ifdef DEBUG_MALLOC
#define low_index_type(X,Y,Z) ((struct pike_type *)debug_malloc_pass(debug_low_index_type((X),(Y),(Z))))
#else
#define low_index_type debug_low_index_type
#endif
/* FIXME, add the index */
static struct pike_type *debug_low_index_type(struct pike_type *t,
struct pike_type *index_type,
node *n)
{
struct pike_type *tmp;
struct program *p;
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | int pragmas = 0;
if (n) {
struct compilation *c = THIS_COMPILATION;
CHECK_COMPILER();
pragmas = c->lex.pragmas;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
switch(low_check_indexing(t, index_type, n))
{
case 0: return 0;
case -1:
add_ref(zero_type_string);
return zero_type_string;
}
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | while((t->type == PIKE_T_NAME) ||
|
0551da | 2013-12-13 | Henrik Grubbström (Grubba) | | (t->type == PIKE_T_ATTRIBUTE) ||
(t->type == T_ASSIGN) ||
(t->type == T_SCOPE)) {
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | t = t->cdr;
}
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | while((index_type->type == PIKE_T_NAME) ||
|
0551da | 2013-12-13 | Henrik Grubbström (Grubba) | | (index_type->type == PIKE_T_ATTRIBUTE) ||
(index_type->type == T_ASSIGN) ||
(index_type->type == T_SCOPE)) {
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | index_type = index_type->cdr;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | switch(t->type)
{
case T_OBJECT:
{
|
d2361e | 2003-06-30 | Martin Stjernholm | | p = id_to_program(CDR_TO_INT(t));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
comefrom_int_index:
if(p && n)
{
INT32 i;
if(n->token == F_ARROW)
{
if((i=FIND_LFUN(p,LFUN_ARROW))!=-1)
{
|
6b5c9d | 2008-06-27 | Henrik Grubbström (Grubba) | | INT32 args = 0;
add_ref(tmp = ID_FROM_INT(p, i)->type);
|
e11fb2 | 2008-06-29 | Henrik Grubbström (Grubba) | | if ((tmp = new_check_call(lfun_strings[LFUN_ARROW], tmp, CDR(n),
&args, 0))) {
|
6b5c9d | 2008-06-27 | Henrik Grubbström (Grubba) | | struct pike_type *ret = new_get_return_type(tmp, 0);
free_type(tmp);
if (ret) return ret;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
6b5c9d | 2008-06-27 | Henrik Grubbström (Grubba) | | /* Invalid type for lfun::`->(). */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | add_ref(mixed_type_string);
return mixed_type_string;
}
}else{
if((i=FIND_LFUN(p,LFUN_INDEX)) != -1)
{
|
6b5c9d | 2008-06-27 | Henrik Grubbström (Grubba) | | INT32 args = 0;
add_ref(tmp = ID_FROM_INT(p, i)->type);
|
e11fb2 | 2008-06-29 | Henrik Grubbström (Grubba) | | if ((tmp = new_check_call(lfun_strings[LFUN_INDEX], tmp, CDR(n),
&args, 0))) {
|
6b5c9d | 2008-06-27 | Henrik Grubbström (Grubba) | | struct pike_type *ret = new_get_return_type(tmp, 0);
free_type(tmp);
if (ret) return ret;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
6b5c9d | 2008-06-27 | Henrik Grubbström (Grubba) | | /* Invalid type for lfun::`[](). */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | add_ref(mixed_type_string);
return mixed_type_string;
}
}
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(CDR(n)->token == F_CONSTANT && TYPEOF(CDR(n)->u.sval) == T_STRING)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
i = find_shared_string_identifier(CDR(n)->u.sval.u.string, p);
if(i==-1)
{
add_ref(mixed_type_string);
return mixed_type_string;
}else{
|
24b27d | 2003-02-24 | Martin Stjernholm | | add_ref(ID_FROM_INT(p, i)->type);
return ID_FROM_INT(p, i)->type;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
78f4a9 | 2013-02-16 | Henrik Grubbström (Grubba) | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | default:
add_ref(mixed_type_string);
return mixed_type_string;
case T_MIXED:
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | if (pragmas & ID_STRICT_TYPES) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | yywarning("Indexing mixed.");
}
add_ref(mixed_type_string);
|
13670c | 2015-05-25 | Martin Nilsson | | return mixed_type_string;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
082ad2 | 2014-10-29 | Martin Nilsson | | case T_INT:
|
c3982f | 2014-10-29 | Martin Nilsson | | p=bignum_program;
|
082ad2 | 2014-10-29 | Martin Nilsson | | goto comefrom_int_index;
|
031171 | 2013-06-17 | Martin Nilsson | |
|
082ad2 | 2014-10-29 | Martin Nilsson | | case T_ZERO:
case T_TYPE:
case PIKE_T_RING:
case T_VOID:
case T_FLOAT:
return 0;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
case T_OR:
{
struct pike_type *a,*b;
a = low_index_type(t->car, index_type, n);
b = low_index_type(t->cdr, index_type,n);
if(!b) return a;
if(!a) return b;
type_stack_mark();
low_or_pike_types(a,b,1);
free_type(a);
free_type(b);
return pop_unfinished_type();
}
case T_AND:
/* FIXME: Shouldn't both branches be looked at? */
return low_index_type(t->cdr, index_type, n);
case T_STRING: /* always int */
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | {
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | if (t->cdr->type == T_ZERO) {
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | | yywarning("Indexing the empty string.");
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | }
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | add_ref(t->cdr);
return t->cdr;
|
157fc6 | 2007-03-03 | Henrik Grubbström (Grubba) | | }
|
4e6c08 | 2007-05-02 | Henrik Grubbström (Grubba) | |
|
d2c0e2 | 2016-01-20 | Henrik Grubbström (Grubba) | | case T_MULTISET: /* always int(0..1) */
type_stack_mark();
push_int_type(0, 1);
return pop_unfinished_type();
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
case T_MAPPING:
add_ref(t = t->cdr);
return t;
case T_ARRAY:
{
struct pike_type *a;
|
daea6d | 2007-03-20 | Henrik Grubbström (Grubba) | | if(low_pike_types_le(string0_type_string, index_type, 0, 0) &&
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | (a = low_index_type(t->cdr, string0_type_string, n))) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* Possible to index the array with a string. */
type_stack_mark();
push_finished_type(a);
free_type(a);
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_ARRAY);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
57545b | 2020-08-20 | Henrik Grubbström (Grubba) | | if (match_types(int_type_string, index_type)) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* Also possible to index the array with an int. */
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | push_finished_type(t->cdr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | push_type(T_OR);
}
return pop_unfinished_type();
}
|
57545b | 2020-08-20 | Henrik Grubbström (Grubba) | | if (match_types(int_type_string, index_type)) {
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | /* Possible to index the array with an int. */
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | add_ref(t->cdr);
return t->cdr;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
/* Bad index type. */
return 0;
}
}
}
struct pike_type *index_type(struct pike_type *type,
struct pike_type *index_type,
node *n)
{
struct pike_type *t;
clear_markers();
t = low_index_type(type, index_type, n);
if(!t) {
|
be6fec | 2001-04-01 | Henrik Grubbström (Grubba) | | copy_pike_type(t, mixed_type_string);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
return t;
}
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | #ifdef DEBUG_MALLOC
#define low_range_type(X,Y,Z) ((struct pike_type *)debug_malloc_pass(debug_low_range_type((X),(Y),(Z))))
#else
#define low_range_type debug_low_range_type
#endif
/* FIXME, add the index
*
* FIXME: Is the above fixme valid for this function too?
*/
static struct pike_type *debug_low_range_type(struct pike_type *t,
struct pike_type *index1_type,
struct pike_type *index2_type)
{
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | struct pike_type *tmp;
struct program *p;
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | CHECK_COMPILER();
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | while((t->type == PIKE_T_NAME) ||
(t->type == PIKE_T_ATTRIBUTE)) {
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | t = t->cdr;
}
|
408a1e | 2004-10-30 | Martin Stjernholm | | if (index1_type)
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | while((index1_type->type == PIKE_T_NAME) ||
(index1_type->type == PIKE_T_ATTRIBUTE)) {
|
408a1e | 2004-10-30 | Martin Stjernholm | | index1_type = index1_type->cdr;
}
if (index2_type)
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | while((index2_type->type == PIKE_T_NAME) ||
(index2_type->type == PIKE_T_ATTRIBUTE)) {
|
408a1e | 2004-10-30 | Martin Stjernholm | | index2_type = index2_type->cdr;
}
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | |
switch(t->type)
{
case T_OBJECT:
{
|
d2361e | 2003-06-30 | Martin Stjernholm | | p = id_to_program(CDR_TO_INT(t));
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | |
if(p)
{
INT32 i;
|
408a1e | 2004-10-30 | Martin Stjernholm | |
if((i = FIND_LFUN(p, LFUN_RANGE)) != -1)
{
struct pike_type *call_type = NULL;
type_stack_mark();
push_finished_type(mixed_type_string);
push_finished_type(void_type_string);
push_type(T_OR); /* Return type */
push_finished_type(void_type_string); /* Many type */
push_type(T_MANY);
push_int_type (INDEX_FROM_BEG, OPEN_BOUND); /* arg4 type */
push_type(T_FUNCTION);
if (index2_type) /* arg3 type */
push_finished_type(index2_type);
else
push_type (T_ZERO);
push_type(T_FUNCTION);
push_int_type (INDEX_FROM_BEG, OPEN_BOUND); /* arg2 type */
push_type(T_FUNCTION);
if (index1_type) /* arg1 type */
push_finished_type(index1_type);
else
push_type (T_ZERO);
push_type(T_FUNCTION);
call_type = pop_unfinished_type();
|
13670c | 2015-05-25 | Martin Nilsson | |
|
408a1e | 2004-10-30 | Martin Stjernholm | | if((tmp = check_call(call_type, ID_FROM_INT(p, i)->type, 0))) {
free_type(call_type);
return tmp;
}
|
7cfead | 2005-04-06 | Henrik Grubbström (Grubba) | | free_type(call_type);
|
408a1e | 2004-10-30 | Martin Stjernholm | |
add_ref(mixed_type_string);
return mixed_type_string;
}
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | if((i = FIND_LFUN(p, LFUN_INDEX)) != -1)
{
|
408a1e | 2004-10-30 | Martin Stjernholm | | /* FIXME: Should check for a _sizeof operator if from-the-end
* indexing is done. */
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | struct pike_type *call_type = NULL;
/* FIXME: function_type_string should be replaced with something
* derived from type_string
*/
type_stack_mark();
push_finished_type(mixed_type_string);
push_finished_type(void_type_string);
push_type(T_OR); /* Return type */
push_finished_type(void_type_string); /* Many type */
push_type(T_MANY);
|
408a1e | 2004-10-30 | Martin Stjernholm | | if (index2_type) /* arg2 type */
push_finished_type(index2_type);
else
push_int_type (MAX_INT_TYPE, MAX_INT_TYPE);
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | push_type(T_FUNCTION);
|
408a1e | 2004-10-30 | Martin Stjernholm | | if (index1_type) /* arg1 type */
push_finished_type(index1_type);
else
push_type (T_ZERO);
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | push_type(T_FUNCTION);
call_type = pop_unfinished_type();
|
13670c | 2015-05-25 | Martin Nilsson | |
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | if((tmp = check_call(call_type, ID_FROM_INT(p, i)->type, 0))) {
free_type(call_type);
return tmp;
}
|
7cfead | 2005-04-06 | Henrik Grubbström (Grubba) | | free_type(call_type);
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | |
add_ref(mixed_type_string);
return mixed_type_string;
}
|
408a1e | 2004-10-30 | Martin Stjernholm | |
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | yywarning("Ranging object without index operator.");
return 0;
}
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | if (c->lex.pragmas & ID_STRICT_TYPES) {
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | yywarning("Ranging generic object.");
}
add_ref(mixed_type_string);
|
13670c | 2015-05-25 | Martin Nilsson | | return mixed_type_string;
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | }
case T_MIXED:
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | if (c->lex.pragmas & ID_STRICT_TYPES) {
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | yywarning("Ranging mixed.");
}
add_ref(mixed_type_string);
|
13670c | 2015-05-25 | Martin Nilsson | | return mixed_type_string;
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | |
case T_INT:
case T_ZERO:
case T_TYPE:
case PIKE_T_RING:
case T_VOID:
case T_FLOAT:
case T_MULTISET:
case T_MAPPING:
/* Illegal range operation. */
/* FIXME: Strict type warning. */
return 0;
|
502670 | 2020-05-18 | Henrik Grubbström (Grubba) | | case T_ARRAY: /* FIXME: cdr */
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | case T_STRING:
/* Check that the index types are compatible with int. */
{
|
57545b | 2020-08-20 | Henrik Grubbström (Grubba) | | if (index1_type && !match_types(int_type_string, index1_type)) {
|
94d66b | 2008-05-24 | Henrik Grubbström (Grubba) | | ref_push_type_value(t);
yytype_report(REPORT_WARNING, NULL, 0, int_type_string,
NULL, 0, index1_type,
1, "Bad argument 1 to range operator on %O.");
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | /* Bad index1 type. */
return 0;
}
|
57545b | 2020-08-20 | Henrik Grubbström (Grubba) | | if (index2_type && !match_types(int_type_string, index2_type)) {
|
94d66b | 2008-05-24 | Henrik Grubbström (Grubba) | | ref_push_type_value(t);
yytype_report(REPORT_WARNING, NULL, 0, int_type_string,
NULL, 0, index2_type,
1, "Bad argument 2 to range operator on %O.");
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | /* Bad index2 type. */
return 0;
}
}
/* FALLTHROUGH */
default:
/* Identity. */
add_ref(t);
return t;
case T_OR:
{
struct pike_type *a,*b;
a = low_range_type(t->car, index1_type, index2_type);
b = low_range_type(t->cdr, index1_type, index2_type);
if(!b) return a;
if(!a) return b;
type_stack_mark();
low_or_pike_types(a,b,1);
free_type(a);
free_type(b);
return pop_unfinished_type();
}
case T_AND:
/* FIXME: Shouldn't both branches be looked at? */
return low_range_type(t->cdr, index1_type, index2_type);
}
}
struct pike_type *range_type(struct pike_type *type,
struct pike_type *index1_type,
struct pike_type *index2_type)
{
struct pike_type *t;
clear_markers();
t = low_range_type(type, index1_type, index2_type);
if(!t) {
|
94d66b | 2008-05-24 | Henrik Grubbström (Grubba) | | yytype_report(REPORT_ERROR, NULL, 0, NULL, NULL, 0, NULL,
0, "Invalid range operation.");
|
663cbf | 2002-05-15 | Henrik Grubbström (Grubba) | | copy_pike_type(t, type);
}
return t;
}
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
static struct pike_type *low_array_value_type(struct pike_type *arr_t)
{
struct pike_type *res = NULL;
struct pike_type *sub_t;
while (arr_t->type == T_OR) {
sub_t = low_array_value_type(arr_t->car);
arr_t = arr_t->cdr;
if (sub_t) {
if (res) {
struct pike_type *new = or_pike_types(res, sub_t, 1);
free_type(res);
free_type(sub_t);
res = new;
} else {
res = sub_t;
}
}
}
if (arr_t->type != T_ARRAY)
return res;
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | copy_pike_type(sub_t, arr_t->cdr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
if (res) {
struct pike_type *new = or_pike_types(res, sub_t, 1);
free_type(res);
free_type(sub_t);
return new;
}
return sub_t;
}
struct pike_type *array_value_type(struct pike_type *array_type)
{
struct pike_type *t = low_array_value_type(array_type);
if (!t) {
|
be6fec | 2001-04-01 | Henrik Grubbström (Grubba) | | copy_pike_type(t, mixed_type_string);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
return t;
}
#ifdef DEBUG_MALLOC
#define low_key_type(X,Y) ((struct pike_type *)debug_malloc_pass(debug_low_key_type((X),(Y))))
#else
#define low_key_type debug_low_key_type
#endif
/* FIXME, add the index */
static struct pike_type *debug_low_key_type(struct pike_type *t, node *n)
{
switch(t->type)
{
case T_OBJECT:
{
|
d2361e | 2003-06-30 | Martin Stjernholm | | struct program *p = id_to_program(CDR_TO_INT(t));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(p && n)
{
if(n->token == F_ARROW)
{
|
911526 | 2008-06-29 | Henrik Grubbström (Grubba) | | int i;
if((i = FIND_LFUN(p,LFUN_ARROW))!=-1 ||
(i = FIND_LFUN(p,LFUN_ASSIGN_ARROW))!=-1)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
911526 | 2008-06-29 | Henrik Grubbström (Grubba) | | /* Get the type of the first argument of the function. */
struct pike_type *res =
|
e1483f | 2011-12-11 | Henrik Grubbström (Grubba) | | get_first_arg_type(ID_FROM_INT(p, i)->type, CALL_NOT_LAST_ARG);
|
911526 | 2008-06-29 | Henrik Grubbström (Grubba) | | if (res) return res;
/* FIXME: Warn? */
add_ref(string_type_string);
return string_type_string;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
}else{
|
911526 | 2008-06-29 | Henrik Grubbström (Grubba) | | int i;
if((i = FIND_LFUN(p,LFUN_INDEX)) != -1 ||
(i = FIND_LFUN(p,LFUN_ASSIGN_INDEX)) != -1)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
911526 | 2008-06-29 | Henrik Grubbström (Grubba) | | /* Get the type of the first argument of the function. */
struct pike_type *res =
|
e1483f | 2011-12-11 | Henrik Grubbström (Grubba) | | get_first_arg_type(ID_FROM_INT(p, i)->type, CALL_NOT_LAST_ARG);
|
911526 | 2008-06-29 | Henrik Grubbström (Grubba) | | if (res) return res;
/* FIXME: Warn? */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | add_ref(mixed_type_string);
return mixed_type_string;
}
}
}
add_ref(string_type_string);
return string_type_string;
}
default:
add_ref(mixed_type_string);
return mixed_type_string;
case T_VOID:
case T_ZERO:
case T_TYPE:
|
ce88d6 | 2001-03-19 | Henrik Grubbström (Grubba) | | case PIKE_T_RING:
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_FLOAT:
case T_INT:
return 0;
case T_OR:
{
struct pike_type *a,*b;
a = low_key_type(t->car, n);
b = low_key_type(t->cdr, n);
if(!b) return a;
if(!a) return b;
type_stack_mark();
low_or_pike_types(a,b,1);
free_type(a);
free_type(b);
return pop_unfinished_type();
}
case T_AND:
/* FIXME: Shouldn't this look at both branches? */
return low_key_type(t->cdr, n);
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | return low_key_type(t->cdr, n);
|
502670 | 2020-05-18 | Henrik Grubbström (Grubba) | | case T_ARRAY: /* FIXME: cdr */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_STRING: /* always int */
add_ref(int_type_string);
return int_type_string;
case T_MAPPING:
case T_MULTISET:
|
be6fec | 2001-04-01 | Henrik Grubbström (Grubba) | | copy_pike_type(t, t->car);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return t;
}
}
struct pike_type *key_type(struct pike_type *type, node *n)
{
struct pike_type *t;
clear_markers();
t = low_key_type(type,n);
if(!t) {
|
be6fec | 2001-04-01 | Henrik Grubbström (Grubba) | | copy_pike_type(t, mixed_type_string);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
return t;
}
|
e11fb2 | 2008-06-29 | Henrik Grubbström (Grubba) | | /* Returns whether a value of type 'type' may be indexed with a value
* of type 'index_type'. Returns -1 if the indexing operation is valid,
* but will always fail.
* The node 'n' is the node with the indexing operator.
*/
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | static int low_check_indexing(struct pike_type *type,
struct pike_type *index_type,
node *n)
{
switch(type->type)
{
case T_OR:
return low_check_indexing(type->car, index_type, n) ||
low_check_indexing(type->cdr, index_type, n);
case T_AND:
return low_check_indexing(type->car, index_type, n) &&
low_check_indexing(type->cdr, index_type, n);
case T_NOT:
return low_check_indexing(type->car, index_type, n) != 1;
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
45e5a7 | 2019-07-11 | Henrik Grubbström (Grubba) | | if (low_check_indexing(type->cdr, index_type, n)) {
/* Valid index, so let's check if the attribute
* handler has any other opinion.
*/
ref_push_string((struct pike_string *)type->car);
ref_push_type_value(type->cdr);
ref_push_type_value(index_type);
safe_apply_current2(PC_INDEX_TYPE_ATTRIBUTE_FUN_NUM, 3,
"index_type_attribute");
if ((TYPEOF(Pike_sp[-1]) == T_INT) &&
(SUBTYPEOF(Pike_sp[-1]) == NUMBER_NUMBER) &&
(!Pike_sp[-1].u.integer)) {
pop_stack();
return 0;
}
pop_stack();
return 1;
}
return 0;
case PIKE_T_NAME:
|
0551da | 2013-12-13 | Henrik Grubbström (Grubba) | | case T_ASSIGN:
case T_SCOPE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | return low_check_indexing(type->cdr, index_type, n);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_ARRAY:
|
57545b | 2020-08-20 | Henrik Grubbström (Grubba) | | if(match_types(string_type_string, index_type) &&
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | low_check_indexing(type->cdr, index_type, n))
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 1;
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_STRING:
|
57545b | 2020-08-20 | Henrik Grubbström (Grubba) | | return match_types(int_type_string, index_type);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
case T_OBJECT:
{
|
d2361e | 2003-06-30 | Martin Stjernholm | | struct program *p = id_to_program(CDR_TO_INT(type));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(p)
{
|
911526 | 2008-06-29 | Henrik Grubbström (Grubba) | | int i = -1;
/* Check against the LFUN types. */
|
78f4a9 | 2013-02-16 | Henrik Grubbström (Grubba) | | if(n && (n->token == F_ARROW))
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
|
911526 | 2008-06-29 | Henrik Grubbström (Grubba) | | (i = FIND_LFUN(p,LFUN_ARROW))!=-1 ||
(i = FIND_LFUN(p,LFUN_ASSIGN_ARROW));
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }else{
|
911526 | 2008-06-29 | Henrik Grubbström (Grubba) | | (i = FIND_LFUN(p,LFUN_INDEX))!=-1 ||
(i = FIND_LFUN(p,LFUN_ASSIGN_INDEX));
}
if (i != -1) {
if ((type = low_new_check_call(ID_FROM_INT(p, i)->type, index_type,
|
a794a5 | 2011-12-14 | Henrik Grubbström (Grubba) | | CALL_NOT_LAST_ARG, NULL))) {
|
911526 | 2008-06-29 | Henrik Grubbström (Grubba) | | free_type(type);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return 1;
|
911526 | 2008-06-29 | Henrik Grubbström (Grubba) | | }
return 0;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
|
57545b | 2020-08-20 | Henrik Grubbström (Grubba) | | return match_types(string_type_string, index_type);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }else{
return 1;
}
}
case T_MULTISET:
case T_MAPPING:
|
e11fb2 | 2008-06-29 | Henrik Grubbström (Grubba) | | /* FIXME: Why -1 and not 0?
*
|
911526 | 2008-06-29 | Henrik Grubbström (Grubba) | | * - There were complaints when people got compilation errors
* for indexing operations that would always fail.
|
e11fb2 | 2008-06-29 | Henrik Grubbström (Grubba) | | */
|
57545b | 2020-08-20 | Henrik Grubbström (Grubba) | | return match_types(type->car, index_type) ? 1 : -1;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
afa24a | 2014-04-08 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
while ((type = type->cdr) && (type->type == T_FUNCTION))
;
if (!type) return 0;
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | | if (type->type != T_MANY) return 0;
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
afa24a | 2014-04-08 | Henrik Grubbström (Grubba) | |
case T_MANY:
type = type->cdr;
if (!type || (type->type != T_OBJECT) || !type->car)
return 0;
/* function(... : object(is foo)) -- ie probably program(foo). */
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
afa24a | 2014-04-08 | Henrik Grubbström (Grubba) | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_INT:
case T_PROGRAM:
|
57545b | 2020-08-20 | Henrik Grubbström (Grubba) | | return match_types(string_type_string, index_type);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
case T_MIXED:
return 1;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | default:
return 0;
}
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | int check_indexing(struct pike_type *type,
struct pike_type *index_type,
node *n)
{
return low_check_indexing(type, index_type, n);
}
static int low_count_arguments(struct pike_type *q)
{
int num=0, num2;
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(q->type & PIKE_T_MASK)
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | {
case T_OR:
num = low_count_arguments(q->car);
num2 = low_count_arguments(q->cdr);
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->car);
num2 = low_count_arguments(q->cdr);
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;
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
0551da | 2013-12-13 | Henrik Grubbström (Grubba) | | case T_ASSIGN:
case T_SCOPE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | return low_count_arguments(q->cdr);
|
477550 | 2008-06-29 | Martin Stjernholm | | default: return MAX_INT32;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | case PIKE_T_OPERATOR:
{
struct pike_type *t = apply_type_operator(q->type, q->car, q->cdr);
num = low_count_arguments(t);
free_type(t);
return num;
}
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
num = low_count_arguments(q->car);
if (num == MAX_INT32) return num;
if (num < 0) return num;
return ~num;
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
while(q->type == T_FUNCTION)
{
num++;
q = q->cdr;
}
|
0bd03e | 2020-07-13 | Henrik Grubbström (Grubba) | |
if (q->type != T_MANY) {
num2 = low_count_arguments(q);
if (num2 == MAX_INT32) return num2;
if (num2 < 0) {
num += ~num2;
return ~num;
}
return num + num2;
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_MANY:
q = q->car;
if(q->type != T_VOID) return ~num;
return num;
}
}
/* Count the number of arguments for a funciton type.
* return -1-n if the function can take number of arguments
* >= n (varargs)
*/
int count_arguments(struct pike_type *s)
{
return low_count_arguments(s);
}
static int low_minimum_arguments(struct pike_type *q)
{
int num;
switch(q->type)
{
case T_OR:
case T_AND:
return MAXIMUM(low_count_arguments(q->car),
low_count_arguments(q->cdr));
default: return 0;
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
|
0551da | 2013-12-13 | Henrik Grubbström (Grubba) | | case T_ASSIGN:
case T_SCOPE:
|
f62c41 | 2001-03-05 | Henrik Grubbström (Grubba) | | return low_minimum_arguments(q->cdr);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
num = 0;
while(q->type == T_FUNCTION)
{
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | struct pike_type *t;
if ((t = low_match_types(void_type_string, q->car, B_EXACT))) {
free_type(t);
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | return num;
|
162e88 | 2020-08-21 | Henrik Grubbström (Grubba) | | }
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | |
num++;
q = q->cdr;
}
return num;
case T_MANY:
return 0;
}
}
|
96f8e8 | 2005-11-17 | Henrik Grubbström (Grubba) | | /* Count the minimum number of arguments for a function type.
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | */
int minimum_arguments(struct pike_type *s)
{
int ret;
ret = low_minimum_arguments(s);
#if 0
fprintf(stderr,"minimum_arguments(");
simple_describe_type(s);
fprintf(stderr," ) -> %d\n",ret);
#endif
return ret;
}
struct pike_type *check_call(struct pike_type *args,
struct pike_type *type,
int strict)
{
clear_markers();
type_stack_mark();
max_correct_args=0;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | if(low_get_return_type(type, args))
{
if (strict) {
if (!strict_check_call(type, args)) {
struct pike_type *func_zero_type;
MAKE_CONSTANT_TYPE(func_zero_type, tFuncV(tNone,tZero,tMix));
if (!low_pike_types_le(type, func_zero_type, 0, 0)) {
|
94d66b | 2008-05-24 | Henrik Grubbström (Grubba) | | yytype_report(REPORT_WARNING, NULL, 0, function_type_string,
NULL, 0, type,
0, "Calling non-function value.");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | } else {
|
94d66b | 2008-05-24 | Henrik Grubbström (Grubba) | | yytype_report(REPORT_WARNING, NULL, 0, type,
NULL, 0, args,
0, "Arguments not strictly compatible.");
|
71a967 | 2001-03-03 | Henrik Grubbström (Grubba) | | }
free_type(func_zero_type);
}
}
return pop_unfinished_type();
}else{
pop_stack_mark();
return 0;
}
}
|
2d787e | 2006-10-27 | Henrik Grubbström (Grubba) | | /* Get the type for the specified argument in a function type.
* Argument number -1 is the return type.
* True arguments are counted from zero.
*/
struct pike_type *get_argument_type(struct pike_type *fun, int arg_no)
{
|
e38fc1 | 2018-01-25 | Henrik Grubbström (Grubba) | | struct pike_type *tmp, *tmp2;
|
637aac | 2014-04-29 | Henrik Grubbström (Grubba) | |
|
2d787e | 2006-10-27 | Henrik Grubbström (Grubba) | | loop:
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | switch(fun->type & PIKE_T_MASK) {
|
2d787e | 2006-10-27 | Henrik Grubbström (Grubba) | | case T_OR:
|
e38fc1 | 2018-01-25 | Henrik Grubbström (Grubba) | | fun = or_pike_types(tmp = get_argument_type(fun->car, arg_no),
tmp2 = get_argument_type(fun->cdr, arg_no),
1);
free_type(tmp);
free_type(tmp2);
return fun;
|
d79bff | 2020-07-17 | Henrik Grubbström (Grubba) | | case PIKE_T_OPERATOR:
tmp = apply_type_operator(fun->type, fun->car, fun->cdr);
tmp2 = get_argument_type(tmp, arg_no);
free_type(tmp);
return tmp2;
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | | case PIKE_T_TRANSITIVE:
if (arg_no < 0) {
fun = fun->cdr;
goto loop;
}
|
bdfff3 | 2020-09-14 | Henrik Grubbström (Grubba) | | tmp2 = expand_transitive(fun, a_markers, 0);
tmp = get_argument_type(tmp2, arg_no);
free_type(tmp2);
return tmp;
|
5fc964 | 2020-08-17 | Henrik Grubbström (Grubba) | |
|
2d787e | 2006-10-27 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
if (arg_no > 0) {
arg_no--;
fun = fun->cdr;
goto loop;
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
2d787e | 2006-10-27 | Henrik Grubbström (Grubba) | | case T_MANY:
if (arg_no < 0) {
add_ref(fun->cdr);
return fun->cdr;
}
add_ref(fun->car);
return fun->car;
case T_MIXED:
add_ref(fun);
return fun;
case T_ARRAY:
if (arg_no < 0) {
type_stack_mark();
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | push_finished_type(fun = get_argument_type(fun->cdr, arg_no));
|
04017d | 2020-01-02 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_ARRAY);
|
2d787e | 2006-10-27 | Henrik Grubbström (Grubba) | | free_type(fun);
return pop_unfinished_type();
}
return get_argument_type(fun->car, arg_no);
|
d4a74d | 2014-04-16 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
type_stack_mark();
|
637aac | 2014-04-29 | Henrik Grubbström (Grubba) | | push_finished_type(tmp = get_argument_type(fun->cdr, arg_no));
|
d4a74d | 2014-04-16 | Henrik Grubbström (Grubba) | | push_type_attribute((struct pike_string *)(fun->car));
|
637aac | 2014-04-29 | Henrik Grubbström (Grubba) | | free_type(tmp);
|
d4a74d | 2014-04-16 | Henrik Grubbström (Grubba) | | return pop_unfinished_type();
case PIKE_T_SCOPE:
case T_ASSIGN:
case PIKE_T_NAME:
fun = fun->cdr;
goto loop;
|
2d787e | 2006-10-27 | Henrik Grubbström (Grubba) | | default:
|
d4a74d | 2014-04-16 | Henrik Grubbström (Grubba) | | #if 0
fprintf(stderr,
"Failed to resolve argument type for argument %d.\n"
"Type: ",
arg_no);
simple_describe_type(fun);
fprintf(stderr, "\n"
"Node type: %d\n",
fun->type);
#endif
|
2d787e | 2006-10-27 | Henrik Grubbström (Grubba) | | add_ref(zero_type_string);
return zero_type_string;
}
}
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | /* Get the resulting type from a soft cast.
*
* Flags:
* 1 SOFT_WEAKER Weaker type.
*/
struct pike_type *soft_cast(struct pike_type *soft_type,
struct pike_type *orig_type,
int flags)
{
struct pike_type *res = NULL;
struct pike_type *tmp = NULL;
struct pike_type *tmp2 = NULL;
struct pike_type *tmp3 = NULL;
if (soft_type == orig_type) {
copy_pike_type(res, soft_type);
return res;
}
loop:
switch(soft_type->type) {
case T_OR:
|
80f7aa | 2007-06-29 | Henrik Grubbström (Grubba) | | tmp = soft_cast(soft_type->car, orig_type, flags);
if (tmp == orig_type) return tmp;
tmp2 = soft_cast(soft_type->cdr, orig_type, flags);
if (tmp2 == orig_type) {
res = tmp2;
tmp2 = NULL;
} else {
res = or_pike_types(tmp, tmp2, 1);
}
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | break;
case T_AND:
|
80f7aa | 2007-06-29 | Henrik Grubbström (Grubba) | | /* FIXME: Make stricter analogous to OR above. */
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | res = and_pike_types(tmp = soft_cast(soft_type->car, orig_type, flags),
tmp2 = soft_cast(soft_type->cdr, orig_type, flags));
break;
case T_SCOPE:
case T_ASSIGN:
case PIKE_T_NAME:
soft_type = soft_type->cdr;
goto loop;
/* FIXME: TUPLE, RING */
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
if ((res = soft_cast(soft_type->cdr, orig_type, flags))) {
type_stack_mark();
push_finished_type(res);
push_type_attribute((struct pike_string *)soft_type->car);
free_type(res);
res = pop_unfinished_type();
}
return res;
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | case T_MIXED:
if (flags & SOFT_WEAKER) {
copy_pike_type(res, soft_type);
} else if (orig_type->type == T_VOID) {
copy_pike_type(res, zero_type_string);
} else {
copy_pike_type(res, orig_type);
}
break;
case T_ZERO:
if (!(flags & SOFT_WEAKER) || (orig_type->type == T_VOID)) {
copy_pike_type(res, soft_type);
} else {
copy_pike_type(res, orig_type);
}
break;
}
if (!res) {
loop2:
switch(orig_type->type) {
case T_OR:
|
80f7aa | 2007-06-29 | Henrik Grubbström (Grubba) | | tmp = soft_cast(soft_type, orig_type->car, flags);
if (tmp == soft_type) return tmp;
tmp2 = soft_cast(soft_type, orig_type->cdr, flags);
if (tmp2 == soft_type) {
res = tmp2;
tmp2 = NULL;
} else {
res = or_pike_types(tmp, tmp2, 1);
}
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | break;
case T_AND:
|
6f8f68 | 2008-09-12 | Henrik Grubbström (Grubba) | | /* Note: We need to handle T_NOT here. */
if (orig_type->car->type != T_NOT) {
tmp = soft_cast(soft_type, orig_type->car, flags);
if (!tmp) return NULL;
if (tmp == orig_type->car) {
/* The original type is stricter than the soft type. */
free_type(tmp);
add_ref(orig_type);
return orig_type;
}
}
if (orig_type->cdr->type != T_NOT) {
tmp2 = soft_cast(soft_type, orig_type->cdr, flags);
if (!tmp2) {
if (tmp) free_type(tmp);
return NULL;
}
if (tmp2 == orig_type->cdr) {
/* The original type is stricter than the soft type. */
if (tmp) free_type(tmp);
free_type(tmp2);
add_ref(orig_type);
return orig_type;
}
}
res = and_pike_types(tmp?tmp:orig_type->car, tmp2?tmp2:orig_type->cdr);
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | break;
case T_SCOPE:
|
dd4fd4 | 2008-09-12 | Henrik Grubbström (Grubba) | | if ((res = soft_cast(soft_type, orig_type->cdr, flags))) {
type_stack_mark();
push_finished_type(res);
push_scope_type(CAR_TO_INT(orig_type));
free_type(res);
res = pop_unfinished_type();
}
return res;
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | case T_ASSIGN:
case PIKE_T_NAME:
orig_type = orig_type->cdr;
goto loop2;
|
912912 | 2007-04-21 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
if ((res = soft_cast(soft_type, orig_type->cdr, flags))) {
type_stack_mark();
push_finished_type(res);
push_type_attribute((struct pike_string *)orig_type->car);
free_type(res);
res = pop_unfinished_type();
}
return res;
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | case T_MIXED:
if (flags & SOFT_WEAKER) {
copy_pike_type(res, orig_type);
} else {
copy_pike_type(res, soft_type);
}
break;
case T_VOID:
case T_ZERO:
if (flags & SOFT_WEAKER) {
copy_pike_type(res, soft_type);
} else {
copy_pike_type(res, zero_type_string);
}
break;
}
}
if (!res) {
switch(soft_type->type) {
case T_VOID:
if (orig_type->type == T_VOID) {
copy_pike_type(res, soft_type);
} else {
return NULL;
}
break;
|
34b26e | 2008-05-10 | Henrik Grubbström (Grubba) | | case T_TYPE:
/* Convert to a function returning the subtype and retry. */
type_stack_mark();
push_finished_type(soft_type->car);
push_type(T_VOID);
push_type(T_MANY);
push_type(T_MIXED);
push_type(T_FUNCTION);
tmp = pop_unfinished_type();
res = soft_cast(tmp, orig_type, flags);
break;
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | case T_PROGRAM:
/* Convert to a function returning an object. */
copy_pike_type(tmp3, soft_type->car); /* Return type */
if ((tmp2 = low_object_lfun_type(tmp3, LFUN_CREATE))) {
soft_type = tmp2;
tmp2 = NULL;
} else {
/* FIXME: Multiple cases. */
soft_type = function_type_string;
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
case T_MANY:
{
int array_cnt = 0;
int loop_cnt = 0;
while(orig_type->type == T_ARRAY) {
array_cnt++;
|
d5a7dc | 2019-12-16 | Henrik Grubbström (Grubba) | | orig_type = orig_type->cdr;
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | }
if (orig_type->type == T_PROGRAM) {
copy_pike_type(tmp, orig_type->car); /* Return type */
if ((tmp2 = low_object_lfun_type(tmp, LFUN_CREATE))) {
orig_type = tmp2;
tmp2 = NULL;
} else {
/* FIXME: Multiple cases. */
tmp2 = soft_type;
while(tmp2->type == T_FUNCTION) tmp2 = tmp2->cdr;
if (tmp2->type == T_MANY) {
if ((tmp2 = soft_cast(tmp2->car, tmp, flags ^ SOFT_WEAKER))) {
/* FIXME: Adjust the return type to tmp2! */
copy_pike_type(res, soft_type);
}
} else {
tmp2 = NULL;
copy_pike_type(res, soft_type);
}
break;
}
} else if (orig_type->type == T_OBJECT) {
|
d4540d | 2007-04-26 | Henrik Grubbström (Grubba) | | if ((tmp = low_object_lfun_type(orig_type, LFUN_CALL))) {
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | orig_type = tmp;
tmp = NULL;
} else {
/* FIXME: Multiple cases. */
copy_pike_type(res, orig_type);
break;
}
}
|
9e5e9b | 2020-09-16 | Henrik Grubbström (Grubba) | | if ((orig_type->type & PIKE_T_MASK) == PIKE_T_OPERATOR) {
|
95a7af | 2020-09-12 | Henrik Grubbström (Grubba) | | /* Assume ok. */
copy_pike_type(res, orig_type);
break;
}
|
d77106 | 2007-04-13 | Henrik Grubbström (Grubba) | | /* FIXME: Loop above until function? */
if ((orig_type->type != T_FUNCTION) &&
(orig_type->type != T |