git @ Cat's Eye Technologies Befunge-93 / 5cbe14e
Expand tabs to spaces! Chris Pressey 7 years ago
3 changed file(s) with 1034 addition(s) and 1034 deletion(s). Raw diff Collapse all Expand all
7070
7171 v2.22: Mar 2011, Chris Pressey
7272 don't insert bogus EOF/directive characters into
73 playfield when loading otherwise blank source file
73 playfield when loading otherwise blank source file
7474 (thanks to whoever sent me this patch 6 years ago)
7575 truncate long lines instead of wrapping them, so that
7676 programs that use the full 80 characters on adjacent
9191 relicensed under BSD
9292
9393 v2.12, Mar 1998, Chris Pressey / compiles under Borland C++ v3.1
94 added -i and -= options. You must specify -= if
95 you want to use b97-esque directives or the Un*x-ish
96 # comment thing, or both.
97 automatically appends '.bf' to filenames containing no periods.
98 explicitly pops remaining stack elements at end of execution.
99 compatibility messages are displayed when quiet is not specified.
100 debug mode is much improved, especially I/O under BorlandC.
101 bounds checking on 'p' and 'g' instructions.
94 added -i and -= options. You must specify -= if
95 you want to use b97-esque directives or the Un*x-ish
96 # comment thing, or both.
97 automatically appends '.bf' to filenames containing no periods.
98 explicitly pops remaining stack elements at end of execution.
99 compatibility messages are displayed when quiet is not specified.
100 debug mode is much improved, especially I/O under BorlandC.
101 bounds checking on 'p' and 'g' instructions.
102102
103103 v2.11, Jan 1998, Chris Pressey / compiles under Borland C++ v3.1
104 divide by zero now produces the correct result
105 improved some minor aesthetic features (messages & debug)
106 ANSI is used only if not compiling under Borland C.
104 divide by zero now produces the correct result
105 improved some minor aesthetic features (messages & debug)
106 ANSI is used only if not compiling under Borland C.
107107
108108 v2.10: Jul 1997, Chris Pressey
109 added -q command line option.
110 added primitive understanding of = directive from b97 spec.
111 any file with a =l directive but without =l b93 is rejected.
112 also understands # as a pre-directive line prefix for
113 Un*x-ish systems.
109 added -q command line option.
110 added primitive understanding of = directive from b97 spec.
111 any file with a =l directive but without =l b93 is rejected.
112 also understands # as a pre-directive line prefix for
113 Un*x-ish systems.
114114
115115 v2.02: Jun 1997, Chris Pressey
116 pads playfield with space characters. all unread
117 locations remain spaces.
116 pads playfield with space characters. all unread
117 locations remain spaces.
118118
119119 v2.01: Jun 1997, Chris Pressey
120 command line switches are not case-insensitive.
121 fixes gcc Segmentation Fault error.
120 command line switches are not case-insensitive.
121 fixes gcc Segmentation Fault error.
122122
123123 v2.00: Jun 1997, Chris Pressey
124 combines interpreter and debugger.
125 fixes ANSI error in debugger.
124 combines interpreter and debugger.
125 fixes ANSI error in debugger.
126126 v1.02: Feb 1996, Chris Pressey
127 @ now pushes '@' onto the stack in stringmode instead of quitting.
127 @ now pushes '@' onto the stack in stringmode instead of quitting.
128128
129129 v1.01: Feb 1996, Chris Pressey
130 fixes off-by-one error.
130 fixes off-by-one error.
131131
132132 v1.00: Sept 1993, Chris Pressey
133 original Befunge-93 distribution.
133 original Befunge-93 distribution.
134134
135135 ****************************************************************** */
136136
283283 {
284284 tc = fgetc (f);
285285 if (feof (f))
286 break;
286 break;
287287 if (use_b97directives && (x == 0) &&
288 ((tc == dc) || (accept_pound && (tc == '#'))))
288 ((tc == dc) || (accept_pound && (tc == '#'))))
289289 {
290 if (tc != '#') accept_pound = 0;
291 tc = fgetc (f);
292 if (tc == 'l')
293 {
294 while (tc != ' ')
295 {
296 tc = fgetc (f);
297 }
298 while (tc != '\n')
299 {
300 tc = fgetc (f);
301 if (tc != '\n') { s[tt++] = tc; s[tt] = (char)0; }
302 }
303 if (strcmp(s, "b93"))
304 {
305 fprintf(stderr, "Error: only Befunge-93 (not %s) sources are supported by bef.\n", s);
306 exit(10);
307 }
308 }
309 while (tc != '\n')
310 {
311 tc = fgetc (f);
312 }
290 if (tc != '#') accept_pound = 0;
291 tc = fgetc (f);
292 if (tc == 'l')
293 {
294 while (tc != ' ')
295 {
296 tc = fgetc (f);
297 }
298 while (tc != '\n')
299 {
300 tc = fgetc (f);
301 if (tc != '\n') { s[tt++] = tc; s[tt] = (char)0; }
302 }
303 if (strcmp(s, "b93"))
304 {
305 fprintf(stderr, "Error: only Befunge-93 (not %s) sources are supported by bef.\n", s);
306 exit(10);
307 }
308 }
309 while (tc != '\n')
310 {
311 tc = fgetc (f);
312 }
313313 } else
314314 {
315 accept_pound = 0;
316 if (tc == '\n')
317 {
318 x = 0;
319 y++;
320 if (y >= PAGEHEIGHT) break;
321 } else
322 {
323 cur = tc;
324 x++;
325 if (x >= LINEWIDTH)
326 {
327 if (!wrap_long_program_lines)
328 {
329 while (tc != '\n')
330 {
331 tc = fgetc (f);
332 if (feof(f)) { y = PAGEHEIGHT; break; }
333 }
334 }
335 x = 0;
336 y++;
337 if (y >= PAGEHEIGHT) break;
338 }
339 }
315 accept_pound = 0;
316 if (tc == '\n')
317 {
318 x = 0;
319 y++;
320 if (y >= PAGEHEIGHT) break;
321 } else
322 {
323 cur = tc;
324 x++;
325 if (x >= LINEWIDTH)
326 {
327 if (!wrap_long_program_lines)
328 {
329 while (tc != '\n')
330 {
331 tc = fgetc (f);
332 if (feof(f)) { y = PAGEHEIGHT; break; }
333 }
334 }
335 x = 0;
336 y++;
337 if (y >= PAGEHEIGHT) break;
338 }
339 }
340340 }
341341 }
342342 fclose (f);
390390 {
391391 for(x = 0; x < SCREENWIDTH; x++)
392392 {
393 if (isprint((int)cur))
394 {
395 printf("%c", cur);
396 }
393 if (isprint((int)cur))
394 {
395 printf("%c", cur);
396 }
397397 }
398398 printf("\n");
399399 }
413413 if ((y < SCREENHEIGHT) && (x < SCREENWIDTH))
414414 {
415415 #ifdef CONSOLE
416 gotoxy(x+1, y+1);
417 if (kbhit())
418 {
419 char c;
420 /* ideally, pop up a debugging tool. for now, exit. */
421 c = getch();
422 if (c == 0)
423 {
424 c = getch();
425 } else
426 {
427 if (c == 27)
428 {
429 /* pause */
430 c = getch();
431 if (c == 0)
432 {
433 c = getch();
434 } else
435 {
436 if (c == 27)
437 {
438 goto the_end;
439 }
440 }
441 }
442 }
443 }
416 gotoxy(x+1, y+1);
417 if (kbhit())
418 {
419 char c;
420 /* ideally, pop up a debugging tool. for now, exit. */
421 c = getch();
422 if (c == 0)
423 {
424 c = getch();
425 } else
426 {
427 if (c == 27)
428 {
429 /* pause */
430 c = getch();
431 if (c == 0)
432 {
433 c = getch();
434 } else
435 {
436 if (c == 27)
437 {
438 goto the_end;
439 }
440 }
441 }
442 }
443 }
444444 #else
445 printf ("%c[%d;%dH", 27, y+1, x+1);
446 fflush (stdout);
445 printf ("%c[%d;%dH", 27, y+1, x+1);
446 fflush (stdout);
447447 #endif /* CONSOLE */
448448 }
449449 befsleep (deldur);
451451 if (stringmode && (cur != '"'))
452452 push (cur);
453453 else if (isdigit ((int)cur))
454 push (cur - '0');
454 push (cur - '0');
455455 else
456 switch (cur)
457 {
458 case '>': /* PC Right */
459 dx = 1;
460 dy = 0;
461 break;
462 case '<': /* PC Left */
463 dx = -1;
464 dy = 0;
465 break;
466 case '^': /* PC Up */
467 dx = 0;
468 dy = -1;
469 break;
470 case 'v': /* PC Down */
471 dx = 0;
472 dy = 1;
473 break;
474 case '|': /* Vertical 'If' */
475 dx = 0;
476 if (pop ())
477 dy = -1;
478 else
479 dy = 1;
480 break;
481 case '_': /* Horizontal 'If' */
482 dy = 0;
483 if (pop ())
484 dx = -1;
485 else
486 dx = 1;
487 break;
488 case '+': /* Add */
489 push (pop () + pop ());
490 break;
491 case '-': /* Subtract */
492 {
493 long a = pop();
494 long b = pop();
495 push(b - a);
496 }
497 break;
498 case '*': /* Multiply */
499 push (pop () * pop ());
500 break;
501 case '/': /* Integer Divide */
502 {
503 signed long a = pop ();
504 signed long b = pop ();
505 if (a == 0)
506 {
507 if (!outfile)
508 {
509 printf("What do you want %ld/0 to be? ", b);
510 } else
511 {
512 fprintf(fo, "What do you want %ld/0 to be? ", b);
513 }
514 if (infile)
515 {
516 fscanf (fi, "%ld", &b);
517 push (b);
518 } else
519 {
520 if (!debug)
521 {
522 fscanf (stdin, "%ld", &b);
523 push (b);
524 }
525 }
526 } else
527 {
528 push (b / a);
529 }
530 }
531 break;
532 case '%': /* Modulo */
533 {
534 signed long a = pop ();
535 signed long b = pop ();
536 push (b % a);
537 }
538 break;
539 case '\\': /* Swap */
540 {
541 signed long a = pop ();
542 signed long b = pop ();
543 push (a);
544 push (b);
545 }
546 break;
547 case '.': /* Pop Out Integer */
548 {
549 if (outfile)
550 {
551 fprintf (fo, "%ld ", pop ());
552 fflush (fo);
553 } else
554 {
555 if (!debug)
556 {
557 fprintf (stdout, "%ld ", pop ());
558 fflush (stdout);
559 } else
560 {
456 switch (cur)
457 {
458 case '>': /* PC Right */
459 dx = 1;
460 dy = 0;
461 break;
462 case '<': /* PC Left */
463 dx = -1;
464 dy = 0;
465 break;
466 case '^': /* PC Up */
467 dx = 0;
468 dy = -1;
469 break;
470 case 'v': /* PC Down */
471 dx = 0;
472 dy = 1;
473 break;
474 case '|': /* Vertical 'If' */
475 dx = 0;
476 if (pop ())
477 dy = -1;
478 else
479 dy = 1;
480 break;
481 case '_': /* Horizontal 'If' */
482 dy = 0;
483 if (pop ())
484 dx = -1;
485 else
486 dx = 1;
487 break;
488 case '+': /* Add */
489 push (pop () + pop ());
490 break;
491 case '-': /* Subtract */
492 {
493 long a = pop();
494 long b = pop();
495 push(b - a);
496 }
497 break;
498 case '*': /* Multiply */
499 push (pop () * pop ());
500 break;
501 case '/': /* Integer Divide */
502 {
503 signed long a = pop ();
504 signed long b = pop ();
505 if (a == 0)
506 {
507 if (!outfile)
508 {
509 printf("What do you want %ld/0 to be? ", b);
510 } else
511 {
512 fprintf(fo, "What do you want %ld/0 to be? ", b);
513 }
514 if (infile)
515 {
516 fscanf (fi, "%ld", &b);
517 push (b);
518 } else
519 {
520 if (!debug)
521 {
522 fscanf (stdin, "%ld", &b);
523 push (b);
524 }
525 }
526 } else
527 {
528 push (b / a);
529 }
530 }
531 break;
532 case '%': /* Modulo */
533 {
534 signed long a = pop ();
535 signed long b = pop ();
536 push (b % a);
537 }
538 break;
539 case '\\': /* Swap */
540 {
541 signed long a = pop ();
542 signed long b = pop ();
543 push (a);
544 push (b);
545 }
546 break;
547 case '.': /* Pop Out Integer */
548 {
549 if (outfile)
550 {
551 fprintf (fo, "%ld ", pop ());
552 fflush (fo);
553 } else
554 {
555 if (!debug)
556 {
557 fprintf (stdout, "%ld ", pop ());
558 fflush (stdout);
559 } else
560 {
561561 #ifdef CONSOLE
562 int x, y;
563 char s[172], t[172];
564 x = wherex();
565 y = wherey();
566 sprintf(s, "%ld ", pop());
567 gettext(1+strlen(s), DEBUGROW, 80, DEBUGROW, t);
568 puttext(1, DEBUGROW, 80-strlen(s), DEBUGROW, t);
569 gotoxy(81-strlen(s), DEBUGROW);
570 cputs(s);
571 gotoxy(x, y);
562 int x, y;
563 char s[172], t[172];
564 x = wherex();
565 y = wherey();
566 sprintf(s, "%ld ", pop());
567 gettext(1+strlen(s), DEBUGROW, 80, DEBUGROW, t);
568 puttext(1, DEBUGROW, 80-strlen(s), DEBUGROW, t);
569 gotoxy(81-strlen(s), DEBUGROW);
570 cputs(s);
571 gotoxy(x, y);
572572 #endif /* CONSOLE */
573 }
574 }
575 }
576 break;
577 case ',': /* Pop Out ASCII */
578 {
579 if (outfile)
580 {
581 fprintf (fo, "%c", (char)pop ());
582 fflush (fo);
583 } else
584 {
585 if (!debug)
586 {
587 fprintf (stdout, "%c", (char)pop ());
588 fflush (stdout);
589 } else
590 {
573 }
574 }
575 }
576 break;
577 case ',': /* Pop Out ASCII */
578 {
579 if (outfile)
580 {
581 fprintf (fo, "%c", (char)pop ());
582 fflush (fo);
583 } else
584 {
585 if (!debug)
586 {
587 fprintf (stdout, "%c", (char)pop ());
588 fflush (stdout);
589 } else
590 {
591591 #ifdef CONSOLE
592 int x, y;
593 long int p = pop();
594 char t[172];
595 x = wherex();
596 y = wherey();
597 gettext(2, DEBUGROW, 80, DEBUGROW, t);
598 puttext(1, DEBUGROW, 79, DEBUGROW, t);
599 gotoxy(80, DEBUGROW);
600 if ((p >= 32) && (p <= 255))
601 {
602 putch((int)p);
603 } else
604 {
605 if (p == 10)
606 {
607 putch(179);
608 } else
609 {
610 putch(168);
611 }
612 }
613 gotoxy(x, y);
592 int x, y;
593 long int p = pop();
594 char t[172];
595 x = wherex();
596 y = wherey();
597 gettext(2, DEBUGROW, 80, DEBUGROW, t);
598 puttext(1, DEBUGROW, 79, DEBUGROW, t);
599 gotoxy(80, DEBUGROW);
600 if ((p >= 32) && (p <= 255))
601 {
602 putch((int)p);
603 } else
604 {
605 if (p == 10)
606 {
607 putch(179);
608 } else
609 {
610 putch(168);
611 }
612 }
613 gotoxy(x, y);
614614 #endif /* CONSOLE */
615 }
616 }
617 }
618 break;
619 case '"': /* Toggle String Mode */
620 stringmode = !stringmode;
621 break;
622 case ':': /* Duplicate */
623 {
624 signed long a = pop ();
625 push (a);
626 push (a);
627 }
628 break;
629 case '!': /* Negate */
630 if (pop())
631 push(0);
632 else
633 push(1);
634 break;
635 case '`':
636 {
637 signed long b = pop ();
638 signed long a = pop ();
639 push (a > b);
640 }
641 break;
642 case '#': /* Bridge */
643 x += dx;
644 y += dy;
645 break;
646 case '$': /* Pop and Discard */
647 pop ();
648 break;
649 case '?': /* Random Redirect */
650 switch ((rand () / 32) % 4)
651 {
652 case 0:
653 dx = 1;
654 dy = 0;
655 break;
656 case 1:
657 dx = -1;
658 dy = 0;
659 break;
660 case 2:
661 dx = 0;
662 dy = -1;
663 break;
664 case 3:
665 dx = 0;
666 dy = 1;
667 break;
668 }
669 break;
670 case '&': /* Input Integer */
671 {
672 signed long b;
673 if (infile)
674 {
675 fscanf (fi, "%ld", &b);
676 push (b);
677 } else
678 {
679 if (!debug)
680 {
681 fscanf (stdin, "%ld", &b);
682 push (b);
683 } else
684 {
615 }
616 }
617 }
618 break;
619 case '"': /* Toggle String Mode */
620 stringmode = !stringmode;
621 break;
622 case ':': /* Duplicate */
623 {
624 signed long a = pop ();
625 push (a);
626 push (a);
627 }
628 break;
629 case '!': /* Negate */
630 if (pop())
631 push(0);
632 else
633 push(1);
634 break;
635 case '`':
636 {
637 signed long b = pop ();
638 signed long a = pop ();
639 push (a > b);
640 }
641 break;
642 case '#': /* Bridge */
643 x += dx;
644 y += dy;
645 break;
646 case '$': /* Pop and Discard */
647 pop ();
648 break;
649 case '?': /* Random Redirect */
650 switch ((rand () / 32) % 4)
651 {
652 case 0:
653 dx = 1;
654 dy = 0;
655 break;
656 case 1:
657 dx = -1;
658 dy = 0;
659 break;
660 case 2:
661 dx = 0;
662 dy = -1;
663 break;
664 case 3:
665 dx = 0;
666 dy = 1;
667 break;
668 }
669 break;
670 case '&': /* Input Integer */
671 {
672 signed long b;
673 if (infile)
674 {
675 fscanf (fi, "%ld", &b);
676 push (b);
677 } else
678 {
679 if (!debug)
680 {
681 fscanf (stdin, "%ld", &b);
682 push (b);
683 } else
684 {
685685 #ifdef CONSOLE
686 int x, y;
687 long int p;
688 char t[172];
689 x = wherex();
690 y = wherey();
691 gettext(10, DEBUGROW, 80, DEBUGROW, t);
692 puttext(1, DEBUGROW, 71, DEBUGROW, t);
693 gotoxy(72, DEBUGROW);
694 clreol();
695 cscanf("%ld", &p);
696 push(p);
697 gotoxy(x, y);
686 int x, y;
687 long int p;
688 char t[172];
689 x = wherex();
690 y = wherey();
691 gettext(10, DEBUGROW, 80, DEBUGROW, t);
692 puttext(1, DEBUGROW, 71, DEBUGROW, t);
693 gotoxy(72, DEBUGROW);
694 clreol();
695 cscanf("%ld", &p);
696 push(p);
697 gotoxy(x, y);
698698 #endif /* CONSOLE */
699 }
700 }
701 }
702 break;
703 case '~': /* Input ASCII */
704 {
705 char c;
706 if (infile)
707 {
708 c = fgetc (fi);
709 push (c);
710 } else
711 {
712 if (!debug)
713 {
714 c = fgetc (stdin);
715 push (c);
716 } else
717 {
699 }
700 }
701 }
702 break;
703 case '~': /* Input ASCII */
704 {
705 char c;
706 if (infile)
707 {
708 c = fgetc (fi);
709 push (c);
710 } else
711 {
712 if (!debug)
713 {
714 c = fgetc (stdin);
715 push (c);
716 } else
717 {
718718 #ifdef CONSOLE
719 int x, y;
720 long int p;
721 char t[172];
722 x = wherex();
723 y = wherey();
724 gettext(2, DEBUGROW, 80, DEBUGROW, t);
725 puttext(1, DEBUGROW, 79, DEBUGROW, t);
726 gotoxy(80, DEBUGROW);
727 clreol();
728 p = getche();
729 if (p == '\r')
730 {
731 p = '\n';
732 gotoxy(80, DEBUGROW);
733 putch(179);
734 }
735 push(p);
736 gotoxy(x, y);
719 int x, y;
720 long int p;
721 char t[172];
722 x = wherex();
723 y = wherey();
724 gettext(2, DEBUGROW, 80, DEBUGROW, t);
725 puttext(1, DEBUGROW, 79, DEBUGROW, t);
726 gotoxy(80, DEBUGROW);
727 clreol();
728 p = getche();
729 if (p == '\r')
730 {
731 p = '\n';
732 gotoxy(80, DEBUGROW);
733 putch(179);
734 }
735 push(p);
736 gotoxy(x, y);
737737 #endif /* CONSOLE */
738 }
739 }
740 }
741 break;
742 case 'g': /* Get Value */
743 {
744 signed long y = pop (), x = pop ();
745 if ((y < PAGEHEIGHT) && (y >= 0) && (x < LINEWIDTH) && (x >= 0))
746 {
747 push (cur);
748 } else
749 {
750 if (!debug)
751 {
752 if (!quiet)
753 {
754 fprintf(stderr, "g 'Get' instruction out of bounds (%ld,%ld)\n", x, y);
755 }
756 }
757 push (0);
758 }
759 }
760 break;
761 case 'p': /* Put Value */
762 {
763 signed long y = pop (), x = pop ();
764 if ((y < PAGEHEIGHT) && (y >= 0) && (x < LINEWIDTH) && (x >= 0))
765 {
766 cur = pop ();
767 } else
768 {
769 if (!debug)
770 {
771 if (!quiet)
772 {
773 fprintf(stderr, "p 'Put' instruction out of bounds (%ld,%ld)\n", x, y);
774 }
775 }
776 pop();
777 }
778 if ((debug) && (y < SCREENHEIGHT) && (x < SCREENWIDTH))
779 {
738 }
739 }
740 }
741 break;
742 case 'g': /* Get Value */
743 {
744 signed long y = pop (), x = pop ();
745 if ((y < PAGEHEIGHT) && (y >= 0) && (x < LINEWIDTH) && (x >= 0))
746 {
747 push (cur);
748 } else
749 {
750 if (!debug)
751 {
752 if (!quiet)
753 {
754 fprintf(stderr, "g 'Get' instruction out of bounds (%ld,%ld)\n", x, y);
755 }
756 }
757 push (0);
758 }
759 }
760 break;
761 case 'p': /* Put Value */
762 {
763 signed long y = pop (), x = pop ();
764 if ((y < PAGEHEIGHT) && (y >= 0) && (x < LINEWIDTH) && (x >= 0))
765 {
766 cur = pop ();
767 } else
768 {
769 if (!debug)
770 {
771 if (!quiet)
772 {
773 fprintf(stderr, "p 'Put' instruction out of bounds (%ld,%ld)\n", x, y);
774 }
775 }
776 pop();
777 }
778 if ((debug) && (y < SCREENHEIGHT) && (x < SCREENWIDTH))
779 {
780780 #ifdef CONSOLE
781 gotoxy(x+1,y+1);
781 gotoxy(x+1,y+1);
782782 #else
783 printf ("%c[%d;%dH", 27, (int)(y+1), (int)(x+1));
783 printf ("%c[%d;%dH", 27, (int)(y+1), (int)(x+1));
784784 #endif /* CONSOLE */
785 if (isprint ((int)cur)) printf ("%c", cur); else printf(".");
786 }
787 }
788 break;
789 case ' ':
790 break;
791 default:
792 if ((!debug) && (!ignore_unsupported) && (!quiet))
793 {
794 fprintf(stderr, "Unsupported instruction '%c' (0x%02x) (maybe not Befunge-93?)\n", cur, cur);
795 }
796 break;
797 }
785 if (isprint ((int)cur)) printf ("%c", cur); else printf(".");
786 }
787 }
788 break;
789 case ' ':
790 break;
791 default:
792 if ((!debug) && (!ignore_unsupported) && (!quiet))
793 {
794 fprintf(stderr, "Unsupported instruction '%c' (0x%02x) (maybe not Befunge-93?)\n", cur, cur);
795 }
796 break;
797 }
798798 x += dx;
799799 y += dy;
800800 if (x < 0)
801 if (v10err_compat)
802 {
803 x = LINEWIDTH;
804 } else if (inconsistent_trampoline)
805 {
806 x = LINEWIDTH - 1;
807 } else
801 if (v10err_compat)
802 {
803 x = LINEWIDTH;
804 } else if (inconsistent_trampoline)
805 {
806 x = LINEWIDTH - 1;
807 } else
808808 {
809809 x += LINEWIDTH;
810810 }
811811 else
812 x = x % LINEWIDTH;
812 x = x % LINEWIDTH;
813813 if (y < 0)
814 if (v10err_compat)
815 {
816 y = PAGEHEIGHT;
817 } else if (inconsistent_trampoline)
818 {
819 y = PAGEHEIGHT - 1;
820 } else
814 if (v10err_compat)
815 {
816 y = PAGEHEIGHT;
817 } else if (inconsistent_trampoline)
818 {
819 y = PAGEHEIGHT - 1;
820 } else
821821 {
822822 y += PAGEHEIGHT;
823823 }
824824 else
825 y = y % PAGEHEIGHT;
825 y = y % PAGEHEIGHT;
826826 if (stackfile)
827827 {
828 struct stack *s;
829 for (s = head; s; s = s->next)
830 fprintf(fs, "%ld ", s->val);
831 fprintf(fs, "\n");
832 fflush(fs);
828 struct stack *s;
829 for (s = head; s; s = s->next)
830 fprintf(fs, "%ld ", s->val);
831 fprintf(fs, "\n");
832 fflush(fs);
833833 }
834834 }
835835
868868 delay (dur);
869869 #else
870870 #ifdef _POSIX_C_SOURCE
871 struct timespec tv;
871 struct timespec tv;
872872
873873 tv.tv_sec = dur / 1000;
874874 tv.tv_nsec = (dur % 1000) * 1000000;
875875
876 nanosleep(&tv, NULL);
876 nanosleep(&tv, NULL);
877877 #else
878 sleep (dur / 1000);
878 sleep (dur / 1000);
879879 #endif
880880 #endif
881881 }
4747
4848 Known to Compile Under :
4949
50 Borland C++ v3.1 (DOS)
50 Borland C++ v3.1 (DOS)
5151
5252 History:
5353
9999 #define ALL RIGHT ": " LEFT ": " UP ": " DOWN ":\n"
100100
101101 #define ECHO(s) fprintf(fo, RIGHT ": " s " goto " RIGHT ";\n", x, y, x_right, y); \
102 fprintf(fo, LEFT ": " s " goto " LEFT ";\n", x, y, x_left, y); \
103 fprintf(fo, UP ": " s " goto " UP ";\n", x, y, x, y_up); \
104 fprintf(fo, DOWN ": " s " goto " DOWN ";\n", x, y, x, y_down);
102 fprintf(fo, LEFT ": " s " goto " LEFT ";\n", x, y, x_left, y); \
103 fprintf(fo, UP ": " s " goto " UP ";\n", x, y, x, y_up); \
104 fprintf(fo, DOWN ": " s " goto " DOWN ";\n", x, y, x, y_down);
105105
106106 /*************************************************** GLOBAL VARIABLES */
107107
108108 char in[255];
109109 char pg[2000]; /* befunge 'page' of source */
110110 int x = 0, y = 0, d = 0; /* loopers */
111 int pre_optimize = 1; /* flag: optimize before compile? */
112 int post_optimize = 1; /* flag: optimize after compile? */
111 int pre_optimize = 1; /* flag: optimize before compile? */
112 int post_optimize = 1; /* flag: optimize after compile? */
113113
114114 int labelrefs[8000]; /* postoptimization table */
115115 char s[255];
160160 if ((y+1)>pageheight) pageheight=y+1;
161161 if (cur == '\n')
162162 {
163 cur = ' ';
164 x = 0;
165 y++;
166 if (y >= 25) break;
163 cur = ' ';
164 x = 0;
165 y++;
166 if (y >= 25) break;
167167 } else
168168 {
169 x++;
170 if (x >= 80)
171 {
172 x = 0;
173 y++;
174 if (y >= 25) break;
175 }
169 x++;
170 if (x >= 80)
171 {
172 x = 0;
173 y++;
174 if (y >= 25) break;
175 }
176176 }
177177 }
178178 fclose (fi);
191191 printf ("Compiling");
192192
193193 fprintf (fo, "/* %s converted to ANSI C from %s by bef2c */\n",
194 argv[argc-1], argv[argc-2]);
194 argv[argc-1], argv[argc-2]);
195195 fprintf (fo, "#include <stdio.h>\n");
196196 fprintf (fo, "#include <stdlib.h>\n");
197197 fprintf (fo, "#include <time.h>\n\n");
210210 {
211211 if (cur!='\\')
212212 {
213 fprintf (fo, " pg[%d]='%c';\n", y * 80 + x, cur);
213 fprintf (fo, " pg[%d]='%c';\n", y * 80 + x, cur);
214214 } else
215215 {
216 fprintf (fo, " pg[%d]='%c%c';\n", y * 80 + x, cur, cur);
216 fprintf (fo, " pg[%d]='%c%c';\n", y * 80 + x, cur, cur);
217217 }
218218 }
219219 }
226226 {
227227 switch (cur)
228228 {
229 case '0': case '1': case '2': case '3': case '4':
230 case '5': case '6': case '7': case '8': case '9':
231 fprintf(fo, RIGHT ": push(%c); goto " RIGHT ";\n", x, y, cur, x_right, y);
232 fprintf(fo, LEFT ": push(%c); goto " LEFT ";\n", x, y, cur, x_left, y);
233 fprintf(fo, UP ": push(%c); goto " UP ";\n", x, y, cur, x, y_up);
234 fprintf(fo, DOWN ": push(%c); goto " DOWN ";\n", x, y, cur, x, y_down);
235 break;
236 case '>': /* PC Right */
237 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
238 fprintf(fo, " goto " RIGHT ";\n", x_right, y);
239 break;
240 case '<': /* PC Left */
241 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
242 fprintf(fo, " goto " LEFT ";\n", x_left, y);
243 break;
244 case '^': /* PC Up */
245 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
246 fprintf(fo, " goto " UP ";\n", x, y_up);
247 break;
248 case 'v': /* PC Down */
249 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
250 fprintf(fo, " goto " DOWN ";\n", x, y_down);
251 break;
252 case '|': /* Vert If */
253 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
254 fprintf(fo, " if (pop ()) goto " UP "; else goto " DOWN ";\n", x, y_up, x, y_down);
255 break;
256 case '_': /* Horiz If */
257 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
258 fprintf(fo, " if (pop ()) goto " LEFT "; else goto " RIGHT ";\n", x_left, y, x_right, y);
259 break;
260 case '+':
261 ECHO("push(pop()+pop());");
262 break;
263 case '-':
264 ECHO("a=pop();b=pop();push(b-a);");
265 break;
266 case '*':
267 ECHO("push(pop()*pop());");
268 break;
269 case '/':
270 ECHO("a=pop();b=pop();push(b/a);");
271 break;
272 case '%':
273 sprintf(t, "a=pop();b=pop();push(b%ca);", '%');
274 fprintf(fo, RIGHT ": %s goto " RIGHT ";\n", x, y, t, x_right, y);
275 fprintf(fo, LEFT ": %s goto " LEFT ";\n", x, y, t, x_left, y);
276 fprintf(fo, UP ": %s goto " UP ";\n", x, y, t, x, y_up);
277 fprintf(fo, DOWN ": %s goto " DOWN ";\n", x, y, t, x, y_down);
278 break;
279 case '\\':
280 ECHO("a=pop();b=pop();push(a);push(b);");
281 break;
282 case ':':
283 ECHO("a=pop();push(a);push(a);");
284 break;
285 case '.':
286 fprintf(fo, RIGHT ": fprintf(stdout,\"%cld \",pop());fflush(stdout); goto " RIGHT ";\n", x, y, '%', x_right, y);
287 fprintf(fo, LEFT ": fprintf(stdout,\"%cld \",pop());fflush(stdout); goto " LEFT ";\n", x, y, '%', x_left, y);
288 fprintf(fo, UP ": fprintf(stdout,\"%cld \",pop());fflush(stdout); goto " UP ";\n", x, y, '%', x, y_up);
289 fprintf(fo, DOWN ": fprintf(stdout,\"%cld \",pop());fflush(stdout); goto " DOWN ";\n", x, y, '%', x, y_down);
290 break;
291 case ',':
292 fprintf(fo, RIGHT ": fprintf(stdout,\"%cc\",pop());fflush(stdout); goto " RIGHT ";\n", x, y, '%', x_right, y);
293 fprintf(fo, LEFT ": fprintf(stdout,\"%cc\",pop());fflush(stdout); goto " LEFT ";\n", x, y, '%', x_left, y);
294 fprintf(fo, UP ": fprintf(stdout,\"%cc\",pop());fflush(stdout); goto " UP ";\n", x, y, '%', x, y_up);
295 fprintf(fo, DOWN ": fprintf(stdout,\"%cc\",pop());fflush(stdout); goto " DOWN ";\n", x, y, '%', x, y_down);
296 break;
297 case '&':
298 fprintf(fo, RIGHT ": fscanf(stdin,\"%cld\",&b);push(b); goto " RIGHT ";\n", x, y, '%', x_right, y);
299 fprintf(fo, LEFT ": fscanf(stdin,\"%cld\",&b);push(b); goto " LEFT ";\n", x, y, '%', x_left, y);
300 fprintf(fo, UP ": fscanf(stdin,\"%cld\",&b);push(b); goto " UP ";\n", x, y, '%', x, y_up);
301 fprintf(fo, DOWN ": fscanf(stdin,\"%cld\",&b);push(b); goto " DOWN ";\n", x, y, '%', x, y_down);
302 break;
303 case '~':
304 fprintf(fo, RIGHT ": c=fgetc(stdin);push(c); goto " RIGHT ";\n", x, y, x_right, y);
305 fprintf(fo, LEFT ": c=fgetc(stdin);push(c); goto " LEFT ";\n", x, y, x_left, y);
306 fprintf(fo, UP ": c=fgetc(stdin);push(c); goto " UP ";\n", x, y, x, y_up);
307 fprintf(fo, DOWN ": c=fgetc(stdin);push(c); goto " DOWN ";\n", x, y, x, y_down);
308 break;
309 case '"': /* ha! */
310 ECHO("puts(\"Error: compiled Befunge does not support stringmode\n\");");
311 break;
312 case '!':
313 ECHO("if(pop()) push(0); else push(1);");
314 break;
315 case '`':
316 ECHO("b=pop();a=pop();push(a>b);");
317 break;
318 case '$':
319 ECHO("pop();");
320 break;
321 case '?':
322 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
323 fprintf(fo, " switch ((rand () / 32) %c 4) \n"
324 " { case 0: goto " RIGHT ";\n"
325 " case 1: goto " LEFT ";\n"
326 " case 2: goto " UP ";\n"
327 " case 3: goto " DOWN "; }\n",
328 '%', x_right, y, x_left, y, x, y_up, x, y_down);
329 break;
330 case '#':
331 fprintf(fo, RIGHT ": goto " RIGHT ";\n", x, y, x_2right, y);
332 fprintf(fo, LEFT ": goto " LEFT ";\n", x, y, x_2left, y);
333 fprintf(fo, UP ": goto " UP ";\n", x, y, x, y_2up);
334 fprintf(fo, DOWN ": goto " DOWN ";\n", x, y, x, y_2down);
335 break;
336 case 'g':
337 ECHO("a=pop();b=pop();push(pg[a*80+b]);");
338 break;
339 case 'p':
340 ECHO("a=pop();b=pop();pg[a*80+b]=pop();");
341 break;
342 case '@':
343 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
344 fprintf(fo, " exit(0);");
345 break;
346 default:
347 ECHO("");
348 break;
229 case '0': case '1': case '2': case '3': case '4':
230 case '5': case '6': case '7': case '8': case '9':
231 fprintf(fo, RIGHT ": push(%c); goto " RIGHT ";\n", x, y, cur, x_right, y);
232 fprintf(fo, LEFT ": push(%c); goto " LEFT ";\n", x, y, cur, x_left, y);
233 fprintf(fo, UP ": push(%c); goto " UP ";\n", x, y, cur, x, y_up);
234 fprintf(fo, DOWN ": push(%c); goto " DOWN ";\n", x, y, cur, x, y_down);
235 break;
236 case '>': /* PC Right */
237 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
238 fprintf(fo, " goto " RIGHT ";\n", x_right, y);
239 break;
240 case '<': /* PC Left */
241 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
242 fprintf(fo, " goto " LEFT ";\n", x_left, y);
243 break;
244 case '^': /* PC Up */
245 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
246 fprintf(fo, " goto " UP ";\n", x, y_up);
247 break;
248 case 'v': /* PC Down */
249 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
250 fprintf(fo, " goto " DOWN ";\n", x, y_down);
251 break;
252 case '|': /* Vert If */
253 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
254 fprintf(fo, " if (pop ()) goto " UP "; else goto " DOWN ";\n", x, y_up, x, y_down);
255 break;
256 case '_': /* Horiz If */
257 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
258 fprintf(fo, " if (pop ()) goto " LEFT "; else goto " RIGHT ";\n", x_left, y, x_right, y);
259 break;
260 case '+':
261 ECHO("push(pop()+pop());");
262 break;
263 case '-':
264 ECHO("a=pop();b=pop();push(b-a);");
265 break;
266 case '*':
267 ECHO("push(pop()*pop());");
268 break;
269 case '/':
270 ECHO("a=pop();b=pop();push(b/a);");
271 break;
272 case '%':
273 sprintf(t, "a=pop();b=pop();push(b%ca);", '%');
274 fprintf(fo, RIGHT ": %s goto " RIGHT ";\n", x, y, t, x_right, y);
275 fprintf(fo, LEFT ": %s goto " LEFT ";\n", x, y, t, x_left, y);
276 fprintf(fo, UP ": %s goto " UP ";\n", x, y, t, x, y_up);
277 fprintf(fo, DOWN ": %s goto " DOWN ";\n", x, y, t, x, y_down);
278 break;
279 case '\\':
280 ECHO("a=pop();b=pop();push(a);push(b);");
281 break;
282 case ':':
283 ECHO("a=pop();push(a);push(a);");
284 break;
285 case '.':
286 fprintf(fo, RIGHT ": fprintf(stdout,\"%cld \",pop());fflush(stdout); goto " RIGHT ";\n", x, y, '%', x_right, y);
287 fprintf(fo, LEFT ": fprintf(stdout,\"%cld \",pop());fflush(stdout); goto " LEFT ";\n", x, y, '%', x_left, y);
288 fprintf(fo, UP ": fprintf(stdout,\"%cld \",pop());fflush(stdout); goto " UP ";\n", x, y, '%', x, y_up);
289 fprintf(fo, DOWN ": fprintf(stdout,\"%cld \",pop());fflush(stdout); goto " DOWN ";\n", x, y, '%', x, y_down);
290 break;
291 case ',':
292 fprintf(fo, RIGHT ": fprintf(stdout,\"%cc\",pop());fflush(stdout); goto " RIGHT ";\n", x, y, '%', x_right, y);
293 fprintf(fo, LEFT ": fprintf(stdout,\"%cc\",pop());fflush(stdout); goto " LEFT ";\n", x, y, '%', x_left, y);
294 fprintf(fo, UP ": fprintf(stdout,\"%cc\",pop());fflush(stdout); goto " UP ";\n", x, y, '%', x, y_up);
295 fprintf(fo, DOWN ": fprintf(stdout,\"%cc\",pop());fflush(stdout); goto " DOWN ";\n", x, y, '%', x, y_down);
296 break;
297 case '&':
298 fprintf(fo, RIGHT ": fscanf(stdin,\"%cld\",&b);push(b); goto " RIGHT ";\n", x, y, '%', x_right, y);
299 fprintf(fo, LEFT ": fscanf(stdin,\"%cld\",&b);push(b); goto " LEFT ";\n", x, y, '%', x_left, y);
300 fprintf(fo, UP ": fscanf(stdin,\"%cld\",&b);push(b); goto " UP ";\n", x, y, '%', x, y_up);
301 fprintf(fo, DOWN ": fscanf(stdin,\"%cld\",&b);push(b); goto " DOWN ";\n", x, y, '%', x, y_down);
302 break;
303 case '~':
304 fprintf(fo, RIGHT ": c=fgetc(stdin);push(c); goto " RIGHT ";\n", x, y, x_right, y);
305 fprintf(fo, LEFT ": c=fgetc(stdin);push(c); goto " LEFT ";\n", x, y, x_left, y);
306 fprintf(fo, UP ": c=fgetc(stdin);push(c); goto " UP ";\n", x, y, x, y_up);
307 fprintf(fo, DOWN ": c=fgetc(stdin);push(c); goto " DOWN ";\n", x, y, x, y_down);
308 break;
309 case '"': /* ha! */
310 ECHO("puts(\"Error: compiled Befunge does not support stringmode\n\");");
311 break;
312 case '!':
313 ECHO("if(pop()) push(0); else push(1);");
314 break;
315 case '`':
316 ECHO("b=pop();a=pop();push(a>b);");
317 break;
318 case '$':
319 ECHO("pop();");
320 break;
321 case '?':
322 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
323 fprintf(fo, " switch ((rand () / 32) %c 4) \n"
324 " { case 0: goto " RIGHT ";\n"
325 " case 1: goto " LEFT ";\n"
326 " case 2: goto " UP ";\n"
327 " case 3: goto " DOWN "; }\n",
328 '%', x_right, y, x_left, y, x, y_up, x, y_down);
329 break;
330 case '#':
331 fprintf(fo, RIGHT ": goto " RIGHT ";\n", x, y, x_2right, y);
332 fprintf(fo, LEFT ": goto " LEFT ";\n", x, y, x_2left, y);
333 fprintf(fo, UP ": goto " UP ";\n", x, y, x, y_2up);
334 fprintf(fo, DOWN ": goto " DOWN ";\n", x, y, x, y_2down);
335 break;
336 case 'g':
337 ECHO("a=pop();b=pop();push(pg[a*80+b]);");
338 break;
339 case 'p':
340 ECHO("a=pop();b=pop();pg[a*80+b]=pop();");
341 break;
342 case '@':
343 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
344 fprintf(fo, " exit(0);");
345 break;
346 default:
347 ECHO("");
348 break;
349349 }
350350 }
351351 printf (".");
370370 {
371371 for(y = 0; y < 25; y++)
372372 {
373 for(x = 0; x < 80; x++)
374 {
375 labelrefs[y * 80 + x] = 0;
376 }
373 for(x = 0; x < 80; x++)
374 {
375 labelrefs[y * 80 + x] = 0;
376 }
377377 }
378378 if ((fi = fopen (argv[argc - 1], "r")) != NULL)
379379 {
380 while (!feof(fi))
381 {
382 fscanf(fi, "%s", in);
383 if (!strcmp(in, "goto"))
384 {
385 fscanf(fi, "%d_%d_%s", &x, &y, s);
386 switch (s[0]) { case 'L': d = 0; break;
387 case 'R': d = 1; break;
388 case 'U': d = 2; break;
389 case 'D': d = 3; break; }
390 labelrefs[d * 2000 + y * 80 + x]++;
391 }
392 }
393 rewind(fi);
380 while (!feof(fi))
381 {
382 fscanf(fi, "%s", in);
383 if (!strcmp(in, "goto"))
384 {
385 fscanf(fi, "%d_%d_%s", &x, &y, s);
386 switch (s[0]) { case 'L': d = 0; break;
387 case 'R': d = 1; break;
388 case 'U': d = 2; break;
389 case 'D': d = 3; break; }
390 labelrefs[d * 2000 + y * 80 + x]++;
391 }
392 }
393 rewind(fi);
394394 }
395395 printf (".");
396396 if ((fo = fopen ("temp.c", "w")) != NULL)
397397 {
398 while (!feof(fi))
399 {
400 fgets(in, 255, fi);
401 if (sscanf(in, "_%d_%d_%s: goto _%d_%d_%s;\n", &x0, &y0, t, &x1, &y1, s))
402 {
403 switch (s[0]) { case 'L': d = 0; break;
404 case 'R': d = 1; break;
405 case 'U': d = 2; break;
406 case 'D': d = 3; break; }
407 if (labelrefs[d * 2000 + y1 * 80 + x1])
408 {
409 fprintf(fo, "_%2.2d_%2.2d_%s ", x0, y0, t);
410 fprintf(fo, "goto _%2.2d_%2.2d_%s;\n", x1, y1, s);
411 }
412 } else
413 {
414 fprintf(fo, "%s", in);
415 }
416 }
398 while (!feof(fi))
399 {
400 fgets(in, 255, fi);
401 if (sscanf(in, "_%d_%d_%s: goto _%d_%d_%s;\n", &x0, &y0, t, &x1, &y1, s))
402 {
403 switch (s[0]) { case 'L': d = 0; break;
404 case 'R': d = 1; break;
405 case 'U': d = 2; break;
406 case 'D': d = 3; break; }
407 if (labelrefs[d * 2000 + y1 * 80 + x1])
408 {
409 fprintf(fo, "_%2.2d_%2.2d_%s ", x0, y0, t);
410 fprintf(fo, "goto _%2.2d_%2.2d_%s;\n", x1, y1, s);
411 }
412 } else
413 {
414 fprintf(fo, "%s", in);
415 }
416 }
417417 }
418418 fclose (fi);
419419 fclose (fo);
420420 if ((fi = fopen ("temp.c", "r")) != NULL)
421421 {
422 if ((fo = fopen (argv[argc - 1], "w")) != NULL)
423 {
424 while (!feof(fi))
425 {
426 fgets(in, 255, fi);
427 fprintf(fo, "%s", in);
428 }
429 }
422 if ((fo = fopen (argv[argc - 1], "w")) != NULL)
423 {
424 while (!feof(fi))
425 {
426 fgets(in, 255, fi);
427 fprintf(fo, "%s", in);
428 }
429 }
430430 }
431431 printf (".");
432432 }
3939 Usage :
4040
4141 befprof [-l] [-i] [-n count] [-r input-file] [-w report-file]
42 <befunge-source>
42 <befunge-source>
4343
4444 -i: use interactive I/O
4545 -r: redirect input from a specified file instead of stdin
46 generally use these only if random input and logic
47 does not well reflect reality, or causes a problem
48 with your source code (e.g. anagram.bf)
46 generally use these only if random input and logic
47 does not well reflect reality, or causes a problem
48 with your source code (e.g. anagram.bf)
4949 -l: randomize logic - makes | and _ execute randomly.
5050 -w: specify an output filename for report (if omitted,
51 <input-file>.map is used)
51 <input-file>.map is used)
5252 -n: repeat execution a given number of times (def. 1)
53 use to generate data with a better resolution.
54 although note that cells are stored as 2-byte words,
55 so too many repetitions may cause them to wrap back to 0.
53 use to generate data with a better resolution.
54 although note that cells are stored as 2-byte words,
55 so too many repetitions may cause them to wrap back to 0.
5656
5757 ******************************************************************
5858
6565 relicensed under BSD license
6666
6767 v0.92: Mar 1998, Chris Pressey
68 original Befunge-93 Profiler 'befprof' distribution.
68 original Befunge-93 Profiler 'befprof' distribution.
6969
7070 ****************************************************************** */
7171
221221 curbuf = fgetc (f);
222222 if (curbuf == '\n')
223223 {
224 curbuf = ' ';
225 x = 0;
226 y++;
227 if (y >= PAGEHEIGHT) break;
224 curbuf = ' ';
225 x = 0;
226 y++;
227 if (y >= PAGEHEIGHT) break;
228228 } else
229229 {
230 x++;
231 if (x >= LINEWIDTH)
232 {
233 x = 0;
234 y++;
235 if (y >= PAGEHEIGHT) break;
236 }
230 x++;
231 if (x >= LINEWIDTH)
232 {
233 x = 0;
234 y++;
235 if (y >= PAGEHEIGHT) break;
236 }
237237 }
238238 }
239239 fclose (f);
264264 {
265265 if (!(fi = fopen (argv[ia], "r")))
266266 {
267 printf ("Error : couldn't open '%s' for input.\n", argv[ia]);
268 exit (0);
267 printf ("Error : couldn't open '%s' for input.\n", argv[ia]);
268 exit (0);
269269 }
270270 }
271271
278278 if ((dx == 0) && (dy == -1)) incprof(INGRESS_SOUTH);
279279 if (stringmode && (cur != '"'))
280280 {
281 push (cur);
282 } else
281 push (cur);
282 } else
283283 if (isdigit ((int)cur))
284284 {
285 push (cur - '0');
285 push (cur - '0');
286286 } else
287287 switch (cur)
288288 {
289 case '>': /* PC Right */
290 dx = 1;
291 dy = 0;
292 break;
293 case '<': /* PC Left */
294 dx = -1;
295 dy = 0;
296 break;
297 case '^': /* PC Up */
298 dx = 0;
299 dy = -1;
300 break;
301 case 'v': /* PC Down */
302 dx = 0;
303 dy = 1;
304 break;
305 case '|': /* Vertical 'If' */
306 {
307 long int pp = pop();
308 dx = 0;
309 if (rand_logic) pp = ((rand () >> 3) % 2);
310 if (pp)
311 {
312 dy = -1;
313 } else
314 {
315 dy = 1;
316 }
317 break;
318 }
319 case '_': /* Horizontal 'If' */
320 {
321 long int pp = pop();
322 dy = 0;
323 if (rand_logic) pp = ((rand () >> 3) % 2);
324 if (pp)
325 {
326 dx = -1;
327 } else
328 {
329 dx = 1;
330 }
331 break;
332 }
333 case '+': /* Add */
334 push (pop () + pop ());
335 break;
336 case '-': /* Subtract */
337 {
338 long a = pop();
339 long b = pop();
340 push(b - a);
341 break;
342 }
343 case '*': /* Multiply */
344 push (pop () * pop ());
345 break;
346 case '/': /* Integer Divide */
347 {
348 signed long a = pop ();
349 signed long b = pop ();
350 if (a == 0)
351 {
352 if (infile)
353 {
354 fscanf (fi, "%ld", &b);
355 push (b);
356 } else
357 if (interactive)
358 {
359 printf("What do you want %ld/0 to be? ", b);
360 scanf ("%ld", &b);
361 push (b);
362 } else
363 {
364 push (rand() - 32767);
365 }
366 } else
367 {
368 push (b / a);
369 }
370 break;
371 }
372 case '%': /* Modulo */
373 {
374 signed long a = pop ();
375 signed long b = pop ();
376 push (b % a);
377 break;
378 }
379 case '\\': /* Swap */
380 {
381 signed long a = pop ();
382 signed long b = pop ();
383 push (a);
384 push (b);
385 break;
386 }
387 case '.': /* Pop Out Integer */
388 {
389 if (interactive)
390 {
391 printf ("%ld ", pop ());
392 fflush (stdout);
393 } else pop();
394 break;
395 }
396 case ',': /* Pop Out ASCII */
397 {
398 if (interactive)
399 {
400 printf ("%c", (char)pop ());
401 fflush (stdout);
402 } else pop();
403 break;
404 }
405 case '"': /* Toggle String Mode */
406 stringmode = !stringmode;
407 break;
408 case ':': /* Duplicate */
409 {
410 signed long a = pop ();
411 push (a);
412 push (a);
413 break;
414 }
415 case '!': /* Negate */
416 {
417 if (pop())
418 {
419 push(0);
420 } else
421 {
422 push(1);
423 }
424 break;
425 }
426 case '`':
427 {
428 signed long b = pop ();
429 signed long a = pop ();
430 if (a > b)
431 {
432 push(1);
433 } else
434 {
435 push(0);
436 }
437 break;
438 }
439 case '#': /* Bridge */
440 {
441 if ((dx == 1) && (dy == 0)) incprof(EGRESS_EAST);
442 if ((dx == -1) && (dy == 0)) incprof(EGRESS_WEST);
443 if ((dx == 0) && (dy == 1)) incprof(EGRESS_SOUTH);
444 if ((dx == 0) && (dy == -1)) incprof(EGRESS_NORTH);
445 x += dx;
446 y += dy;
447 flag_egress = 1;
448 break;
449 }
450 case '$': /* Pop and Discard */
451 {
452 pop ();
453 break;
454 }
455 case '?': /* Random Redirect */
456 {
457 switch ((rand () / 32) % 4)
458 {
459 case 0:
460 dx = 1;
461 dy = 0;
462 break;
463 case 1:
464 dx = -1;
465 dy = 0;
466 break;
467 case 2:
468 dx = 0;
469 dy = -1;
470 break;
471 case 3:
472 dx = 0;
473 dy = 1;
474 break;
475 }
476 break;
477 }
478 case '&': /* Input Integer */
479 {
480 signed long b;
481 if (infile)
482 {
483 fscanf (fi, "%ld", &b);
484 push (b);
485 } else
486 if (interactive)
487 {
488 scanf ("%ld", &b);
489 push (b);
490 } else
491 {
492 push (rand() - 32767);
493 }
494 break;
495 }
496 case '~': /* Input ASCII */
497 {
498 char c;
499 if (infile)
500 {
501 c = fgetc (fi);
502 push (c);
503 } else
504 if (interactive)
505 {
506 c = fgetc (stdin);
507 push (c);
508 } else
509 {
510 c = ((rand() / 32) % 128);
511 while (c < 32)
512 {
513 c = ((rand() / 32) % 128);
514 }
515 push (c);
516 }
517 break;
518 }
519 case 'g': /* Get Value */
520 {
521 signed long y = pop (), x = pop ();
522 incprof(GET_CELL);
523 push (cur);
524 break;
525 }
526 case 'p': /* Put Value */
527 {
528 signed long y = pop (), x = pop ();
529 if ((y < PAGEHEIGHT) && (y >= 0) && (x < LINEWIDTH) && (x >= 0))
530 {
531 incprof(PUT_CELL);
532 cur = pop ();
533 } else
534 {
535 /* fprintf(stderr, "p 'Put' instruction out of bounds (%d,%d)\n", x, y); */
536 putoob++;
537 }
538 break;
539 }
540 case ' ':
541 break;
542 default:
543 {
544 unsupp++;
545 break;
546 }
289 case '>': /* PC Right */
290 dx = 1;
291 dy = 0;
292 break;
293 case '<': /* PC Left */
294 dx = -1;
295 dy = 0;
296 break;
297 case '^': /* PC Up */
298 dx = 0;
299 dy = -1;
300 break;
301 case 'v': /* PC Down */
302 dx = 0;
303 dy = 1;
304 break;
305 case '|': /* Vertical 'If' */
306 {
307 long int pp = pop();
308 dx = 0;
309 if (rand_logic) pp = ((rand () >> 3) % 2);
310 if (pp)
311 {
312 dy = -1;
313 } else
314 {
315 dy = 1;
316 }
317 break;
318 }
319 case '_': /* Horizontal 'If' */
320 {
321 long int pp = pop();
322 dy = 0;
323 if (rand_logic) pp = ((rand () >> 3) % 2);
324 if (pp)
325 {
326 dx = -1;
327 } else
328 {
329 dx = 1;
330 }
331 break;
332 }
333 case '+': /* Add */
334 push (pop () + pop ());
335 break;
336 case '-': /* Subtract */
337 {
338 long a = pop();
339 long b = pop();
340 push(b - a);
341 break;
342 }
343 case '*': /* Multiply */
344 push (pop () * pop ());
345 break;
346 case '/': /* Integer Divide */
347 {
348 signed long a = pop ();
349 signed long b = pop ();
350 if (a == 0)
351 {
352 if (infile)
353 {
354 fscanf (fi, "%ld", &b);
355 push (b);
356 } else
357 if (interactive)
358 {
359 printf("What do you want %ld/0 to be? ", b);
360 scanf ("%ld", &b);
361 push (b);
362 } else
363 {
364 push (rand() - 32767);
365 }
366 } else
367 {
368 push (b / a);
369 }
370 break;
371 }
372 case '%': /* Modulo */
373 {
374 signed long a = pop ();
375 signed long b = pop ();
376 push (b % a);
377 break;
378 }
379 case '\\': /* Swap */
380 {
381 signed long a = pop ();
382 signed long b = pop ();
383 push (a);
384 push (b);
385 break;
386 }
387 case '.': /* Pop Out Integer */
388 {
389 if (interactive)
390 {
391 printf ("%ld ", pop ());
392 fflush (stdout);
393 } else pop();
394 break;
395 }
396 case ',': /* Pop Out ASCII */
397 {
398 if (interactive)
399 {
400 printf ("%c", (char)pop ());
401 fflush (stdout);
402 } else pop();
403 break;
404 }
405 case '"': /* Toggle String Mode */
406 stringmode = !stringmode;
407 break;
408 case ':': /* Duplicate */
409 {
410 signed long a = pop ();
411 push (a);
412 push (a);
413 break;
414 }
415 case '!': /* Negate */
416 {
417 if (pop())
418 {
419 push(0);
420 } else
421 {
422 push(1);
423 }
424 break;
425 }
426 case '`':
427 {
428 signed long b = pop ();
429 signed long a = pop ();
430 if (a > b)
431 {
432 push(1);
433 } else
434 {
435 push(0);
436 }
437 break;
438 }
439 case '#': /* Bridge */
440 {
441 if ((dx == 1) && (dy == 0)) incprof(EGRESS_EAST);
442 if ((dx == -1) && (dy == 0)) incprof(EGRESS_WEST);
443 if ((dx == 0) && (dy == 1)) incprof(EGRESS_SOUTH);
444 if ((dx == 0) && (dy == -1)) incprof(EGRESS_NORTH);
445 x += dx;
446 y += dy;
447 flag_egress = 1;
448 break;
449 }
450 case '$': /* Pop and Discard */
451 {
452 pop ();
453 break;
454 }
455 case '?': /* Random Redirect */
456 {
457 switch ((rand () / 32) % 4)
458 {
459 case 0:
460 dx = 1;
461 dy = 0;
462 break;
463 case 1:
464 dx = -1;
465 dy = 0;
466 break;
467 case 2:
468 dx = 0;
469 dy = -1;
470 break;
471 case 3:
472 dx = 0;
473 dy = 1;
474 break;
475 }
476 break;
477 }
478 case '&': /* Input Integer */
479 {
480 signed long b;
481 if (infile)
482 {
483 fscanf (fi, "%ld", &b);
484 push (b);
485 } else
486 if (interactive)
487 {
488 scanf ("%ld", &b);
489 push (b);
490 } else
491 {
492 push (rand() - 32767);
493 }
494 break;
495 }
496 case '~': /* Input ASCII */
497 {
498 char c;
499 if (infile)
500 {
501 c = fgetc (fi);
502 push (c);
503 } else
504 if (interactive)
505 {
506 c = fgetc (stdin);
507 push (c);
508 } else
509 {
510 c = ((rand() / 32) % 128);
511 while (c < 32)
512 {
513 c = ((rand() / 32) % 128);
514 }
515 push (c);
516 }
517 break;
518 }
519 case 'g': /* Get Value */
520 {
521 signed long y = pop (), x = pop ();
522 incprof(GET_CELL);
523 push (cur);
524 break;
525 }
526 case 'p': /* Put Value */
527 {
528 signed long y = pop (), x = pop ();
529 if ((y < PAGEHEIGHT) && (y >= 0) && (x < LINEWIDTH) && (x >= 0))
530 {
531 incprof(PUT_CELL);
532 cur = pop ();
533 } else
534 {
535 /* fprintf(stderr, "p 'Put' instruction out of bounds (%d,%d)\n", x, y); */
536 putoob++;
537 }
538 break;
539 }
540 case ' ':
541 break;
542 default:
543 {
544 unsupp++;
545 break;
546 }
547547 }
548548 if (!flag_egress)
549549 {
550 if ((dx == 1) && (dy == 0)) incprof(EGRESS_EAST);
551 if ((dx == -1) && (dy == 0)) incprof(EGRESS_WEST);
552 if ((dx == 0) && (dy == 1)) incprof(EGRESS_SOUTH);
553 if ((dx == 0) && (dy == -1)) incprof(EGRESS_NORTH);
550 if ((dx == 1) && (dy == 0)) incprof(EGRESS_EAST);
551 if ((dx == -1) && (dy == 0)) incprof(EGRESS_WEST);
552 if ((dx == 0) && (dy == 1)) incprof(EGRESS_SOUTH);
553 if ((dx == 0) && (dy == -1)) incprof(EGRESS_NORTH);
554554 }
555555 x += dx;
556556 y += dy;
557557 if (x < 0)
558558 {
559 x = LINEWIDTH - 1;
559 x = LINEWIDTH - 1;
560560 } else
561561 {
562 x = x % LINEWIDTH;
562 x = x % LINEWIDTH;
563563 }
564564 if (y < 0)
565565 {
566 y = PAGEHEIGHT - 1;
566 y = PAGEHEIGHT - 1;
567567 } else
568568 {
569 y = y % PAGEHEIGHT;
569 y = y % PAGEHEIGHT;
570570 }
571571
572572 curiter++;
573573 if (curiter > maxiter)
574574 {
575 printf("more than %ld iterations\n", maxiter);
576 break;
575 printf("more than %ld iterations\n", maxiter);
576 break;
577577 }
578578 }
579579
597597 {
598598 for (x=0;x<LINEWIDTH;x++)
599599 {
600 fprintf(fp, "%c", cur);
600 fprintf(fp, "%c", cur);
601601 }
602602 fprintf(fp, "\n");
603603 }
607607 fprintf(fp, "BEGIN map %d; bf93prof %s ", z + 1, filename);
608608 switch(z)
609609 {
610 case INGRESS_NORTH: fprintf(fp, "ip enters from north"); break;
611 case INGRESS_SOUTH: fprintf(fp, "ip enters from south"); break;
612 case INGRESS_EAST: fprintf(fp, "ip enters from east"); break;
613 case INGRESS_WEST: fprintf(fp, "ip enters from west"); break;
614 case EGRESS_NORTH: fprintf(fp, "ip exits to north"); break;
615 case EGRESS_SOUTH: fprintf(fp, "ip exits to south"); break;
616 case EGRESS_EAST: fprintf(fp, "ip exits to east"); break;
617 case EGRESS_WEST: fprintf(fp, "ip exits to west"); break;
618 case PUT_CELL: fprintf(fp, "g (get) addresses cell"); break;
619 case GET_CELL: fprintf(fp, "p (put) addresses cell"); break;
610 case INGRESS_NORTH: fprintf(fp, "ip enters from north"); break;
611 case INGRESS_SOUTH: fprintf(fp, "ip enters from south"); break;
612 case INGRESS_EAST: fprintf(fp, "ip enters from east"); break;
613 case INGRESS_WEST: fprintf(fp, "ip enters from west"); break;
614 case EGRESS_NORTH: fprintf(fp, "ip exits to north"); break;
615 case EGRESS_SOUTH: fprintf(fp, "ip exits to south"); break;
616 case EGRESS_EAST: fprintf(fp, "ip exits to east"); break;
617 case EGRESS_WEST: fprintf(fp, "ip exits to west"); break;
618 case PUT_CELL: fprintf(fp, "g (get) addresses cell"); break;
619 case GET_CELL: fprintf(fp, "p (put) addresses cell"); break;
620620 }
621621 fprintf(fp, "\n");
622622 maxprof = 0;
623623 {
624 for (y=0;y<PAGEHEIGHT;y++)
625 {
626 for (x=0;x<LINEWIDTH;x++)
627 {
628 if (curprof(z) > maxprof) maxprof = curprof(z);
629 }
630 }
631 for (y=0;y<PAGEHEIGHT;y++)
632 {
633 for (x=0;x<LINEWIDTH;x++)
634 {
635 if (maxprof > 0)
636 {
637 c = '0' + ((curprof(z) * 10) / maxprof);
638 if (curprof(z) == 0) c = '.';
639 if (curprof(z) == maxprof) c = '*';
640 if ((c > '9') && (c != '*') && (c != '.'))
641 {
642 c = '*';
643 }
644 fprintf(fp, "%c", c);
645 } else
646 {
647 fprintf(fp, ".");
648 }
649 }
650 fprintf(fp, "\n");
651 }
624 for (y=0;y<PAGEHEIGHT;y++)
625 {
626 for (x=0;x<LINEWIDTH;x++)
627 {
628 if (curprof(z) > maxprof) maxprof = curprof(z);
629 }
630 }
631 for (y=0;y<PAGEHEIGHT;y++)
632 {
633 for (x=0;x<LINEWIDTH;x++)
634 {
635 if (maxprof > 0)
636 {
637 c = '0' + ((curprof(z) * 10) / maxprof);
638 if (curprof(z) == 0) c = '.';
639 if (curprof(z) == maxprof) c = '*';
640 if ((c > '9') && (c != '*') && (c != '.'))
641 {
642 c = '*';
643 }
644 fprintf(fp, "%c", c);
645 } else
646 {
647 fprintf(fp, ".");
648 }
649 }
650 fprintf(fp, "\n");
651 }
652652 }
653653 fprintf(fp, "END map %d\n", z + 1);
654654 }
660660 {
661661 for (x=0;x<LINEWIDTH;x++)
662662 {
663 int b=0;
664 if (curprof(INGRESS_NORTH) > 0) { b |= 0x08; }
665 if (curprof(INGRESS_SOUTH) > 0) { b |= 0x04; }
666 if (curprof(INGRESS_EAST) > 0) { b |= 0x02; }
667 if (curprof(INGRESS_WEST) > 0) { b |= 0x01; }
668 if (b)
669 {
670 fprintf(fp, "%x", b);
671 } else
672 {
673 fprintf(fp, ".");
674 }
663 int b=0;
664 if (curprof(INGRESS_NORTH) > 0) { b |= 0x08; }
665 if (curprof(INGRESS_SOUTH) > 0) { b |= 0x04; }
666 if (curprof(INGRESS_EAST) > 0) { b |= 0x02; }
667 if (curprof(INGRESS_WEST) > 0) { b |= 0x01; }
668 if (b)
669 {
670 fprintf(fp, "%x", b);
671 } else
672 {
673 fprintf(fp, ".");
674 }
675675 }
676676 fprintf(fp, "\n");
677677 }
684684 {
685685 for (x=0;x<LINEWIDTH;x++)
686686 {
687 int b=0;
688 if (curprof(EGRESS_NORTH) > 0) { b |= 0x08; }
689 if (curprof(EGRESS_SOUTH) > 0) { b |= 0x04; }
690 if (curprof(EGRESS_EAST) > 0) { b |= 0x02; }
691 if (curprof(EGRESS_WEST) > 0) { b |= 0x01; }
692 if (b)
693 {
694 fprintf(fp, "%x", b);
695 } else
696 {
697 fprintf(fp, ".");
698 }
687 int b=0;
688 if (curprof(EGRESS_NORTH) > 0) { b |= 0x08; }
689 if (curprof(EGRESS_SOUTH) > 0) { b |= 0x04; }
690 if (curprof(EGRESS_EAST) > 0) { b |= 0x02; }
691 if (curprof(EGRESS_WEST) > 0) { b |= 0x01; }
692 if (b)
693 {
694 fprintf(fp, "%x", b);
695 } else
696 {
697 fprintf(fp, ".");
698 }
699699 }
700700 fprintf(fp, "\n");
701701 }
708708 {
709709 for (x=0;x<LINEWIDTH;x++)
710710 {
711 int b=0;
712 if ((curprof(EGRESS_NORTH) > 0) ||
713 (curprof(EGRESS_SOUTH) > 0) ||
714 (curprof(EGRESS_EAST) > 0) ||
715 (curprof(EGRESS_WEST) > 0) ||
716 (curprof(INGRESS_NORTH) > 0) ||
717 (curprof(INGRESS_SOUTH) > 0) ||
718 (curprof(INGRESS_EAST) > 0) ||
719 (curprof(INGRESS_WEST) > 0))
720 {
721 b |= 0x01;
722 }
723 if (curprof(PUT_CELL) > 0)
724 {
725 b |= 0x02;
726 }
727 if (curprof(GET_CELL) > 0)
728 {
729 b |= 0x04;
730 }
731 if (b)
732 {
733 fprintf(fp, "%x", b);
734 } else
735 {
736 fprintf(fp, ".");
737 }
711 int b=0;
712 if ((curprof(EGRESS_NORTH) > 0) ||
713 (curprof(EGRESS_SOUTH) > 0) ||
714 (curprof(EGRESS_EAST) > 0) ||
715 (curprof(EGRESS_WEST) > 0) ||
716 (curprof(INGRESS_NORTH) > 0) ||
717 (curprof(INGRESS_SOUTH) > 0) ||
718 (curprof(INGRESS_EAST) > 0) ||
719 (curprof(INGRESS_WEST) > 0))
720 {
721 b |= 0x01;
722 }
723 if (curprof(PUT_CELL) > 0)
724 {
725 b |= 0x02;
726 }
727 if (curprof(GET_CELL) > 0)
728 {
729 b |= 0x04;
730 }
731 if (b)
732 {
733 fprintf(fp, "%x", b);
734 } else
735 {
736 fprintf(fp, ".");
737 }
738738 }
739739 fprintf(fp, "\n");
740740 }