1 /* load.c: This code "loads" code into the code segments. */
3 /* This file is part of GNU bc.
4 Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License , or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not, write to
18 The Free Software Foundation, Inc.
19 59 Temple Place, Suite 330
22 You may contact the author by:
23 e-mail: philnelson@acm.org
24 us-mail: Philip A. Nelson
25 Computer Science Department, 9062
26 Western Washington University
27 Bellingham, WA 98226-9062
29 *************************************************************************/
37 program_counter load_adr;
41 /* Initialize the load sequence. */
52 /* addbyte adds one BYTE to the current code segment. */
61 /* If there was an error, don't continue. */
62 if (had_error) return;
64 /* Calculate the segment and offset. */
65 pc = load_adr.pc_addr++;
66 f = &functions[load_adr.pc_func];
68 if (pc >= f->f_body_size)
71 new_body = (char *) bc_malloc (f->f_body_size);
72 memcpy(new_body, f->f_body, f->f_body_size/2);
83 /* Define a label LAB to be the current program counter. */
90 int group, offset, func;
92 /* Get things ready. */
93 group = lab >> BC_LABEL_LOG;
94 offset = lab % BC_LABEL_GROUP;
95 func = load_adr.pc_func;
97 /* Make sure there is at least one label group. */
98 if (functions[func].f_label == NULL)
100 functions[func].f_label =
101 (bc_label_group *) bc_malloc (sizeof(bc_label_group));
102 functions[func].f_label->l_next = NULL;
105 /* Add the label group. */
106 temp = functions[func].f_label;
109 if (temp->l_next == NULL)
111 temp->l_next = (bc_label_group *) bc_malloc (sizeof(bc_label_group));
112 temp->l_next->l_next = NULL;
119 temp->l_adrs [offset] = load_adr.pc_addr;
122 /* Several instructions have integers in the code. They
123 are all known to be legal longs. So, no error code
124 is added. STR is the pointer to the load string and
125 must be moved to the last non-digit character. */
138 while (isdigit((int)(**str)))
139 val = val*10 + *(*str)++ - '0';
148 /* load_code loads the CODE into the machine. */
155 long ap_name; /* auto or parameter name. */
157 long vaf_name; /* variable, array or function number. */
159 static program_counter save_adr;
167 /* If there was an error, don't continue. */
168 if (had_error) return;
172 if (*str == '"') load_str = FALSE;
192 addbyte (*str++ + 10 - 'A');
194 addbyte (*str++ - '0');
202 case '"': /* Starts a string. */
206 case 'N': /* A label */
208 label_no = long_val (&str);
209 def_label (label_no);
212 case 'B': /* Branch to label. */
213 case 'J': /* Jump to label. */
214 case 'Z': /* Branch Zero to label. */
216 label_no = long_val (&str);
217 if (label_no > 65535L)
218 { /* Better message? */
219 fprintf (stderr,"Program too big.\n");
222 addbyte ( (char) (label_no & 0xFF));
223 addbyte ( (char) (label_no >> 8));
226 case 'F': /* A function, get the name and initialize it. */
228 func = long_val (&str);
231 printf ("Loading function number %d\n", func);
233 /* get the parameters */
234 while (*str++ != '.')
244 ap_name = long_val (&str);
246 printf ("var parameter number %d\n", ap_name);
248 functions[(int)func].f_params =
249 nextarg (functions[(int)func].f_params, ap_name,
254 ap_name = long_val (&str);
256 printf ("parameter number %d\n", ap_name);
258 functions[(int)func].f_params =
259 nextarg (functions[(int)func].f_params, ap_name,
264 /* get the auto vars */
267 if (*str == ',') str++;
268 ap_name = long_val (&str);
270 printf ("auto number %d\n", ap_name);
272 functions[(int)func].f_autos =
273 nextarg (functions[(int)func].f_autos, ap_name, FALSE);
276 load_adr.pc_func = func;
277 load_adr.pc_addr = 0;
280 case ']': /* A function end */
281 functions[load_adr.pc_func].f_defined = TRUE;
285 case 'C': /* Call a function. */
287 func = long_val (&str);
289 addbyte ( (char) func);
292 addbyte (((func >> 8) & 0xff) | 0x80);
293 addbyte (func & 0xff);
295 if (*str == ',') str++;
301 case 'c': /* Call a special function. */
306 case 'K': /* A constant.... may have an "F" in it. */
311 case 'd': /* Decrement. */
312 case 'i': /* Increment. */
313 case 'l': /* Load. */
314 case 's': /* Store. */
315 case 'A': /* Array Increment */
316 case 'M': /* Array Decrement */
317 case 'L': /* Array Load */
318 case 'S': /* Array Store */
320 vaf_name = long_val (&str);
325 addbyte (((vaf_name >> 8) & 0xff) | 0x80);
326 addbyte (vaf_name & 0xff);
330 case '@': /* A command! */
342 case '\n': /* Ignore the newlines */
345 default: /* Anything else */