Subversion Repositories tendra.SVN

Rev

Rev 2 | 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
7 7u83 33
 
2 7u83 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:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 7u83 45
 
2 7u83 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;
7 7u83 49
 
2 7u83 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;
7 7u83 53
 
2 7u83 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
#include "config.h"
62
#include "types.h"
63
#include "ascii.h"
64
#include "basic.h"
65
#include "binding.h"
66
#include "capsule.h"
67
#include "file.h"
68
#include "sort.h"
69
#include "tree.h"
70
#include "tdf.h"
71
#include "unit.h"
72
#include "utility.h"
73
 
74
 
75
/*
76
    WARN ABOUT UNDECLARED TOKENS
77
*/
78
 
7 7u83 79
int warn_undeclared = 0;
2 7u83 80
 
81
 
82
/*
83
    DECODING TOKENS
84
 
85
    Simple TOKENs are represented by TDF integers.  They may also be
86
    tokenised themselves.
87
*/
88
 
7 7u83 89
object *
90
de_token_aux(sortname s, char *nm)
2 7u83 91
{
7 7u83 92
    word *w;
93
    long bits, t;
94
    object *obj = null;
95
    int ap = 1, simple = 1;
96
    int just_tok = (s == sort_unknown ? 1 : 0);
2 7u83 97
 
98
    /* Find the token number */
7 7u83 99
    long n = de_token();
100
    if (n == token_make_tok) {
101
	t = tdf_int();
2 7u83 102
    } else {
7 7u83 103
	simple = 0;
2 7u83 104
    }
105
 
106
    /* Look up simple tokens */
7 7u83 107
    if (simple) {
108
	SET(t);
109
	obj = find_binding(crt_binding, var_token, t);
110
	if (obj == null) {
111
	    obj = new_object(var_token);
112
	    set_binding(crt_binding, var_token, t, obj);
2 7u83 113
	}
114
 
115
	/* Check token sort */
7 7u83 116
	if (res_sort(obj) == sort_unknown) {
117
	    sortname is = implicit_sort(obj);
118
	    if (is == sort_unknown && warn_undeclared) {
119
		int old_recover = recover;
120
		int old_exit_status = exit_status;
121
		recover = 1;
122
		input_error("Warning : token %s used before it is declared",
123
			      object_name(var_token, t));
124
		recover = old_recover;
125
		exit_status = old_exit_status;
2 7u83 126
	    }
7 7u83 127
	    if (is != sort_unknown && is != s) {
128
		sortid es;
129
		out("<error>");
130
		es = find_sort(s);
131
		input_error("Implicit sort error, token %s, %s expected",
132
			      object_name(var_token, t), es.name);
2 7u83 133
	    }
7 7u83 134
	    implicit_sort(obj) = s;
135
	} else if (res_sort(obj)!= s && !just_tok) {
136
	    sortid es;
137
	    out("<error>");
138
	    es = find_sort(s);
139
	    input_error("Sort error, token %s, %s expected",
140
			  object_name(var_token, t), es.name);
2 7u83 141
	}
142
 
143
	/* Output token name if appropriate */
7 7u83 144
	if (!dumb_mode) {
145
	     if (obj->named) {
146
		if (obj->name.simple) {
147
		    out_string(obj->name.val.str);
148
		    ap = 0;
2 7u83 149
		}
150
	    } else {
7 7u83 151
		char buff[50];
152
		IGNORE sprintf(buff, "~token_%ld", obj->id);
153
		out_string(buff);
154
		ap = 0;
2 7u83 155
	    }
156
	}
157
    }
158
 
159
    /* Output "apply_token" if appropriate */
7 7u83 160
    if (ap) {
161
	if (just_tok) {
162
	    out_string("make_token");
2 7u83 163
	} else {
7 7u83 164
	    out_string("apply_");
165
	    out_string(nm);
166
	    out_string("_token");
2 7u83 167
	}
7 7u83 168
	w = new_word(VERT_BRACKETS);
169
	if (simple) {
170
	    SET(t);
171
	    out_object(t, obj, var_token);
2 7u83 172
	} else {
7 7u83 173
	    if (n == token_token_apply_token) {
174
		object *subobj = de_token_aux(sort_token, "token");
175
		if (subobj)obj = subobj->aux;
2 7u83 176
	    } else {
177
		/* use_tokdef */
7 7u83 178
		long len = tdf_int();
179
		skip_bits(len);
180
		out_string("use_tokdef(....)");
181
		IGNORE new_word(SIMPLE);
2 7u83 182
	    }
183
	}
184
    } else {
185
	/* Applications of named tokens are indicated by "*" */
7 7u83 186
	out_string("*");
2 7u83 187
    }
188
 
189
    /* Quit here if just reading token */
7 7u83 190
    if (just_tok) {
191
	if (ap) {
192
	    SET(w);
193
	    end_word(w);
2 7u83 194
	} else {
7 7u83 195
	    IGNORE new_word(SIMPLE);
2 7u83 196
	}
7 7u83 197
	return(obj);
2 7u83 198
    }
199
 
200
    /* Read length of token arguments */
7 7u83 201
    bits = tdf_int();
2 7u83 202
 
203
    /* Deal with tokens without arguments */
7 7u83 204
    if (bits == 0) {
205
	if (obj && res_sort(obj)!= sort_unknown) {
206
	    char *ps = arg_sorts(obj);
207
	    if (ps && *ps) {
208
		if (simple) {
209
		    SET(t);
210
		    input_error("Token arguments missing, token %s",
211
				  object_name(var_token, t));
2 7u83 212
		} else {
7 7u83 213
		    input_error("Token arguments missing");
2 7u83 214
		}
215
	    }
216
	}
7 7u83 217
	if (ap) {
218
	    SET(w);
219
	    end_word(w);
2 7u83 220
	} else {
7 7u83 221
	    IGNORE new_word(SIMPLE);
2 7u83 222
	}
7 7u83 223
	return(obj);
2 7u83 224
    }
225
 
226
    /* Deal with tokens with arguments */
7 7u83 227
    if (obj && res_sort(obj)!= sort_unknown && !is_foreign(obj)) {
2 7u83 228
	/* Known token - decode arguments */
7 7u83 229
	if (arg_sorts(obj)) {
230
	    long p = posn(here);
231
	    if (!ap)w = new_word(VERT_BRACKETS);
232
	    decode(arg_sorts(obj));
233
	    if (p + bits != posn(here)) {
234
		if (simple) {
235
		    SET(t);
236
		    input_error("Token arguments length wrong, token %s",
237
				  object_name(var_token, t));
2 7u83 238
		} else {
7 7u83 239
		    input_error("Token arguments length wrong");
2 7u83 240
		}
241
	    }
242
	} else {
7 7u83 243
	    if (ap) {
244
		SET(w);
245
		end_word(w);
2 7u83 246
	    } else {
7 7u83 247
		IGNORE new_word(SIMPLE);
2 7u83 248
	    }
7 7u83 249
	    return(obj);
2 7u83 250
	}
251
    } else {
252
	/* Unknown token - step over arguments */
7 7u83 253
	if (!ap)w = new_word(VERT_BRACKETS);
254
	out("....");
255
	skip_bits(bits);
2 7u83 256
    }
7 7u83 257
    SET(w);
258
    end_word(w);
259
    return(obj);
2 7u83 260
}
261
 
262
 
263
/*
264
    DECODING SIMPLE LABELS
265
*/
266
 
7 7u83 267
void
268
de_make_label(long lab_no)
2 7u83 269
{
7 7u83 270
    if (dumb_mode) {
271
	word *w;
272
	out_string("label");
273
	w = new_word(HORIZ_BRACKETS);
274
	out_int(lab_no);
275
	end_word(w);
2 7u83 276
    } else {
7 7u83 277
	out_string("~label_");
278
	out_int(lab_no);
2 7u83 279
    }
7 7u83 280
    if (lab_no < 0 || lab_no >= max_lab_no) {
281
	input_error("Label number %ld out of range", lab_no);
2 7u83 282
    }
7 7u83 283
    return;
2 7u83 284
}
285
 
286
 
287
/*
288
    FORMATTING SIZE FOR TDF STRINGS
289
 
290
    A string will be split by de_format_string into sections of length
291
    at most STRING_WIDTH.
292
*/
293
 
294
#define STRING_WIDTH		40
295
 
296
 
297
/*
298
    DECODING FORMATTED STRINGS
299
 
300
    A TDF string is read and output in a formatted form.
301
*/
302
 
7 7u83 303
void
304
de_tdfstring_format(void)
2 7u83 305
{
7 7u83 306
    string s;
307
    word *ptr1;
308
    long sz = tdf_int();
309
    long n = tdf_int();
310
    if (sz != 8) {
311
	char sbuff[100];
312
	IGNORE sprintf(sbuff, "make_string_%ld", sz);
313
	out_string(sbuff);
314
	ptr1 = new_word(HORIZ_BRACKETS);
2 7u83 315
    }
7 7u83 316
    if (sz > 8) {
317
	long i;
318
	for (i = 0; i < n; i++) {
319
	    long v = fetch((int)sz);
320
	    out_int(v);
2 7u83 321
	}
322
    } else {
7 7u83 323
	s = get_string(n, sz);
324
	n = (long)strlen(s);
325
	if (n == 0) {
326
	    out("\"\"");
327
	    return;
2 7u83 328
	}
7 7u83 329
	while (n) {
330
	    long m = (n < STRING_WIDTH ? n : STRING_WIDTH);
331
	    char *w = alloc_nof(char, m + 3);
332
	    IGNORE memcpy(w + 1, s,(size_t)m);
333
	    w[0] = QUOTE;
334
	    w[m + 1] = QUOTE;
335
	    w[m + 2] = 0;
336
	    out(w);
337
	    n -= m;
338
	    s += m;
2 7u83 339
	}
340
    }
7 7u83 341
    if (sz != 8) {
342
	SET(ptr1);
343
	end_word(ptr1);
2 7u83 344
    }
7 7u83 345
    return;
2 7u83 346
}
347
 
348
 
349
/*
350
    DECODING THE EXP "solve" (OR "labelled")
351
 
352
    This is tricky because it is encoded as :
353
 
354
		    A1, ..., An, B, C1, ..., Cn
355
 
356
    where n is a TDF integer, Ai is given by the decode string str1,
357
    B is given by str2, and Ci is given by str3, but we want to print
358
    it in the order :
359
 
360
		      B, A1, C1, ..., An, Cn
361
 
362
    so there is a certain amount of to-ing and fro-ing.
363
*/
364
 
7 7u83 365
void
366
de_solve_fn(char *nm, char *str1, char *str2, char *str3, int ntwice)
2 7u83 367
{
7 7u83 368
    long i, n;
369
    word *ptr1, *ptr2;
370
    place posn1, posn2;
2 7u83 371
 
7 7u83 372
    int tempflag = printflag;
2 7u83 373
 
7 7u83 374
    out_string(nm);
375
    ptr1 = new_word(VERT_BRACKETS);
2 7u83 376
 
377
    /* Read the number of statements A1, ..., An */
7 7u83 378
    check_list();
379
    n = tdf_int();
2 7u83 380
 
381
    /* Record the position of A1 */
7 7u83 382
    posn1.byte = here.byte;
383
    posn1.bit = here.bit;
2 7u83 384
 
385
    /* Step over A1, ..., An */
7 7u83 386
    printflag = 0;
387
    for (i = 0; i < n; i++)decode(str1);
388
    printflag = tempflag;
2 7u83 389
 
390
    /* Decode B */
7 7u83 391
    decode(str2);
2 7u83 392
 
7 7u83 393
    if (ntwice) {
2 7u83 394
	/* Read and check the number of statements C1, ..., Cn */
7 7u83 395
	long m;
396
	check_list();
397
	m = tdf_int();
398
	if (m != n)input_error("Illegal %s construct", nm);
2 7u83 399
    }
400
 
7 7u83 401
    for (i = 0; i < n; i++) {
402
	ptr2 = new_word(VERT_BRACKETS);
2 7u83 403
 
404
	/* Record the position of Ci */
7 7u83 405
	posn2.byte = here.byte;
406
	posn2.bit = here.bit;
2 7u83 407
 
408
	/* Go back and read Ai */
7 7u83 409
	set_place(&posn1);
410
	decode(str1);
2 7u83 411
 
412
	/* Record the position of A(i+1) */
7 7u83 413
	posn1.byte = here.byte;
414
	posn1.bit = here.bit;
2 7u83 415
 
416
	/* Go forward and read Ci */
7 7u83 417
	set_place(&posn2);
418
	decode(str3);
2 7u83 419
 
7 7u83 420
	end_word(ptr2);
2 7u83 421
    }
7 7u83 422
    end_word(ptr1);
423
    return;
2 7u83 424
}
425
 
426
 
427
/*
428
    DECODING THE EXP "case"
429
 
430
    Only the layout makes this a special case.  The general form is :
431
 
432
		      A, L1, B1, ..., Ln, Bn
433
 
434
    where A is given by the decode string str1, Li is a label and Bi
435
    is given by str2.
436
*/
437
 
7 7u83 438
void
439
de_case_fn(char *nm, char *str1, char *str2)
2 7u83 440
{
7 7u83 441
    long i, n;
442
    word *ptr1, *ptr2, *ptr3;
2 7u83 443
 
7 7u83 444
    out_string(nm);
445
    ptr1 = new_word(VERT_BRACKETS);
446
    decode(str1);
447
    ptr2 = new_word(VERT_BRACKETS);
448
    check_list();
449
    n = tdf_int();
450
    for (i = 0; i < n; i++) {
451
	ptr3 = new_word(HORIZ_NONE);
452
	IGNORE de_label();
453
	out(":");
454
	format(HORIZ_BRACKETS, "", str2);
455
	end_word(ptr3);
2 7u83 456
    }
7 7u83 457
    end_word(ptr2);
458
    end_word(ptr1);
459
    return;
2 7u83 460
}
461
 
462
 
463
/*
464
    DECODING THE EXP "make_proc"
465
 
466
    The general form is :
467
 
468
			A, B1, ..., Bn, C
469
 
470
    where A is given by the decode string str1, B by str2 and C by str3.
471
    However each Bi is grouped as a "make_proc_arg".
472
*/
473
 
7 7u83 474
void
475
de_mk_proc_fn(char *nm, char *str1, char *str2, char *str3)
2 7u83 476
{
7 7u83 477
    long i, n;
478
    word *ptr;
479
    out_string(nm);
480
    ptr = new_word(VERT_BRACKETS);
481
    decode(str1);
482
    check_list();
483
    n = tdf_int();
484
    if (n == 0) {
485
	out("empty");
2 7u83 486
    } else {
7 7u83 487
	for (i = 0; i < n; i++) {
488
	    out_string(nm);
489
	    format(VERT_BRACKETS, "_arg", str2);
2 7u83 490
	}
491
    }
7 7u83 492
    decode(str3);
493
    end_word(ptr);
494
    return;
2 7u83 495
}