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
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
#include "config.h"
32
#include "types.h"
33
#include "binding.h"
34
#include "capsule.h"
35
#include "tdf.h"
36
#include "tree.h"
37
#include "utility.h"
38
 
39
 
40
/*
41
    CREATE A NEW OBJECT
42
 
43
    This routine allocates a new object of type v.
44
*/
45
 
46
object *new_object
47
    PROTO_N ( ( v ) )
48
    PROTO_T ( long v )
49
{
50
    static object *free_objs = null ;
51
    static int objs_left = 0 ;
52
 
53
    object *p ;
54
    if ( objs_left == 0 ) {
55
	objs_left = 200 ;
56
	free_objs = alloc_nof ( object, objs_left ) ;
57
    }
58
    objs_left-- ;
59
    p = free_objs + objs_left ;
60
    p->named = 0 ;
61
    p->id = ( var_count [v] )++ ;
62
    p->order = -1 ;
63
    p->aux = null ;
64
    if ( v == var_tag ) {
65
	var ( p ) = 3 ;
66
    } else if ( v == var_token ) {
67
	is_foreign ( p ) = 0 ;
68
	res_sort ( p ) = sort_unknown ;
69
	implicit_sort ( p ) = sort_unknown ;
70
	arg_sorts ( p ) = null ;
71
    }
72
    return ( p ) ;
73
}
74
 
75
 
76
/*
77
    SPARE BINDING TABLE
78
 
79
    In fact only two binding tables are ever needed.  The one not in use
80
    is stored in spare_bt.
81
*/
82
 
83
static binding *spare_bt = null ;
84
 
85
 
86
/*
87
    CREATE A NEW BINDING TABLE
88
 
89
    This routine allocates a new binding table and initializes its entries.
90
*/
91
 
92
binding *new_binding_table
93
    PROTO_Z ()
94
{
95
    binding *bt ;
96
    long i, n = no_variables ;
97
    if ( n == 0 ) return ( null ) ;
98
    if ( spare_bt ) {
99
	bt = spare_bt ;
100
	spare_bt = null ;
101
	for ( i = 0 ; i < n ; i++ ) {
102
	    bt [i].max_no = 0 ;
103
	}
104
    } else {
105
	bt = alloc_nof ( binding, n ) ;
106
	for ( i = 0 ; i < n ; i++ ) {
107
	    bt [i].max_no = 0 ;
108
	    bt [i].sz = 0 ;
109
	    bt [i].table = null ;
110
	}
111
    }
112
    return ( bt ) ;
113
}
114
 
115
 
116
/*
117
    FREE A BINDING
118
 
119
    The binding bt is returned to free.
120
*/
121
 
122
void free_binding_table
123
    PROTO_N ( ( bt ) )
124
    PROTO_T ( binding *bt )
125
{
126
    spare_bt = bt ;
127
    return ;
128
}
129
 
130
 
131
/*
132
    SET THE SIZE OF A BINDING
133
 
134
    The vth entry of bt is set to size n.
135
*/
136
 
137
void set_binding_size
138
    PROTO_N ( ( bt, v, n ) )
139
    PROTO_T ( binding *bt X long v X long n )
140
{
141
    object **p ;
142
    binding *b ;
143
    long i, m = n + 10 ;
144
    if ( v < 0 || v >= no_variables ) {
145
	input_error ( "Illegal binding sort" ) ;
146
	return ;
147
    }
148
    b = bt + v ;
149
    b->max_no = n ;
150
    if ( b->sz < m ) {
151
	p = realloc_nof ( b->table, object *, m ) ;
152
	b->sz = m ;
153
	b->table = p ;
154
    } else {
155
	p = b->table ;
156
    }
157
    for ( i = 0 ; i < b->sz ; i++ ) p [i] = null ;
158
    return ;
159
}
160
 
161
 
162
/*
163
    SET AN ENTRY IN A BINDING
164
 
165
    The nth entry of the vth entry of the binding bt is set to p.
166
*/
167
 
168
void set_binding
169
    PROTO_N ( ( bt, v, n, p ) )
170
    PROTO_T ( binding *bt X long v X long n X object *p )
171
{
172
    binding *b ;
173
    if ( v < 0 || v >= no_variables ) {
174
	input_error ( "Illegal binding sort" ) ;
175
	return ;
176
    }
177
    b = bt + v ;
178
    if ( n >= b->max_no || n < 0 ) {
179
	out ( "<error>" ) ;
180
	input_error ( "Object number %ld (%s) too big", n, var_types [v] ) ;
181
	while ( n >= b->sz ) {
182
	    /* Table is extended (errors only) */
183
	    long i, m = b->sz + 100 ;
184
	    b->sz = m ;
185
	    b->table = realloc_nof ( b->table, object *, m ) ;
186
	    for ( i = 1 ; i <= 100 ; i++ ) b->table [ m - i ] = null ;
187
	}
188
    }
189
    if ( b->table [n] ) {
190
	input_error ( "Object %s (%s) already bound", object_name ( v, n ),
191
		      var_types [v] ) ;
192
    }
193
    b->table [n] = p ;
194
    return ;
195
}
196
 
197
 
198
/*
199
    FILL IN BLANK ENTRIES IN A BINDING
200
 
201
    Objects are allocated for all the entries in the binding bt which
202
    are not associated with an existing object.
203
*/
204
 
205
void complete_binding
206
    PROTO_N ( ( bt ) )
207
    PROTO_T ( binding *bt )
208
{
209
    long v ;
210
    for ( v = 0 ; v < no_variables ; v++ ) {
211
	long i ;
212
	binding *b = bt + v ;
213
	for ( i = 0 ; i < b->max_no ; i++ ) {
214
	    if ( b->table [i] == null ) {
215
		b->table [i] = new_object ( v ) ;
216
	    }
217
	}
218
    }
219
    return ;
220
}
221
 
222
 
223
/*
224
    FIND AN ENTRY IN A BINDING
225
 
226
    The nth entry of the vth entry of binding bt is returned.
227
*/
228
 
229
object *find_binding
230
    PROTO_N ( ( bt, v, n ) )
231
    PROTO_T ( binding *bt X long v X long n )
232
{
233
    binding *b ;
234
    if ( v < 0 || v >= no_variables ) {
235
	input_error ( "Illegal binding sort" ) ;
236
	return ( null ) ;
237
    }
238
    b = bt + v ;
239
    if ( n >= b->max_no || n < 0 ) {
240
	out ( "<error>" ) ;
241
	input_error ( "Object number %ld (%s) too big", n, var_types [v] ) ;
242
    }
243
    if ( n >= b->sz ) return ( null ) ;
244
    return ( b->table [n] ) ;
245
}
246
 
247
 
248
/*
249
    OUTPUT AN OBJECT
250
 
251
    The object p of type v and number n is output.
252
*/
253
 
254
void out_object
255
    PROTO_N ( ( n, p, v ) )
256
    PROTO_T ( long n X object *p X long v )
257
{
258
    if ( v < 0 || v >= no_variables ) {
259
	out ( "<error>" ) ;
260
	input_error ( "Illegal binding sort" ) ;
261
	return ;
262
    }
263
    if ( dumb_mode ) {
264
	word *w ;
265
	out_string ( var_types [v] ) ;
266
	w = new_word ( HORIZ_BRACKETS ) ;
267
	out_int ( n ) ;
268
	end_word ( w ) ;
269
	return ;
270
    }
271
    if ( p == null ) {
272
	p = find_binding ( crt_binding, v, n ) ;
273
	if ( p == null ) {
274
	    p = new_object ( v ) ;
275
	    set_binding ( crt_binding, v, n, p ) ;
276
	}
277
    }
278
    if ( p->named ) {
279
	if ( p->name.simple ) {
280
	    out ( p->name.val.str ) ;
281
	} else {
282
	    out_unique ( p->name.val.uniq ) ;
283
	}
284
	return ;
285
    }
286
    out_char ( '~' ) ;
287
    out_string ( var_types [v] ) ;
288
    out_char ( '_' ) ;
289
    out_int ( p->id ) ;
290
    return ;
291
}
292
 
293
 
294
/*
295
    RETURN AN OBJECT NAME (FOR ERROR REPORTING)
296
 
297
    The name of object type v and number n is returned.
298
*/
299
 
300
char *object_name
301
    PROTO_N ( ( v, n ) )
302
    PROTO_T ( long v X long n )
303
{
304
    object *p ;
305
    char *buff = alloc_nof ( char, 1000 ) ;
306
    if ( dumb_mode ) {
307
	IGNORE sprintf ( buff, "%ld", n ) ;
308
	return ( buff ) ;
309
    }
310
    p = find_binding ( crt_binding, v, n ) ;
311
    if ( p->named ) {
312
	if ( p->name.simple ) {
313
	    IGNORE sprintf ( buff, "%s", p->name.val.str ) ;
314
	} else {
315
	    IGNORE sprintf ( buff, "unique(%ld)", p->id ) ;
316
	}
317
    } else {
318
	IGNORE sprintf ( buff, "%ld", p->id ) ;
319
    }
320
    return ( buff ) ;
321
}