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