Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/algol60/src/tools/disp/binding.c – Rev 7

Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | 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 "binding.h"
64
#include "capsule.h"
65
#include "tdf.h"
66
#include "tree.h"
67
#include "utility.h"
68
 
69
 
70
/*
71
    CREATE A NEW OBJECT
72
 
73
    This routine allocates a new object of type v.
74
*/
75
 
7 7u83 76
object *
77
new_object(long v)
2 7u83 78
{
7 7u83 79
    static object *free_objs = null;
80
    static int objs_left = 0;
2 7u83 81
 
7 7u83 82
    object *p;
83
    if (objs_left == 0) {
84
	objs_left = 200;
85
	free_objs = alloc_nof(object, objs_left);
2 7u83 86
    }
7 7u83 87
    objs_left--;
88
    p = free_objs + objs_left;
89
    p->named = 0;
90
    p->id = (var_count[v]) ++;
91
    p->order = -1;
92
    p->aux = null;
93
    if (v == var_tag) {
94
	var(p) = 3;
95
    } else if (v == var_token) {
96
	is_foreign(p) = 0;
97
	res_sort(p) = sort_unknown;
98
	implicit_sort(p) = sort_unknown;
99
	arg_sorts(p) = null;
2 7u83 100
    }
7 7u83 101
    return(p);
2 7u83 102
}
103
 
104
 
105
/*
106
    SPARE BINDING TABLE
107
 
108
    In fact only two binding tables are ever needed.  The one not in use
109
    is stored in spare_bt.
110
*/
111
 
7 7u83 112
static binding *spare_bt = null;
2 7u83 113
 
114
 
115
/*
116
    CREATE A NEW BINDING TABLE
117
 
118
    This routine allocates a new binding table and initializes its entries.
119
*/
120
 
7 7u83 121
binding *
122
new_binding_table(void)
2 7u83 123
{
7 7u83 124
    binding *bt;
125
    long i, n = no_variables;
126
    if (n == 0) return(null);
127
    if (spare_bt) {
128
	bt = spare_bt;
129
	spare_bt = null;
130
	for (i = 0; i < n; i++) {
131
	    bt[i].max_no = 0;
2 7u83 132
	}
133
    } else {
7 7u83 134
	bt = alloc_nof(binding, n);
135
	for (i = 0; i < n; i++) {
136
	    bt[i].max_no = 0;
137
	    bt[i].sz = 0;
138
	    bt[i].table = null;
2 7u83 139
	}
140
    }
7 7u83 141
    return(bt);
2 7u83 142
}
143
 
144
 
145
/*
146
    FREE A BINDING
147
 
148
    The binding bt is returned to free.
149
*/
150
 
7 7u83 151
void
152
free_binding_table(binding *bt)
2 7u83 153
{
7 7u83 154
    spare_bt = bt;
155
    return;
2 7u83 156
}
157
 
158
 
159
/*
160
    SET THE SIZE OF A BINDING
161
 
162
    The vth entry of bt is set to size n.
163
*/
164
 
7 7u83 165
void
166
set_binding_size(binding *bt, long v, long n)
2 7u83 167
{
7 7u83 168
    object **p;
169
    binding *b;
170
    long i, m = n + 10;
171
    if (v < 0 || v >= no_variables) {
172
	input_error("Illegal binding sort");
173
	return;
2 7u83 174
    }
7 7u83 175
    b = bt + v;
176
    b->max_no = n;
177
    if (b->sz < m) {
178
	p = realloc_nof(b->table, object *, m);
179
	b->sz = m;
180
	b->table = p;
2 7u83 181
    } else {
7 7u83 182
	p = b->table;
2 7u83 183
    }
7 7u83 184
    for (i = 0; i < b->sz; i++)p[i] = null;
185
    return;
2 7u83 186
}
187
 
188
 
189
/*
190
    SET AN ENTRY IN A BINDING
191
 
192
    The nth entry of the vth entry of the binding bt is set to p.
193
*/
194
 
7 7u83 195
void
196
set_binding(binding *bt, long v, long n, object *p)
2 7u83 197
{
7 7u83 198
    binding *b;
199
    if (v < 0 || v >= no_variables) {
200
	input_error("Illegal binding sort");
201
	return;
2 7u83 202
    }
7 7u83 203
    b = bt + v;
204
    if (n >= b->max_no || n < 0) {
205
	out("<error>");
206
	input_error("Object number %ld (%s) too big", n, var_types[v]);
207
	while (n >= b->sz) {
2 7u83 208
	    /* Table is extended (errors only) */
7 7u83 209
	    long i, m = b->sz + 100;
210
	    b->sz = m;
211
	    b->table = realloc_nof(b->table, object *, m);
212
	    for (i = 1; i <= 100; i++)b->table[m - i] = null;
2 7u83 213
	}
214
    }
7 7u83 215
    if (b->table[n]) {
216
	input_error("Object %s (%s) already bound", object_name(v, n),
217
		      var_types[v]);
2 7u83 218
    }
7 7u83 219
    b->table[n] = p;
220
    return;
2 7u83 221
}
222
 
223
 
224
/*
225
    FILL IN BLANK ENTRIES IN A BINDING
226
 
227
    Objects are allocated for all the entries in the binding bt which
228
    are not associated with an existing object.
229
*/
230
 
7 7u83 231
void
232
complete_binding(binding *bt)
2 7u83 233
{
7 7u83 234
    long v;
235
    for (v = 0; v < no_variables; v++) {
236
	long i;
237
	binding *b = bt + v;
238
	for (i = 0; i < b->max_no; i++) {
239
	    if (b->table[i] == null) {
240
		b->table[i] = new_object(v);
2 7u83 241
	    }
242
	}
243
    }
7 7u83 244
    return;
2 7u83 245
}
246
 
247
 
248
/*
249
    FIND AN ENTRY IN A BINDING
250
 
251
    The nth entry of the vth entry of binding bt is returned.
252
*/
253
 
7 7u83 254
object *
255
find_binding(binding *bt, long v, long n)
2 7u83 256
{
7 7u83 257
    binding *b;
258
    if (v < 0 || v >= no_variables) {
259
	input_error("Illegal binding sort");
260
	return(null);
2 7u83 261
    }
7 7u83 262
    b = bt + v;
263
    if (n >= b->max_no || n < 0) {
264
	out("<error>");
265
	input_error("Object number %ld (%s) too big", n, var_types[v]);
2 7u83 266
    }
7 7u83 267
    if (n >= b->sz) return(null);
268
    return(b->table[n]);
2 7u83 269
}
270
 
271
 
272
/*
273
    OUTPUT AN OBJECT
274
 
275
    The object p of type v and number n is output.
276
*/
277
 
7 7u83 278
void
279
out_object(long n, object *p, long v)
2 7u83 280
{
7 7u83 281
    if (v < 0 || v >= no_variables) {
282
	out("<error>");
283
	input_error("Illegal binding sort");
284
	return;
2 7u83 285
    }
7 7u83 286
    if (dumb_mode) {
287
	word *w;
288
	out_string(var_types[v]);
289
	w = new_word(HORIZ_BRACKETS);
290
	out_int(n);
291
	end_word(w);
292
	return;
2 7u83 293
    }
7 7u83 294
    if (p == null) {
295
	p = find_binding(crt_binding, v, n);
296
	if (p == null) {
297
	    p = new_object(v);
298
	    set_binding(crt_binding, v, n, p);
2 7u83 299
	}
300
    }
7 7u83 301
    if (p->named) {
302
	if (p->name.simple) {
303
	    out(p->name.val.str);
2 7u83 304
	} else {
7 7u83 305
	    out_unique(p->name.val.uniq);
2 7u83 306
	}
7 7u83 307
	return;
2 7u83 308
    }
7 7u83 309
    out_char('~');
310
    out_string(var_types[v]);
311
    out_char('_');
312
    out_int(p->id);
313
    return;
2 7u83 314
}
315
 
316
 
317
/*
318
    RETURN AN OBJECT NAME (FOR ERROR REPORTING)
319
 
320
    The name of object type v and number n is returned.
321
*/
322
 
7 7u83 323
char *
324
object_name(long v, long n)
2 7u83 325
{
7 7u83 326
    object *p;
327
    char *buff = alloc_nof(char, 1000);
328
    if (dumb_mode) {
329
	IGNORE sprintf(buff, "%ld", n);
330
	return(buff);
2 7u83 331
    }
7 7u83 332
    p = find_binding(crt_binding, v, n);
333
    if (p->named) {
334
	if (p->name.simple) {
335
	    IGNORE sprintf(buff, "%s", p->name.val.str);
2 7u83 336
	} else {
7 7u83 337
	    IGNORE sprintf(buff, "unique(%ld)", p->id);
2 7u83 338
	}
339
    } else {
7 7u83 340
	IGNORE sprintf(buff, "%ld", p->id);
2 7u83 341
    }
7 7u83 342
    return(buff);
2 7u83 343
}