git @ Cat's Eye Technologies Befunge-93 / 282c5dd
Merge branch 'develop-2018-1' of https://github.com/catseye/Befunge-93 into defined-input-integer-error-mode Chris Pressey 3 years ago
2 changed file(s) with 108 addition(s) and 73 deletion(s). Raw diff Collapse all Expand all
00 /********************************************************************
11
22 bef2c.c - Befunge-93 to ANSI C Compiler in ANSI C
3 v0.94 Sep 20 2004 Chris Pressey, Cat's-Eye Technologies
4
5 Copyright (c)1997-2012, Chris Pressey, Cat's Eye Technologies.
3
4 Copyright (c)1997-2018, Chris Pressey, Cat's Eye Technologies.
65 All rights reserved.
76
87 Redistribution and use in source and binary forms, with or without
3837
3938 Usage :
4039
41 bef2c [-p] [-o] [-w width] [-h height] <befunge-source> <c-destination>
42
43 -p : suppress pre-optimization
44 -o : suppress post-optimization
40 bef2c [-O] [-w width] [-h height] <befunge-source> <c-destination>
41
42 -O : enable [buggy] post-optimization phase
4543 -w : explicit width
4644 -h : explicit height
4745
4846 Known to Compile Under :
4947
5048 Borland C++ v3.1 (DOS)
49 gcc 5.4.0 (Ubuntu 16.04)
5150
5251 History:
52
53 v1.0: circa Jun 2018
54 fixes submitted by https://github.com/serprex (thanks!):
55 - avoid double free due to double fclose
56 - handle trampoline at leftmost/topmost edges
57 - don't load NULs into playfield
58 - use %% instead of %c with '%' being passed in
59 - avoid freeing fo/fi on failure to open
60 removed -p flag as it is equivalent to
61 `-w 80 -h 25`, just use that instead
62 replaced -o (disable post-optimization) flag
63 with -O (enable post-optimization) because buggy
64 show usage and exit if unrecognized command-line
65 options are given
66 exit with a non-zero exit code if an error occurs
67 when detecing pageheight, add one on the assumption
68 that the source does not end with a newline
69 (this lets some existing example programs compile)
5370
5471 v0.94: Sep 2004, Chris Pressey
5572 display correct version number
7996 int pageheight = 1; /* 25 */
8097
8198 #define cur pg[y * 80 + x]
82 #define shrink(s) s[strlen(s)-1]=0
8399
84100 #define RIGHT "_%2.2d_%2.2d_R"
85101 #define LEFT "_%2.2d_%2.2d_L"
92108 #define x_left (x ? x-1 : linewidth-1)
93109
94110 #define y_2down (y+2)%pageheight
95 #define y_2up ((y>1) ? y-2 : ((pageheight-2)<0 ? 0 : (pageheight-2)))
111 #define y_2up ((y>1) ? y-2 : ((pageheight-2)<0 ? 0 : (y-2+pageheight)))
96112 #define x_2right (x+2)%linewidth
97 #define x_2left ((x>1) ? x-2 : ((linewidth-2)<0 ? 0 : (linewidth-2)))
113 #define x_2left ((x>1) ? x-2 : ((linewidth-2)<0 ? 0 : (x-2+linewidth)))
98114
99115 #define ALL RIGHT ": " LEFT ": " UP ": " DOWN ":\n"
100116
108124 char in[255];
109125 char pg[2000]; /* befunge 'page' of source */
110126 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? */
127 int post_optimize = 0; /* flag: optimize after compile? */
113128
114129 int labelrefs[8000]; /* postoptimization table */
115130 char s[255];
117132
118133 /********************************************************* PROTOTYPES */
119134
135 void usage(char *);
120136 int main (int, char **);
137
138 /********************************************************** FUNCTIONS */
139
140 void usage(char *e)
141 {
142 printf ("USAGE : %s [-O] [-w width] [-h height] <befunge-source> <c-destination>\n", e);
143 exit (1);
144 }
121145
122146 /******************************************************* MAIN PROGRAM */
123147
136160
137161 srand (time (0));
138162
139 printf ("Befunge-93 to ANSI C Compiler v0.94\n");
140
141 if (argc < 3)
142 {
143 printf ("USAGE : %s [-p] [-o] [-w width] [-h height] <befunge-source> <c-destination>\n", argv[0]);
144 exit (0);
145 }
163 printf ("Befunge-93 to ANSI C Compiler v1.0\n");
164
165 if (argc < 3) usage(argv[0]);
146166 for (i = 1; i < argc; i++)
147167 {
148 if (!strcmp(argv[i], "-p")) { pre_optimize = 0; linewidth=80; pageheight=25; }
149 if (!strcmp(argv[i], "-o")) { post_optimize = 0; }
150 if (!strcmp(argv[i], "-w")) { linewidth = atoi(argv[i+1]); }
151 if (!strcmp(argv[i], "-h")) { pageheight = atoi(argv[i+1]); }
168 if (argv[i][0] == '-')
169 {
170 if (!strcmp(argv[i], "-O")) { post_optimize = 1; }
171 else if (!strcmp(argv[i], "-w")) { linewidth = atoi(argv[i+1]); }
172 else if (!strcmp(argv[i], "-h")) { pageheight = atoi(argv[i+1]); }
173 else usage(argv[0]);
174 }
152175 }
153176 if ((fi = fopen (argv[argc - 2], "r")) != NULL) /*** Input Phase */
154177 {
155178 int x = 0, y = 0;
156179 while (!feof (fi))
157180 {
158 cur = fgetc (fi);
159 if ((x+1)>linewidth) linewidth=x+1;
160 if ((y+1)>pageheight) pageheight=y+1;
161 if (cur == '\n')
162 {
163 cur = ' ';
181 int ch = fgetc (fi);
182 if (ch == -1) break;
183 if (ch == '\n')
184 {
164185 x = 0;
165186 y++;
166187 if (y >= 25) break;
188 else if (y > pageheight) pageheight=y;
167189 } else
168190 {
191 cur = ch;
169192 x++;
170193 if (x >= 80)
171194 {
172195 x = 0;
173196 y++;
174197 if (y >= 25) break;
198 else if (y > pageheight) pageheight=y;
199 } else if (x > linewidth)
200 {
201 linewidth = x;
175202 }
176203 }
177204 }
178 fclose (fi);
179205 } else
180206 {
181207 printf ("Error : couldn't open '%s' for input.\n", argv[argc - 1]);
182 exit (0);
183 }
208 exit (1);
209 }
210
211 /* Most Befunge-93 sources do not end with a newline. Therefore: */
212 if (pageheight < 25) pageheight++;
184213
185214 if (!(fo = fopen (argv[argc - 1], "w"))) /*** Output */
186215 {
187216 printf ("Error : couldn't open '%s' for output.\n", argv[argc - 1]);
188 exit (0);
189 }
190
217 exit (1);
218 }
219
220 printf ("Loaded %d columns by %d rows.\n", linewidth, pageheight);
191221 printf ("Compiling");
192222
193223 fprintf (fo, "/* %s converted to ANSI C from %s by bef2c */\n",
208238 {
209239 for(x = 0; x < linewidth; x++)
210240 {
211 if (cur!='\\')
212 {
213 fprintf (fo, " pg[%d]='%c';\n", y * 80 + x, cur);
214 } else
215 {
216 fprintf (fo, " pg[%d]='%c%c';\n", y * 80 + x, cur, cur);
217 }
241 if (cur) fprintf (fo, " pg[%d]=%d;\n", y * 80 + x, cur);
218242 }
219243 }
220244
270294 ECHO("a=pop();b=pop();push(b/a);");
271295 break;
272296 case '%':
273 sprintf(t, "a=pop();b=pop();push(b%ca);", '%');
297 sprintf(t, "a=pop();b=pop();push(b%%a);");
274298 fprintf(fo, RIGHT ": %s goto " RIGHT ";\n", x, y, t, x_right, y);
275299 fprintf(fo, LEFT ": %s goto " LEFT ";\n", x, y, t, x_left, y);
276300 fprintf(fo, UP ": %s goto " UP ";\n", x, y, t, x, y_up);
283307 ECHO("a=pop();push(a);push(a);");
284308 break;
285309 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);
310 fprintf(fo, RIGHT ": fprintf(stdout,\"%%ld \",pop());fflush(stdout); goto " RIGHT ";\n", x, y, x_right, y);
311 fprintf(fo, LEFT ": fprintf(stdout,\"%%ld \",pop());fflush(stdout); goto " LEFT ";\n", x, y, x_left, y);
312 fprintf(fo, UP ": fprintf(stdout,\"%%ld \",pop());fflush(stdout); goto " UP ";\n", x, y, x, y_up);
313 fprintf(fo, DOWN ": fprintf(stdout,\"%%ld \",pop());fflush(stdout); goto " DOWN ";\n", x, y, x, y_down);
290314 break;
291315 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);
316 fprintf(fo, RIGHT ": fprintf(stdout,\"%%c\",pop());fflush(stdout); goto " RIGHT ";\n", x, y, x_right, y);
317 fprintf(fo, LEFT ": fprintf(stdout,\"%%c\",pop());fflush(stdout); goto " LEFT ";\n", x, y, x_left, y);
318 fprintf(fo, UP ": fprintf(stdout,\"%%c\",pop());fflush(stdout); goto " UP ";\n", x, y, x, y_up);
319 fprintf(fo, DOWN ": fprintf(stdout,\"%%c\",pop());fflush(stdout); goto " DOWN ";\n", x, y, x, y_down);
296320 break;
297321 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);
322 fprintf(fo, RIGHT ": fscanf(stdin,\"%%ld\",&b);push(b); goto " RIGHT ";\n", x, y, x_right, y);
323 fprintf(fo, LEFT ": fscanf(stdin,\"%%ld\",&b);push(b); goto " LEFT ";\n", x, y, x_left, y);
324 fprintf(fo, UP ": fscanf(stdin,\"%%ld\",&b);push(b); goto " UP ";\n", x, y, x, y_up);
325 fprintf(fo, DOWN ": fscanf(stdin,\"%%ld\",&b);push(b); goto " DOWN ";\n", x, y, x, y_down);
302326 break;
303327 case '~':
304328 fprintf(fo, RIGHT ": c=fgetc(stdin);push(c); goto " RIGHT ";\n", x, y, x_right, y);
307331 fprintf(fo, DOWN ": c=fgetc(stdin);push(c); goto " DOWN ";\n", x, y, x, y_down);
308332 break;
309333 case '"': /* ha! */
310 ECHO("puts(\"Error: compiled Befunge does not support stringmode\n\");");
334 ECHO("puts(\"Error: compiled Befunge does not support stringmode\\n\");");
311335 break;
312336 case '!':
313337 ECHO("if(pop()) push(0); else push(1);");
320344 break;
321345 case '?':
322346 fprintf(fo, ALL, x, y, x, y, x, y, x, y);
323 fprintf(fo, " switch ((rand () / 32) %c 4) \n"
347 fprintf(fo, " switch ((rand () / 32) %% 4) \n"
324348 " { case 0: goto " RIGHT ";\n"
325349 " case 1: goto " LEFT ";\n"
326350 " case 2: goto " UP ";\n"
327351 " case 3: goto " DOWN "; }\n",
328 '%', x_right, y, x_left, y, x, y_up, x, y_down);
352 x_right, y, x_left, y, x, y_up, x, y_down);
329353 break;
330354 case '#':
331355 fprintf(fo, RIGHT ": goto " RIGHT ";\n", x, y, x_2right, y);
415439 }
416440 }
417441 }
418 fclose (fi);
419 fclose (fo);
442 if (fi) fclose (fi);
443 if (fo) fclose (fo);
420444 if ((fi = fopen ("temp.c", "r")) != NULL)
421445 {
422446 if ((fo = fopen (argv[argc - 1], "w")) != NULL)
00 /********************************************************************
11
22 befprof.c - Befunge-93 Profiler
3 v0.94 Sep 20 2004 Chris Pressey, Cat's-Eye Technologies
4
5 Copyright (c)1998-2012, Chris Pressey, Cat's Eye Technologies.
3
4 Copyright (c)1998-2018, Chris Pressey, Cat's Eye Technologies.
65 All rights reserved.
76
87 Redistribution and use in source and binary forms, with or without
5554 so too many repetitions may cause them to wrap back to 0.
5655
5756 ******************************************************************
57
58 v1.0: circa Jun 2018
59 handle trampoline at leftmost/topmost edges
60 (thanks to https://github.com/serprex for this fix!)
61 exit with non-zero error code on error
62 remove unimplemented -q option from usage help text
63 don't load invalid (past-EOF) bytes into playfield
5864
5965 v0.94: Sep 2004, Chris Pressey
6066 cleanup only, no functional changes
164170 if ((pg == NULL) || (pgbuf == NULL))
165171 {
166172 printf ("Error: can't allocate %d bytes of memory.\n", LINEWIDTH * PAGEHEIGHT);
167 exit(0);
173 exit (1);
168174 }
169175 memset(pg, ' ', LINEWIDTH * PAGEHEIGHT);
170176 memset(pgbuf, ' ', LINEWIDTH * PAGEHEIGHT);
175181 if (prof[i] == NULL)
176182 {
177183 printf ("Error: can't allocate %lu bytes of memory.\n", (long)(LINEWIDTH * PAGEHEIGHT * sizeof(long int)));
178 exit(0);
184 exit (1);
179185 }
180186 memset(prof[i], 0, LINEWIDTH * PAGEHEIGHT * sizeof(long int));
181187 }
182188
183189 if (argc < 2)
184190 {
185 printf ("USAGE: befprof [-l] [-q] [-i] [-n count] [-r input] [-w foo.map] foo.bf\n");
186 exit (0);
191 printf ("USAGE: befprof [-l] [-i] [-n count] [-r input] [-w foo.map] foo.bf\n");
192 exit (1);
187193 }
188194
189195 strcpy(filename, argv[argc - 1]);
210216 if (!strcmp(argv[i], "-w")) { strcpy(mapfilename, argv[i + 1]); }
211217 }
212218
213 printf ("Befunge-93 Profiler v0.94\n");
219 printf ("Befunge-93 Profiler v1.0\n");
214220
215221 if ((f = fopen (filename, "r")) != NULL) /*** Input Phase */
216222 {
219225 while (!feof (f))
220226 {
221227 curbuf = fgetc (f);
228 if (feof (f))
229 {
230 curbuf = ' ';
231 break;
232 }
222233 if (curbuf == '\n')
223234 {
224235 curbuf = ' ';
240251 } else
241252 {
242253 printf ("Error: couldn't open '%s' for input.\n", filename);
243 exit (0);
254 exit (1);
244255 }
245256
246257 if (!(fp = fopen (mapfilename, "w")))
247258 {
248259 printf ("Error : couldn't open '%s' for output.\n", mapfilename);
249 exit (0);
260 exit (1);
250261 }
251262
252263 while (rep <= reps)
265276 if (!(fi = fopen (argv[ia], "r")))
266277 {
267278 printf ("Error : couldn't open '%s' for input.\n", argv[ia]);
268 exit (0);
279 exit (1);
269280 }
270281 }
271282
556567 y += dy;
557568 if (x < 0)
558569 {
559 x = LINEWIDTH - 1;
570 x += LINEWIDTH;
560571 } else
561572 {
562573 x = x % LINEWIDTH;
563574 }
564575 if (y < 0)
565576 {
566 y = PAGEHEIGHT - 1;
577 y += PAGEHEIGHT;
567578 } else
568579 {
569580 y = y % PAGEHEIGHT;