]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - usr.bin/dc/bcode.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / usr.bin / dc / bcode.c
1 /*      $OpenBSD: bcode.c,v 1.40 2009/10/27 23:59:37 deraadt Exp $      */
2
3 /*
4  * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 #include <sys/cdefs.h>
20 __FBSDID("$FreeBSD$");
21
22 #include <err.h>
23 #include <limits.h>
24 #include <openssl/ssl.h>
25 #include <signal.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "extern.h"
31
32 #define __inline        
33
34 #define MAX_ARRAY_INDEX         2048
35 #define READSTACK_SIZE          8
36
37 #define NO_ELSE                 -2      /* -1 is EOF */
38 #define REG_ARRAY_SIZE_SMALL    (UCHAR_MAX + 1)
39 #define REG_ARRAY_SIZE_BIG      (UCHAR_MAX + 1 + USHRT_MAX + 1)
40
41 struct bmachine {
42         struct source           *readstack;
43         struct stack            *reg;
44         struct stack             stack;
45         u_int                    scale;
46         u_int                    obase;
47         u_int                    ibase;
48         size_t                   readsp;
49         size_t                   reg_array_size;
50         size_t                   readstack_sz;
51         bool                     extended_regs;
52 };
53
54 static struct bmachine   bmachine;
55
56 static __inline int      readch(void);
57 static __inline void     unreadch(void);
58 static __inline char    *readline(void);
59 static __inline void     src_free(void);
60
61 static __inline u_int    max(u_int, u_int);
62 static u_long            get_ulong(struct number *);
63
64 static __inline void     push_number(struct number *);
65 static __inline void     push_string(char *);
66 static __inline void     push(struct value *);
67 static __inline struct value *tos(void);
68 static __inline struct number   *pop_number(void);
69 static __inline char    *pop_string(void);
70 static __inline void     clear_stack(void);
71 static __inline void     print_tos(void);
72 static void              pop_print(void);
73 static void              pop_printn(void);
74 static __inline void     print_stack(void);
75 static __inline void     dup(void);
76 static void              swap(void);
77 static void              drop(void);
78
79 static void              get_scale(void);
80 static void              set_scale(void);
81 static void              get_obase(void);
82 static void              set_obase(void);
83 static void              get_ibase(void);
84 static void              set_ibase(void);
85 static void              stackdepth(void);
86 static void              push_scale(void);
87 static u_int             count_digits(const struct number *);
88 static void              num_digits(void);
89 static void              to_ascii(void);
90 static void              push_line(void);
91 static void              comment(void);
92 static void              bexec(char *);
93 static void              badd(void);
94 static void              bsub(void);
95 static void              bmul(void);
96 static void              bdiv(void);
97 static void              bmod(void);
98 static void              bdivmod(void);
99 static void              bexp(void);
100 static bool              bsqrt_stop(const BIGNUM *, const BIGNUM *, u_int *);
101 static void              bsqrt(void);
102 static void              not(void);
103 static void              equal_numbers(void);
104 static void              less_numbers(void);
105 static void              lesseq_numbers(void);
106 static void              equal(void);
107 static void              not_equal(void);
108 static void              less(void);
109 static void              not_less(void);
110 static void              greater(void);
111 static void              not_greater(void);
112 static void              not_compare(void);
113 static bool              compare_numbers(enum bcode_compare, struct number *,
114                              struct number *);
115 static void              compare(enum bcode_compare);
116 static int               readreg(void);
117 static void              load(void);
118 static void              store(void);
119 static void              load_stack(void);
120 static void              store_stack(void);
121 static void              load_array(void);
122 static void              store_array(void);
123 static void              nop(void);
124 static void              quit(void);
125 static void              quitN(void);
126 static void              skipN(void);
127 static void              skip_until_mark(void);
128 static void              parse_number(void);
129 static void              unknown(void);
130 static void              eval_string(char *);
131 static void              eval_line(void);
132 static void              eval_tos(void);
133
134
135 typedef void            (*opcode_function)(void);
136
137 struct jump_entry {
138         u_char           ch;
139         opcode_function  f;
140 };
141
142 static opcode_function jump_table[UCHAR_MAX];
143
144 static const struct jump_entry jump_table_data[] = {
145         { ' ',  nop             },
146         { '!',  not_compare     },
147         { '#',  comment         },
148         { '%',  bmod            },
149         { '(',  less_numbers    },
150         { '*',  bmul            },
151         { '+',  badd            },
152         { '-',  bsub            },
153         { '.',  parse_number    },
154         { '/',  bdiv            },
155         { '0',  parse_number    },
156         { '1',  parse_number    },
157         { '2',  parse_number    },
158         { '3',  parse_number    },
159         { '4',  parse_number    },
160         { '5',  parse_number    },
161         { '6',  parse_number    },
162         { '7',  parse_number    },
163         { '8',  parse_number    },
164         { '9',  parse_number    },
165         { ':',  store_array     },
166         { ';',  load_array      },
167         { '<',  less            },
168         { '=',  equal           },
169         { '>',  greater         },
170         { '?',  eval_line       },
171         { 'A',  parse_number    },
172         { 'B',  parse_number    },
173         { 'C',  parse_number    },
174         { 'D',  parse_number    },
175         { 'E',  parse_number    },
176         { 'F',  parse_number    },
177         { 'G',  equal_numbers   },
178         { 'I',  get_ibase       },
179         { 'J',  skipN           },
180         { 'K',  get_scale       },
181         { 'L',  load_stack      },
182         { 'M',  nop             },
183         { 'N',  not             },
184         { 'O',  get_obase       },
185         { 'P',  pop_print       },
186         { 'Q',  quitN           },
187         { 'R',  drop            },
188         { 'S',  store_stack     },
189         { 'X',  push_scale      },
190         { 'Z',  num_digits      },
191         { '[',  push_line       },
192         { '\f', nop             },
193         { '\n', nop             },
194         { '\r', nop             },
195         { '\t', nop             },
196         { '^',  bexp            },
197         { '_',  parse_number    },
198         { 'a',  to_ascii        },
199         { 'c',  clear_stack     },
200         { 'd',  dup             },
201         { 'f',  print_stack     },
202         { 'i',  set_ibase       },
203         { 'k',  set_scale       },
204         { 'l',  load            },
205         { 'n',  pop_printn      },
206         { 'o',  set_obase       },
207         { 'p',  print_tos       },
208         { 'q',  quit            },
209         { 'r',  swap            },
210         { 's',  store           },
211         { 'v',  bsqrt           },
212         { 'x',  eval_tos        },
213         { 'z',  stackdepth      },
214         { '{',  lesseq_numbers  },
215         { '~',  bdivmod         }
216 };
217
218 #define JUMP_TABLE_DATA_SIZE \
219         (sizeof(jump_table_data)/sizeof(jump_table_data[0]))
220
221 void
222 init_bmachine(bool extended_registers)
223 {
224         unsigned int i;
225
226         bmachine.extended_regs = extended_registers;
227         bmachine.reg_array_size = bmachine.extended_regs ?
228             REG_ARRAY_SIZE_BIG : REG_ARRAY_SIZE_SMALL;
229
230         bmachine.reg = calloc(bmachine.reg_array_size,
231             sizeof(bmachine.reg[0]));
232         if (bmachine.reg == NULL)
233                 err(1, NULL);
234
235         for (i = 0; i < UCHAR_MAX; i++)
236                 jump_table[i] = unknown;
237         for (i = 0; i < JUMP_TABLE_DATA_SIZE; i++)
238                 jump_table[jump_table_data[i].ch] = jump_table_data[i].f;
239
240         stack_init(&bmachine.stack);
241
242         for (i = 0; i < bmachine.reg_array_size; i++)
243                 stack_init(&bmachine.reg[i]);
244
245         bmachine.readstack_sz = READSTACK_SIZE;
246         bmachine.readstack = calloc(sizeof(struct source),
247             bmachine.readstack_sz);
248         if (bmachine.readstack == NULL)
249                 err(1, NULL);
250         bmachine.obase = bmachine.ibase = 10;
251 }
252
253 u_int
254 bmachine_scale(void)
255 {
256         return (bmachine.scale);
257 }
258
259 /* Reset the things needed before processing a (new) file */
260 void
261 reset_bmachine(struct source *src)
262 {
263
264         bmachine.readsp = 0;
265         bmachine.readstack[0] = *src;
266 }
267
268 static __inline int
269 readch(void)
270 {
271         struct source *src = &bmachine.readstack[bmachine.readsp];
272
273         return (src->vtable->readchar(src));
274 }
275
276 static __inline void
277 unreadch(void)
278 {
279         struct source *src = &bmachine.readstack[bmachine.readsp];
280
281         src->vtable->unreadchar(src);
282 }
283
284 static __inline char *
285 readline(void)
286 {
287         struct source *src = &bmachine.readstack[bmachine.readsp];
288
289         return (src->vtable->readline(src));
290 }
291
292 static __inline void
293 src_free(void)
294 {
295         struct source *src = &bmachine.readstack[bmachine.readsp];
296
297         src->vtable->free(src);
298 }
299
300 #ifdef DEBUGGING
301 void
302 pn(const char *str, const struct number *n)
303 {
304         char *p = BN_bn2dec(n->number);
305
306         if (p == NULL)
307                 err(1, "BN_bn2dec failed");
308         fputs(str, stderr);
309         fprintf(stderr, " %s (%u)\n" , p, n->scale);
310         OPENSSL_free(p);
311 }
312
313 void
314 pbn(const char *str, const BIGNUM *n)
315 {
316         char *p = BN_bn2dec(n);
317
318         if (p == NULL)
319                 err(1, "BN_bn2dec failed");
320         fputs(str, stderr);
321         fprintf(stderr, " %s\n", p);
322         OPENSSL_free(p);
323 }
324
325 #endif
326
327 static __inline u_int
328 max(u_int a, u_int b)
329 {
330
331         return (a > b ? a : b);
332 }
333
334 static unsigned long factors[] = {
335         0, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
336         100000000, 1000000000
337 };
338
339 void
340 scale_number(BIGNUM *n, int s)
341 {
342         unsigned int abs_scale;
343
344         if (s == 0)
345                 return;
346
347         abs_scale = s > 0 ? s : -s;
348
349         if (abs_scale < sizeof(factors)/sizeof(factors[0])) {
350                 if (s > 0)
351                         bn_check(BN_mul_word(n, factors[abs_scale]));
352                 else
353                         BN_div_word(n, factors[abs_scale]);
354         } else {
355                 BIGNUM *a, *p;
356                 BN_CTX *ctx;
357
358                 a = BN_new();
359                 bn_checkp(a);
360                 p = BN_new();
361                 bn_checkp(p);
362                 ctx = BN_CTX_new();
363                 bn_checkp(ctx);
364
365                 bn_check(BN_set_word(a, 10));
366                 bn_check(BN_set_word(p, abs_scale));
367                 bn_check(BN_exp(a, a, p, ctx));
368                 if (s > 0)
369                         bn_check(BN_mul(n, n, a, ctx));
370                 else
371                         bn_check(BN_div(n, NULL, n, a, ctx));
372                 BN_CTX_free(ctx);
373                 BN_free(a);
374                 BN_free(p);
375         }
376 }
377
378 void
379 split_number(const struct number *n, BIGNUM *i, BIGNUM *f)
380 {
381         u_long rem;
382
383         bn_checkp(BN_copy(i, n->number));
384
385         if (n->scale == 0 && f != NULL)
386                 bn_check(BN_zero(f));
387         else if (n->scale < sizeof(factors)/sizeof(factors[0])) {
388                 rem = BN_div_word(i, factors[n->scale]);
389                 if (f != NULL)
390                         bn_check(BN_set_word(f, rem));
391         } else {
392                 BIGNUM  *a, *p;
393                 BN_CTX  *ctx;
394
395                 a = BN_new();
396                 bn_checkp(a);
397                 p = BN_new();
398                 bn_checkp(p);
399                 ctx = BN_CTX_new();
400                 bn_checkp(ctx);
401
402                 bn_check(BN_set_word(a, 10));
403                 bn_check(BN_set_word(p, n->scale));
404                 bn_check(BN_exp(a, a, p, ctx));
405                 bn_check(BN_div(i, f, n->number, a, ctx));
406                 BN_CTX_free(ctx);
407                 BN_free(a);
408                 BN_free(p);
409         }
410 }
411
412 void
413 normalize(struct number *n, u_int s)
414 {
415
416         scale_number(n->number, s - n->scale);
417         n->scale = s;
418 }
419
420 static u_long
421 get_ulong(struct number *n)
422 {
423
424         normalize(n, 0);
425         return (BN_get_word(n->number));
426 }
427
428 void
429 negate(struct number *n)
430 {
431
432         BN_set_negative(n->number, !BN_is_negative(n->number));
433 }
434
435 static __inline void
436 push_number(struct number *n)
437 {
438
439         stack_pushnumber(&bmachine.stack, n);
440 }
441
442 static __inline void
443 push_string(char *string)
444 {
445
446         stack_pushstring(&bmachine.stack, string);
447 }
448
449 static __inline void
450 push(struct value *v)
451 {
452
453         stack_push(&bmachine.stack, v);
454 }
455
456 static __inline struct value *
457 tos(void)
458 {
459
460         return (stack_tos(&bmachine.stack));
461 }
462
463 static __inline struct value *
464 pop(void)
465 {
466
467         return (stack_pop(&bmachine.stack));
468 }
469
470 static __inline struct number *
471 pop_number(void)
472 {
473
474         return (stack_popnumber(&bmachine.stack));
475 }
476
477 static __inline char *
478 pop_string(void)
479 {
480
481         return (stack_popstring(&bmachine.stack));
482 }
483
484 static __inline void
485 clear_stack(void)
486 {
487
488         stack_clear(&bmachine.stack);
489 }
490
491 static __inline void
492 print_stack(void)
493 {
494
495         stack_print(stdout, &bmachine.stack, "", bmachine.obase);
496 }
497
498 static __inline void
499 print_tos(void)
500 {
501         struct value *value = tos();
502
503         if (value != NULL) {
504                 print_value(stdout, value, "", bmachine.obase);
505                 putchar('\n');
506         }
507         else
508                 warnx("stack empty");
509 }
510
511 static void
512 pop_print(void)
513 {
514         struct value *value = pop();
515
516         if (value != NULL) {
517                 switch (value->type) {
518                 case BCODE_NONE:
519                         break;
520                 case BCODE_NUMBER:
521                         normalize(value->u.num, 0);
522                         print_ascii(stdout, value->u.num);
523                         fflush(stdout);
524                         break;
525                 case BCODE_STRING:
526                         fputs(value->u.string, stdout);
527                         fflush(stdout);
528                         break;
529                 }
530                 stack_free_value(value);
531         }
532 }
533
534 static void
535 pop_printn(void)
536 {
537         struct value *value = pop();
538
539         if (value != NULL) {
540                 print_value(stdout, value, "", bmachine.obase);
541                 fflush(stdout);
542                 stack_free_value(value);
543         }
544 }
545
546 static __inline void
547 dup(void)
548 {
549
550         stack_dup(&bmachine.stack);
551 }
552
553 static void
554 swap(void)
555 {
556
557         stack_swap(&bmachine.stack);
558 }
559
560 static void
561 drop(void)
562 {
563         struct value *v = pop();
564         if (v != NULL)
565                 stack_free_value(v);
566 }
567
568 static void
569 get_scale(void)
570 {
571         struct number *n;
572
573         n = new_number();
574         bn_check(BN_set_word(n->number, bmachine.scale));
575         push_number(n);
576 }
577
578 static void
579 set_scale(void)
580 {
581         struct number *n;
582         u_long scale;
583
584         n = pop_number();
585         if (n != NULL) {
586                 if (BN_is_negative(n->number))
587                         warnx("scale must be a nonnegative number");
588                 else {
589                         scale = get_ulong(n);
590                         if (scale != BN_MASK2 && scale <= UINT_MAX)
591                                 bmachine.scale = (u_int)scale;
592                         else
593                                 warnx("scale too large");
594                         }
595                 free_number(n);
596         }
597 }
598
599 static void
600 get_obase(void)
601 {
602         struct number *n;
603
604         n = new_number();
605         bn_check(BN_set_word(n->number, bmachine.obase));
606         push_number(n);
607 }
608
609 static void
610 set_obase(void)
611 {
612         struct number *n;
613         u_long base;
614
615         n = pop_number();
616         if (n != NULL) {
617                 base = get_ulong(n);
618                 if (base != BN_MASK2 && base > 1 && base <= UINT_MAX)
619                         bmachine.obase = (u_int)base;
620                 else
621                         warnx("output base must be a number greater than 1");
622                 free_number(n);
623         }
624 }
625
626 static void
627 get_ibase(void)
628 {
629         struct number *n;
630
631         n = new_number();
632         bn_check(BN_set_word(n->number, bmachine.ibase));
633         push_number(n);
634 }
635
636 static void
637 set_ibase(void)
638 {
639         struct number *n;
640         u_long base;
641
642         n = pop_number();
643         if (n != NULL) {
644                 base = get_ulong(n);
645                 if (base != BN_MASK2 && 2 <= base && base <= 16)
646                         bmachine.ibase = (u_int)base;
647                 else
648                         warnx("input base must be a number between 2 and 16 "
649                             "(inclusive)");
650                 free_number(n);
651         }
652 }
653
654 static void
655 stackdepth(void)
656 {
657         struct number *n;
658         size_t i;
659
660         i = stack_size(&bmachine.stack);
661         n = new_number();
662         bn_check(BN_set_word(n->number, i));
663         push_number(n);
664 }
665
666 static void
667 push_scale(void)
668 {
669         struct number *n;
670         struct value *value;
671         u_int scale = 0;
672
673         value = pop();
674         if (value != NULL) {
675                 switch (value->type) {
676                 case BCODE_NONE:
677                         return;
678                 case BCODE_NUMBER:
679                         scale = value->u.num->scale;
680                         break;
681                 case BCODE_STRING:
682                         break;
683                 }
684                 stack_free_value(value);
685                 n = new_number();
686                 bn_check(BN_set_word(n->number, scale));
687                 push_number(n);
688         }
689 }
690
691 static u_int
692 count_digits(const struct number *n)
693 {
694         struct number *int_part, *fract_part;
695         u_int i;
696
697         if (BN_is_zero(n->number))
698                 return (n->scale ? n->scale : 1);
699
700         int_part = new_number();
701         fract_part = new_number();
702         fract_part->scale = n->scale;
703         split_number(n, int_part->number, fract_part->number);
704
705         i = 0;
706         while (!BN_is_zero(int_part->number)) {
707                 BN_div_word(int_part->number, 10);
708                 i++;
709         }
710         free_number(int_part);
711         free_number(fract_part);
712         return (i + n->scale);
713 }
714
715 static void
716 num_digits(void)
717 {
718         struct number *n = NULL;
719         struct value *value;
720         size_t digits;
721
722         value = pop();
723         if (value != NULL) {
724                 switch (value->type) {
725                 case BCODE_NONE:
726                         return;
727                 case BCODE_NUMBER:
728                         digits = count_digits(value->u.num);
729                         n = new_number();
730                         bn_check(BN_set_word(n->number, digits));
731                         break;
732                 case BCODE_STRING:
733                         digits = strlen(value->u.string);
734                         n = new_number();
735                         bn_check(BN_set_word(n->number, digits));
736                         break;
737                 }
738                 stack_free_value(value);
739                 push_number(n);
740         }
741 }
742
743 static void
744 to_ascii(void)
745 {
746         struct number *n;
747         struct value *value;
748         char str[2];
749
750         value = pop();
751         if (value != NULL) {
752                 str[1] = '\0';
753                 switch (value->type) {
754                 case BCODE_NONE:
755                         return;
756                 case BCODE_NUMBER:
757                         n = value->u.num;
758                         normalize(n, 0);
759                         if (BN_num_bits(n->number) > 8)
760                                 bn_check(BN_mask_bits(n->number, 8));
761                         str[0] = (char)BN_get_word(n->number);
762                         break;
763                 case BCODE_STRING:
764                         str[0] = value->u.string[0];
765                         break;
766                 }
767                 stack_free_value(value);
768                 push_string(bstrdup(str));
769         }
770 }
771
772 static int
773 readreg(void)
774 {
775         int ch1, ch2, idx;
776
777         idx = readch();
778         if (idx == 0xff && bmachine.extended_regs) {
779                 ch1 = readch();
780                 ch2 = readch();
781                 if (ch1 == EOF || ch2 == EOF) {
782                         warnx("unexpected eof");
783                         idx = -1;
784                 } else
785                         idx = (ch1 << 8) + ch2 + UCHAR_MAX + 1;
786         }
787         if (idx < 0 || (unsigned)idx >= bmachine.reg_array_size) {
788                 warnx("internal error: reg num = %d", idx);
789                 idx = -1;
790         }
791         return (idx);
792 }
793
794 static void
795 load(void)
796 {
797         struct number *n;
798         struct value *v;
799         struct value copy;
800         int idx;
801
802         idx = readreg();
803         if (idx >= 0) {
804                 v = stack_tos(&bmachine.reg[idx]);
805                 if (v == NULL) {
806                         n = new_number();
807                         bn_check(BN_zero(n->number));
808                         push_number(n);
809                 } else
810                         push(stack_dup_value(v, &copy));
811         }
812 }
813
814 static void
815 store(void)
816 {
817         struct value *val;
818         int idx;
819
820         idx = readreg();
821         if (idx >= 0) {
822                 val = pop();
823                 if (val == NULL) {
824                         return;
825                 }
826                 stack_set_tos(&bmachine.reg[idx], val);
827         }
828 }
829
830 static void
831 load_stack(void)
832 {
833         struct stack *stack;
834         struct value *value;
835         int idx;
836
837         idx = readreg();
838         if (idx >= 0) {
839                 stack = &bmachine.reg[idx];
840                 value = NULL;
841                 if (stack_size(stack) > 0) {
842                         value = stack_pop(stack);
843                 }
844                 if (value != NULL)
845                         push(value);
846                 else
847                         warnx("stack register '%c' (0%o) is empty",
848                             idx, idx);
849         }
850 }
851
852 static void
853 store_stack(void)
854 {
855         struct value *value;
856         int idx;
857
858         idx = readreg();
859         if (idx >= 0) {
860                 value = pop();
861                 if (value == NULL)
862                         return;
863                 stack_push(&bmachine.reg[idx], value);
864         }
865 }
866
867 static void
868 load_array(void)
869 {
870         struct number *inumber, *n;
871         struct stack *stack;
872         struct value *v;
873         struct value copy;
874         u_long idx;
875         int reg;
876
877         reg = readreg();
878         if (reg >= 0) {
879                 inumber = pop_number();
880                 if (inumber == NULL)
881                         return;
882                 idx = get_ulong(inumber);
883                 if (BN_is_negative(inumber->number))
884                         warnx("negative idx");
885                 else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX)
886                         warnx("idx too big");
887                 else {
888                         stack = &bmachine.reg[reg];
889                         v = frame_retrieve(stack, idx);
890                         if (v == NULL || v->type == BCODE_NONE) {
891                                 n = new_number();
892                                 bn_check(BN_zero(n->number));
893                                 push_number(n);
894                         }
895                         else
896                                 push(stack_dup_value(v, &copy));
897                 }
898                 free_number(inumber);
899         }
900 }
901
902 static void
903 store_array(void)
904 {
905         struct number *inumber;
906         struct value *value;
907         struct stack *stack;
908         u_long idx;
909         int reg;
910
911         reg = readreg();
912         if (reg >= 0) {
913                 inumber = pop_number();
914                 if (inumber == NULL)
915                         return;
916                 value = pop();
917                 if (value == NULL) {
918                         free_number(inumber);
919                         return;
920                 }
921                 idx = get_ulong(inumber);
922                 if (BN_is_negative(inumber->number)) {
923                         warnx("negative idx");
924                         stack_free_value(value);
925                 } else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) {
926                         warnx("idx too big");
927                         stack_free_value(value);
928                 } else {
929                         stack = &bmachine.reg[reg];
930                         frame_assign(stack, idx, value);
931                 }
932                 free_number(inumber);
933         }
934 }
935
936 static void
937 push_line(void)
938 {
939
940         push_string(read_string(&bmachine.readstack[bmachine.readsp]));
941 }
942
943 static void
944 comment(void)
945 {
946
947         free(readline());
948 }
949
950 static void
951 bexec(char *line)
952 {
953
954         system(line);
955         free(line);
956 }
957
958 static void
959 badd(void)
960 {
961         struct number   *a, *b, *r;
962
963         a = pop_number();
964         if (a == NULL) {
965                 return;
966         }
967         b = pop_number();
968         if (b == NULL) {
969                 push_number(a);
970                 return;
971         }
972
973         r = new_number();
974         r->scale = max(a->scale, b->scale);
975         if (r->scale > a->scale)
976                 normalize(a, r->scale);
977         else if (r->scale > b->scale)
978                 normalize(b, r->scale);
979         bn_check(BN_add(r->number, a->number, b->number));
980         push_number(r);
981         free_number(a);
982         free_number(b);
983 }
984
985 static void
986 bsub(void)
987 {
988         struct number   *a, *b, *r;
989
990         a = pop_number();
991         if (a == NULL) {
992                 return;
993         }
994         b = pop_number();
995         if (b == NULL) {
996                 push_number(a);
997                 return;
998         }
999
1000         r = new_number();
1001
1002         r->scale = max(a->scale, b->scale);
1003         if (r->scale > a->scale)
1004                 normalize(a, r->scale);
1005         else if (r->scale > b->scale)
1006                 normalize(b, r->scale);
1007         bn_check(BN_sub(r->number, b->number, a->number));
1008         push_number(r);
1009         free_number(a);
1010         free_number(b);
1011 }
1012
1013 void
1014 bmul_number(struct number *r, struct number *a, struct number *b, u_int scale)
1015 {
1016         BN_CTX *ctx;
1017
1018         /* Create copies of the scales, since r might be equal to a or b */
1019         u_int ascale = a->scale;
1020         u_int bscale = b->scale;
1021         u_int rscale = ascale + bscale;
1022
1023         ctx = BN_CTX_new();
1024         bn_checkp(ctx);
1025         bn_check(BN_mul(r->number, a->number, b->number, ctx));
1026         BN_CTX_free(ctx);
1027
1028         r->scale = rscale;
1029         if (rscale > bmachine.scale && rscale > ascale && rscale > bscale)
1030                 normalize(r, max(scale, max(ascale, bscale)));
1031 }
1032
1033 static void
1034 bmul(void)
1035 {
1036         struct number *a, *b, *r;
1037
1038         a = pop_number();
1039         if (a == NULL) {
1040                 return;
1041         }
1042         b = pop_number();
1043         if (b == NULL) {
1044                 push_number(a);
1045                 return;
1046         }
1047
1048         r = new_number();
1049         bmul_number(r, a, b, bmachine.scale);
1050
1051         push_number(r);
1052         free_number(a);
1053         free_number(b);
1054 }
1055
1056 static void
1057 bdiv(void)
1058 {
1059         struct number *a, *b, *r;
1060         BN_CTX *ctx;
1061         u_int scale;
1062
1063         a = pop_number();
1064         if (a == NULL) {
1065                 return;
1066         }
1067         b = pop_number();
1068         if (b == NULL) {
1069                 push_number(a);
1070                 return;
1071         }
1072
1073         r = new_number();
1074         r->scale = bmachine.scale;
1075         scale = max(a->scale, b->scale);
1076
1077         if (BN_is_zero(a->number))
1078                 warnx("divide by zero");
1079         else {
1080                 normalize(a, scale);
1081                 normalize(b, scale + r->scale);
1082
1083                 ctx = BN_CTX_new();
1084                 bn_checkp(ctx);
1085                 bn_check(BN_div(r->number, NULL, b->number, a->number, ctx));
1086                 BN_CTX_free(ctx);
1087         }
1088         push_number(r);
1089         free_number(a);
1090         free_number(b);
1091 }
1092
1093 static void
1094 bmod(void)
1095 {
1096         struct number *a, *b, *r;
1097         BN_CTX *ctx;
1098         u_int scale;
1099
1100         a = pop_number();
1101         if (a == NULL) {
1102                 return;
1103         }
1104         b = pop_number();
1105         if (b == NULL) {
1106                 push_number(a);
1107                 return;
1108         }
1109
1110         r = new_number();
1111         scale = max(a->scale, b->scale);
1112         r->scale = max(b->scale, a->scale + bmachine.scale);
1113
1114         if (BN_is_zero(a->number))
1115                 warnx("remainder by zero");
1116         else {
1117                 normalize(a, scale);
1118                 normalize(b, scale + bmachine.scale);
1119
1120                 ctx = BN_CTX_new();
1121                 bn_checkp(ctx);
1122                 bn_check(BN_mod(r->number, b->number, a->number, ctx));
1123                 BN_CTX_free(ctx);
1124         }
1125         push_number(r);
1126         free_number(a);
1127         free_number(b);
1128 }
1129
1130 static void
1131 bdivmod(void)
1132 {
1133         struct number *a, *b, *rdiv, *rmod;
1134         BN_CTX *ctx;
1135         u_int scale;
1136
1137         a = pop_number();
1138         if (a == NULL) {
1139                 return;
1140         }
1141         b = pop_number();
1142         if (b == NULL) {
1143                 push_number(a);
1144                 return;
1145         }
1146
1147         rdiv = new_number();
1148         rmod = new_number();
1149         rdiv->scale = bmachine.scale;
1150         rmod->scale = max(b->scale, a->scale + bmachine.scale);
1151         scale = max(a->scale, b->scale);
1152
1153         if (BN_is_zero(a->number))
1154                 warnx("divide by zero");
1155         else {
1156                 normalize(a, scale);
1157                 normalize(b, scale + bmachine.scale);
1158
1159                 ctx = BN_CTX_new();
1160                 bn_checkp(ctx);
1161                 bn_check(BN_div(rdiv->number, rmod->number,
1162                     b->number, a->number, ctx));
1163                 BN_CTX_free(ctx);
1164         }
1165         push_number(rdiv);
1166         push_number(rmod);
1167         free_number(a);
1168         free_number(b);
1169 }
1170
1171 static void
1172 bexp(void)
1173 {
1174         struct number *a, *p, *r;
1175         u_int rscale;
1176         bool neg;
1177
1178         p = pop_number();
1179         if (p == NULL) {
1180                 return;
1181         }
1182         a = pop_number();
1183         if (a == NULL) {
1184                 push_number(p);
1185                 return;
1186         }
1187
1188         if (p->scale != 0) {
1189                 BIGNUM *i, *f;
1190                 i = BN_new();
1191                 bn_checkp(i);
1192                 f = BN_new();
1193                 bn_checkp(f);
1194                 split_number(p, i, f);
1195                 if (!BN_is_zero(f))
1196                         warnx("Runtime warning: non-zero fractional part "
1197                             "in exponent");
1198                 BN_free(i);
1199                 BN_free(f);
1200         }
1201
1202         normalize(p, 0);
1203
1204         neg = false;
1205         if (BN_is_negative(p->number)) {
1206                 neg = true;
1207                 negate(p);
1208                 rscale = bmachine.scale;
1209         } else {
1210                 /* Posix bc says min(a.scale * b, max(a.scale, scale) */
1211                 u_long b;
1212                 u_int m;
1213
1214                 b = BN_get_word(p->number);
1215                 m = max(a->scale, bmachine.scale);
1216                 rscale = a->scale * (u_int)b;
1217                 if (rscale > m || (a->scale > 0 && (b == BN_MASK2 ||
1218                     b > UINT_MAX)))
1219                         rscale = m;
1220         }
1221
1222         if (BN_is_zero(p->number)) {
1223                 r = new_number();
1224                 bn_check(BN_one(r->number));
1225                 normalize(r, rscale);
1226         } else {
1227                 u_int ascale, mscale;
1228
1229                 ascale = a->scale;
1230                 while (!BN_is_bit_set(p->number, 0)) {
1231                         ascale *= 2;
1232                         bmul_number(a, a, a, ascale);
1233                         bn_check(BN_rshift1(p->number, p->number));
1234                 }
1235
1236                 r = dup_number(a);
1237                 bn_check(BN_rshift1(p->number, p->number));
1238
1239                 mscale = ascale;
1240                 while (!BN_is_zero(p->number)) {
1241                         ascale *= 2;
1242                         bmul_number(a, a, a, ascale);
1243                         if (BN_is_bit_set(p->number, 0)) {
1244                                 mscale += ascale;
1245                                 bmul_number(r, r, a, mscale);
1246                         }
1247                         bn_check(BN_rshift1(p->number, p->number));
1248                 }
1249
1250                 if (neg) {
1251                         BN_CTX *ctx;
1252                         BIGNUM *one;
1253
1254                         one = BN_new();
1255                         bn_checkp(one);
1256                         bn_check(BN_one(one));
1257                         ctx = BN_CTX_new();
1258                         bn_checkp(ctx);
1259                         scale_number(one, r->scale + rscale);
1260
1261                         if (BN_is_zero(r->number))
1262                                 warnx("divide by zero");
1263                         else
1264                                 bn_check(BN_div(r->number, NULL, one,
1265                                     r->number, ctx));
1266                         BN_free(one);
1267                         BN_CTX_free(ctx);
1268                         r->scale = rscale;
1269                 } else
1270                         normalize(r, rscale);
1271         }
1272         push_number(r);
1273         free_number(a);
1274         free_number(p);
1275 }
1276
1277 static bool
1278 bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount)
1279 {
1280         BIGNUM *r;
1281         bool ret;
1282
1283         r = BN_new();
1284         bn_checkp(r);
1285         bn_check(BN_sub(r, x, y));
1286         if (BN_is_one(r))
1287                 (*onecount)++;
1288         ret = BN_is_zero(r);
1289         BN_free(r);
1290         return (ret || *onecount > 1);
1291 }
1292
1293 static void
1294 bsqrt(void)
1295 {
1296         struct number *n, *r;
1297         BIGNUM *x, *y;
1298         BN_CTX *ctx;
1299         u_int onecount, scale;
1300
1301         onecount = 0;
1302         n = pop_number();
1303         if (n == NULL) {
1304                 return;
1305         }
1306         if (BN_is_zero(n->number)) {
1307                 r = new_number();
1308                 push_number(r);
1309         } else if (BN_is_negative(n->number))
1310                 warnx("square root of negative number");
1311         else {
1312                 scale = max(bmachine.scale, n->scale);
1313                 normalize(n, 2*scale);
1314                 x = BN_dup(n->number);
1315                 bn_checkp(x);
1316                 bn_check(BN_rshift(x, x, BN_num_bits(x)/2));
1317                 y = BN_new();
1318                 bn_checkp(y);
1319                 ctx = BN_CTX_new();
1320                 bn_checkp(ctx);
1321                 for (;;) {
1322                         bn_checkp(BN_copy(y, x));
1323                         bn_check(BN_div(x, NULL, n->number, x, ctx));
1324                         bn_check(BN_add(x, x, y));
1325                         bn_check(BN_rshift1(x, x));
1326                         if (bsqrt_stop(x, y, &onecount))
1327                                 break;
1328                 }
1329                 r = bmalloc(sizeof(*r));
1330                 r->scale = scale;
1331                 r->number = y;
1332                 BN_free(x);
1333                 BN_CTX_free(ctx);
1334                 push_number(r);
1335         }
1336
1337         free_number(n);
1338 }
1339
1340 static void
1341 not(void)
1342 {
1343         struct number *a;
1344
1345         a = pop_number();
1346         if (a == NULL) {
1347                 return;
1348         }
1349         a->scale = 0;
1350         bn_check(BN_set_word(a->number, BN_get_word(a->number) ? 0 : 1));
1351         push_number(a);
1352 }
1353
1354 static void
1355 equal(void)
1356 {
1357
1358         compare(BCODE_EQUAL);
1359 }
1360
1361 static void
1362 equal_numbers(void)
1363 {
1364         struct number *a, *b, *r;
1365
1366         a = pop_number();
1367         if (a == NULL) {
1368                 return;
1369         }
1370         b = pop_number();
1371         if (b == NULL) {
1372                 push_number(a);
1373                 return;
1374         }
1375         r = new_number();
1376         bn_check(BN_set_word(r->number,
1377             compare_numbers(BCODE_EQUAL, a, b) ? 1 : 0));
1378         push_number(r);
1379 }
1380
1381 static void
1382 less_numbers(void)
1383 {
1384         struct number *a, *b, *r;
1385
1386         a = pop_number();
1387         if (a == NULL) {
1388                 return;
1389         }
1390         b = pop_number();
1391         if (b == NULL) {
1392                 push_number(a);
1393                 return;
1394         }
1395         r = new_number();
1396         bn_check(BN_set_word(r->number,
1397             compare_numbers(BCODE_LESS, a, b) ? 1 : 0));
1398         push_number(r);
1399 }
1400
1401 static void
1402 lesseq_numbers(void)
1403 {
1404         struct number *a, *b, *r;
1405
1406         a = pop_number();
1407         if (a == NULL) {
1408                 return;
1409         }
1410         b = pop_number();
1411         if (b == NULL) {
1412                 push_number(a);
1413                 return;
1414         }
1415         r = new_number();
1416         bn_check(BN_set_word(r->number,
1417             compare_numbers(BCODE_NOT_GREATER, a, b) ? 1 : 0));
1418         push_number(r);
1419 }
1420
1421 static void
1422 not_equal(void)
1423 {
1424
1425         compare(BCODE_NOT_EQUAL);
1426 }
1427
1428 static void
1429 less(void)
1430 {
1431
1432         compare(BCODE_LESS);
1433 }
1434
1435 static void
1436 not_compare(void)
1437 {
1438
1439         switch (readch()) {
1440         case '<':
1441                 not_less();
1442                 break;
1443         case '>':
1444                 not_greater();
1445                 break;
1446         case '=':
1447                 not_equal();
1448                 break;
1449         default:
1450                 unreadch();
1451                 bexec(readline());
1452                 break;
1453         }
1454 }
1455
1456 static void
1457 not_less(void)
1458 {
1459
1460         compare(BCODE_NOT_LESS);
1461 }
1462
1463 static void
1464 greater(void)
1465 {
1466
1467         compare(BCODE_GREATER);
1468 }
1469
1470 static void
1471 not_greater(void)
1472 {
1473
1474         compare(BCODE_NOT_GREATER);
1475 }
1476
1477 static bool
1478 compare_numbers(enum bcode_compare type, struct number *a, struct number *b)
1479 {
1480         u_int scale;
1481         int cmp;
1482
1483         scale = max(a->scale, b->scale);
1484
1485         if (scale > a->scale)
1486                 normalize(a, scale);
1487         else if (scale > b->scale)
1488                 normalize(b, scale);
1489
1490         cmp = BN_cmp(a->number, b->number);
1491
1492         free_number(a);
1493         free_number(b);
1494
1495         switch (type) {
1496         case BCODE_EQUAL:
1497                 return (cmp == 0);
1498         case BCODE_NOT_EQUAL:
1499                 return (cmp != 0);
1500         case BCODE_LESS:
1501                 return (cmp < 0);
1502         case BCODE_NOT_LESS:
1503                 return (cmp >= 0);
1504         case BCODE_GREATER:
1505                 return (cmp > 0);
1506         case BCODE_NOT_GREATER:
1507                 return (cmp <= 0);
1508         }
1509         return (false);
1510 }
1511
1512 static void
1513 compare(enum bcode_compare type)
1514 {
1515         struct number *a, *b;
1516         struct value *v;
1517         int idx, elseidx;
1518         bool ok;
1519
1520         elseidx = NO_ELSE;
1521         idx = readreg();
1522         if (readch() == 'e')
1523                 elseidx = readreg();
1524         else
1525                 unreadch();
1526
1527         a = pop_number();
1528         if (a == NULL)
1529                 return;
1530         b = pop_number();
1531         if (b == NULL) {
1532                 push_number(a);
1533                 return;
1534         }
1535
1536         ok = compare_numbers(type, a, b);
1537
1538         if (!ok && elseidx != NO_ELSE)
1539                 idx = elseidx;
1540
1541         if (idx >= 0 && (ok || (!ok && elseidx != NO_ELSE))) {
1542                 v = stack_tos(&bmachine.reg[idx]);
1543                 if (v == NULL)
1544                         warnx("register '%c' (0%o) is empty", idx, idx);
1545                 else {
1546                         switch(v->type) {
1547                         case BCODE_NONE:
1548                                 warnx("register '%c' (0%o) is empty", idx, idx);
1549                                 break;
1550                         case BCODE_NUMBER:
1551                                 warn("eval called with non-string argument");
1552                                 break;
1553                         case BCODE_STRING:
1554                                 eval_string(bstrdup(v->u.string));
1555                                 break;
1556                         }
1557                 }
1558         }
1559 }
1560
1561
1562 static void
1563 nop(void)
1564 {
1565
1566 }
1567
1568 static void
1569 quit(void)
1570 {
1571
1572         if (bmachine.readsp < 2)
1573                 exit(0);
1574         src_free();
1575         bmachine.readsp--;
1576         src_free();
1577         bmachine.readsp--;
1578 }
1579
1580 static void
1581 quitN(void)
1582 {
1583         struct number *n;
1584         u_long i;
1585
1586         n = pop_number();
1587         if (n == NULL)
1588                 return;
1589         i = get_ulong(n);
1590         free_number(n);
1591         if (i == BN_MASK2 || i == 0)
1592                 warnx("Q command requires a number >= 1");
1593         else if (bmachine.readsp < i)
1594                 warnx("Q command argument exceeded string execution depth");
1595         else {
1596                 while (i-- > 0) {
1597                         src_free();
1598                         bmachine.readsp--;
1599                 }
1600         }
1601 }
1602
1603 static void
1604 skipN(void)
1605 {
1606         struct number *n;
1607         u_long i;
1608
1609         n = pop_number();
1610         if (n == NULL)
1611                 return;
1612         i = get_ulong(n);
1613         if (i == BN_MASK2)
1614                 warnx("J command requires a number >= 0");
1615         else if (i > 0 && bmachine.readsp < i)
1616                 warnx("J command argument exceeded string execution depth");
1617         else {
1618                 while (i-- > 0) {
1619                         src_free();
1620                         bmachine.readsp--;
1621                 }
1622                 skip_until_mark();
1623         }
1624 }
1625
1626 static void
1627 skip_until_mark(void)
1628 {
1629
1630         for (;;) {
1631                 switch (readch()) {
1632                 case 'M':
1633                         return;
1634                 case EOF:
1635                         errx(1, "mark not found");
1636                         return;
1637                 case 'l':
1638                 case 'L':
1639                 case 's':
1640                 case 'S':
1641                 case ':':
1642                 case ';':
1643                 case '<':
1644                 case '>':
1645                 case '=':
1646                         readreg();
1647                         if (readch() == 'e')
1648                                 readreg();
1649                         else
1650                                 unreadch();
1651                         break;
1652                 case '[':
1653                         free(read_string(&bmachine.readstack[bmachine.readsp]));
1654                         break;
1655                 case '!':
1656                         switch (readch()) {
1657                                 case '<':
1658                                 case '>':
1659                                 case '=':
1660                                         readreg();
1661                                         if (readch() == 'e')
1662                                                 readreg();
1663                                         else
1664                                                 unreadch();
1665                                         break;
1666                                 default:
1667                                         free(readline());
1668                                         break;
1669                         }
1670                         break;
1671                 default:
1672                         break;
1673                 }
1674         }
1675 }
1676
1677 static void
1678 parse_number(void)
1679 {
1680
1681         unreadch();
1682         push_number(readnumber(&bmachine.readstack[bmachine.readsp],
1683             bmachine.ibase));
1684 }
1685
1686 static void
1687 unknown(void)
1688 {
1689         int ch = bmachine.readstack[bmachine.readsp].lastchar;
1690         warnx("%c (0%o) is unimplemented", ch, ch);
1691 }
1692
1693 static void
1694 eval_string(char *p)
1695 {
1696         int ch;
1697
1698         if (bmachine.readsp > 0) {
1699                 /* Check for tail call. Do not recurse in that case. */
1700                 ch = readch();
1701                 if (ch == EOF) {
1702                         src_free();
1703                         src_setstring(&bmachine.readstack[bmachine.readsp], p);
1704                         return;
1705                 } else
1706                         unreadch();
1707         }
1708         if (bmachine.readsp == bmachine.readstack_sz - 1) {
1709                 size_t newsz = bmachine.readstack_sz * 2;
1710                 struct source *stack;
1711                 stack = realloc(bmachine.readstack, newsz *
1712                     sizeof(struct source));
1713                 if (stack == NULL)
1714                         err(1, "recursion too deep");
1715                 bmachine.readstack_sz = newsz;
1716                 bmachine.readstack = stack;
1717         }
1718         src_setstring(&bmachine.readstack[++bmachine.readsp], p);
1719 }
1720
1721 static void
1722 eval_line(void)
1723 {
1724         /* Always read from stdin */
1725         struct source in;
1726         char *p;
1727
1728         clearerr(stdin);
1729         src_setstream(&in, stdin);
1730         p = (*in.vtable->readline)(&in);
1731         eval_string(p);
1732 }
1733
1734 static void
1735 eval_tos(void)
1736 {
1737         char *p;
1738
1739         p = pop_string();
1740         if (p == NULL)
1741                 return;
1742         eval_string(p);
1743 }
1744
1745 void
1746 eval(void)
1747 {
1748         int ch;
1749
1750         for (;;) {
1751                 ch = readch();
1752                 if (ch == EOF) {
1753                         if (bmachine.readsp == 0)
1754                                 return;
1755                         src_free();
1756                         bmachine.readsp--;
1757                         continue;
1758                 }
1759 #ifdef DEBUGGING
1760                 fprintf(stderr, "# %c\n", ch);
1761                 stack_print(stderr, &bmachine.stack, "* ",
1762                     bmachine.obase);
1763                 fprintf(stderr, "%zd =>\n", bmachine.readsp);
1764 #endif
1765
1766                 if (0 <= ch && ch < (signed)UCHAR_MAX)
1767                         (*jump_table[ch])();
1768                 else
1769                         warnx("internal error: opcode %d", ch);
1770
1771 #ifdef DEBUGGING
1772                 stack_print(stderr, &bmachine.stack, "* ",
1773                     bmachine.obase);
1774                 fprintf(stderr, "%zd ==\n", bmachine.readsp);
1775 #endif
1776         }
1777 }