Subversion Repositories tendra.SVN

Rev

Rev 7 | 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 */
2 7u83 243
 
89 7u83 244
		failer(UNDEFINED_TOK);
245
 
7 7u83 246
		if (td->is_capsule_token &&
247
		    td->tok_index < capsule_no_of_tokens &&
248
		    td->tok_index >= 0 &&
249
		    td->tok_name != (char *)0) {
250
			IGNORE fprintf(stderr, "token is: %s\n",
251
				       td -> tok_name);
252
		} else {
253
			if (td->is_capsule_token &&
254
			    td->tok_index < capsule_no_of_tokens &&
255
			    td->tok_index >= 0) {
256
				IGNORE fprintf(stderr,
257
					       "capsule token number: %d\n",
258
					       td -> tok_index);
259
			} else {
260
				if (td->tok_index >= 0 &&
261
				    td->tok_index < unit_no_of_tokens) {
262
					IGNORE fprintf(stderr,
263
					    "local unit token number: %d\n",
264
					    td->tok_index);
265
				} else {
266
					IGNORE fprintf(stderr,
267
					    "token number out of bounds\n");
268
				}
269
			}
270
		}
89 7u83 271
		exit(EXIT_FAILURE);
7 7u83 272
	}
2 7u83 273
 
7 7u83 274
	{
275
		/* number of parameters */
276
		int npars = td->params.number;
277
		/* to construct the bindings for this expansion */
278
		context new_context;
279
		context *old_context = crt_context;
2 7u83 280
 
7 7u83 281
		tokval val;
282
		/* to record the current place in the input stream */
283
		place old_place;
2 7u83 284
 
7 7u83 285
		tok_define *new_bindings;
286
		int i, j;
287
		dec **old_tagtab;
288
		/* to remember the current tag table */
289
		exp *old_labtab;
290
		/* to remember the current label table */
291
		tok_define **old_toktab;
292
		/* to remember the current token table */
293
		aldef **old_altab;
294
		/* to remember the current alignment tag table */
295
		diag_tagdef **old_diagtab;		/* OLD DIAGS */
296
		dgtag_struct **old_dgtab;		/* NEW DIAGS */
2 7u83 297
 
7 7u83 298
		/* now remember them */
299
		old_tagtab = unit_ind_tags;
300
		old_labtab = unit_labtab;
301
		old_toktab = unit_ind_tokens;
302
		old_altab = unit_ind_als;
303
		old_diagtab = unit_ind_diagtags;	/* OLD DIAGS */
304
		old_dgtab = unit_ind_dgtags;		/* NEW DIAGS */
2 7u83 305
 
7 7u83 306
		new_context.no_toks = (short)npars;
307
		nil_params.number = 0;
2 7u83 308
 
7 7u83 309
		if (td -> valpresent &&
310
				(td -> unit_number == crt_tagdef_unit_no)) {
311
			/* if a value has already been computed (there
312
			 * will be no parameters) */
2 7u83 313
 
7 7u83 314
			if (sortcode == f_exp.code) {
315
				tokval v;
316
				v.tk_exp = copy(td->tdvalue.tk_exp);
317
				/* copy it if the result is an
318
				 * expression since we may be going to
319
				 * alter it */
320
				return v;
321
			} else  {
322
				return td -> tdvalue;
323
			}
324
		}
2 7u83 325
 
7 7u83 326
		/* remember the current input stream */
327
		old_place = keep_place();
2 7u83 328
 
7 7u83 329
		set_place(pars);
2 7u83 330
 
7 7u83 331
		/* now set up the new parameter bindings */
332
		if (npars > LOCAL_TOKS) {
333
			new_context.othertoks =
334
				(tok_define *)xcalloc(npars - LOCAL_TOKS,
335
						      sizeof(tok_define));
336
		}
2 7u83 337
 
7 7u83 338
		new_bindings = &new_context.loctoks[0];
2 7u83 339
 
7 7u83 340
		for (j = 0; j < npars; ++j) {
341
			/* read in the parameter values and bind them
342
			 * to the formals */
343
			sortname sn;
344
			exp old_crt_repeat;  /* XX008 */
345
			if (j >= LOCAL_TOKS) {
346
				i = j - LOCAL_TOKS;
347
				new_bindings = new_context.othertoks;
348
			} else {
349
				i = j;
350
			}
351
			sn = (td->params.par_sorts)[j];
352
			new_bindings[i].tdsort = sn;
353
			/* parameter sort */
354
			new_bindings[i].tdtoken =
355
				(td->params.par_names)[j];
356
			/* formal */
357
			new_bindings[i].valpresent = 1;
358
			/* the value is known */
359
			new_bindings[i].unit_number =
360
				crt_tagdef_unit_no;
361
			new_bindings[i].re_evaluate = 0;
362
			/* and does not need re-evaluating */
363
			new_bindings[i].params = nil_params;
364
			/* it has no parameters itself */
2 7u83 365
 
7 7u83 366
			/* XX008 */
367
			if (sn.code == f_exp.code) {
368
				old_crt_repeat = crt_repeat;
369
				crt_repeat = nilexp;
370
			} else {
371
				SET(old_crt_repeat);
372
			}
373
			if (actual_pars != (tokval*)0) {
374
				/* this is not used at present*/
375
				new_bindings[i].tdvalue =
376
					actual_pars[j];
377
			} else {
378
				new_bindings[i].tdvalue =
379
					read_sort(sn.code);
380
			}
381
			/* read a parameter */
382
			/* XX008 */
383
			if (sn.code == f_exp.code) {
384
				crt_repeat = old_crt_repeat;
385
			}
2 7u83 386
 
7 7u83 387
			new_bindings[i].defined = 1;
388
			/* and say it is defined */
389
			new_bindings[i].tok_special = 0;
390
			/* and say it is not special */
391
			new_bindings[i].recursive = (sn.code == TOKEN);
392
			/* and say it is not recursive for simple
393
			 * sorts */
394
			new_bindings[i].tok_context = crt_context;
395
		}
2 7u83 396
 
7 7u83 397
		/* set up the place to read the definition */
398
		set_place(td->tdplace);
2 7u83 399
 
7 7u83 400
		new_context.recursive = td->recursive;
401
		new_context.outer = td->tok_context;
402
		new_context.tags = (tag_con *)0;
403
		new_context.labs = (lab_con *)0;
2 7u83 404
 
7 7u83 405
		crt_context = &new_context;
2 7u83 406
 
7 7u83 407
		/* now set up the tables which belong to the place
408
		 * where the token was defined */
409
		unit_ind_tags = td->my_tagtab;
410
		unit_labtab = td->my_labtab;
411
		unit_ind_tokens = td->my_toktab;
412
		unit_ind_als = td->my_altab;
413
		unit_ind_diagtags = td->my_diagtab;	/* OLD DIAGS */
414
		unit_ind_dgtags = td->my_dgtab;		/* NEW DIAGS */
2 7u83 415
 
7 7u83 416
		/* read the body of the definition */
417
		td->recursive = 1;  /* set up to detect recursion */
418
		val = read_sort(sortcode);
419
		td->recursive = new_context.recursive;
2 7u83 420
 
7 7u83 421
		/* restore the place in the input stream */
422
		set_place(old_place);
2 7u83 423
 
7 7u83 424
		new_bindings = &new_context.loctoks[0];
2 7u83 425
 
7 7u83 426
		/* kill off exps (they were copied) */
427
		for (j = 0; j < npars; ++j) {
428
			tok_define *q;
429
			if (j >= LOCAL_TOKS) {
430
				i = j - LOCAL_TOKS;
431
				new_bindings = new_context.othertoks;
432
			} else {
433
				i = j;
434
			}
435
			q = &new_bindings[i];
436
			if (q->tdsort.code == f_exp.code) {
437
				exp ek = q->tdvalue.tk_exp;
438
				kill_exp(ek, ek);
439
			}
440
		}
2 7u83 441
 
7 7u83 442
		/* restore the old environment of tables */
443
		crt_context = old_context;
444
		unit_ind_tags = old_tagtab;
445
		unit_labtab = old_labtab;
446
		unit_ind_tokens = old_toktab;
447
		unit_ind_als = old_altab;
448
		unit_ind_diagtags = old_diagtab;	/* OLD DIAGS */
449
		unit_ind_dgtags = old_dgtab;		/* NEW DIAGS */
450
 
451
		if (!doing_aldefs && npars == 0 &&
452
				new_context.recursive == 0) {
453
			/* if there were no parameters, record the
454
			 * value for the next application of the
455
			 * token */
456
			td->valpresent = 1;
457
			td->tdvalue = val;
458
			if (sortcode == f_exp.code) {
459
				tokval v;
460
				v.tk_exp = copy(val.tk_exp);
461
				/* if we are remembering it we must
462
				 * copy, because the returned value
463
				 * might be altered */
464
				IGNORE hold(val.tk_exp);
465
				return v;
466
			}
467
		} else {
468
			if (npars > LOCAL_TOKS) {
469
				xfree((void *)new_context.othertoks);
470
				/* free the space used for parameter
471
				 * binding */
472
			}
473
		}
474
		while (new_context.tags != (tag_con *)0) {
475
			tag_con *r = new_context.tags;
476
			new_context.tags =
477
				new_context.tags->rest;
478
			xfree((void *)r);
479
		}
480
		while (new_context.labs != (lab_con *)0) {
481
			lab_con *r = new_context.labs;
482
			new_context.labs =
483
				new_context.labs->rest;
484
			xfree((void *)r);
485
		}
486
		return val;
487
	}
2 7u83 488
}