Download code

Jump to: navigation, search

Back to Befunge_interpreter_(C)

Download for Windows: single file, zip

Download for UNIX: single file, zip, tar.gz, tar.bz2

build.log

1 /tmp/litprog7587264/befunge.c: In function 'main':
2 /tmp/litprog7587264/befunge.c:131:19: warning: ignoring return value of 'scanf', declared with attribute warn_unused_result [-Wunused-result]


befunge.c

  1 /* The authors of this work have released all rights to it and placed it
  2 in the public domain under the Creative Commons CC0 1.0 waiver
  3 (http://creativecommons.org/publicdomain/zero/1.0/).
  4 
  5 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  6 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  7 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  8 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  9 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 10 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 11 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 12 
 13 Retrieved from: http://en.literateprograms.org/Befunge_interpreter_(C)?oldid=11797
 14 */
 15 
 16 #include<stdio.h>
 17 #include<stdlib.h>
 18 #include<ctype.h>
 19 #include<time.h>
 20 
 21 #define NCOLS         80
 22 #define NLINES        25
 23 #define INITSTACK   4096
 24 enum {dir_left=0, dir_right=1, dir_up=2, dir_down=3};
 25 
 26 long *stack=NULL;
 27 int maxstack=0;
 28 int nstack=0;
 29 
 30 
 31 void push(long v)
 32 {
 33 	if(!stack) {
 34 		if(!maxstack) maxstack=INITSTACK;
 35 		if(!(stack=malloc(sizeof *stack * maxstack))) {
 36 			fprintf(stderr, "ERROR: Not enough memory.\n");
 37 			exit(EXIT_FAILURE);
 38 		}
 39 	} else if(nstack<maxstack) stack[nstack++]=v;
 40 	else {
 41 		maxstack+=INITSTACK;
 42 		if(!(stack=realloc(stack, sizeof *stack * maxstack))) {
 43 			fprintf(stderr, "ERROR: Not enough memory.\n");
 44 			exit(EXIT_FAILURE);
 45 		}
 46 	}
 47 }
 48 
 49 long pop(void)
 50 {
 51 	if(nstack>0) return stack[--nstack];
 52 	else return 0;
 53 }
 54 
 55 void dup(void)
 56 {
 57 	long tmp;
 58 	
 59 	tmp=pop();
 60 	push(tmp);
 61 	push(tmp);
 62 }
 63 
 64 void swap(void)
 65 {
 66 	long tmp, tmp2;
 67 	
 68 	tmp=pop();
 69 	tmp2=pop();
 70 	push(tmp);
 71 	push(tmp2);
 72 }
 73 
 74 int main(int argc, char *argv[])
 75 {
 76 	char prog[NLINES][NCOLS+1]={{0}};
 77 	int ncol=0, nline=0;
 78 	int cmd=0;
 79 	int dir=dir_right;
 80 	long tmp;
 81 	int textmode=0;
 82 	int step=1;
 83 	int y, x;
 84 	FILE *fp;
 85 
 86 	if(argc>1) {
 87 		if(!(fp=fopen(argv[1], "r"))) {
 88 			fprintf(stderr, "ERROR: Can\'t open file %s\n", argv[1]);
 89 			exit(EXIT_FAILURE);
 90 		}
 91 	} else fp=stdin;
 92 
 93 	while(nline<NLINES && fgets(prog[nline], NCOLS+1, fp)) ++nline;
 94 
 95 	if(fp!=stdin) fclose(fp);
 96 
 97 
 98 	srand(time(NULL));
 99 
100 
101 	nline=0;
102 	while((cmd=prog[nline][ncol])!='@' || textmode) {
103 		if(textmode) {
104 			if(cmd=='\"') textmode=0;
105 			else push(cmd);
106 		} else {
107 			switch(cmd) {
108 			case '+': push(pop()+pop()); break;
109 			case '-': tmp=pop(); push(pop()-tmp); break;
110 			case '*': push(pop()*pop()); break;
111 			case '/': tmp=pop(); push(pop()/tmp); break;
112 			case '%': tmp=pop(); push(pop()%tmp); break;
113 			case '!': push(!pop()); break;
114 			case '`': tmp=pop(); push(pop()>tmp); break;
115 			case '_': dir=pop()?dir_left:dir_right; break;
116 			case '|': dir=pop()?dir_up:dir_down; break;
117 			case '<': dir=dir_left; break;
118 			case '>': dir=dir_right; break;
119 			case '^': dir=dir_up; break;
120 			case 'v': dir=dir_down; break;
121 			case ':': dup(); break;
122 			case '\\': swap(); break;
123 			case '$': pop(); break;
124 			case '.': printf("%ld", pop()); break;
125 			case ',': putchar(pop()); break;
126 			case '"': textmode=1; break;
127 			case '#': step=2; break;
128 			case '@': exit(EXIT_SUCCESS);
129 			case 'p': y=pop(); x=pop(); prog[y][x]=pop(); break;
130 			case 'g': y=pop(); x=pop(); push(prog[y][x]); break;
131 			case '&': scanf("%ld", &tmp); push(tmp); break;
132 			case '~': push(getchar()); break;
133 			case '?': dir=(rand()/7)&3; break;
134 			default:
135 				if(cmd>='0' && cmd<='9') push(cmd-'0');
136 			}
137 		}
138 
139 		while(step) {
140 			switch(dir) {
141 			case dir_left: 
142 				if(--ncol<0) ncol=NCOLS-1;
143 				break;
144 			case dir_right: 
145 				if(++ncol>=NCOLS) ncol=0;
146 				break;
147 			case dir_up: 
148 				if(--nline<0) nline=NLINES-1;
149 				break;
150 			case dir_down: 
151 				if(++nline>=NLINES) nline=0;
152 				break;
153 			}
154 			--step;
155 		}
156 		++step;
157 	}
158 
159 	return EXIT_SUCCESS;
160 }


hijacker
hijacker
hijacker
hijacker