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