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