Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
33
 
34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
42
 
43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
45
 
46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
49
 
50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
53
 
54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
/**********************************************************************
62
$Author: release $
63
$Date: 1998/01/17 15:55:45 $
64
$Revision: 1.1.1.1 $
65
$Log: table_fns.c,v $
66
 * Revision 1.1.1.1  1998/01/17  15:55:45  release
67
 * First version to be checked into rolling release.
68
 *
69
 * Revision 1.2  1997/08/23  13:31:07  pwe
70
 * no invert order, and initial ANDF-DE
71
 *
72
 * Revision 1.1  1995/04/06  10:43:34  currie
73
 * Initial revision
74
 *
75
***********************************************************************/
76
 
77
 
78
#include "config.h"
79
#include "common_types.h"
80
#include "readglob.h"
81
#include "xalloc.h"
82
#include "basicread.h"
83
#include "sortmacs.h"
84
#include "exp.h"
85
#include "expmacs.h"
86
#include "main_reads.h"
87
#include "externs.h"
88
#include "spec_tok.h"
89
#include "read_sort.h"
90
#include "messages_r.h"
91
#include "installglob.h"
92
#include "install_fns.h"
93
#include "diagglob.h"
94
#include "dg_fns.h"
95
#include "check.h"
96
 
97
#include "table_fns.h"
98
 
99
 
100
/* VARIABLES */
101
/* The initial values are only to give something to push, jmf */
102
 
7 7u83 103
context *crt_context = (context *)0;
2 7u83 104
 
105
 
106
/* IDENTITY */
107
 
108
static tokformals_list nil_params;
109
 
110
 
111
/* PROCEDURES */
112
 
113
 
7 7u83 114
exp
115
get_lab(label l)
2 7u83 116
{
117
	/* find the exp which is labelled by l */
7 7u83 118
	context *con = crt_context;
119
	while (con != (context *)0) {
120
	   lab_con *lc = con->labs;
121
	   while (lc != (lab_con *)0) {
122
	   	if (lc->namel == l) {
123
			return lc->e;
124
		}
2 7u83 125
		lc = lc->rest;
126
	   }
127
	   con = con->outer;
128
	}
129
	return *l;
130
}
131
 
7 7u83 132
 
133
void
134
set_lab(label l, exp e)
2 7u83 135
{
7 7u83 136
	/* set the exp which is labelled by l */
137
	if (crt_context == (context *)0 || crt_context->recursive == 0) {
138
		*l = e;
139
	} else {
140
		lab_con *lc = (lab_con *)xmalloc(sizeof(lab_con));
141
		lc->namel = l; lc->e = e; lc->rest = crt_context->labs;
142
		crt_context->labs = lc;
143
	}
144
	return;
2 7u83 145
}
146
 
147
 
7 7u83 148
dec *
149
get_dec(int tg)
2 7u83 150
{
7 7u83 151
	/* find the tag declaration indexed by tg */
152
	dec *res = unit_ind_tags[tg];
153
	res->dec_u.dec_val.index = tg;
154
	return res;
2 7u83 155
}
156
 
7 7u83 157
 
158
aldef *
159
get_aldef(int tg)
2 7u83 160
{
7 7u83 161
	/* find the alignment tag value indexed by tg */
162
	return unit_ind_als[tg];
2 7u83 163
}
164
 
7 7u83 165
 
166
tok_define *
167
get_tok(int tk)
2 7u83 168
{
7 7u83 169
	/* find the token declaration indexed by tg */
170
	context *con = crt_context;
171
	while (con != (context *)0) {
172
		int n = con->no_toks;
173
		int nl = (n > LOCAL_TOKS) ? LOCAL_TOKS : n;
174
		tok_define *cbind = &con->loctoks[0];
175
		int i;
176
		for (i = 0; i < nl; i++) {
177
			if (tk == cbind[i].tdtoken) {
178
				return &cbind[i];
179
			}
180
		}
181
		cbind = con->othertoks;
182
		for (i = LOCAL_TOKS; i < n; i++) {
183
			if (tk == cbind[i - LOCAL_TOKS].tdtoken) {
184
				return &cbind[i-LOCAL_TOKS];
185
			}
186
		}
187
		con = con->outer;
2 7u83 188
	}
7 7u83 189
	return unit_ind_tokens[tk];
2 7u83 190
}
191
 
192
 
7 7u83 193
exp
194
get_tag(tag tg)
2 7u83 195
{
196
	/* find the exp known as tg */
7 7u83 197
	context *con = crt_context;
198
	while (con != (context *)0) {
199
		tag_con *tc = con->tags;
200
		while (tc != (tag_con *)0) {
201
			if (tc->namet == tg) {
202
				return tc->e;
203
			}
204
			tc = tc->rest;
205
		}
206
		con = con->outer;
2 7u83 207
	}
7 7u83 208
	return tg->dec_u.dec_val.dec_exp;
2 7u83 209
}
210
 
211
 
7 7u83 212
void
213
set_tag(tag tg, exp e)
2 7u83 214
{
7 7u83 215
	/* set the exp known as tg */
216
	if (crt_context == (context *)0 || crt_context->recursive == 0) {
217
		tg->dec_u.dec_val.dec_exp = e;
218
	} else {
219
		tag_con *tc = (tag_con *)xmalloc(sizeof(tag_con));
220
		tc->namet = tg; tc->e = e; tc->rest = crt_context->tags;
221
		crt_context->tags = tc;
222
	}
223
	return;
2 7u83 224
}
225
 
226
 
7 7u83 227
/* apply tk to its parameters in pars, and return the result */
228
tokval
229
apply_tok(token td, bitstream pars, int sortcode, tokval * actual_pars)
2 7u83 230
{
7 7u83 231
	if (td->tok_special || td -> defined == 0) {
232
		/* handle the special tokens */
233
		tokval tkv;
234
		int done = 0;
235
		tkv = special_token(td, pars, sortcode, &done);
236
		if (done) {
237
			return tkv;
238
		}
239
	}
2 7u83 240
 
7 7u83 241
	if (td->defined == 0) {
242
		/* detect various errors and give helpful information */
243
		if (td->defined == 0) {
244
			failer(UNDEFINED_TOK);
245
		}
2 7u83 246
 
7 7u83 247
		if (td->is_capsule_token &&
248
		    td->tok_index < capsule_no_of_tokens &&
249
		    td->tok_index >= 0 &&
250
		    td->tok_name != (char *)0) {
251
			IGNORE fprintf(stderr, "token is: %s\n",
252
				       td -> tok_name);
253
		} else {
254
			if (td->is_capsule_token &&
255
			    td->tok_index < capsule_no_of_tokens &&
256
			    td->tok_index >= 0) {
257
				IGNORE fprintf(stderr,
258
					       "capsule token number: %d\n",
259
					       td -> tok_index);
260
			} else {
261
				if (td->tok_index >= 0 &&
262
				    td->tok_index < unit_no_of_tokens) {
263
					IGNORE fprintf(stderr,
264
					    "local unit token number: %d\n",
265
					    td->tok_index);
266
				} else {
267
					IGNORE fprintf(stderr,
268
					    "token number out of bounds\n");
269
				}
270
			}
271
			exit(EXIT_FAILURE);
272
		}
273
	}
2 7u83 274
 
7 7u83 275
	{
276
		/* number of parameters */
277
		int npars = td->params.number;
278
		/* to construct the bindings for this expansion */
279
		context new_context;
280
		context *old_context = crt_context;
2 7u83 281
 
7 7u83 282
		tokval val;
283
		/* to record the current place in the input stream */
284
		place old_place;
2 7u83 285
 
7 7u83 286
		tok_define *new_bindings;
287
		int i, j;
288
		dec **old_tagtab;
289
		/* to remember the current tag table */
290
		exp *old_labtab;
291
		/* to remember the current label table */
292
		tok_define **old_toktab;
293
		/* to remember the current token table */
294
		aldef **old_altab;
295
		/* to remember the current alignment tag table */
296
		diag_tagdef **old_diagtab;		/* OLD DIAGS */
297
		dgtag_struct **old_dgtab;		/* NEW DIAGS */
2 7u83 298
 
7 7u83 299
		/* now remember them */
300
		old_tagtab = unit_ind_tags;
301
		old_labtab = unit_labtab;
302
		old_toktab = unit_ind_tokens;
303
		old_altab = unit_ind_als;
304
		old_diagtab = unit_ind_diagtags;	/* OLD DIAGS */
305
		old_dgtab = unit_ind_dgtags;		/* NEW DIAGS */
2 7u83 306
 
7 7u83 307
		new_context.no_toks = (short)npars;
308
		nil_params.number = 0;
2 7u83 309
 
7 7u83 310
		if (td -> valpresent &&
311
				(td -> unit_number == crt_tagdef_unit_no)) {
312
			/* if a value has already been computed (there
313
			 * will be no parameters) */
2 7u83 314
 
7 7u83 315
			if (sortcode == f_exp.code) {
316
				tokval v;
317
				v.tk_exp = copy(td->tdvalue.tk_exp);
318
				/* copy it if the result is an
319
				 * expression since we may be going to
320
				 * alter it */
321
				return v;
322
			} else  {
323
				return td -> tdvalue;
324
			}
325
		}
2 7u83 326
 
7 7u83 327
		/* remember the current input stream */
328
		old_place = keep_place();
2 7u83 329
 
7 7u83 330
		set_place(pars);
2 7u83 331
 
7 7u83 332
		/* now set up the new parameter bindings */
333
		if (npars > LOCAL_TOKS) {
334
			new_context.othertoks =
335
				(tok_define *)xcalloc(npars - LOCAL_TOKS,
336
						      sizeof(tok_define));
337
		}
2 7u83 338
 
7 7u83 339
		new_bindings = &new_context.loctoks[0];
2 7u83 340
 
7 7u83 341
		for (j = 0; j < npars; ++j) {
342
			/* read in the parameter values and bind them
343
			 * to the formals */
344
			sortname sn;
345
			exp old_crt_repeat;  /* XX008 */
346
			if (j >= LOCAL_TOKS) {
347
				i = j - LOCAL_TOKS;
348
				new_bindings = new_context.othertoks;
349
			} else {
350
				i = j;
351
			}
352
			sn = (td->params.par_sorts)[j];
353
			new_bindings[i].tdsort = sn;
354
			/* parameter sort */
355
			new_bindings[i].tdtoken =
356
				(td->params.par_names)[j];
357
			/* formal */
358
			new_bindings[i].valpresent = 1;
359
			/* the value is known */
360
			new_bindings[i].unit_number =
361
				crt_tagdef_unit_no;
362
			new_bindings[i].re_evaluate = 0;
363
			/* and does not need re-evaluating */
364
			new_bindings[i].params = nil_params;
365
			/* it has no parameters itself */
2 7u83 366
 
7 7u83 367
			/* XX008 */
368
			if (sn.code == f_exp.code) {
369
				old_crt_repeat = crt_repeat;
370
				crt_repeat = nilexp;
371
			} else {
372
				SET(old_crt_repeat);
373
			}
374
			if (actual_pars != (tokval*)0) {
375
				/* this is not used at present*/
376
				new_bindings[i].tdvalue =
377
					actual_pars[j];
378
			} else {
379
				new_bindings[i].tdvalue =
380
					read_sort(sn.code);
381
			}
382
			/* read a parameter */
383
			/* XX008 */
384
			if (sn.code == f_exp.code) {
385
				crt_repeat = old_crt_repeat;
386
			}
2 7u83 387
 
7 7u83 388
			new_bindings[i].defined = 1;
389
			/* and say it is defined */
390
			new_bindings[i].tok_special = 0;
391
			/* and say it is not special */
392
			new_bindings[i].recursive = (sn.code == TOKEN);
393
			/* and say it is not recursive for simple
394
			 * sorts */
395
			new_bindings[i].tok_context = crt_context;
396
		}
2 7u83 397
 
7 7u83 398
		/* set up the place to read the definition */
399
		set_place(td->tdplace);
2 7u83 400
 
7 7u83 401
		new_context.recursive = td->recursive;
402
		new_context.outer = td->tok_context;
403
		new_context.tags = (tag_con *)0;
404
		new_context.labs = (lab_con *)0;
2 7u83 405
 
7 7u83 406
		crt_context = &new_context;
2 7u83 407
 
7 7u83 408
		/* now set up the tables which belong to the place
409
		 * where the token was defined */
410
		unit_ind_tags = td->my_tagtab;
411
		unit_labtab = td->my_labtab;
412
		unit_ind_tokens = td->my_toktab;
413
		unit_ind_als = td->my_altab;
414
		unit_ind_diagtags = td->my_diagtab;	/* OLD DIAGS */
415
		unit_ind_dgtags = td->my_dgtab;		/* NEW DIAGS */
2 7u83 416
 
7 7u83 417
		/* read the body of the definition */
418
		td->recursive = 1;  /* set up to detect recursion */
419
		val = read_sort(sortcode);
420
		td->recursive = new_context.recursive;
2 7u83 421
 
7 7u83 422
		/* restore the place in the input stream */
423
		set_place(old_place);
2 7u83 424
 
7 7u83 425
		new_bindings = &new_context.loctoks[0];
2 7u83 426
 
7 7u83 427
		/* kill off exps (they were copied) */
428
		for (j = 0; j < npars; ++j) {
429
			tok_define *q;
430
			if (j >= LOCAL_TOKS) {
431
				i = j - LOCAL_TOKS;
432
				new_bindings = new_context.othertoks;
433
			} else {
434
				i = j;
435
			}
436
			q = &new_bindings[i];
437
			if (q->tdsort.code == f_exp.code) {
438
				exp ek = q->tdvalue.tk_exp;
439
				kill_exp(ek, ek);
440
			}
441
		}
2 7u83 442
 
7 7u83 443
		/* restore the old environment of tables */
444
		crt_context = old_context;
445
		unit_ind_tags = old_tagtab;
446
		unit_labtab = old_labtab;
447
		unit_ind_tokens = old_toktab;
448
		unit_ind_als = old_altab;
449
		unit_ind_diagtags = old_diagtab;	/* OLD DIAGS */
450
		unit_ind_dgtags = old_dgtab;		/* NEW DIAGS */
451
 
452
		if (!doing_aldefs && npars == 0 &&
453
				new_context.recursive == 0) {
454
			/* if there were no parameters, record the
455
			 * value for the next application of the
456
			 * token */
457
			td->valpresent = 1;
458
			td->tdvalue = val;
459
			if (sortcode == f_exp.code) {
460
				tokval v;
461
				v.tk_exp = copy(val.tk_exp);
462
				/* if we are remembering it we must
463
				 * copy, because the returned value
464
				 * might be altered */
465
				IGNORE hold(val.tk_exp);
466
				return v;
467
			}
468
		} else {
469
			if (npars > LOCAL_TOKS) {
470
				xfree((void *)new_context.othertoks);
471
				/* free the space used for parameter
472
				 * binding */
473
			}
474
		}
475
		while (new_context.tags != (tag_con *)0) {
476
			tag_con *r = new_context.tags;
477
			new_context.tags =
478
				new_context.tags->rest;
479
			xfree((void *)r);
480
		}
481
		while (new_context.labs != (lab_con *)0) {
482
			lab_con *r = new_context.labs;
483
			new_context.labs =
484
				new_context.labs->rest;
485
			xfree((void *)r);
486
		}
487
		return val;
488
	}
2 7u83 489
}