1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
  
11
  
12
  
13
  
14
  
15
  
16
  
17
  
18
  
19
  
20
  
21
  
22
  
23
  
24
  
25
  
26
  
27
  
28
  
29
  
30
  
31
  
32
  
33
  
34
  
35
  
36
  
37
  
38
  
39
  
40
  
41
  
42
  
43
  
44
  
45
  
46
  
47
  
48
  
49
  
50
  
51
  
52
  
53
  
54
  
55
  
56
  
57
  
58
  
59
  
60
  
61
  
62
  
63
  
64
  
65
  
66
  
67
  
68
  
69
  
70
  
71
  
72
  
73
  
74
  
75
  
76
  
77
  
78
  
79
  
80
  
81
  
82
  
83
  
84
  
85
  
86
  
87
  
88
  
89
  
90
  
91
  
92
  
93
  
94
  
95
  
96
  
97
  
98
  
99
  
100
  
101
  
102
  
103
  
104
  
105
  
106
  
107
  
108
  
109
  
110
  
111
  
112
  
113
  
114
  
115
  
116
  
117
  
118
  
119
  
120
  
121
  
122
  
123
  
124
  
125
  
126
  
127
  
128
  
129
  
130
  
131
  
132
  
133
  
134
  
135
  
136
  
137
  
138
  
139
  
140
  
141
  
142
  
143
  
144
  
145
  
146
  
147
  
148
  
149
  
150
  
151
  
152
  
153
  
154
  
155
  
156
  
157
  
158
  
159
  
160
  
161
  
162
  
163
  
164
  
165
  
166
  
167
  
168
  
169
  
170
  
171
  
172
  
173
  
174
  
175
  
176
  
177
  
178
  
179
  
180
  
181
  
182
  
183
  
184
  
185
  
186
  
187
  
188
  
189
  
190
  
191
  
192
  
193
  
194
  
195
  
196
  
197
  
198
  
199
  
200
  
201
  
202
  
203
  
204
  
205
  
206
  
207
  
208
  
209
  
210
  
211
  
212
  
213
  
214
  
215
  
216
  
217
  
218
  
219
  
220
  
221
  
222
  
223
  
224
  
225
  
226
  
227
  
228
  
229
  
230
  
231
  
232
  
233
  
234
  
235
  
236
  
237
  
238
  
239
  
240
  
241
  
242
  
243
  
244
  
245
  
246
  
247
  
248
  
249
  
250
  
251
  
252
  
253
  
254
  
255
  
256
  
257
  
258
  
259
  
260
  
261
  
262
  
263
  
264
  
265
  
266
  
267
  
268
  
269
  
270
  
271
  
272
  
273
  
274
  
275
  
276
  
277
  
278
  
279
  
/*\ 
||| This file a part of Pike, and is copyright by Fredrik Hubinette 
||| Pike is distributed as GPL (General Public License) 
||| See the files COPYING and DISCLAIMER for more information. 
\*/ 
 
/* 
 * $Id: pike_types.h,v 1.47 2001/02/09 10:29:54 hubbe Exp $ 
 */ 
#ifndef PIKE_TYPES_H 
#define PIKE_TYPES_H 
 
#include "svalue.h" 
 
/* Also used in struct node_identifier */ 
union node_data 
{ 
  struct 
  { 
    int number; 
    struct program *prog; 
  } id; 
  struct svalue sval; 
  struct 
  { 
    struct node_s *a, *b; 
  } node; 
  struct 
  { 
    struct node_identifier *a, *b; 
  } node_id; 
  struct 
  { 
    int a, b; 
  } integer; 
}; 
 
struct node_s 
{ 
#if defined(SHARED_NODES) 
  unsigned INT32 refs; 
  size_t hash; 
  struct node_s *next; 
#endif /* SHARED_NODES */ 
#ifdef PIKE_DEBUG 
  struct pike_string *current_file; 
#endif 
  struct pike_string *type; 
  struct pike_string *name; 
  struct node_s *parent; 
  unsigned INT16 line_number; 
  unsigned INT16 node_info; 
  unsigned INT16 tree_info; 
  /* The stuff from this point on is hashed. */ 
  unsigned INT16 token; 
  union node_data u; 
}; 
 
#ifdef SHARED_NODES_MK2 
 
struct node_identifier 
{ 
  ptrdiff_t refs; 
  struct node_identifier *next; 
  size_t hash; 
  INT16 token; 
  union node_data u; 
}; 
 
#endif /* SHARED_NODES_MK2 */ 
 
#ifndef STRUCT_NODE_S_DECLARED 
#define STRUCT_NODE_S_DECLARED 
#endif 
 
 
typedef struct node_s node; 
 
#define PIKE_TYPE_STACK_SIZE 100000 
 
extern unsigned char type_stack[PIKE_TYPE_STACK_SIZE]; 
extern unsigned char *pike_type_mark_stack[PIKE_TYPE_STACK_SIZE/4]; 
 
extern int max_correct_args; 
PMOD_EXPORT extern struct pike_string *string_type_string; 
PMOD_EXPORT extern struct pike_string *int_type_string; 
PMOD_EXPORT extern struct pike_string *float_type_string; 
PMOD_EXPORT extern struct pike_string *object_type_string; 
PMOD_EXPORT extern struct pike_string *function_type_string; 
PMOD_EXPORT extern struct pike_string *program_type_string; 
PMOD_EXPORT extern struct pike_string *array_type_string; 
PMOD_EXPORT extern struct pike_string *list_type_string; 
PMOD_EXPORT extern struct pike_string *mapping_type_string; 
PMOD_EXPORT extern struct pike_string *type_type_string; 
PMOD_EXPORT extern struct pike_string *mixed_type_string; 
PMOD_EXPORT extern struct pike_string *void_type_string; 
PMOD_EXPORT extern struct pike_string *zero_type_string; 
PMOD_EXPORT extern struct pike_string *any_type_string; 
PMOD_EXPORT extern struct pike_string *weak_type_string; 
 
#define CONSTTYPE(X) make_shared_binary_string(X,CONSTANT_STRLEN(X)) 
 
#ifdef PIKE_DEBUG 
#define init_type_stack() type_stack_mark() 
#define exit_type_stack() do {\ 
    ptrdiff_t q_q_q_q = pop_stack_mark(); \ 
    if(q_q_q_q) fatal("Type stack out of wack! %ld\n", \ 
                      PTRDIFF_T_TO_LONG(q_q_q_q)); \ 
  } while(0) 
#else 
#define init_type_stack type_stack_mark 
#define exit_type_stack pop_stack_mark 
#endif 
 
/* Hmm, these will cause fatals if they fail... */ 
#define push_type(X) do {                             \ 
  if(Pike_compiler->type_stackp >= type_stack + sizeof(type_stack))     \ 
    yyerror("Type stack overflow.");                    \ 
  else {                                                \ 
    *Pike_compiler->type_stackp=(X);                                    \ 
    Pike_compiler->type_stackp++;                                       \ 
  }                                                     \ 
} while(0) 
 
#define unsafe_push_type(X) do {                      \ 
  *Pike_compiler->type_stackp=(X);                                      \ 
  Pike_compiler->type_stackp++;                                 \ 
} while(0) 
 
#define type_stack_mark() do {                                \ 
  if(Pike_compiler->pike_type_mark_stackp >= pike_type_mark_stack + NELEM(pike_type_mark_stack))        \ 
    fatal("Type mark stack overflow.");         \ 
  else {                                                \ 
    *Pike_compiler->pike_type_mark_stackp=Pike_compiler->type_stackp;                           \ 
    Pike_compiler->pike_type_mark_stackp++;                                     \ 
  }                                                     \ 
} while(0) 
 
#define unsafe_type_stack_mark() do {                         \ 
  *Pike_compiler->pike_type_mark_stackp=Pike_compiler->type_stackp;                             \ 
  Pike_compiler->pike_type_mark_stackp++;                                       \ 
} while(0) 
 
#define reset_type_stack() do {                       \ 
   type_stack_pop_to_mark();                    \ 
  type_stack_mark();                            \ 
} while(0) 
 
/* Prototypes begin here */ 
void check_type_string(struct pike_string *s); 
void init_types(void); 
ptrdiff_t pop_stack_mark(void); 
void pop_type_stack(void); 
void type_stack_pop_to_mark(void); 
void type_stack_reverse(void); 
void push_type_int(INT32 i); 
void push_type_int_backwards(INT32 i); 
INT32 extract_type_int(char *p); 
void push_unfinished_type(char *s); 
void push_finished_type(struct pike_string *type); 
void push_finished_type_backwards(struct pike_string *type); 
struct pike_string *debug_pop_unfinished_type(void); 
struct pike_string *debug_pop_type(void); 
struct pike_string *debug_compiler_pop_type(void); 
struct pike_string *parse_type(char *s); 
void stupid_describe_type(char *a, ptrdiff_t len); 
void simple_describe_type(struct pike_string *s); 
char *low_describe_type(char *t); 
struct pike_string *describe_type(struct pike_string *type); 
TYPE_T compile_type_to_runtime_type(struct pike_string *s); 
struct pike_string *or_pike_types(struct pike_string *a, 
                                  struct pike_string *b, 
                                  int zero_implied); 
struct pike_string *and_pike_types(struct pike_string *a, 
                                   struct pike_string *b); 
int strict_check_call(char *fun_type, char *arg_type); 
int check_soft_cast(struct pike_string *to, struct pike_string *from); 
int match_types(struct pike_string *a,struct pike_string *b); 
int pike_types_le(struct pike_string *a,struct pike_string *b); 
struct pike_string *index_type(struct pike_string *type, 
                               struct pike_string *index_type, 
                               node *n); 
struct pike_string *array_value_type(struct pike_string *array_type); 
struct pike_string *key_type(struct pike_string *type, node *n); 
int check_indexing(struct pike_string *type, 
                   struct pike_string *index_type, 
                   node *n); 
int count_arguments(struct pike_string *s); 
int minimum_arguments(struct pike_string *s); 
struct pike_string *check_call(struct pike_string *args, 
                               struct pike_string *type, 
                               int strict); 
INT32 get_max_args(struct pike_string *type); 
struct pike_string *zzap_function_return(char *a, INT32 id); 
struct pike_string *get_type_of_svalue(struct svalue *s); 
struct pike_string *object_type_to_program_type(struct pike_string *obj_t); 
char *get_name_of_type(int t); 
void cleanup_pike_types(void); 
int type_may_overload(char *type, int lfun); 
void yyexplain_nonmatching_types(struct pike_string *type_a, 
                                 struct pike_string *type_b, 
                                 int flags); 
struct pike_string *make_pike_type(char *t); 
int pike_type_allow_premature_toss(char *type); 
/* Prototypes end here */ 
 
/* "Dynamic types" - use with ADD_FUNCTION_DTYPE */ 
#define dtStore(TYPE) {int e; for (e=0; e<CONSTANT_STRLEN(TYPE); e++) unsafe_push_type((TYPE)[e]);} 
#define dtArr(VAL) {unsafe_push_type(PIKE_T_ARRAY); {VAL}} 
#define dtArray dtArr(dtMix) 
#define dtMap(IND,VAL) {unsafe_push_type(PIKE_T_MAPPING); {VAL} {IND}} 
#define dtMapping dtMap(dtMix,dtMix) 
#define dtSet(IND) {unsafe_push_type(PIKE_T_MULTISET); {IND}} 
#define dtMultiset dtSet(dtMix) 
#define dtObjImpl(PROGRAM) {unsafe_push_type(PIKE_T_OBJECT); unsafe_push_type(0); push_type_int_backwards((PROGRAM)->id);} 
#define dtObjIs(PROGRAM) {unsafe_push_type(PIKE_T_OBJECT); unsafe_push_type(1); push_type_int_backwards((PROGRAM)->id);} 
#define dtObj dtStore(tObj) 
#define dtFuncV(ARGS,REST,RET) MagicdtFuncV(RET,REST,ARGS) 
#define dtFunc(ARGS,RET) MagicdtFunc(RET,ARGS) 
#define MagicdtFuncV(RET,REST,ARGS) {unsafe_push_type(PIKE_T_FUNCTION); {ARGS} unsafe_push_type(T_MANY); {REST} {RET}} 
#define MagicdtFunc(RET,ARGS) dtFuncV(ARGS {}, dtVoid, RET) 
#define dtFunction dtFuncV({},dtAny,dtAny) 
#define dtNone {} 
#define dtPrg {unsafe_push_type(PIKE_T_PROGRAM);} 
#define dtProgram {unsafe_push_type(PIKE_T_PROGRAM);} 
#define dtStr {unsafe_push_type(PIKE_T_STRING);} 
#define dtString {unsafe_push_type(PIKE_T_STRING);} 
#define dtType {unsafe_push_type(PIKE_T_TYPE);} 
#define dtFlt {unsafe_push_type(PIKE_T_FLOAT);} 
#define dtFloat {unsafe_push_type(PIKE_T_FLOAT);} 
#define dtIntRange(LOW,HIGH) {unsafe_push_type(PIKE_T_INT); push_type_int_backwards(LOW); push_type_int_backwards(HIGH);} 
#define dtInt dtStore(tInt) 
#define dtZero {unsafe_push_type(PIKE_T_ZERO);} 
#define dtVoid {unsafe_push_type(T_VOID);} 
#define dtVar(X) {unsafe_push_type(X);} 
#define dtSetvar(X,TYPE) {unsafe_push_type(T_ASSIGN); {TYPE}} 
#define dtNot(TYPE) {unsafe_push_type(T_NOT); {TYPE}} 
#define dtAnd(A,B) {unsafe_push_type(T_AND); {A} {B}} 
#define dtOr(A,B) {unsafe_push_type(T_OR); {A} {B}} 
#define dtOr3(A,B,C) dtOr(A,dtOr(B,C)) 
#define dtOr4(A,B,C,D) dtOr(A,dtOr3(B,C,D)) 
#define dtOr5(A,B,C,D,E) dtOr(A,dtOr4(B,C,D,E)) 
#define dtOr6(A,B,C,D,E,F) dtOr(A,dtOr5(B,C,D,E,F)) 
#define dtMix {unsafe_push_type(PIKE_T_MIXED);} 
#define dtMixed {unsafe_push_type(PIKE_T_MIXED);} 
#define dtComplex dtStore(tComplex) 
#define dtStringIndicable dtStore(tStringIndicable) 
#define dtRef dtStore(tRef) 
#define dtIfnot(A,B) dtAnd(dtNot(A),B) 
#define dtAny dtStore(tAny) 
#define DTYPE_START do {                                            \ 
  unsafe_type_stack_mark();                                             \ 
  unsafe_type_stack_mark();                                             \ 
} while (0) 
#define DTYPE_END(TYPESTR) do {                                             \ 
  if(Pike_compiler->type_stackp >= type_stack + sizeof(type_stack))                     \ 
    fatal("Type stack overflow.");                                      \ 
  type_stack_reverse();                                                 \ 
  (TYPESTR)=pop_unfinished_type();                                      \ 
} while (0) 
 
#ifdef DEBUG_MALLOC 
#define pop_type() ((struct pike_string *)debug_malloc_pass(debug_pop_type())) 
#define compiler_pop_type() ((struct pike_string *)debug_malloc_pass(debug_compiler_pop_type())) 
#define pop_unfinished_type() \ 
 ((struct pike_string *)debug_malloc_pass(debug_pop_unfinished_type())) 
#else 
#define pop_type debug_pop_type 
#define compiler_pop_type debug_compiler_pop_type 
#define pop_unfinished_type debug_pop_unfinished_type 
#endif 
 
#ifndef PIKE_DEBUG 
#define check_type_string(X) 
#endif 
 
#endif