1 /*
2 * $Id: byte-compile.c,v 1.12 2000/11/22 19:33:00 danny Exp $
3 *
4 * Copyright � 1990, 1992, 1993 Free Software Foundation, Inc.
5 *
6 * This file is part of Oleo, the GNU Spreadsheet.
7 *
8 * Oleo is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * Oleo is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with Oleo; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #ifdef WITH_DMALLOC
28 #include <dmalloc.h>
29 #endif
30
31 /* FIXME #include "funcdef.h" */
32 #include <stdio.h>
33
34 #include "sysdef.h"
35
36 #ifdef HAVE_MALLOC_H
37 #include <malloc.h>
38 #endif
39
40 #ifdef _DEBUG_MALLOC_INC
41 static void
local_free(p)42 local_free (p)
43 void * p;
44 {
45 free (p);
46 }
47 #define obstack_chunk_free local_free
48 #else /* ndef _DEBUG_MALLOC_INC */
49 #define obstack_chunk_free free
50 #endif /* ndef _DEBUG_MALLOC_INC */
51
52 #define obstack_chunk_alloc ck_malloc
53 #include "obstack.h"
54
55 #include "global.h"
56 #include "node.h"
57 #include "eval.h"
58 #include "hash.h"
59 #include "ref.h"
60
61 extern int yyparse (void);
62
63 extern struct function date_funs[];
64 extern struct function busi_funs[];
65 extern struct function string_funs[];
66 extern struct function cells_funs[];
67 extern struct function mysql_functions[];
68 extern struct function gsl_functions[];
69
70 extern char *instr;
71 extern int parse_error;
72 extern struct node *parse_return;
73 extern void sort ();
74
75 static void add_backpatch (unsigned, unsigned);
76
77 struct backpatch
78 {
79 unsigned from, to;
80 };
81
82 static struct backpatch *patches;
83 static int patches_allocated;
84 static int patches_used;
85 static void *fn_stack;
86 static void *str_stack;
87 struct obstack tmp_mem;
88 void *tmp_mem_start;
89
90
91 #define V (void(*)())
92
93 /* These have to go in some file or other, so it is stuck in here (for now).
94 */
95 struct function the_funs[] =
96 {
97 {0, X_A0, "", 0, "<END>"},
98 {0, X_A0, "", 0, "<DUMMY1>"},
99
100 {C_IF | R | INF (1), X_A1 | X_J, "D", 0, "?"},
101 {C_IF | R | INF (1), X_A1 | X_JL, "D", 0, "?"},
102 {C_IF, X_A1 | X_J, "D", 0, "if"},
103 {C_IF, X_A1 | X_JL, "D", 0, "if"},
104 {C_ANDOR, X_A1 | X_J, "D", 0, "and"},
105 /* { C_ANDOR|L|INF(3), X_A1, "DD", 0, "&" }, */
106 {C_ANDOR, X_A1 | X_JL, "D", 0, "and"},
107 /* { C_ANDOR|L|INF(3), X_A1, "DD", 0, "&" }, */
108 {C_ANDOR, X_A1 | X_J, "D", 0, "or"},
109 /* { C_ANDOR|L|INF(2), X_A1, "DD", 0, "|" }, */
110 {C_ANDOR, X_A1 | X_JL, "D", 0, "or"},
111 /* { C_ANDOR|L|INF(2), X_A1, "DD", 0, "|" }, */
112 {C_STR, X_A0 | X_J, "", 0, "\"%s\""},
113 {C_STR, X_A0 | X_JL, "", 0, "\"%s\""},
114
115 {C_CELL, X_A0, "", 0, "$%s$%u"},
116 {C_CELL, X_A0, "", 0, "$%s%u"},
117 {C_CELL, X_A0, "", 0, "%s$%u"},
118 {C_CELL, X_A0, "", 0, "%s%u"},
119 {C_RANGE, X_A0, "", 0, "$%s$%u:$%s$%u"},
120 {C_RANGE, X_A0, "", 0, "$%s%u:$%s$%u"},
121 {C_RANGE, X_A0, "", 0, "$%s$%u:$%s%u"},
122 {C_RANGE, X_A0, "", 0, "$%s%u:$%s%u"},
123 {C_RANGE, X_A0, "", 0, "%s$%u:$%s$%u"},
124 {C_RANGE, X_A0, "", 0, "%s%u:$%s$%u"},
125 {C_RANGE, X_A0, "", 0, "%s$%u:$%s%u"},
126 {C_RANGE, X_A0, "", 0, "%s%u:$%s%u"},
127 {C_RANGE, X_A0, "", 0, "$%s$%u:%s$%u"},
128 {C_RANGE, X_A0, "", 0, "$%s%u:%s$%u"},
129 {C_RANGE, X_A0, "", 0, "$%s$%u:%s%u"},
130 {C_RANGE, X_A0, "", 0, "$%s%u:%s%u"},
131 {C_RANGE, X_A0, "", 0, "%s$%u:%s$%u"},
132 {C_RANGE, X_A0, "", 0, "%s%u:%s$%u"},
133 {C_RANGE, X_A0, "", 0, "%s$%u:%s%u"},
134 {C_RANGE, X_A0, "", 0, "%s%u:%s%u"},
135
136 {C_CONST, X_A0, "", 0, tname},
137 {C_CONST, X_A0, "", 0, fname},
138
139 {C_CONST, X_A0, "", 0, iname},
140 {C_CONST, X_A0, "", 0, mname},
141 {C_CONST, X_A0, "", 0, nname},
142 {C_ERR, X_A0 | X_J, "", 0, "%s"},
143 {C_FLT, X_A0, "", 0, "%.15g"},
144 {C_INT, X_A0, "", 0, "%ld"},
145
146 {C_VAR, X_A0, "", 0, "%s"},
147
148 {C_UNA, X_A1, "F", 0, "-"},
149 {C_UNA, X_A1, "B", 0, "!"},
150
151 {C_INF | L | INF (6), X_A2, "NN", 0, "-"},
152 {C_INF | L | INF (7), X_A2, "NN", 0, "/"},
153 {C_INF | L | INF (7), X_A2, "NN", 0, "%"},
154 {C_INF | L | INF (7), X_A2, "NN", 0, "*"},
155 {C_INF | L | INF (6), X_A2, "NN", 0, "+"},
156 {C_INF | L | INF (2), X_A2, "SS", 0, "&"},
157 {C_INF | N | INF (4), X_A2, "AA", 0, "="},
158 {C_INF | N | INF (5), X_A2, "AA", 0, ">="},
159 {C_INF | N | INF (5), X_A2, "AA", 0, ">"},
160 {C_INF | N | INF (5), X_A2, "AA", 0, "<"},
161 {C_INF | N | INF (5), X_A2, "AA", 0, "<="},
162 {C_INF | N | INF (4), X_A2, "AA", 0, "!="},
163 {C_INF | R | INF (8), X_A2, "FF", V pow, "^"},
164
165 {C_FN0, X_A0, "", 0, "pi"},
166 {C_FN0X, X_A0, "", 0, "row"},
167 {C_FN0X, X_A0, "", 0, "col"},
168 {C_FN0 | C_T, X_A0, "", 0, "now"},
169
170 {C_FN1, X_A1, "F", V fabs, "abs"},
171 {C_FN1, X_A1, "F", V acos, "acos"},
172 {C_FN1, X_A1, "F", V asin, "asin"},
173 {C_FN1, X_A1, "F", V atan, "atan"},
174 {C_FN1, X_A1, "F", V ceil, "ceil"},
175 {C_FN1, X_A1, "F", V to_int, "int"},
176 {C_FN1, X_A1, "F", V floor, "floor"},
177 {C_FN1, X_A1, "F", V cos, "cos"},
178 {C_FN1, X_A1, "F", V dtr, "dtr"},
179 {C_FN1, X_A1, "F", V exp, "exp"},
180 {C_FN1, X_A1, "F", V log, "log"},
181 {C_FN1, X_A1, "F", V log10, "log10"},
182 {C_FN1, X_A1, "F", V rtd, "rtd"},
183 {C_FN1, X_A1, "F", V sin, "sin"},
184 {C_FN1, X_A1, "F", V sqrt, "sqrt"},
185 {C_FN1, X_A1, "F", V tan, "tan"},
186 {C_FN1, X_A1, "I", 0, "ctime"},
187 {C_FN1, X_A1, "A", 0, "negate"},
188 {C_FN1, X_A1, "A", 0, "not"},
189 {C_FN1, X_A1, "A", 0, "iserr"},
190 {C_FN1, X_A1, "A", 0, "isnum"},
191
192 {C_FN1 | C_T, X_A1, "I", 0, "rnd"},
193 {C_FN1, X_A1, "R", 0, "rows"},
194 {C_FN1, X_A1, "R", 0, "cols"},
195 {C_FN2, X_A2, "FF", V atan2, "atan2"},
196 #ifdef HAVE_HYPOT
197 {C_FN2, X_A2, "FF", V hypot, "hypot"},
198 #else
199 {C_FN2, X_A2, "FF", 0, "*&%$%*"},
200 #endif
201 {C_FN2, X_A2, "FI", 0, "fixed"},
202 {C_FN2, X_A2, "AA", 0, "iferr"},
203 {C_FN2, X_A2, "RI", 0, "index"},
204 {C_FN3, X_A3, "RII", 0, "index"},
205 {C_FNN, X_AN, "IAAA", 0, "oneof"},
206
207 {C_FNN, X_AN, "SIIA", 0, "file"},
208 {C_FNN, X_AN, "EEEE", 0, "sum"},
209 {C_FNN, X_AN, "EEEE", 0, "prod"},
210 {C_FNN, X_AN, "EEEE", 0, "avg"},
211 {C_FNN, X_AN, "EEEE", 0, "std"},
212 {C_FNN, X_AN, "EEEE", 0, "max"},
213 {C_FNN, X_AN, "EEEE", 0, "min"},
214 {C_FNN, X_AN, "EEEE", 0, "count"},
215 {C_FNN, X_AN, "EEEE", 0, "var"},
216
217 };
218
219 /*
220 * This is the place where you can add extra functions
221 */
222 static struct function *__usr_funs[] =
223 {
224 date_funs,
225 busi_funs,
226 string_funs,
227 cells_funs,
228 mysql_functions,
229 gsl_functions,
230 /* Add something here */
231 };
232
233 /*
234 * A small function in each module tells us how many functions
235 * it defines.
236 */
237 extern int init_date_function_count(void);
238 extern int init_busi_function_count(void);
239 extern int init_string_function_count(void);
240 extern int init_cells_function_count(void);
241 extern int init_mysql_function_count(void);
242 extern int init_gsl_function_count(void);
243 /* Add something here */
244
245 typedef int (*init_function_count)(void);
246
247 static init_function_count init_function_counts[] = {
248 &init_date_function_count,
249 &init_busi_function_count,
250 &init_string_function_count,
251 &init_cells_function_count,
252 &init_mysql_function_count,
253 &init_gsl_function_count
254 /* Add something here */
255 };
256
257 /* Determine how many groups of functions we have */
258 int n_usr_funs = sizeof(init_function_counts) / sizeof(init_function_count);
259
260 /*
261 * This is an array containing the number of functions in each group.
262 * It is allocated and initialised in init_mem() below.
263 * Previous versions of Oleo required manual maintenance of this.
264 */
265 int *usr_n_funs = NULL;
266
267 struct function **usr_funs = __usr_funs;
268
269 /* ... A whole huge empty space, then ... */
270 struct function skip_funs[] =
271 {
272 {C_SKIP, X_A0 | X_J, "", 0, "<Skip %u>"},
273 {C_SKIP, X_A0 | X_JL, "", 0, "<SkipL %u>"},
274 };
275
276 /* The memory allocated here is used for several things, but byte_compile
277 is a small file, so it might as well be here */
278 void
init_mem()279 init_mem ()
280 {
281 int n, i;
282
283 /* Initialise counters */
284 usr_n_funs = (int *)calloc(n_usr_funs, sizeof(int));
285 for (i=0; i<n_usr_funs; i++)
286 usr_n_funs[i] = init_function_counts[i]();
287
288 parse_hash = hash_new ();
289 hash_insert (parse_hash, the_funs[F_IF].fn_str, &the_funs[F_IF]);
290 hash_insert (parse_hash, the_funs[AND].fn_str, &the_funs[AND]);
291 hash_insert (parse_hash, the_funs[OR].fn_str, &the_funs[OR]);
292 for (n = F_PI; n < USR1; n++)
293 hash_insert (parse_hash, the_funs[n].fn_str, &the_funs[n]);
294
295 for (n = 0; n < n_usr_funs; n++)
296 {
297 int nn;
298
299 for (nn = 0; usr_funs[n][nn].fn_str; nn++)
300 hash_insert (parse_hash, usr_funs[n][nn].fn_str, &usr_funs[n][nn]);
301 #ifdef TEST
302 if (usr_n_funs[n] != nn)
303 {
304 fprintf (stderr, "Usr_n_funs[%d]%d!=%d", n, usr_n_funs[n], nn);
305 usr_n_funs[n] = nn;
306
307 }
308 #endif
309 }
310
311 fn_stack = init_stack ();
312 str_stack = init_stack ();
313 obstack_begin (&tmp_mem, 400);
314 tmp_mem_start = obstack_alloc (&tmp_mem, 0);
315 }
316
317 /* Stash away a backpatch for future editing. */
318 static void
add_backpatch(from,to)319 add_backpatch (from, to)
320 unsigned from;
321 unsigned to;
322 {
323 if (!patches)
324 {
325 patches_allocated = 5;
326 patches = (struct backpatch *) ck_malloc (patches_allocated * sizeof (struct backpatch));
327 patches_used = 0;
328 }
329 if (patches_allocated == patches_used)
330 {
331 patches_allocated *= 2;
332 patches = (struct backpatch *) ck_realloc (patches, patches_allocated * sizeof (struct backpatch));
333 }
334 patches[patches_used].from = from;
335 patches[patches_used].to = to;
336 patches_used++;
337 }
338
339 static int
cmp_patch(n1,n2)340 cmp_patch (n1, n2)
341 int n1;
342 int n2;
343 {
344 int ret;
345
346 ret = (patches[n1].from == patches[n2].from) ? patches[n1].to - patches[n2].to : patches[n1].from - patches[n2].from;
347 return ret;
348 }
349
350 static void
swp_patch(n1,n2)351 swp_patch (n1, n2)
352 int n1;
353 int n2;
354 {
355 struct backpatch tmp;
356
357 tmp = patches[n1];
358 patches[n1] = patches[n2];
359 patches[n2] = tmp;
360 }
361
362 static void
rot_patch(n1,n2)363 rot_patch (n1, n2)
364 int n1;
365 int n2;
366 {
367 struct backpatch tmp;
368 tmp = patches[n2];
369 while (n2 > n1)
370 {
371 patches[n2] = patches[n2 - 1];
372 --n2;
373 }
374 patches[n2] = tmp;
375 }
376
377
378 /* This takes an ascii string and returns a pointer to the byte-compiled
379 result. It calls yyparse() to do the actual parsing. This is complicated
380 only because yyparse returns a parse tree which needs to be turned into
381 postfix compiled bytes. This is further complicated by the presence of
382 forward branches in the byte-compiled code. That's what the backpatch
383 stuff is for.
384
385 It'd be nice if oneof() could compile into
386 arg1
387 ONEOF n_possibilities
388 JUMP poss1
389 JUMP poss2
390 JUMP poss3
391 ...
392 JUMP error
393 {poss 1}
394 JUMP end
395 {poss 2}
396 JUMP end
397 ...
398 end: {rest of expression}
399 instead of the simplistic (and slow-to-execute) version currently used
400
401 It'd also be nice if byte-compiled expressions could have *BIG*
402 subexpressions, instead of silently failing as they do now. Error checking
403 and a way to encode longer branches would be a *good* idea.
404 */
405 unsigned char *
parse_and_compile(string)406 parse_and_compile (string)
407 char *string;
408 {
409 struct node *new_node;
410 struct node *node;
411 const struct function *f;
412 unsigned char *ret;
413 int n;
414 unsigned buf_siz;
415 int need_relax;
416 int byte;
417
418 instr = string;
419 parse_error = 0;
420 patches_used = 0;
421 if (yyparse () || parse_error)
422 {
423 ret = ck_malloc (strlen (string) + 5);
424 ret[0] = CONST_ERR;
425 ret[1] = 2;
426 ret[2] = parse_error;
427 ret[3] = ENDCOMP;
428 strcpy ((char *) &ret[4], string);
429 (void) obstack_free (&tmp_mem, tmp_mem_start);
430 return ret;
431 }
432
433 node = parse_return;
434 if (!node)
435 return 0;
436
437 loop:
438 if (node->comp_value < USR1)
439 {
440 f = &the_funs[node->comp_value];
441 }
442 else if (node->comp_value < SKIP)
443 {
444 n = node->sub_value;
445 f = &usr_funs[node->comp_value - USR1][n];
446 }
447 else
448 {
449 f = &skip_funs[node->comp_value - SKIP];
450 }
451 byte = node->comp_value;
452
453 #ifdef TEST
454 if (!f)
455 panic ("f is zero in byte_compile!");
456 #endif
457 switch (GET_COMP (f->fn_comptype))
458 {
459 case C_IF:
460 /* if compiles to
461 test-code IF amt-to-skip-on-false true-code SKIP
462 amt-to-skip-on-true false-code */
463 if (node->n_x.v_subs[0])
464 {
465 if (node->n_x.v_subs[0]->n_x.v_subs[0])
466 {
467 /* Put out the test-code */
468 push_stack (fn_stack, node);
469 new_node = node->n_x.v_subs[0]->n_x.v_subs[0];
470 node->n_x.v_subs[0]->n_x.v_subs[0] = 0;
471 node = new_node;
472 goto loop;
473 }
474 /* Put out IF, null-byte to backpatch */
475 (void) obstack_1grow (&tmp_mem, byte);
476 node->add_byte = obstack_object_size (&tmp_mem);
477 (void) obstack_1grow (&tmp_mem, 0);
478
479 /* put out true-code */
480 push_stack (fn_stack, node);
481 new_node = node->n_x.v_subs[0]->n_x.v_subs[1];
482 node->n_x.v_subs[0] = 0;
483 node = new_node;
484 goto loop;
485 }
486 if (node->n_x.v_subs[1])
487 {
488
489 (void) obstack_1grow (&tmp_mem, (char)SKIP);
490 (void) obstack_1grow (&tmp_mem, 0);
491 add_backpatch (node->add_byte, obstack_object_size (&tmp_mem));
492 node->add_byte = obstack_object_size (&tmp_mem) - 1;
493
494 push_stack (fn_stack, node);
495 new_node = node->n_x.v_subs[1];
496 node->n_x.v_subs[1] = 0;
497 node = new_node;
498 goto loop;
499 }
500 add_backpatch (node->add_byte, obstack_object_size (&tmp_mem));
501 break;
502
503 case C_ANDOR:
504 if (node->n_x.v_subs[0])
505 {
506 push_stack (fn_stack, node);
507 new_node = node->n_x.v_subs[0];
508 node->n_x.v_subs[0] = 0;
509 node = new_node;
510 goto loop;
511 }
512 if (node->n_x.v_subs[1])
513 {
514 (void) obstack_1grow (&tmp_mem, byte);
515 node->add_byte = obstack_object_size (&tmp_mem);
516 (void) obstack_1grow (&tmp_mem, 0); /* for backpatching */
517 push_stack (fn_stack, node);
518 new_node = node->n_x.v_subs[1];
519 node->n_x.v_subs[1] = 0;
520 node = new_node;
521 goto loop;
522 }
523 add_backpatch (node->add_byte, obstack_object_size (&tmp_mem));
524 break;
525
526 case C_ERR:
527 (void) obstack_1grow (&tmp_mem, byte);
528 node->add_byte = obstack_object_size (&tmp_mem);
529 (void) obstack_1grow (&tmp_mem, 0);
530 (void) obstack_1grow (&tmp_mem, node->n_x.v_int);
531 node->n_x.v_string = ename[node->n_x.v_int];
532 push_stack (str_stack, node);
533 break;
534
535 case C_FLT:
536 (void) obstack_1grow (&tmp_mem, byte);
537 (void) obstack_grow (&tmp_mem, &(node->n_x.v_float), sizeof (double));
538 break;
539
540 case C_INT:
541 (void) obstack_1grow (&tmp_mem, byte);
542 (void) obstack_grow (&tmp_mem, &(node->n_x.v_int), sizeof (long));
543 break;
544
545 case C_STR:
546 (void) obstack_1grow (&tmp_mem, byte);
547 node->add_byte = obstack_object_size (&tmp_mem);
548 (void) obstack_1grow (&tmp_mem, 0);
549 push_stack (str_stack, node);
550 break;
551
552 case C_VAR:
553 add_ref_to (obstack_object_size (&tmp_mem));
554 add_var_ref (node->n_x.v_var);
555 (void) obstack_1grow (&tmp_mem, byte);
556 (void) obstack_grow (&tmp_mem, &(node->n_x.v_var), sizeof (struct var *));
557 break;
558
559 case C_CELL:
560 add_ref_to (obstack_object_size (&tmp_mem));
561 add_ref (node->n_x.v_rng.lr, node->n_x.v_rng.lc);
562 (void) obstack_1grow (&tmp_mem, byte);
563 #if BITS_PER_CELLREF==16
564 (void) obstack_1grow (&tmp_mem, node->n_x.v_rng.lr >> 8);
565 (void) obstack_1grow (&tmp_mem, node->n_x.v_rng.lr);
566 (void) obstack_1grow (&tmp_mem, node->n_x.v_rng.lc >> 8);
567 (void) obstack_1grow (&tmp_mem, node->n_x.v_rng.lc);
568 #else
569 #if BITS_PER_CELLREF==8
570 (void) obstack_1grow (&tmp_mem, node->n_x.v_rng.lr);
571 (void) obstack_1grow (&tmp_mem, node->n_x.v_rng.lc);
572 #else
573 Insert appropriate code here
574 #endif
575 #endif
576 break;
577
578 case C_RANGE:
579 add_ref_to (obstack_object_size (&tmp_mem));
580 add_range_ref (&(node->n_x.v_rng));
581 (void) obstack_1grow (&tmp_mem, byte);
582 (void) obstack_grow (&tmp_mem, &(node->n_x.v_rng), sizeof (struct rng));
583 break;
584
585 case C_FN0X:
586 add_ref_to (obstack_object_size (&tmp_mem));
587 /* FALLTHROUGH */
588 case C_FN0:
589 case C_CONST:
590 add_byte:
591 if (f->fn_comptype & C_T)
592 add_timer_ref (obstack_object_size (&tmp_mem));
593 (void) obstack_1grow (&tmp_mem, byte);
594 if (byte >= USR1 && byte < SKIP)
595 (void) obstack_1grow (&tmp_mem, (int) node->sub_value);
596 break;
597
598 case C_FN1:
599 case C_UNA:
600 if (node->n_x.v_subs[0])
601 {
602 push_stack (fn_stack, node);
603 new_node = node->n_x.v_subs[0];
604 node->n_x.v_subs[0] = 0;
605 node = new_node;
606 goto loop;
607 }
608 goto add_byte;
609
610 case C_FN2:
611 case C_INF:
612 if (node->n_x.v_subs[0])
613 {
614 push_stack (fn_stack, node);
615 new_node = node->n_x.v_subs[0];
616 node->n_x.v_subs[0] = 0;
617 node = new_node;
618 goto loop;
619 }
620 if (node->n_x.v_subs[1])
621 {
622 push_stack (fn_stack, node);
623 new_node = node->n_x.v_subs[1];
624 node->n_x.v_subs[1] = 0;
625 node = new_node;
626 goto loop;
627 }
628 goto add_byte;
629
630 case C_FN3:
631 if (node->n_x.v_subs[0])
632 {
633 if (node->n_x.v_subs[0]->n_x.v_subs[0])
634 {
635 push_stack (fn_stack, node);
636 new_node = node->n_x.v_subs[0]->n_x.v_subs[0];
637 node->n_x.v_subs[0]->n_x.v_subs[0] = 0;
638 node = new_node;
639 goto loop;
640 }
641 push_stack (fn_stack, node);
642 new_node = node->n_x.v_subs[0]->n_x.v_subs[1];
643 node->n_x.v_subs[0] = 0;
644 node = new_node;
645 goto loop;
646 }
647 if (node->n_x.v_subs[1])
648 {
649 push_stack (fn_stack, node);
650 new_node = node->n_x.v_subs[1];
651 node->n_x.v_subs[1] = 0;
652 node = new_node;
653 goto loop;
654 }
655 goto add_byte;
656
657 case C_FN4:
658 if (node->n_x.v_subs[0])
659 {
660 if (node->n_x.v_subs[0]->n_x.v_subs[0])
661 {
662 push_stack (fn_stack, node);
663 new_node = node->n_x.v_subs[0]->n_x.v_subs[0];
664 node->n_x.v_subs[0]->n_x.v_subs[0] = 0;
665 node = new_node;
666 goto loop;
667 }
668 push_stack (fn_stack, node);
669 new_node = node->n_x.v_subs[0]->n_x.v_subs[1];
670 node->n_x.v_subs[0] = 0;
671 node = new_node;
672 goto loop;
673 }
674 if (node->n_x.v_subs[1])
675 {
676 if (node->n_x.v_subs[1]->n_x.v_subs[0])
677 {
678 push_stack (fn_stack, node);
679 new_node = node->n_x.v_subs[1]->n_x.v_subs[0];
680 node->n_x.v_subs[1]->n_x.v_subs[0] = 0;
681 node = new_node;
682 goto loop;
683 }
684 push_stack (fn_stack, node);
685 new_node = node->n_x.v_subs[1]->n_x.v_subs[1];
686 node->n_x.v_subs[1] = 0;
687 node = new_node;
688 goto loop;
689 }
690 goto add_byte;
691
692 case C_FNN:
693 if (node->n_x.v_subs[1])
694 {
695 if (node->add_byte == 0)
696 for (new_node = node; new_node->n_x.v_subs[1]; new_node = new_node->n_x.v_subs[1])
697 node->add_byte++;
698 for (new_node = node; new_node->n_x.v_subs[1]->n_x.v_subs[1]; new_node = new_node->n_x.v_subs[1])
699 ;
700 push_stack (fn_stack, node);
701 node = new_node->n_x.v_subs[1]->n_x.v_subs[0];
702 new_node->n_x.v_subs[1] = 0;
703 goto loop;
704 }
705 (void) obstack_1grow (&tmp_mem, byte);
706 if (byte >= USR1 && byte < SKIP)
707 (void) obstack_1grow (&tmp_mem, (int) node->sub_value);
708 (void) obstack_1grow (&tmp_mem, node->add_byte);
709 break;
710
711 default:
712 panic ("Bad comptype %d", f->fn_comptype);
713 }
714 node = (struct node *) pop_stack (fn_stack);
715 if (node)
716 goto loop;
717
718 (void) obstack_1grow (&tmp_mem, 0);
719
720 while ((node = (pop_stack (str_stack))))
721 {
722 add_backpatch (node->add_byte, obstack_object_size (&tmp_mem));
723 (void) obstack_grow (&tmp_mem, node->n_x.v_string, strlen (node->n_x.v_string) + 1);
724 }
725
726 buf_siz = obstack_object_size (&tmp_mem);
727 ret = (unsigned char *) ck_malloc (buf_siz);
728 bcopy (obstack_finish (&tmp_mem), ret, buf_siz);
729
730 need_relax = 0;
731 for (n = 0; n < patches_used; n++)
732 {
733 long offset;
734
735 offset = (patches[n].to - patches[n].from) - 1;
736 if (offset < 0 || offset > 255)
737 need_relax++;
738 else
739 ret[patches[n].from] = offset;
740 }
741 if (need_relax)
742 {
743 int n_lo;
744 long offset;
745 int start;
746
747 /* ... Sort the patches list ... */
748 sort (patches_used, cmp_patch, swp_patch, rot_patch);
749
750 while (need_relax)
751 {
752 ret = ck_realloc (ret, buf_siz + need_relax);
753 for (n_lo = 0; n_lo < patches_used; n_lo++)
754 {
755 offset = (patches[n_lo].to - patches[n_lo].from) - 1;
756 if (offset < 0 || offset > 255 - need_relax)
757 break;
758 }
759
760 /* n_lo points to the first jump that may need to be relaxed */
761 for (n = n_lo; n < patches_used; n++)
762 {
763 offset = (patches[n].to - patches[n].from) - 1;
764 if (offset < 0 || offset > 255)
765 {
766 int nn;
767
768 start = patches[n].from;
769
770 ret[start - 1]++; /* Translate insn to LONG */
771 ret[start] = offset;
772 bcopy (&ret[start + 1], &ret[start + 2], buf_siz - start);
773 ret[start + 1] = offset >> 8;
774 need_relax--;
775 buf_siz++;
776 for (nn = 0; nn < patches_used; nn++)
777 {
778 if (patches[nn].from > start)
779 patches[nn].from++;
780 if (patches[nn].to > start)
781 patches[nn].to++;
782 if (patches[nn].from < start && patches[nn].to > start && ret[patches[nn].from]++ == 255)
783 {
784 if (ret[patches[nn].from - 1] & 01)
785 ret[patches[nn].from + 1]++;
786 else
787 need_relax++;
788 }
789 }
790 }
791 }
792 }
793 }
794
795 (void) obstack_free (&tmp_mem, tmp_mem_start);
796
797 patches_used = 0;
798
799 return ret;
800 }
801
802 /* Back when strings stored a char*, they needed to be freed when a
803 byte-compiled expression was freed. Now that they're appended to the end,
804 they don't need to be specially freed anymore.
805 */
806 void
byte_free(form)807 byte_free (form)
808 unsigned char *form;
809 {
810 /* no longer needed
811 unsigned char *f;
812
813 for(f=form;*f;f++) {
814 switch(*f) {
815 case IF:
816 case F_IF:
817 case SKIP:
818 case AND:
819 case OR:
820 case CONST_STR:
821 f++;
822 break;
823 case CONST_INT:
824 f+=sizeof(long);
825 break;
826 case CONST_FLT:
827 f+=sizeof(double);
828 break;
829 case VAR:
830 f+=sizeof(struct var *);
831 break;
832 case R_CELL:
833 case R_CELL|ROWREL:
834 case R_CELL|COLREL:
835 case R_CELL|ROWREL|COLREL:
836 f+=EXP_ADD;
837 break;
838 case RANGE:
839 case RANGE|LRREL:
840 case RANGE|LRREL|LCREL:
841 case RANGE|LRREL|LCREL|HCREL:
842 case RANGE|LRREL|HCREL:
843 case RANGE|LRREL|HRREL:
844 case RANGE|LRREL|HRREL|LCREL:
845 case RANGE|LRREL|HRREL|LCREL|HCREL:
846 case RANGE|LRREL|HRREL|HCREL:
847 case RANGE|HRREL:
848 case RANGE|HRREL|LCREL:
849 case RANGE|HRREL|LCREL|HCREL:
850 case RANGE|HRREL|HCREL:
851 case RANGE|LCREL:
852 case RANGE|LCREL|HCREL:
853 case RANGE|HCREL:
854 f+=EXP_ADD_RNG;
855 break;
856 case F_PRINTF:
857 case F_CONCAT:
858 case F_ONEOF:
859 case F_STRSTR:
860 case F_EDIT:
861 case AREA_SUM:
862 case AREA_PROD:
863 case AREA_AVG:
864 case AREA_STD:
865 case AREA_MAX:
866 case AREA_MIN:
867 case AREA_CNT:
868 case AREA_VAR:
869 f++;
870 break;
871 default:
872 break;
873 }
874 } */
875 free (form);
876 }
877
878 /* This tries to tell if a byte-compiled expression is a constant. If it
879 is a constant, we can free it, and never try to recompute its value.
880 This returns non-zero if the expression is constant.*/
881 int
is_constant(bytes)882 is_constant (bytes)
883 unsigned char *bytes;
884 {
885 /* It's constant, but it's already been dealt with.
886 Pretend it isn't. */
887 if (!bytes)
888 return 0;
889
890 switch (bytes[0])
891 {
892 case CONST_ERR:
893 return (bytes[3] == 0 && !strcmp ((char *) bytes + 4, ename[bytes[2]]));
894 case CONST_INT:
895 return bytes[sizeof (long) + 1] == ENDCOMP;
896 case CONST_FLT:
897 return bytes[sizeof (double) + 1] == ENDCOMP;
898 case CONST_STR:
899 return bytes[2] == ENDCOMP;
900 case F_TRUE:
901 case F_FALSE:
902 case CONST_INF:
903 case CONST_NINF:
904 case CONST_NAN:
905 return bytes[1] == ENDCOMP;
906 default:
907 return 0;
908 }
909 }
910