00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "bcdefs.h"
00030 #include "global.h"
00031 #include "proto.h"
00032
00033
00034
00035
00036 void
00037 init_storage ()
00038 {
00039
00040
00041 f_count = 0;
00042 more_functions ();
00043 f_names[0] = "(main)";
00044
00045
00046 v_count = 0;
00047 more_variables ();
00048
00049
00050 a_count = 0;
00051 more_arrays ();
00052
00053
00054 ex_stack = NULL;
00055 fn_stack = NULL;
00056 i_base = 10;
00057 o_base = 10;
00058 scale = 0;
00059 c_code = FALSE;
00060 init_numbers();
00061 }
00062
00063
00064
00065
00066 void
00067 more_functions (VOID)
00068 {
00069 int old_count;
00070 int indx1, indx2;
00071 bc_function *old_f;
00072 bc_function *f;
00073 char **old_names;
00074
00075
00076 old_count = f_count;
00077 old_f = functions;
00078 old_names = f_names;
00079
00080
00081 f_count += STORE_INCR;
00082 functions = (bc_function *) bc_malloc (f_count*sizeof (bc_function));
00083 f_names = (char **) bc_malloc (f_count*sizeof (char *));
00084
00085
00086 for (indx1 = 0; indx1 < old_count; indx1++)
00087 {
00088 functions[indx1] = old_f[indx1];
00089 f_names[indx1] = old_names[indx1];
00090 }
00091
00092
00093 for (; indx1 < f_count; indx1++)
00094 {
00095 f = &functions[indx1];
00096 f->f_defined = FALSE;
00097 for (indx2 = 0; indx2 < BC_MAX_SEGS; indx2++)
00098 f->f_body [indx2] = NULL;
00099 f->f_code_size = 0;
00100 f->f_label = NULL;
00101 f->f_autos = NULL;
00102 f->f_params = NULL;
00103 }
00104
00105
00106 if (old_count != 0)
00107 {
00108 free (old_f);
00109 free (old_names);
00110 }
00111 }
00112
00113 void
00114 more_variables ()
00115 {
00116 int indx;
00117 int old_count;
00118 bc_var **old_var;
00119 char **old_names;
00120
00121
00122 old_count = v_count;
00123 old_var = variables;
00124 old_names = v_names;
00125
00126
00127 v_count += STORE_INCR;
00128 variables = (bc_var **) bc_malloc (v_count*sizeof(bc_var *));
00129 v_names = (char **) bc_malloc (v_count*sizeof(char *));
00130
00131
00132 for (indx = 3; indx < old_count; indx++)
00133 variables[indx] = old_var[indx];
00134
00135
00136 for (; indx < v_count; indx++)
00137 variables[indx] = NULL;
00138
00139
00140 if (old_count != 0)
00141 {
00142 free (old_var);
00143 free (old_names);
00144 }
00145 }
00146
00147 void
00148 more_arrays ()
00149 {
00150 int indx;
00151 int old_count;
00152 bc_var_array **old_ary;
00153 char **old_names;
00154
00155
00156 old_count = a_count;
00157 old_ary = arrays;
00158 old_names = a_names;
00159
00160
00161 a_count += STORE_INCR;
00162 arrays = (bc_var_array **) bc_malloc (a_count*sizeof(bc_var_array *));
00163 a_names = (char **) bc_malloc (a_count*sizeof(char *));
00164
00165
00166 for (indx = 1; indx < old_count; indx++)
00167 arrays[indx] = old_ary[indx];
00168
00169
00170
00171 for (; indx < v_count; indx++)
00172 arrays[indx] = NULL;
00173
00174
00175 if (old_count != 0)
00176 {
00177 free (old_ary);
00178 free (old_names);
00179 }
00180 }
00181
00182
00183
00184
00185 void
00186 clear_func (func)
00187 char func;
00188 {
00189 bc_function *f;
00190 int indx;
00191 bc_label_group *lg;
00192
00193
00194 f = &functions[func];
00195 f->f_defined = FALSE;
00196
00197
00198 for (indx = 0; indx < BC_MAX_SEGS; indx++)
00199 {
00200 if (f->f_body[indx] != NULL)
00201 {
00202 free (f->f_body[indx]);
00203 f->f_body[indx] = NULL;
00204 }
00205 }
00206
00207 f->f_code_size = 0;
00208 if (f->f_autos != NULL)
00209 {
00210 free_args (f->f_autos);
00211 f->f_autos = NULL;
00212 }
00213 if (f->f_params != NULL)
00214 {
00215 free_args (f->f_params);
00216 f->f_params = NULL;
00217 }
00218 while (f->f_label != NULL)
00219 {
00220 lg = f->f_label->l_next;
00221 free (f->f_label);
00222 f->f_label = lg;
00223 }
00224 }
00225
00226
00227
00228
00229 int
00230 fpop()
00231 {
00232 fstack_rec *temp;
00233 int retval;
00234
00235 if (fn_stack != NULL)
00236 {
00237 temp = fn_stack;
00238 fn_stack = temp->s_next;
00239 retval = temp->s_val;
00240 free (temp);
00241 }
00242 return (retval);
00243 }
00244
00245
00246
00247
00248 void
00249 fpush (val)
00250 int val;
00251 {
00252 fstack_rec *temp;
00253
00254 temp = (fstack_rec *) bc_malloc (sizeof (fstack_rec));
00255 temp->s_next = fn_stack;
00256 temp->s_val = val;
00257 fn_stack = temp;
00258 }
00259
00260
00261
00262
00263 void
00264 pop ()
00265 {
00266 estack_rec *temp;
00267
00268 if (ex_stack != NULL)
00269 {
00270 temp = ex_stack;
00271 ex_stack = temp->s_next;
00272 free_num (&temp->s_num);
00273 free (temp);
00274 }
00275 }
00276
00277
00278
00279
00280 void
00281 push_copy (num)
00282 bc_num num;
00283 {
00284 estack_rec *temp;
00285
00286 temp = (estack_rec *) bc_malloc (sizeof (estack_rec));
00287 temp->s_num = copy_num (num);
00288 temp->s_next = ex_stack;
00289 ex_stack = temp;
00290 }
00291
00292
00293
00294
00295 void
00296 push_num (num)
00297 bc_num num;
00298 {
00299 estack_rec *temp;
00300
00301 temp = (estack_rec *) bc_malloc (sizeof (estack_rec));
00302 temp->s_num = num;
00303 temp->s_next = ex_stack;
00304 ex_stack = temp;
00305 }
00306
00307
00308
00309
00310
00311
00312 char
00313 check_stack (depth)
00314 int depth;
00315 {
00316 estack_rec *temp;
00317
00318 temp = ex_stack;
00319 while ((temp != NULL) && (depth > 0))
00320 {
00321 temp = temp->s_next;
00322 depth--;
00323 }
00324 if (depth > 0)
00325 {
00326 rt_error ("Stack error.");
00327 return FALSE;
00328 }
00329 return TRUE;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339 bc_var *
00340 get_var (var_name)
00341 int var_name;
00342 {
00343 bc_var *var_ptr;
00344
00345 var_ptr = variables[var_name];
00346 if (var_ptr == NULL)
00347 {
00348 var_ptr = variables[var_name] = (bc_var *) bc_malloc (sizeof (bc_var));
00349 init_num (&var_ptr->v_value);
00350 }
00351 return var_ptr;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361 bc_num *
00362 get_array_num (var_index, index)
00363 int var_index;
00364 long index;
00365 {
00366 bc_var_array *ary_ptr;
00367 bc_array *a_var;
00368 bc_array_node *temp;
00369 int log, ix, ix1;
00370 int sub [NODE_DEPTH];
00371
00372
00373 ary_ptr = arrays[var_index];
00374 if (ary_ptr == NULL)
00375 {
00376 ary_ptr = arrays[var_index] =
00377 (bc_var_array *) bc_malloc (sizeof (bc_var_array));
00378 ary_ptr->a_value = NULL;
00379 ary_ptr->a_next = NULL;
00380 ary_ptr->a_param = FALSE;
00381 }
00382
00383 a_var = ary_ptr->a_value;
00384 if (a_var == NULL) {
00385 a_var = ary_ptr->a_value = (bc_array *) bc_malloc (sizeof (bc_array));
00386 a_var->a_tree = NULL;
00387 a_var->a_depth = 0;
00388 }
00389
00390
00391 sub[0] = index & NODE_MASK;
00392 ix = index >> NODE_SHIFT;
00393 log = 1;
00394 while (ix > 0 || log < a_var->a_depth)
00395 {
00396 sub[log] = ix & NODE_MASK;
00397 ix >>= NODE_SHIFT;
00398 log++;
00399 }
00400
00401
00402 while (log > a_var->a_depth)
00403 {
00404 temp = (bc_array_node *) bc_malloc (sizeof(bc_array_node));
00405 if (a_var->a_depth != 0)
00406 {
00407 temp->n_items.n_down[0] = a_var->a_tree;
00408 for (ix=1; ix < NODE_SIZE; ix++)
00409 temp->n_items.n_down[ix] = NULL;
00410 }
00411 else
00412 {
00413 for (ix=0; ix < NODE_SIZE; ix++)
00414 temp->n_items.n_num[ix] = copy_num(_zero_);
00415 }
00416 a_var->a_tree = temp;
00417 a_var->a_depth++;
00418 }
00419
00420
00421 temp = a_var->a_tree;
00422 while ( log-- > 1)
00423 {
00424 ix1 = sub[log];
00425 if (temp->n_items.n_down[ix1] == NULL)
00426 {
00427 temp->n_items.n_down[ix1] =
00428 (bc_array_node *) bc_malloc (sizeof(bc_array_node));
00429 temp = temp->n_items.n_down[ix1];
00430 if (log > 1)
00431 for (ix=0; ix < NODE_SIZE; ix++)
00432 temp->n_items.n_down[ix] = NULL;
00433 else
00434 for (ix=0; ix < NODE_SIZE; ix++)
00435 temp->n_items.n_num[ix] = copy_num(_zero_);
00436 }
00437 else
00438 temp = temp->n_items.n_down[ix1];
00439 }
00440
00441
00442 return &(temp->n_items.n_num[sub[0]]);
00443 }
00444
00445
00446
00447
00448
00449 void
00450 store_var (var_name)
00451 int var_name;
00452 {
00453 bc_var *var_ptr;
00454 long temp;
00455 char toobig;
00456
00457 if (var_name > 2)
00458 {
00459
00460 var_ptr = get_var (var_name);
00461 if (var_ptr != NULL)
00462 {
00463 free_num(&var_ptr->v_value);
00464 var_ptr->v_value = copy_num (ex_stack->s_num);
00465 }
00466 }
00467 else
00468 {
00469
00470 toobig = FALSE;
00471 if (is_neg (ex_stack->s_num))
00472 {
00473 switch (var_name)
00474 {
00475 case 0:
00476 rt_warn ("negative ibase, set to 2");
00477 temp = 2;
00478 break;
00479 case 1:
00480 rt_warn ("negative obase, set to 2");
00481 temp = 2;
00482 break;
00483 case 2:
00484 rt_warn ("negative scale, set to 0");
00485 temp = 0;
00486 break;
00487 }
00488 }
00489 else
00490 {
00491 temp = num2long (ex_stack->s_num);
00492 if (!is_zero (ex_stack->s_num) && temp == 0)
00493 toobig = TRUE;
00494 }
00495 switch (var_name)
00496 {
00497 case 0:
00498 if (temp < 2 && !toobig)
00499 {
00500 i_base = 2;
00501 rt_warn ("ibase too small, set to 2");
00502 }
00503 else
00504 if (temp > 16 || toobig)
00505 {
00506 i_base = 16;
00507 rt_warn ("ibase too large, set to 16");
00508 }
00509 else
00510 i_base = (int) temp;
00511 break;
00512
00513 case 1:
00514 if (temp < 2 && !toobig)
00515 {
00516 o_base = 2;
00517 rt_warn ("obase too small, set to 2");
00518 }
00519 else
00520 if (temp > BC_BASE_MAX || toobig)
00521 {
00522 o_base = BC_BASE_MAX;
00523 rt_warn ("obase too large, set to %d", BC_BASE_MAX);
00524 }
00525 else
00526 o_base = (int) temp;
00527 break;
00528
00529 case 2:
00530
00531
00532 if (temp > BC_SCALE_MAX || toobig )
00533 {
00534 scale = BC_SCALE_MAX;
00535 rt_warn ("scale too large, set to %d", BC_SCALE_MAX);
00536 }
00537 else
00538 scale = (int) temp;
00539 }
00540 }
00541 }
00542
00543
00544
00545
00546
00547
00548 void
00549 store_array (var_name)
00550 int var_name;
00551 {
00552 bc_num *num_ptr;
00553 long index;
00554
00555 if (!check_stack(2)) return;
00556 index = num2long (ex_stack->s_next->s_num);
00557 if (index < 0 || index > BC_DIM_MAX ||
00558 (index == 0 && !is_zero(ex_stack->s_next->s_num)))
00559 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
00560 else
00561 {
00562 num_ptr = get_array_num (var_name, index);
00563 if (num_ptr != NULL)
00564 {
00565 free_num (num_ptr);
00566 *num_ptr = copy_num (ex_stack->s_num);
00567 free_num (&ex_stack->s_next->s_num);
00568 ex_stack->s_next->s_num = ex_stack->s_num;
00569 init_num (&ex_stack->s_num);
00570 pop();
00571 }
00572 }
00573 }
00574
00575
00576
00577
00578
00579 void
00580 load_var (var_name)
00581 int var_name;
00582 {
00583 bc_var *var_ptr;
00584
00585 switch (var_name)
00586 {
00587
00588 case 0:
00589
00590 push_copy (_zero_);
00591 int2num (&ex_stack->s_num, i_base);
00592 break;
00593
00594 case 1:
00595
00596 push_copy (_zero_);
00597 int2num (&ex_stack->s_num, o_base);
00598 break;
00599
00600 case 2:
00601
00602 push_copy (_zero_);
00603 int2num (&ex_stack->s_num, scale);
00604 break;
00605
00606 default:
00607
00608 var_ptr = variables[var_name];
00609 if (var_ptr != NULL)
00610 push_copy (var_ptr->v_value);
00611 else
00612 push_copy (_zero_);
00613 }
00614 }
00615
00616
00617
00618
00619
00620 void
00621 load_array (var_name)
00622 int var_name;
00623 {
00624 bc_num *num_ptr;
00625 long index;
00626
00627 if (!check_stack(1)) return;
00628 index = num2long (ex_stack->s_num);
00629 if (index < 0 || index > BC_DIM_MAX ||
00630 (index == 0 && !is_zero(ex_stack->s_num)))
00631 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
00632 else
00633 {
00634 num_ptr = get_array_num (var_name, index);
00635 if (num_ptr != NULL)
00636 {
00637 pop();
00638 push_copy (*num_ptr);
00639 }
00640 }
00641 }
00642
00643
00644
00645
00646
00647 void
00648 decr_var (var_name)
00649 int var_name;
00650 {
00651 bc_var *var_ptr;
00652
00653 switch (var_name)
00654 {
00655
00656 case 0:
00657 if (i_base > 2)
00658 i_base--;
00659 else
00660 rt_warn ("ibase too small in --");
00661 break;
00662
00663 case 1:
00664 if (o_base > 2)
00665 o_base--;
00666 else
00667 rt_warn ("obase too small in --");
00668 break;
00669
00670 case 2:
00671 if (scale > 0)
00672 scale--;
00673 else
00674 rt_warn ("scale can not be negative in -- ");
00675 break;
00676
00677 default:
00678 var_ptr = get_var (var_name);
00679 if (var_ptr != NULL)
00680 bc_sub (var_ptr->v_value,_one_,&var_ptr->v_value);
00681 }
00682 }
00683
00684
00685
00686
00687
00688 void
00689 decr_array (var_name)
00690 char var_name;
00691 {
00692 bc_num *num_ptr;
00693 long index;
00694
00695
00696 if (!check_stack (1)) return;
00697 index = num2long (ex_stack->s_num);
00698 if (index < 0 || index > BC_DIM_MAX ||
00699 (index == 0 && !is_zero (ex_stack->s_num)))
00700 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
00701 else
00702 {
00703 num_ptr = get_array_num (var_name, index);
00704 if (num_ptr != NULL)
00705 {
00706 pop ();
00707 bc_sub (*num_ptr, _one_, num_ptr);
00708 }
00709 }
00710 }
00711
00712
00713
00714
00715
00716 void
00717 incr_var (var_name)
00718 int var_name;
00719 {
00720 bc_var *var_ptr;
00721
00722 switch (var_name)
00723 {
00724
00725 case 0:
00726 if (i_base < 16)
00727 i_base++;
00728 else
00729 rt_warn ("ibase too big in ++");
00730 break;
00731
00732 case 1:
00733 if (o_base < BC_BASE_MAX)
00734 o_base++;
00735 else
00736 rt_warn ("obase too big in ++");
00737 break;
00738
00739 case 2:
00740 if (scale < BC_SCALE_MAX)
00741 scale++;
00742 else
00743 rt_warn ("Scale too big in ++");
00744 break;
00745
00746 default:
00747 var_ptr = get_var (var_name);
00748 if (var_ptr != NULL)
00749 bc_add (var_ptr->v_value, _one_, &var_ptr->v_value);
00750
00751 }
00752 }
00753
00754
00755
00756
00757
00758 void
00759 incr_array (var_name)
00760 int var_name;
00761 {
00762 bc_num *num_ptr;
00763 long index;
00764
00765 if (!check_stack (1)) return;
00766 index = num2long (ex_stack->s_num);
00767 if (index < 0 || index > BC_DIM_MAX ||
00768 (index == 0 && !is_zero (ex_stack->s_num)))
00769 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
00770 else
00771 {
00772 num_ptr = get_array_num (var_name, index);
00773 if (num_ptr != NULL)
00774 {
00775 pop ();
00776 bc_add (*num_ptr, _one_, num_ptr);
00777 }
00778 }
00779 }
00780
00781
00782
00783
00784
00785
00786 void
00787 auto_var (name)
00788 int name;
00789 {
00790 bc_var *v_temp;
00791 bc_var_array *a_temp;
00792 int ix;
00793
00794 if (name > 0)
00795 {
00796
00797 ix = name;
00798 v_temp = (bc_var *) bc_malloc (sizeof (bc_var));
00799 v_temp->v_next = variables[ix];
00800 init_num (&v_temp->v_value);
00801 variables[ix] = v_temp;
00802 }
00803 else
00804 {
00805
00806 ix = -name;
00807 a_temp = (bc_var_array *) bc_malloc (sizeof (bc_var_array));
00808 a_temp->a_next = arrays[ix];
00809 a_temp->a_value = NULL;
00810 a_temp->a_param = FALSE;
00811 arrays[ix] = a_temp;
00812 }
00813 }
00814
00815
00816
00817
00818
00819 void
00820 free_a_tree ( root, depth )
00821 bc_array_node *root;
00822 int depth;
00823 {
00824 int ix;
00825
00826 if (root != NULL)
00827 {
00828 if (depth > 1)
00829 for (ix = 0; ix < NODE_SIZE; ix++)
00830 free_a_tree (root->n_items.n_down[ix], depth-1);
00831 else
00832 for (ix = 0; ix < NODE_SIZE; ix++)
00833 free_num ( &(root->n_items.n_num[ix]));
00834 free (root);
00835 }
00836 }
00837
00838
00839
00840
00841
00842 void
00843 pop_vars (list)
00844 arg_list *list;
00845 {
00846 bc_var *v_temp;
00847 bc_var_array *a_temp;
00848 int ix;
00849
00850 while (list != NULL)
00851 {
00852 ix = list->av_name;
00853 if (ix > 0)
00854 {
00855
00856 v_temp = variables[ix];
00857 if (v_temp != NULL)
00858 {
00859 variables[ix] = v_temp->v_next;
00860 free_num (&v_temp->v_value);
00861 free (v_temp);
00862 }
00863 }
00864 else
00865 {
00866
00867 ix = -ix;
00868 a_temp = arrays[ix];
00869 if (a_temp != NULL)
00870 {
00871 arrays[ix] = a_temp->a_next;
00872 if (!a_temp->a_param && a_temp->a_value != NULL)
00873 {
00874 free_a_tree (a_temp->a_value->a_tree,
00875 a_temp->a_value->a_depth);
00876 free (a_temp->a_value);
00877 }
00878 free (a_temp);
00879 }
00880 }
00881 list = list->next;
00882 }
00883 }
00884
00885
00886
00887
00888
00889
00890
00891 void
00892 process_params (pc, func)
00893 program_counter *pc;
00894 int func;
00895 {
00896 char ch;
00897 arg_list *params;
00898 char warned = FALSE;
00899 int ix, ix1;
00900 bc_var *v_temp;
00901 bc_var_array *a_src, *a_dest;
00902 bc_num *n_temp;
00903
00904
00905 params = functions[func].f_params;
00906
00907 while ((ch = byte(pc)) != ':')
00908 {
00909 if (params != NULL)
00910 {
00911 if ((ch == '0') && params->av_name > 0)
00912 {
00913
00914 ix = params->av_name;
00915 v_temp = (bc_var *) bc_malloc (sizeof(bc_var));
00916 v_temp->v_next = variables[ix];
00917 v_temp->v_value = ex_stack->s_num;
00918 init_num (&ex_stack->s_num);
00919 variables[ix] = v_temp;
00920 }
00921 else
00922 if ((ch == '1') && (params->av_name < 0))
00923 {
00924
00925
00926
00927 ix = (int) num2long (ex_stack->s_num);
00928 n_temp = get_array_num (ix, 0);
00929
00930
00931 auto_var (params->av_name);
00932 ix1 = -params->av_name;
00933
00934
00935 if (ix == ix1)
00936 a_src = arrays[ix]->a_next;
00937 else
00938 a_src = arrays[ix];
00939 a_dest = arrays[ix1];
00940 a_dest->a_param = TRUE;
00941 a_dest->a_value = a_src->a_value;
00942 }
00943 else
00944 {
00945 if (params->av_name < 0)
00946 rt_error ("Parameter type mismatch parameter %s.",
00947 a_names[-params->av_name]);
00948 else
00949 rt_error ("Parameter type mismatch, parameter %s.",
00950 v_names[params->av_name]);
00951 params++;
00952 }
00953 pop ();
00954 }
00955 else
00956 {
00957 if (!warned)
00958 {
00959 rt_error ("Parameter number mismatch");
00960 warned = TRUE;
00961 }
00962 }
00963 params = params->next;
00964 }
00965 if (params != NULL)
00966 rt_error ("Parameter number mismatch");
00967 }