Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2006 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
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
 
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
Line 59... Line 89...
59
 
89
 
60
Revision 1.1  1995/04/06 10:44:05  currie
90
Revision 1.1  1995/04/06 10:44:05  currie
61
Initial revision
91
Initial revision
62
 
92
 
63
***********************************************************************/
93
***********************************************************************/
64
 
-
 
65
 
-
 
66
 
-
 
67
 
94
 
68
#include "config.h"
95
#include "config.h"
69
#include "common_types.h"
96
#include "common_types.h"
70
#include "exp.h"
97
#include "exp.h"
71
#include "expmacs.h"
98
#include "expmacs.h"
Line 82... Line 109...
82
 
109
 
83
#include "inline.h"
110
#include "inline.h"
84
 
111
 
85
/* PROCEDURES */
112
/* PROCEDURES */
86
 
113
 
87
static exp last_action
114
static exp
88
    PROTO_N ( (e) )
-
 
89
    PROTO_T ( exp e )
115
last_action(exp e)
90
{
116
{
91
  if (e == nilexp)
117
	if (e == nilexp) {
92
    return e;
118
		return e;
-
 
119
	}
93
 
120
 
94
  if (name(e) == ident_tag || name(e) == seq_tag) {
121
	if (name(e) == ident_tag || name(e) == seq_tag) {
95
    return last_action(bro(son(e)));
122
		return last_action(bro(son(e)));
-
 
123
	}
-
 
124
 
-
 
125
	return e;
-
 
126
}
-
 
127
 
-
 
128
 
-
 
129
static void
-
 
130
change_last_shapes(exp e, shape sha)
-
 
131
{
-
 
132
	if (e == nilexp) {
-
 
133
		return;
-
 
134
	}
-
 
135
 
-
 
136
	if (name(e) == ident_tag || name(e) == seq_tag) {
-
 
137
		sh(e) = sha;
-
 
138
		change_last_shapes(bro(son(e)), sha);
-
 
139
	}
-
 
140
 
-
 
141
	return;
-
 
142
}
-
 
143
 
-
 
144
 
-
 
145
/* replaces a formal paramter by an actual parameter */
-
 
146
static void
-
 
147
replace_pars(exp actual, exp formal_par)
-
 
148
{
-
 
149
	exp def;
-
 
150
	if (!last(actual)) {
-
 
151
		replace_pars(bro(actual), bro(son(formal_par)));
96
  }
152
	}
97
 
153
 
98
  return e;
-
 
99
}
-
 
100
 
-
 
101
static void change_last_shapes
-
 
102
    PROTO_N ( (e, sha) )
-
 
103
    PROTO_T ( exp e X shape sha )
-
 
104
{
-
 
105
  if (e == nilexp)
-
 
106
    return;
-
 
107
 
-
 
108
  if (name(e) == ident_tag || name(e) == seq_tag) {
-
 
109
    sh(e) = sha;
-
 
110
    change_last_shapes(bro(son(e)), sha);
-
 
111
  }
-
 
112
 
-
 
113
  return;
-
 
114
}
-
 
115
 
-
 
116
  /* replaces a formal paramter by an actual parameter */
-
 
117
static void replace_pars
-
 
118
    PROTO_N ( (actual, formal_par) )
-
 
119
    PROTO_T ( exp actual X exp formal_par )
-
 
120
{
-
 
121
  exp def;
-
 
122
  if (!last(actual))
-
 
123
     replace_pars(bro(actual), bro(son(formal_par)));
-
 
124
 
-
 
125
  clearparam(formal_par);
154
	clearparam(formal_par);
126
  def = son(formal_par);
155
	def = son(formal_par);
127
  if (no(formal_par) == 1 &&
-
 
128
	shape_size(sh(pt(formal_par))) == 8)
156
	if (no(formal_par) == 1 && shape_size(sh(pt(formal_par))) == 8) {
129
    setvis(formal_par);
157
		setvis(formal_par);
-
 
158
	}
130
  replace(def, actual, formal_par);
159
	replace(def, actual, formal_par);
131
 
160
 
132
  retcell(def);
161
	retcell(def);
133
  return;
162
	return;
134
}
163
}
135
 
164
 
-
 
165
 
136
  /* inlines the procedure application e */
166
/* inlines the procedure application e */
137
void inline_exp
167
void
138
    PROTO_N ( (e) )
-
 
139
    PROTO_T ( exp e )
168
inline_exp(exp e)
140
{
169
{
141
  exp fn = son(e);	/* the name_tag for the function */
170
	exp fn = son(e);	/* the name_tag for the function */
142
  exp pars = bro(fn);	/* the first actual parameter */
171
	exp pars = bro(fn);	/* the first actual parameter */
143
  exp body = son(son(son(fn)));	/* the proc_tag exp */
172
	exp body = son(son(son(fn)));	/* the proc_tag exp */
144
  exp bc, t, q;
173
	exp bc, t, q;
145
  exp lab;
174
	exp lab;
146
  exp var;		/* the destination to which the result is to
175
	exp var;		/* the destination to which the result is to be
147
  			   be assigned */
176
				   assigned */
148
  exp new_var = nilexp;
177
	exp new_var = nilexp;
149
  exp new_dec;	/* a new variable declaration if we make one */
178
	exp new_dec;		/* a new variable declaration if we make one */
150
  shape sha = sh(e);	/* the shape delivered by the application */
179
	shape sha = sh(e);	/* the shape delivered by the application */
151
  exp cond_alt;
180
	exp cond_alt;
152
  exp res;
181
	exp res;
153
  exp last_act;
182
	exp last_act;
154
 
183
 
-
 
184
	if (name(sha) == tophd) {
155
  if (name(sha) == tophd) {	/* not returning a result, no ass needed */
185
		/* not returning a result, no ass needed */
156
    var = nilexp;
186
		var = nilexp;
157
    cond_alt = f_make_top();
187
		cond_alt = f_make_top();
158
  }
-
 
159
  else {
188
	} else {
160
    if (last(e) && name(bro(e)) == ass_tag &&
189
		if (last(e) && name(bro(e)) == ass_tag &&
161
	  name(son(bro(e))) == name_tag) {
190
		    name(son(bro(e))) == name_tag) {
162
	  	/* the result of the application is being assigned to
191
			/* the result of the application is being assigned to
163
		   a name_tag */
192
			   a name_tag */
164
      var = son(bro(e));/* the destination of the ass */
193
			var = son(bro(e));	/* the destination of the ass */
165
      cond_alt = f_make_top();	/* the result is being assigned in the
194
			cond_alt = f_make_top();	/* the result is being
-
 
195
							   assigned in the body
-
 
196
							   - no need for a
166
      				   body - no need for a delivered result */
197
							   delivered result */
167
      e = bro(e); /* NOTE e CHANGED to ass_tag */
198
			e = bro(e); /* NOTE e CHANGED to ass_tag */
168
#ifdef NEWDIAGS
199
#ifdef NEWDIAGS
-
 
200
			if (diagnose) {
169
      if (diagnose) {	/* bro(son(e)) is now the call */
201
				/* bro(son(e)) is now the call */
170
	dg_whole_comp (e, bro(son(e)));
202
				dg_whole_comp(e, bro(son(e)));
171
	dgf(e) = dgf(bro(son(e)));
203
				dgf(e) = dgf(bro(son(e)));
172
      }
204
			}
173
#endif
205
#endif
174
    }
-
 
175
    else {
206
		} else {
176
      new_dec = me_start_clearvar(sha, sha);
207
			new_dec = me_start_clearvar(sha, sha);
177
      	/* make a new variable to assign to at each res_tag */
208
			/* make a new variable to assign to at each res_tag */
178
      setinlined(new_dec);	/* mark the declaration */
209
			setinlined(new_dec);	/* mark the declaration */
179
      new_var = me_obtain(new_dec);
210
			new_var = me_obtain(new_dec);
180
      var = new_var;	/* the destination of assignments
211
			var = new_var;	/* the destination of assignments
181
      			   new_var is killed at end */
212
					   new_var is killed at end */
182
      cond_alt = f_contents(sha, copy(new_var));
213
			cond_alt = f_contents(sha, copy(new_var));
183
      	/* delivers the contents of the variable - hence the value */
214
			/* delivers the contents of the variable - hence the
-
 
215
			 * value */
184
    };
216
		}
185
  };
217
	}
186
 
218
 
187
  lab = me_b3(sh(cond_alt), me_shint(sha, 0), cond_alt, labst_tag);
219
	lab = me_b3(sh(cond_alt), me_shint(sha, 0), cond_alt, labst_tag);
188
  	/* the labst for the new cond_tag we are making up */
220
	/* the labst for the new cond_tag we are making up */
189
  name(son(lab)) = clear_tag;
221
	name(son(lab)) = clear_tag;
190
 
222
 
191
  t = fn; /* start t so that its bro is the first actual parameter */
223
	t = fn;	  /* start t so that its bro is the first actual parameter */
192
  q = body;	/* start q so that its son is the first formal parameter */
224
	q = body; /* start q so that its son is the first formal parameter */
193
 
225
 
-
 
226
	while (!last(t)) {
194
  while (!last(t))	/* check actual and formal shapes */
227
		/* check actual and formal shapes */
195
    {
-
 
196
      if (name(q) != ident_tag || !isparam(q))
228
		if (name(q) != ident_tag || !isparam(q)) {
197
	return;  /* no inline if more actuals than formals */
229
			return;  /* no inline if more actuals than formals */
-
 
230
		}
198
      if (shape_size(sh(bro(t))) != shape_size(sh(son(q))))
231
		if (shape_size(sh(bro(t))) != shape_size(sh(son(q)))) {
199
        return;	/* no inlining if shapes do not match. */
232
			return;	/* no inlining if shapes do not match. */
-
 
233
		}
200
      t = bro(t);	/* next actual */
234
		t = bro(t);		/* next actual */
201
      q = bro(son(q));	/* next formal */
235
		q = bro(son(q));	/* next formal */
202
    };
236
	}
203
 
237
 
204
  if (name(q) == ident_tag && isparam(q))
238
	if (name(q) == ident_tag && isparam(q)) {
205
    return;  /* no inline if more formals than actuals */
239
		return;  /* no inline if more formals than actuals */
-
 
240
	}
206
 
241
 
207
#ifdef NEWDIAGS
242
#ifdef NEWDIAGS
208
  doing_inlining = 1;
243
	doing_inlining = 1;
209
#endif
244
#endif
210
  bc = copy_res(body, var, lab);
245
	bc = copy_res(body, var, lab);
211
  	/* copy the body, making res_tag into assignment to var and
246
	/* copy the body, making res_tag into assignment to var and
212
	   jump to lab */
247
	   jump to lab */
213
#ifdef NEWDIAGS
248
#ifdef NEWDIAGS
214
  doing_inlining = 0;
249
	doing_inlining = 0;
215
#endif
250
#endif
216
  bc = hold(bc);
251
	bc = hold(bc);
217
 
252
 
218
  if (!last(fn)) {	/* if there are any parameters */
253
	/* if there are any parameters */
-
 
254
	if (!last(fn)) {
219
    replace_pars(pars, son(bc)); /* replace formals by actuals */
255
		/* replace formals by actuals */
-
 
256
		replace_pars(pars, son(bc));
220
  }
257
	}
221
 
258
 
222
  IGNORE check(son(bc), son(bc));	/* check the result (proc_tag ?)*/
259
	IGNORE check(son(bc), son(bc));	/* check the result (proc_tag ?)*/
223
  res = son(bc); /* remove the proc_tag */
260
	res = son(bc); /* remove the proc_tag */
224
  retcell(bc);	/* and retcell it */
261
	retcell(bc);	/* and retcell it */
225
 
262
 
226
  last_act = last_action(res);
263
	last_act = last_action(res);
227
  if (no(son(lab)) == 1 && name(last_act) == goto_tag &&
264
	if (no(son(lab)) == 1 && name(last_act) == goto_tag &&
228
        pt(last_act) == lab) {
265
	    pt(last_act) == lab) {
229
     /* there is only one (final) goto replacement for return */
266
		/* there is only one (final) goto replacement for return */
230
    if (name(res) == goto_tag) {
267
		if (name(res) == goto_tag) {
231
      res = (name(sha)==tophd)?f_make_top():f_make_value(sha);
268
			res = (name(sha) == tophd) ? f_make_top() :
232
    }
269
				f_make_value(sha);
233
    else {
270
		} else {
234
      change_last_shapes(res, sh(bro(son(lab))));
271
			change_last_shapes(res, sh(bro(son(lab))));
235
#ifdef NEWDIAGS
272
#ifdef NEWDIAGS
236
      if (diagnose)
273
			if (diagnose) {
237
	dg_whole_comp (last_act, bro(son(lab)));
274
				dg_whole_comp(last_act, bro(son(lab)));
-
 
275
			}
238
#endif
276
#endif
239
      replace(last_act, bro(son(lab)), res);
277
			replace(last_act, bro(son(lab)), res);
240
    }
-
 
241
  }
278
		}
242
  else
279
	} else {
243
    res = me_b3(sh(lab), res, lab, cond_tag);
280
		res = me_b3(sh(lab), res, lab, cond_tag);
-
 
281
	}
244
  	/* make up the cond out of the substituted exp and lab */
282
	/* make up the cond out of the substituted exp and lab */
245
 
283
 
246
  if (var != nilexp)
284
	if (var != nilexp) {
247
    kill_exp(var, var);
285
		kill_exp(var, var);
-
 
286
	}
248
 
287
 
249
  if (new_var != nilexp) { /* we made up a new variable */
288
	if (new_var != nilexp) { /* we made up a new variable */
250
    SET(new_dec);
289
		SET(new_dec);
251
    if (no(new_dec) != 1) {
290
		if (no(new_dec) != 1) {
252
      res = me_complete_id(new_dec, res);	/* complete the variable def */
291
			/* complete the variable def */
253
    }
292
			res = me_complete_id(new_dec, res);
254
    else {
293
		} else {
255
      exp r = f_make_top();
294
			exp r = f_make_top();
256
#ifdef NEWDIAGS
295
#ifdef NEWDIAGS
257
      if (diagnose)
296
			if (diagnose) {
258
	dgf(r) = dgf(bro(son(lab)));
297
				dgf(r) = dgf(bro(son(lab)));
-
 
298
			}
259
#endif
299
#endif
260
      replace(bro(son(lab)), r, r);
300
			replace(bro(son(lab)), r, r);
261
    }
301
		}
262
  };
302
	}
263
 
303
 
264
 
304
 
265
#ifdef NEWDIAGS
305
#ifdef NEWDIAGS
266
  if (diagnose)
306
	if (diagnose) {
267
    dg_complete_inline (e, res);
307
		dg_complete_inline(e, res);
-
 
308
	}
268
#endif
309
#endif
269
  replace(e, res, nilexp);	/* replace the call by the inlined stuff */
310
	replace(e, res, nilexp); /* replace the call by the inlined stuff */
270
  kill_exp(fn, fn);	/* kill off the function name_tag */
311
	kill_exp(fn, fn);	 /* kill off the function name_tag */
271
 
312
 
272
  return;
313
	return;
273
}
314
}