copy_string_to_graph.c 17.7 KB
Newer Older
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
1 2 3

#include <stdlib.h>

John van Groningen's avatar
John van Groningen committed
4 5 6 7 8 9 10 11 12 13 14 15
#ifdef _WIN64
# define Int __int64
# define INT_descriptor dINT
#else
# define Int int
# define INT_descriptor INT
# define __STRING__ _STRING__
# define __ARRAY__ _ARRAY__
#endif

extern void *INT_descriptor,*CHAR,*BOOL,*REAL,*__STRING__,*__ARRAY__;
extern Int small_integers[],static_characters[];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
16

John van Groningen's avatar
John van Groningen committed
17 18
/*inline*/
static void copy (Int *dest_p,Int *source_p,Int n_words)
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
19
{
John van Groningen's avatar
John van Groningen committed
20
	Int i;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
21 22 23 24 25

	for (i=0; i<n_words; ++i)
		dest_p[i]=source_p[i];
}

John van Groningen's avatar
John van Groningen committed
26
Int *copy_string_to_graph (Int *string_p,void *begin_free_heap,void *end_free_heap,Int **last_heap_pa)
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
27
{
John van Groningen's avatar
John van Groningen committed
28
	Int ***stack_p,***stack_begin,***stack_end,*heap_p,**arg_a,*root_node_p,n_free_words;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
29 30 31 32 33 34 35 36 37

	string_p+=2;

	stack_end=end_free_heap;
	stack_begin=end_free_heap;
	stack_p=end_free_heap;
		
	heap_p=begin_free_heap;
	
John van Groningen's avatar
John van Groningen committed
38
	n_free_words=(Int*)end_free_heap-(Int*)begin_free_heap;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
39 40 41 42
	arg_a=&root_node_p;

	for (;;){
		for (;;){
John van Groningen's avatar
John van Groningen committed
43
			Int desc;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
44 45 46 47 48
			
			desc=*string_p;
			
			if (--n_free_words<0){
				*last_heap_pa=heap_p+1+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
49
				return (Int*)((Int)string_p+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
50 51 52
			}

			if (!(desc & 1)){
John van Groningen's avatar
John van Groningen committed
53
				*string_p=(Int)heap_p;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
54 55 56
				*arg_a=heap_p;
				*heap_p=desc;
				if (desc & 2){
John van Groningen's avatar
John van Groningen committed
57
					unsigned Int arity;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
58 59 60
					
					arity=((unsigned short *)desc)[-1];
					if (arity==0){
John van Groningen's avatar
John van Groningen committed
61 62
						if (desc==(Int)&INT_descriptor+2){
							Int i;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
63 64
							
							i=string_p[1];
John van Groningen's avatar
John van Groningen committed
65 66
							if ((unsigned Int)i<=(unsigned Int)32){
								Int *a;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
67 68 69 70
								
								a=&small_integers[i<<1];
								++n_free_words;
								*arg_a=a;
John van Groningen's avatar
John van Groningen committed
71
								*string_p=(Int)a;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
72 73 74
							} else {
								if (--n_free_words<0){
									*last_heap_pa=heap_p+2+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
75
									return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
76 77 78 79 80 81 82
								}
								
								heap_p[1]=i;
								heap_p+=2;
							}
							string_p+=2;
							break;
John van Groningen's avatar
John van Groningen committed
83
						} else if (desc==(Int)&CHAR+2){
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
84
							unsigned char c;
John van Groningen's avatar
John van Groningen committed
85
							Int *a;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
86 87
							
							c=(unsigned char)(string_p[1]);
John van Groningen's avatar
John van Groningen committed
88
							a=&static_characters[(Int)c<<1];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
89 90
							++n_free_words;
							*arg_a=a;
John van Groningen's avatar
John van Groningen committed
91
							*string_p=(Int)a;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
92 93
							string_p+=2;
							break;
John van Groningen's avatar
John van Groningen committed
94 95 96 97 98
						} else if (desc==(Int)&BOOL+2
#ifdef _WIN64
							|| desc==(Int)&REAL+2
#endif
						){
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
99 100
							if (--n_free_words<0){
								*last_heap_pa=heap_p+2+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
101
								return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
102 103 104 105 106 107
							}
							
							heap_p[1]=string_p[1];
							string_p+=2;
							heap_p+=2;
							break;
John van Groningen's avatar
John van Groningen committed
108 109
#ifndef _WIN64
						} else if (desc==(Int)&REAL+2){
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
110 111 112
							n_free_words-=2;
							if (n_free_words<0){
								*last_heap_pa=heap_p+3+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
113
								return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
114 115 116 117 118 119 120
							}
							
							heap_p[1]=string_p[1];
							heap_p[2]=string_p[2];
							string_p+=3;
							heap_p+=3;
							break;
John van Groningen's avatar
John van Groningen committed
121 122 123
#endif
						} else if (desc==(Int)&__STRING__+2){
							unsigned Int length,n_words;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
124 125 126
							
							length=string_p[1];
							string_p+=2;
John van Groningen's avatar
John van Groningen committed
127 128 129
#ifdef _WIN64
							n_words=(length+7)>>3;
#else
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
130
							n_words=(length+3)>>2;
John van Groningen's avatar
John van Groningen committed
131
#endif							
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
132 133 134
							n_free_words-=n_words+1;
							if (n_free_words<0){
								*last_heap_pa=heap_p+2+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
135
								return (Int*)((Int)string_p+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
136 137 138 139 140 141 142 143 144
							}
													
							heap_p[1]=length;
							heap_p+=2;

							copy (heap_p,string_p,n_words);
							string_p+=n_words;
							heap_p+=n_words;
							break;
John van Groningen's avatar
John van Groningen committed
145 146
						} else if (desc==(Int)&__ARRAY__+2){
							Int array_size,elem_desc;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
147 148 149 150

							n_free_words-=2;
							if (n_free_words<0){
								*last_heap_pa=heap_p+3+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
151
								return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
152 153 154 155 156 157 158 159 160 161 162
							}
							
							array_size=string_p[1];
							elem_desc=string_p[2];
							string_p+=3;
		
							heap_p[1]=array_size;
							heap_p[2]=elem_desc;
							heap_p+=3;
													
							if (elem_desc==0){
John van Groningen's avatar
John van Groningen committed
163
								Int i;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
164 165 166
								
								stack_p-=array_size;
								if (stack_p<stack_begin){
John van Groningen's avatar
John van Groningen committed
167
									Int extra_words;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
168 169 170 171 172

									extra_words=stack_begin-stack_p;
									n_free_words-=extra_words;
									if (n_free_words<0){
										*last_heap_pa=heap_p+array_size+(stack_end-stack_p);
John van Groningen's avatar
John van Groningen committed
173
										return (Int*)((Int)string_p+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
174 175 176 177 178 179
									}
									stack_begin=stack_p;
								}
								
								i=array_size;
								while (--i>=0)
John van Groningen's avatar
John van Groningen committed
180
									stack_p[i]=(Int**)&heap_p[i];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
181 182 183

								heap_p+=array_size;
								break;
John van Groningen's avatar
John van Groningen committed
184 185 186 187 188
							} else if (elem_desc==(Int)&INT_descriptor+2
#ifdef _WIN64
								|| elem_desc==(Int)&REAL+2
#endif
							){
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
189 190 191
								n_free_words-=array_size;
								if (n_free_words<0){
									*last_heap_pa=heap_p+array_size+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
192
									return (Int*)((Int)string_p+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
193 194 195 196 197 198
								}

								copy (heap_p,string_p,array_size);
								string_p+=array_size;
								heap_p+=array_size;
								break;
John van Groningen's avatar
John van Groningen committed
199 200
#ifndef _WIN64
							} else if (elem_desc==(Int)&REAL+2){
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
201 202 203 204 205
								array_size<<=1;
							
								n_free_words-=array_size;
								if (n_free_words<0){
									*last_heap_pa=heap_p+array_size+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
206
									return (Int*)((Int)string_p+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
207 208 209 210 211 212
								}
								
								copy (heap_p,string_p,array_size);
								string_p+=array_size;
								heap_p+=array_size;
								break;
John van Groningen's avatar
John van Groningen committed
213 214 215 216 217
#endif
							} else if (elem_desc==(Int)&BOOL+2){
#ifdef _WIN64
								array_size=(array_size+7)>>3;
#else
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
218
								array_size=(array_size+3)>>2;
John van Groningen's avatar
John van Groningen committed
219
#endif
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
220 221 222
								n_free_words-=array_size;
								if (n_free_words<0){
									*last_heap_pa=heap_p+array_size+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
223
									return (Int*)((Int)string_p+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
224 225 226 227 228 229 230
								}
								
								copy (heap_p,string_p,array_size);
								string_p+=array_size;
								heap_p+=array_size;
								break;
							} else {
John van Groningen's avatar
John van Groningen committed
231
								Int n_field_pointers,field_size;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
232 233

								n_field_pointers=*(unsigned short *)elem_desc;
John van Groningen's avatar
John van Groningen committed
234
								field_size=((unsigned short *)elem_desc)[-1]-(Int)256;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
235 236 237 238 239 240 241

								if (n_field_pointers==0){
									array_size*=field_size;
									
									n_free_words-=array_size;
									if (n_free_words<0){
										*last_heap_pa=heap_p+array_size+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
242
										return (Int*)((Int)string_p+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
243 244 245 246 247 248 249
									}
																		
									copy (heap_p,string_p,array_size);
									string_p+=array_size;
									heap_p+=array_size;
									break;
								} else if (n_field_pointers==field_size){
John van Groningen's avatar
John van Groningen committed
250
									Int i;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
251 252 253 254 255
									
									array_size*=field_size;

									stack_p-=array_size;
									if (stack_p<stack_begin){
John van Groningen's avatar
John van Groningen committed
256
										Int extra_words;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
257 258 259 260 261

										extra_words=stack_begin-stack_p;
										n_free_words-=extra_words;
										if (n_free_words<0){
											*last_heap_pa=heap_p+array_size+(stack_end-stack_p);
John van Groningen's avatar
John van Groningen committed
262
											return (Int*)((Int)string_p+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
263 264 265 266 267 268
										}
										stack_begin=stack_p;
									}
									
									i=array_size;
									while (--i>=0)
John van Groningen's avatar
John van Groningen committed
269
										stack_p[i]=(Int**)&heap_p[i];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
270 271 272 273
									
									heap_p+=array_size;
									break;
								} else {
John van Groningen's avatar
John van Groningen committed
274
									Int n_non_field_pointers,i,***pointer_p;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
275 276 277 278 279 280
									
									n_non_field_pointers=field_size-n_field_pointers;
									
									n_free_words-=array_size*field_size;
									if (n_free_words<0){
										*last_heap_pa=heap_p+array_size*field_size+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
281
										return (Int*)((Int)string_p+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
282 283 284 285
									}
									
									stack_p-=array_size*n_field_pointers;
									if (stack_p<stack_begin){
John van Groningen's avatar
John van Groningen committed
286
										Int extra_words;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
287 288 289 290 291

										extra_words=stack_begin-stack_p;
										n_free_words-=extra_words;
										if (n_free_words<0){
											*last_heap_pa=heap_p+(stack_end-stack_p);
John van Groningen's avatar
John van Groningen committed
292
											return (Int*)((Int)string_p+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
293 294 295 296 297 298 299
										}
										stack_begin=stack_p;
									}
									
									pointer_p=stack_p;
									
									for (i=0; i<array_size; ++i){
John van Groningen's avatar
John van Groningen committed
300
										Int n;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
301 302 303
										
										n=n_field_pointers;
										while (--n>=0)
John van Groningen's avatar
John van Groningen committed
304
											pointer_p[n]=(Int**)&heap_p[n];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
305 306 307 308 309 310 311 312 313 314 315 316 317 318
										pointer_p+=n_field_pointers;
										heap_p+=n_field_pointers;
										
										copy (heap_p,string_p,n_non_field_pointers);
										heap_p+=n_non_field_pointers;
										string_p+=n_non_field_pointers;						
									}
									break;
								}
							}
						} else {
#ifdef OLD_DESCRIPTORS
							desc-=10;
#else
John van Groningen's avatar
John van Groningen committed
319 320 321 322 323
# ifdef _WIN64
							desc-=10;
# else
							desc-=6;
# endif
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
324 325
#endif
							++n_free_words;
John van Groningen's avatar
John van Groningen committed
326
							*arg_a=(Int*)desc;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
327 328 329 330 331 332 333
							*string_p=desc;
							++string_p;
							break;
						}
					} else if (arity==1){
						if (--n_free_words<0){
							*last_heap_pa=heap_p+2+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
334
							return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
335
						}
John van Groningen's avatar
John van Groningen committed
336
						arg_a=(Int**)&heap_p[1];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
337 338 339 340 341 342 343
						++string_p;
						heap_p+=2;
						continue;
					} else if (arity==2){
						n_free_words-=2;
						if (n_free_words<0){
							*last_heap_pa=heap_p+3+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
344
							return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
345 346 347 348 349
						}
						
						if (stack_p<=stack_begin){
							if (--n_free_words<0){
								*last_heap_pa=heap_p+3+(stack_end-1-stack_begin);
John van Groningen's avatar
John van Groningen committed
350
								return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
351 352 353 354
							}
							--stack_begin;
						}
						
John van Groningen's avatar
John van Groningen committed
355 356
						*--stack_p=(Int**)&heap_p[2];
						arg_a=(Int**)&heap_p[1];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
357 358 359 360
						++string_p;
						heap_p+=3;
						continue;
					} else if (arity<256){
John van Groningen's avatar
John van Groningen committed
361
						Int n_words;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
362 363 364 365

						n_free_words-=arity+1;
						if (n_free_words<0){
							*last_heap_pa=heap_p+arity+2+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
366
							return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
367 368
						}

John van Groningen's avatar
John van Groningen committed
369 370
						arg_a=(Int**)&heap_p[1];
						heap_p[2]=(Int)&heap_p[3];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
371 372 373 374 375 376
						heap_p+=3;

						n_words=arity-1;

						stack_p-=n_words;
						if (stack_p<stack_begin){
John van Groningen's avatar
John van Groningen committed
377
							Int extra_words;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
378 379 380 381 382

							extra_words=stack_begin-stack_p;
							n_free_words-=extra_words;
							if (n_free_words<0){
								*last_heap_pa=heap_p+arity-1+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
383
								return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
384 385 386 387 388
							}
							stack_begin=stack_p;
						}

						--n_words;
John van Groningen's avatar
John van Groningen committed
389
						stack_p[n_words]=(Int**)&heap_p[n_words];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
390
						--n_words;
John van Groningen's avatar
John van Groningen committed
391
						stack_p[n_words]=(Int**)&heap_p[n_words];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
392
						while (--n_words>=0)
John van Groningen's avatar
John van Groningen committed
393
							stack_p[n_words]=(Int**)&heap_p[n_words];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
394 395 396 397 398

						heap_p+=arity-1;
						++string_p;
						continue;
					} else {
John van Groningen's avatar
John van Groningen committed
399
						Int n_pointers;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
400 401 402 403 404 405 406
						
						n_pointers=*(unsigned short*)desc;
						arity-=256;
						
						if (arity==1){
							if (--n_free_words<0){
								*last_heap_pa=heap_p+2+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
407
								return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
408 409 410 411 412 413 414 415
							}
							
							if (n_pointers==0){						
								heap_p[1]=string_p[1];
								string_p+=2;
								heap_p+=2;
								break;
							} else {
John van Groningen's avatar
John van Groningen committed
416
								arg_a=(Int**)&heap_p[1];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
417 418 419 420 421 422 423 424
								++string_p;
								heap_p+=2;
								continue;
							}
						} else if (arity==2){
							n_free_words-=2;
							if (n_free_words<0){
								*last_heap_pa=heap_p+3+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
425
								return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
							}

							if (n_pointers==0){
								heap_p[1]=string_p[1];
								heap_p[2]=string_p[2];
								string_p+=3;
								heap_p+=3;
								break;
							} else {
								if (n_pointers==1){
									heap_p[2]=string_p[1];
									string_p+=2;
								} else {
									if (stack_p<=stack_begin){
										if (--n_free_words<0){
											*last_heap_pa=heap_p+3+1+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
442
											return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
443 444 445 446
										}
										--stack_begin;
									}
									++string_p;
John van Groningen's avatar
John van Groningen committed
447
									*--stack_p=(Int**)&heap_p[2];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
448
								}
John van Groningen's avatar
John van Groningen committed
449
								arg_a=(Int**)&heap_p[1];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
450 451 452 453 454 455 456
								heap_p+=3;
								continue;							
							}
						} else {
							n_free_words-=arity+1;
							if (n_free_words<0){
								*last_heap_pa=heap_p+arity+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
457
								return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
458 459
							}
							
John van Groningen's avatar
John van Groningen committed
460
							heap_p[2]=(Int)&heap_p[3];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
461 462 463 464 465 466 467 468 469 470 471
							
							if (n_pointers==0){
								heap_p[1]=string_p[1];
								heap_p+=3;
								string_p+=2;
								--arity;
								copy (heap_p,string_p,arity);
								string_p+=arity;
								heap_p+=arity;
								break;
							} else {
John van Groningen's avatar
John van Groningen committed
472
								Int n_non_pointers;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
473

John van Groningen's avatar
John van Groningen committed
474
								arg_a=(Int**)&heap_p[1];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
475 476 477 478 479 480
								heap_p+=3;

								n_non_pointers=arity-n_pointers;
								++string_p;

								if (n_non_pointers>0){
John van Groningen's avatar
John van Groningen committed
481
									Int *non_pointers_p;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
482 483 484 485 486 487 488 489 490

									non_pointers_p=&heap_p[n_pointers-1];

									copy (non_pointers_p,string_p,n_non_pointers);
									string_p+=n_non_pointers;
								}
								
								--n_pointers;
								if (n_pointers>0){
John van Groningen's avatar
John van Groningen committed
491
									Int i;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
492 493 494
									
									stack_p-=n_pointers;
									if (stack_p<stack_begin){
John van Groningen's avatar
John van Groningen committed
495
										Int extra_words;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
496 497 498 499 500

										extra_words=stack_begin-stack_p;
										n_free_words-=extra_words;
										if (n_free_words<0){
											*last_heap_pa=heap_p+n_pointers+n_non_pointers+(stack_end-stack_p);
John van Groningen's avatar
John van Groningen committed
501
											return (Int*)((Int)string_p+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
502 503 504 505 506 507
										}
										stack_begin=stack_p;
									}
									
									i=n_pointers;
									while (--i>=0)
John van Groningen's avatar
John van Groningen committed
508
										stack_p[i]=(Int**)&heap_p[i];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
509 510 511 512 513 514 515
								}
								heap_p+=n_pointers+n_non_pointers;
								continue;
							}
						}
					}
				} else {
John van Groningen's avatar
John van Groningen committed
516
					Int arity;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
517 518 519 520

					arity=((int*)desc)[-1];
					if (arity>1){
						if (arity<256){
John van Groningen's avatar
John van Groningen committed
521
							Int n_words;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
522 523 524 525
							
							n_free_words-=arity;
							if (n_free_words<0){
								*last_heap_pa=heap_p+arity+1+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
526
								return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
527 528 529 530 531 532
							}

							n_words=arity-1;

							stack_p-=n_words;
							if (stack_p<stack_begin){
John van Groningen's avatar
John van Groningen committed
533
								Int extra_words;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
534 535 536 537 538

								extra_words=stack_begin-stack_p;
								n_free_words-=extra_words;
								if (n_free_words<0){
									*last_heap_pa=heap_p+arity+1+(stack_end-stack_p);
John van Groningen's avatar
John van Groningen committed
539
									return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
540 541 542 543
								}
								stack_begin=stack_p;
							}

John van Groningen's avatar
John van Groningen committed
544
							arg_a=(Int**)&heap_p[1];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
545 546 547
							heap_p+=2;
							
							--n_words;
John van Groningen's avatar
John van Groningen committed
548
							stack_p[n_words]=(Int**)&heap_p[n_words];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
549
							while (--n_words>=0)
John van Groningen's avatar
John van Groningen committed
550
								stack_p[n_words]=(Int**)&heap_p[n_words];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
551 552 553

							++string_p;
							heap_p+=arity-1;
John van Groningen's avatar
John van Groningen committed
554
							continue;
555
						} else if (arity!=257){
John van Groningen's avatar
John van Groningen committed
556
							Int n_pointers,n_non_pointers,*non_pointers_p;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
557 558 559 560 561 562 563 564
							
							n_non_pointers=arity>>8;
							arity=arity & 255;
							n_pointers=arity - n_non_pointers;

							n_free_words-=arity;
							if (n_free_words<0){
								*last_heap_pa=heap_p+arity+1+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
565
								return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
566 567 568 569 570 571 572 573 574 575 576 577 578
							}

							++string_p;
							++heap_p;
							non_pointers_p=&heap_p[n_pointers];

							copy (non_pointers_p,string_p,n_non_pointers);
							string_p+=n_non_pointers;
							
							if (n_pointers==0){
								heap_p+=arity;
								break;
							} else {
John van Groningen's avatar
John van Groningen committed
579
								arg_a=(Int**)&heap_p[0];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
580 581 582 583 584 585
								++heap_p;
								if (n_pointers>1){
									--n_pointers;
									
									stack_p-=n_pointers;
									if (stack_p<stack_begin){
John van Groningen's avatar
John van Groningen committed
586
										Int extra_words;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
587 588 589 590 591

										extra_words=stack_begin-stack_p;
										n_free_words-=extra_words;
										if (n_free_words<0){
											*last_heap_pa=heap_p+arity+(stack_end-stack_p);
John van Groningen's avatar
John van Groningen committed
592
											return (Int*)((Int)string_p+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
593 594 595 596 597
										}
										stack_begin=stack_p;
									}
									
									--n_pointers;
John van Groningen's avatar
John van Groningen committed
598
									stack_p[n_pointers]=(Int**)&heap_p[n_pointers];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
599
									while (--n_pointers>=0)
John van Groningen's avatar
John van Groningen committed
600
										stack_p[n_pointers]=(Int**)&heap_p[n_pointers];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
601 602 603 604
								}
								heap_p+=arity-1;
								continue;
							}
605 606 607 608
						} else {
							n_free_words-=2;
							if (n_free_words<0){
								*last_heap_pa=heap_p+3+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
609
								return (Int*)((Int)&string_p[1]+1);
610 611 612 613 614 615
							}

							heap_p[1]=string_p[1];
							string_p+=2;
							heap_p+=3;
							break;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
616 617 618 619 620
						}
					} else {
						n_free_words-=2;
						if (n_free_words<0){
							*last_heap_pa=heap_p+3+(stack_end-stack_begin);
John van Groningen's avatar
John van Groningen committed
621
							return (Int*)((Int)&string_p[1]+1);
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
622 623 624 625 626 627 628
						}
					
						++string_p;
						if (arity==0){
							heap_p+=3;
							break;
						} else {
John van Groningen's avatar
John van Groningen committed
629
							arg_a=(Int**)&heap_p[1];
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
630 631 632 633 634 635
							heap_p+=3;
							continue;
						}
					}
				}
			} else {
John van Groningen's avatar
John van Groningen committed
636
				Int *node_p;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
637
				
John van Groningen's avatar
John van Groningen committed
638
				node_p=*(Int**)((Int)string_p+(desc-1));
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
				*arg_a=node_p;
				++string_p;
				break;
			}
		}

		if (stack_p==stack_end)
			break;
		
		arg_a=*stack_p++;
	}
	
	*last_heap_pa=heap_p;
	return root_node_p;
}

John van Groningen's avatar
John van Groningen committed
655
void remove_forwarding_pointers_from_string (Int *string_p,Int *end_forwarding_pointers)
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
656 657 658 659
{
	string_p+=2;

	while (string_p<end_forwarding_pointers){
John van Groningen's avatar
John van Groningen committed
660
		Int forwarding_pointer;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
661 662 663
			
		forwarding_pointer=*string_p;
		if (!(forwarding_pointer & 1)){
John van Groningen's avatar
John van Groningen committed
664
			Int desc;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
665
			
John van Groningen's avatar
John van Groningen committed
666
			desc=*(Int*)forwarding_pointer;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
667 668
			*string_p=desc;
			if (desc & 2){
John van Groningen's avatar
John van Groningen committed
669
				unsigned Int arity;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
670 671 672
				
				arity=((unsigned short *)desc)[-1];
				if (arity==0){
John van Groningen's avatar
John van Groningen committed
673 674 675 676 677
					if (desc==(Int)&INT_descriptor+2 || desc==(Int)&CHAR+2 || desc==(Int)&BOOL+2
#ifdef _WIN64
						|| desc==(Int)&REAL+2
#endif
					){
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
678
						string_p+=2;
John van Groningen's avatar
John van Groningen committed
679 680
#ifndef _WIN64
					} else if (desc==(Int)&REAL+2){
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
681
						string_p+=3;
John van Groningen's avatar
John van Groningen committed
682 683 684
#endif
					} else if (desc==(Int)&__STRING__+2){
						unsigned Int length,n_words;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
685 686 687
							
						length=string_p[1];
						string_p+=2;
John van Groningen's avatar
John van Groningen committed
688 689 690
#ifdef _WIN64
						n_words=(length+7)>>3;
#else
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
691
						n_words=(length+3)>>2;
John van Groningen's avatar
John van Groningen committed
692
#endif
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
693
						string_p+=n_words;
John van Groningen's avatar
John van Groningen committed
694 695
					} else if (desc==(Int)&__ARRAY__+2){
						Int array_size,elem_desc;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
696 697 698 699 700 701

						array_size=string_p[1];
						elem_desc=string_p[2];
						string_p+=3;
													
						if (elem_desc==0){
John van Groningen's avatar
John van Groningen committed
702 703 704 705 706
						} else if (elem_desc==(Int)&INT_descriptor+2
#ifdef _WIN64
							|| elem_desc==(Int)&REAL+2
#endif
						){
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
707
							string_p+=array_size;
John van Groningen's avatar
John van Groningen committed
708 709
#ifndef _WIN64
						} else if (elem_desc==(Int)&REAL+2){
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
710 711
							array_size<<=1;
							string_p+=array_size;
John van Groningen's avatar
John van Groningen committed
712 713 714 715 716
#endif
						} else if (elem_desc==(Int)&BOOL+2){
#ifdef _WIN64
							array_size=(array_size+7)>>3;
#else
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
717
							array_size=(array_size+3)>>2;
John van Groningen's avatar
John van Groningen committed
718
#endif
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
719 720
							string_p+=array_size;
						} else {
John van Groningen's avatar
John van Groningen committed
721
							Int n_field_pointers,n_non_field_pointers,field_size;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
722 723

							n_field_pointers=*(unsigned short *)elem_desc;
John van Groningen's avatar
John van Groningen committed
724
							field_size=((unsigned short *)elem_desc)[-1]-(Int)256;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
725 726 727 728 729 730 731 732 733 734
							n_non_field_pointers=field_size-n_field_pointers;
						
							string_p+=n_non_field_pointers*array_size;
						}
					} else {
						++string_p;
					}
				} else {
					++string_p;
					if (arity>=256){
John van Groningen's avatar
John van Groningen committed
735
						Int n_pointers,n_non_pointers;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
736 737 738 739 740 741 742 743

						n_pointers=*(unsigned short*)desc;
						arity-=256;
						n_non_pointers=arity-n_pointers;
						string_p+=n_non_pointers;
					}
				}
			} else {
John van Groningen's avatar
John van Groningen committed
744
				Int arity;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
745 746 747 748

				arity=((int*)desc)[-1];
				++string_p;
				if (arity>=256){
John van Groningen's avatar
John van Groningen committed
749
					Int n_non_pointers;
Rinus Plasmeijer's avatar
Rinus Plasmeijer committed
750 751 752 753 754 755 756 757 758 759
					
					n_non_pointers=arity>>8;
					string_p+=n_non_pointers;
				}
			}
		} else {
			++string_p;
		}
	}
}