git @ Cat's Eye Technologies RUBE / b427329
Initial import of RUBE version 1.02 revision 1997.0715. catseye 12 years ago
8 changed file(s) with 907 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 <html><head>
1 <meta http-equiv="Content-Type" content="text/html;CHARSET=iso-8859-1">
2 <meta name="Description" content="Cat's Eye Technologies: The RUBE Language">
3 <title>Cat's Eye Technologies: The RUBE Language</title>
4 </head>
5 <body>
6 <center>
7 <A HREF="/esoteric/index.html">Esoteric Topics in Computer Programming</A> presents...
8 <br><table border=0><tr>
9 <td nowrap align=center valign=center
10 bgcolor="#000000" background="/img/sineblack.gif">&nbsp;<a href="http://www.catseye.mb.ca/index.html"><img
11 align=absmiddle src="/img/3qtrsize.gif"
12 alt="Cat's Eye Technologies" border=0></a>&nbsp;</td>
13 <td nowrap align=center><font size=+3
14 face="century gothic,arial,times new roman" color="#800000">&nbsp;&nbsp;</font><FONT face="arial,monaco" color=#00007f SIZE=+4><B>R</B></FONT>
15 <FONT face="arial,monaco" color=#007f00 SIZE=+4><B>U</B></FONT>
16 <FONT face="arial,monaco" color=#007f7f SIZE=+4><B>B</B></FONT>
17 <FONT face="arial,monaco" color=#7f0000 SIZE=+4><B>E</B></FONT><font></td>
18 </tr></table>
19
20 <TABLE WIDTH="100%"><TR><TD WIDTH="50%" ALIGN=LEFT VALIGN=TOP>
21
22 <p><font face="arial,monaco" size=+2><b>Language</b></font>
23
24 <P>RUBE is a tribute to Rube Goldberg, creator of all those unique
25 cartoon contrivances, showed the world that anything
26 can be done in a more complicated fashion than necessary.
27
28 <p>The language itself is a cellular "bully" automaton: certain state
29 transitions force other, non-adjacent cells to assume certain state
30 transitions. Although this may sound like an interesting notion, the
31 number of interactions climbs quickly as more objects are added, and
32 things get much messier than they normally would in a regular
33 cellular automaton, like John Conway's Game of Life.
34
35 <p>Also unlike a real cellular automaton, RUBE supports rudimentary
36 output functionality; input was planned, but has never been implemented.
37
38 <p><a HREF="/esoteric/alpaca/redgreen/index.html">REDGREEN</A> is an
39 updated version of the RUBE universe, one which is expressible as
40 a proper cellular automaton.
41
42 <p><img src="/img/new.gif" alt="[NEW]" width=26 height=16 border=0> John Colagioia has created a more consistent version of
43 the RUBE language, <a href="klik.txt">RUBE II: Das Klickenklacker</a>.
44
45 </TD><TD WIDTH="50%" ALIGN=RIGHT VALIGN=BOTTOM>
46
47 <p><font face="arial,monaco" size=+2><b>Implementation</b></font>
48
49 <p>You can download the <a href="/esoteric/rube/rubev102.zip"><img src="/img/fileicon.gif" border=0 ALT="[D/L]" width=12 height=12>RUBE</a> distribution from
50 this web server.
51 It contains C source code, documentation, and a precompiled binary for MS-DOS.
52
53 <p>You can also download John's <a href="/esoteric/rube/rube_ii.zip"><img src="/img/fileicon.gif" border=0 ALT="[D/L]" width=12 height=12>RUBE II</a>
54 distribution from this web server.
55 Strangely enough it <i>also</i> contains C source code, documentation, and a precompiled binary for MS-DOS.
56
57 <p><font face="arial,monaco" size=+2><b>Documentation</b></font>
58
59 <p>See <a href="/esoteric/rube/rube.txt">rube.txt</a> for the original
60 description of the interpreter, <a href="/esoteric/rube/klik.txt">klik.txt</a>
61 for RUBE II.
62
63 <p><font face="arial,monaco" size=+2><b>Programs</b></font>
64
65 <p>Attempting to write anything even approaching a single
66 "Turing-power" in this language is an utter nightmare. Partly this
67 is because the playfield in the available implementation is
68 restricted to 80 columns by 25 rows. But mostly it's just because
69 programming anything non-trivial in RUBE is a clumsy job of
70 co-oridnating concurrently operating sections of the playfield.
71
72 </TD></TR></TABLE>
73
74 </body></html>
0 RUBE
1 ====
2 EXPERIMENTAL VERSION - IN DEVELOPMENT June 15 1997
3
4 implementation and grammar (c)1997, 2000 Cat's Eye Technologies.
5
6 RUBE is a twisted programming language named after Rube Goldberg,
7 creator of those convoluted cartoon machines. It has some similarities
8 to said machines. Read on.
9
10 Like Befunge, this is a 2-dimensional language where each instruction
11 is an ASCII character meant to be seen in debugging mode to be
12 appreciated. Coincidentally (because I ripped off the Befunge-93
13 routines) it's currently restricted to an 80x25 source file.
14
15 There is no Program Counter as such - well there is, but it moves
16 like a scan line on a TV or monitor: every command in the program
17 is executed once every tick during a "sweep" of the program. The
18 program changes on every tick. You could say RUBE is just a 30+
19 state automaton with input and output functions, and you might be
20 right.
21
22 Anyone who's played The Incredible Machine (and to some extent,
23 Donkey Kong) will understand RUBE almost immediately. Instructions
24 in the source file interact to execute the algorithm required. A
25 "warehouse" paradigm is used (this is what happens to your brain
26 when you work at a lumberyard...)
27
28 Integral are the crates, 0 to f. These represent data. They also
29 represent movable boxes which are subject to gravity, being pushed
30 around, and conveyor belts, among other things.
31
32 Girders = are stationary parts of the program on which crates can
33 be piled. When there's no girder directly below a crate, that crate
34 falls.
35
36 Dozers ( and ) push crates around. Dozers are subject to gravity,
37 and must travel on girders. Dozers turn around when there is a , in
38 front and above them. As an interesting side effect they also
39 replicate themselves at ,'s.
40
41 Ramps / and \ are used for dozers to move from girder to girder.
42
43 Conveyor belts > and < carry crates along with no help needed from
44 dozers. Note that conveyor belots do not affect dozer motion.
45
46 Winches up W and down M move crates from girder to girder.
47
48 "Swinches" move crates up V or down A and then switch states.
49
50 Gates K compare crates to a reference crate and move the crate
51 depending on if it's less than, or more than/equal to the
52 reference crate.
53
54 t | t = target crate l = lesser crates
55 K | r = reference crate g = greater than or equal to
56 lrg |
57
58 Packers + and Unpackers - perform 4-bit math on crates:
59
60 + + - -
61 12 -> 3 ef -> 1
62 === === === ===
63
64 Furnaces F destroy everything one space left, right, below, and
65 above them.
66
67 Replicators : make a copy below them of whatever is above them,
68 usually a crate or a dozer. Special replicators ; only make
69 copies of crates. Upside-down special replicators . work like ;
70 but make a copy above them of what's below them.
71
72 Dozers turn around when they hit certain instructions.
73 Crumble walls * disappear after being hit horizontally by a dozer.
74
75 Program output provides a print mechanism. If there is a c crate
76 below the O, the ASCII value specified by the two crates above the O
77 (if they exist) is output as an ASCII character. If there is a b
78 crate below the O they are output as a byte value.
79
80 The following outputs a space:
81
82 2
83 0
84 O
85 c
86 =
87
88 Symbol Name Bump R Bump L Surface Gravity
89
90 Implemented:
91 space pass pass no no
92 0..f crate move r move l yes yes
93 ( dozer right move r move l yes yes
94 ) dozer left move r move l yes yes
95 = girder rev rev yes no
96 F furnace die die die no
97 \ ramp +1 elev +1 elev yes no
98 / ramp +1 elev +1 elev yes no
99 > conveyor belt right rev rev yes no
100 < conveyor belt left rev rev yes no
101 : replicator rev rev yes no
102 ; special replicator rev rev yes no
103 . upside down replicator rev rev yes no
104 , turn signal no no
105 * crumble-wall break break yes no
106 O output rev rev yes no
107 b byte<-crate crate
108 c char<-crate crate
109 K gate rev rev yes no
110 W winch up rev rev yes no
111 M winch down rev rev yes no
112 V swinch up rev rev yes no
113 A swinch down rev rev yes no
114 + packer rev rev yes no
115 - unpacker rev rev yes no
116 C crate killer die cr die cr die cr no
117 D dozer killer die doz die doz die doz no
118
119
120 Planned:
121 I input input input yes no
122 b byte->crate crate
123 c char->crate crate
124 T scale rev rev yes no
125 | door rev rev yes no
126
127
128 Kinda Silly (extraneous to real programming):
129 km monkey rev rev yes yes
130 wl weasel rev rev yes yes
131 H mulberry bush rev rev yes yes
132
133 Q supergoo rev rev yes kinda
134
135 ~ water wet wet wet kinda
136 u pontoon rev rev yes yes (floats)
137 sz electric eel die die die yes
138
139 Sadly, the ubiquitous "Hello, world!" in RUBE is a very unfriendly
140
141
142 4666622767662
143 85ccfc07f2c41
144 OOOOOOOOOOOOO
145 ccccccccccccc
146 =============
147
148
149 Or an equally ugly
150
151
152 (21646c726f77202c6f6c6c6548
153 ===========================
154
155 O F
156 c
157 =
158
0 <<<<<<<<<W
1 =
2 ;-W
3 <<W
4 C A>.>>
5 , l ,W>= 1 F
6 ( 36 =
7 =================;;=== <<<
8 F , , F
9 (
10 =======
11 F
12 O
13 F b 73656c74746f62
14 = , ;;;;;;;;;;;;;; ,
15 (
16 ============================
17
18 F O F
19 c
20 =
0
1 abcdef 0123456789
2
3 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>K<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
4 8
5 + <<<<<=>>>>> -
6
7 <<<<<=<<<<<<<<< >>>>>>>>=>>>>
8
9 O O
10 c c
11 = =
12 F F F F
0 0a21646c726f77202c6f6c6c6548
1 , :::::::::::::::::::::::::::: ,
2 )
3 ==============================
4 F
5 O F
6 c
7 =
0
1
2 =( 71f543
3 ==========;;==;;==;=;=;=;;==;;===;;;;;==;;=;;;=====;;========
4 F
5
6
7
8 >>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
9
10
11 O
12 b
13 =
14
0 ~
1
2
3 = =
4 =======
5
6 =~
7 ===
8
9
10
11 = =
12 = =
13 = =
14 ================================
0 /*
1
2 rube.c - RUBE language
3 Interpreter/Debugger Implementation
4 v1.02, Jul 1997, Chris Pressey
5
6 (c)1997, 2000 Cat's Eye Technologies.
7 http://www.catseye.mb.ca/
8
9 Usage :
10
11 rube [-d] [-q] [-r input-file] [-w output-file]
12 [-y delay] [-f frame-skip] [-o offset] <rube-source>
13
14 -d: disable debugging output
15 -q: produce no output but program output
16 -r: redirect input from a specified file instead of stdin
17 -w: redirect output to a specified file instead of stdout
18 -y: specify debugging delay in milliseconds (default 0)
19 -f: specify debugging frame skip in frames (default 1)
20
21 Compilation :
22
23 MS-DOS: used Borland C++ v3.1 to compile RUBE.EXE
24
25 Notes for the DOS version:
26 Load ANSI.SYS or compatible ANSI driver before using.
27
28 v1.00: May/Jun 97 original, minimal implementation
29 v1.01: Jun 97 added K gate, AV swinches, + packer, - unpacker
30 v1.02: Jul 97 fixed bug in WM winches, - unpacker, added . and C
31 doubled height of playfield and improved debugger.
32 added Ben Olmstead's cursor-turner-offer-thingy.
33 added -q option.
34
35 */
36
37 /********************************************************* #INCLUDE'S */
38
39 #define CURSORON
40
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <ctype.h>
45 #include <time.h>
46 #if __BORLANDC__
47 #include <dos.h>
48 #endif
49
50 /********************************************************** #DEFINE'S */
51
52 #define LINEWIDTH 80
53 #define PAGEHEIGHT 50
54
55 #define SCREENWIDTH 79
56 #define SCREENHEIGHT 22
57
58 #define cur pg[y * LINEWIDTH + x].c
59 #define curv pg[y * LINEWIDTH + x].v
60 #define curd(dx,dy) pg[(y+dy) * LINEWIDTH + (x+dx)].c
61 #define nex pg2[y * LINEWIDTH + x].c
62 #define nexv pg2[y * LINEWIDTH + x].v
63 #define nexd(dx,dy) pg2[(y+dy) * LINEWIDTH + (x+dx)].c
64
65 #define shrink(s) s[strlen(s)-1]=0
66
67 typedef struct cellstruct
68 {
69 char c;
70 signed long int v;
71 } cell;
72
73 /*************************************************** GLOBAL VARIABLES */
74
75 cell pg[LINEWIDTH * PAGEHEIGHT]; /* playfield */
76 cell pg2[LINEWIDTH * PAGEHEIGHT];/* playfield' */
77
78 cell *head = NULL;
79
80 int x = 0, y = 0; /* x and y looping */
81 int dx = 1, dy = 0; /* direction of looping */
82 int debug = 1; /* flag : display ANSI debugging? */
83 int infile = 0, ia; /* flag : use input file, and assoc arg? */
84 int outfile = 0, oa; /* flag : use output file, and assoc arg? */
85 int deldur = 0; /* debugging delay in milliseconds */
86 int debskip = 1; /* frame skip in debug view */
87 int debopos = 1; /* output column in debugger */
88 int frame = 1;
89 int quiet = 0;
90
91 /********************************************************* PROTOTYPES */
92
93 int isramp(char c);
94 int isblock(char c);
95 int issupport(char c);
96 int iscrate(char c);
97 int ctoh(char c);
98 char htoc(int i);
99
100 /******************************************************* MAIN PROGRAM */
101
102 void main (argc, argv)
103 int argc;
104 char **argv;
105 {
106 FILE *f;
107 FILE *fi;
108 FILE *fo;
109 FILE *fs;
110 int i;
111 int done=0;
112 int maxy=0; int maxx=0;
113 short signed oldcursor;
114
115 #ifdef CURSOROFF
116 __asm
117 {
118 mov al,0x03
119 mov bl,0x00
120 int 0x10
121 mov oldcursor,cx
122 mov al,0x01
123 mov cx,0x0001
124 int 0x10
125 }
126 #endif
127
128 srand (time (0));
129
130 if (argc < 2)
131 {
132 printf ("USAGE: rube [-d] [-q] [-r input] [-w output] [-y delay] [-f skip] foo.rub\n");
133 exit (0);
134 }
135 for (i = 1; i < argc; i++)
136 {
137 if (!stricmp(argv[i], "-d")) { debug = 0; }
138 if (!stricmp(argv[i], "-q")) { quiet = 1; debug = 0; }
139 if (!stricmp(argv[i], "-r")) { infile = 1; ia = i + 1; }
140 if (!stricmp(argv[i], "-w")) { outfile = 1; oa = i + 1; }
141 if (!stricmp(argv[i], "-y")) { deldur = atoi(argv[i + 1]); }
142 if (!stricmp(argv[i], "-f")) { debskip = atoi(argv[i + 1]); }
143 }
144 if (!quiet) printf ("Cat's Eye Technologies RUBE Interpreter v1.02\n");
145 if ((f = fopen (argv[argc - 1], "r")) != NULL) /*** Input Phase */
146 {
147 int x = 0, y = 0;
148 while (!feof (f))
149 {
150 cur = fgetc (f);
151 if (cur == '\n')
152 {
153 cur = ' ';
154 x = 0;
155 y++;
156 if (y >= PAGEHEIGHT) break;
157 } else
158 {
159 x++;
160 if (x > maxx) maxx = x;
161 if (x >= LINEWIDTH)
162 {
163 x = 0;
164 y++;
165 if (y >= PAGEHEIGHT) break;
166 }
167 }
168 }
169 fclose (f);
170 maxy = y;
171 } else
172 {
173 printf ("Error : couldn't open '%s' for input.\n", argv[argc - 1]);
174 exit (0);
175 }
176
177 if (infile)
178 {
179 if (!(fi = fopen (argv[ia], "r")))
180 {
181 printf ("Error : couldn't open '%s' for input.\n", argv[ia]);
182 exit (0);
183 }
184 }
185
186 if (outfile)
187 {
188 if (!(fo = fopen (argv[oa], "w")))
189 {
190 printf ("Error : couldn't open '%s' for output.\n", argv[oa]);
191 exit (0);
192 }
193 }
194
195 #if __BORLANDC__
196 setcbrk(1);
197 #endif
198
199 while (!done) /*** Intepreting Phase */
200 {
201 if ((debug) && (!(frame++ % debskip) || (!frame)))
202 {
203 printf ("%c[1;1H", 27);
204 for(y = 0; (y <= maxy) && (y <= SCREENHEIGHT); y++)
205 {
206 for(x = 0; (x <= maxx) && (x <= SCREENWIDTH); x++)
207 {
208 putc(isprint(cur) ? cur : ' ', stdout);
209 }
210 printf("\n");
211 }
212 } else
213 {
214 // putc('.', stdout);
215 }
216 fflush (stdout);
217 fflush (stdin);
218 for (x=0; x<=(maxx); x++)
219 {
220 for (y=0; y<=(maxy); y++)
221 {
222 switch (cur)
223 {
224 case 0: case 1: case 2: case 3: case 4:
225 case 5: case 6: case 7: case 8: case 9:
226 case 10: case 11: case 12: case 13: case 14:
227 case 15: case 16: case 17: case 18: case 19:
228 case 20: case 21: case 22: case 23: case 24:
229 case 25: case 26: case 27: case 28: case 29:
230 case 30: case 31: case 32:
231 if (iscrate(curd(0,-1))) nex = curd(0,-1); // falling in from above
232 if (curd(0,-1) == '(') nex = '(';
233 if (curd(0,-1) == ')') nex = ')';
234
235 if (curd(1,1) == 'W') nex = curd(2,2);
236 if (curd(-1,1) == 'W') nex = curd(-2,2);
237
238 if ((curd(1,1) == 'V') && iscrate(curd(2,1))) nex = curd(2,1);
239 if ((curd(-1,1) == 'V') && iscrate(curd(-2,1))) nex = curd(-2,1);
240
241 if (curd(1,-1) == 'M') nex = curd(2,-2);
242 if (curd(-1,-1) == 'M') nex = curd(-2,-2);
243
244 if ((curd(1,-1) == 'A') && iscrate(curd(2,-1))) nex = curd(2,-1);
245 if ((curd(-1,-1) == 'A') && iscrate(curd(-2,-1))) nex = curd(-2,-1);
246
247 if (curd(0,-1) == '~') nex = '~';
248 if ((curd(-1,0) == '~') && (issupport(curd(-1,1)))) nex = '~';
249 if ((curd(1,0) == '~') && (issupport(curd(1,1)))) nex = '~';
250
251 if (curd(1,-1) == '+')
252 {
253 if (iscrate(curd(1,0)) && iscrate(curd(2,0)))
254 {
255 nex = htoc((ctoh(curd(1,0))+ctoh(curd(2,0))) % 16);
256 }
257 }
258
259 if (curd(-1,-1) == '+')
260 {
261 if (iscrate(curd(-1,0)) && iscrate(curd(-2,0)))
262 {
263 nex = htoc((ctoh(curd(-1,0))+ctoh(curd(-2,0))) % 16);
264 }
265 }
266
267 if (curd(1,-1) == '-')
268 {
269 if (iscrate(curd(1,0)) && iscrate(curd(2,0)))
270 {
271 int i;
272 i = ctoh(curd(2,0)) - ctoh(curd(1,0));
273 while (i < 0) i += 16;
274 nex = htoc(i);
275 }
276 }
277
278 if (curd(-1,-1) == '-')
279 {
280 if (iscrate(curd(-1,0)) && iscrate(curd(-2,0)))
281 {
282 int i;
283 i = ctoh(curd(-2,0)) - ctoh(curd(-1,0));
284 while (i < 0) i += 16;
285 nex = htoc(i);
286 }
287 }
288
289 if ((curd(1,-1) == 'K') && (iscrate(curd(1,-2))))
290 {
291 if(ctoh(curd(1,-2)) < ctoh(curd(1,0))) nex = curd(1,-2);
292 }
293
294 if ((curd(-1,-1) == 'K') && (iscrate(curd(-1,-2))))
295 {
296 if(ctoh(curd(-1,-2)) >= ctoh(curd(-1,0))) nex = curd(-1,-2);
297 }
298
299 if ((iscrate(curd(-1,0))) && (curd(-1,1) == '>')) nex = curd(-1,0);
300 if ((iscrate(curd(1,0))) && (curd(1,1) == '<')) nex = curd(1,0);
301 if (curd(0,-1) == ':') nex = curd(0,-2);
302 if ((curd(0,-1) == ';') && (iscrate(curd(0,-2)))) nex = curd(0,-2);
303 if ((curd(0,1) == '.') && (iscrate(curd(0,2)))) nex = curd(0,2);
304 if ((curd(-1,0) == '(') && (curd(1,0) == ')')) // collision
305 {
306 nex = ' ';
307 } else
308 {
309 if ((curd(-1,0) == '(') && (issupport(curd(-1,1)))) nex = '(';
310 if ((curd(1,0) == ')') && (issupport(curd(1,1)))) nex = ')';
311 if ((curd(0,1) == '/') || (curd(0,1) == '\\'))
312 {
313 if ((curd(-1,1) == '(') && (issupport(curd(-1,2)))) nex = '(';
314 if ((curd(1,1) == ')') && (issupport(curd(1,2)))) nex = ')';
315 }
316 }
317 if (iscrate(curd(-1,0)))
318 { // shift crates
319 int bx=-1;
320 while ((iscrate(curd(bx,0))) && (issupport(curd(bx,1))))
321 {
322 if (curd(bx-1,0) == '(')
323 {
324 nex = curd(-1,0);
325 }
326 bx--;
327 }
328 }
329 if (iscrate(curd(1,0)))
330 {
331 int bx=1;
332 while ((iscrate(curd(bx,0))) && (issupport(curd(bx,1))))
333 {
334 if (curd(bx+1,0) == ')')
335 {
336 nex = curd(1,0);
337 }
338 bx++;
339 }
340 }
341 break;
342 case '(':
343 if (((curd(1,0) == '(') ||
344 (curd(1,0) <= ' ') ||
345 (curd(0,1) <= ' ') ||
346 (curd(0,1) == '('))) nex = ' ';
347 if (isramp(curd(0,1))) nex = ' ';
348 if (isramp(curd(1,0))) nex = ' ';
349 if (isramp(curd(-1,0))) nex = ' ';
350 if ((isblock(curd(1,0))) ||
351 (curd(1,-1) == ',') ||
352 (curd(1,0) == '*')) nex = ')';
353 if (iscrate(curd(1,0)))
354 {
355 int bx=1;
356 while ((iscrate(curd(bx,0))) && (issupport(curd(bx,1))))
357 {
358 if (isblock(curd(bx+1,0)))
359 {
360 nex = ')';
361 }
362 bx++;
363 }
364 }
365 break;
366 case ')':
367 if (((curd(-1,0) == ')') ||
368 (curd(-1,0) <= ' ') ||
369 (curd(0,1) <= ' ') ||
370 (curd(0,1) == ')'))) nex = ' ';
371 if (isramp(curd(0,1))) nex = ' ';
372 if (isramp(curd(1,0))) nex = ' ';
373 if (isramp(curd(-1,0))) nex = ' ';
374 if ((isblock(curd(-1,0))) ||
375 (curd(-1,-1) == ',') ||
376 (curd(-1,0) == '*')) nex = '(';
377 if (iscrate(curd(-1,0)))
378 {
379 int bx=-1;
380 while ((iscrate(curd(bx,0))) && (issupport(curd(bx,1))))
381 {
382 if (isblock(curd(bx-1,0)))
383 {
384 nex = '(';
385 }
386 bx--;
387 }
388 }
389 break;
390 case 'O':
391 if ((iscrate(curd(0,-1))) && (iscrate(curd(0,-2))))
392 {
393 int d;
394
395 d = ctoh(curd(0,-1)) + ctoh(curd(0,-2)) * 16;
396 if (curd(0, 1) == 'b')
397 {
398 if (debug)
399 {
400 char s[80];
401 printf ("%c[%d;%dH", 27, 25, debopos);
402 sprintf(s, "%d ", (int)d);
403 debopos += strlen(s);
404 if (debopos > SCREENWIDTH)
405 {
406 debopos = 1;
407 printf ("%c[%d;%dH%c[K", 27, 25, 1, 27);
408 debopos += strlen(s);
409 }
410 printf(s);
411 } else
412 {
413 printf("%d ", (int)d);
414 }
415 }
416 if (curd(0, 1) == 'c')
417 {
418 if (debug)
419 {
420 printf ("%c[%d;%dH", 27, 25, debopos++);
421 if (debopos > SCREENWIDTH)
422 {
423 debopos = 1;
424 printf ("%c[%d;%dH%c[K", 27, 25, 1, 27);
425 debopos++;
426 }
427 printf ("%c", (char)d);
428 } else
429 {
430 putc((char)d, stdout);
431 }
432 }
433 }
434 case 'A':
435 if (iscrate(curd(-1,0)) || iscrate(curd(1,0))) nex = 'V'; else nex = cur;
436 break;
437 case 'V':
438 if (iscrate(curd(-1,0)) || iscrate(curd(1,0))) nex = 'A'; else nex = cur;
439 break;
440 default: nex = cur;
441 }
442 if (iscrate(cur))
443 {
444 if (issupport(curd(0,1))) nex = cur; else nex = ' ';
445 if ((curd(1,0) <= ' ') && (curd(0,1) == '>')) nex = ' ';
446 if ((curd(-1,0) <= ' ') && (curd(0,1) == '<')) nex = ' ';
447 if ((curd(1,-1) == 'W') && (curd(2,-2) == cur)) nex = ' ';
448 if ((curd(-1,-1) == 'W') && (curd(2,-2) == cur)) nex = ' ';
449 if ((curd(1,1) == 'M') && (curd(2,2) == cur)) nex = ' ';
450 if ((curd(-1,1) == 'M') && (curd(-2,2) == cur)) nex = ' ';
451 if (curd(1,0) == 'V') nex = ' ';
452 if (curd(-1,0) == 'V') nex = ' ';
453 if (curd(1,0) == 'A') nex = ' ';
454 if (curd(-1,0) == 'A') nex = ' ';
455 if (iscrate(curd(-1,0)) && ((curd(-1,-1) == '+')
456 || (curd(-1,-1) == '-'))) nex = ' ';
457 if (iscrate(curd(1,0)) && ((curd(1,-1) == '+')
458 || (curd(1,-1) == '-'))) nex = ' ';
459 if ((iscrate(curd(-1,0)) || iscrate(curd(1,0))) && ((curd(0,-1) == '+')
460 || (curd(0,-1) == '-'))) nex = ' ';
461 }
462 }
463 }
464 // fix nex array
465 for (x=0; x<=(maxx); x++)
466 {
467 for (y=0; y<=(maxy); y++)
468 {
469 switch (cur)
470 {
471 case '*':
472 if (curd(-1,0) == ')') nex = ' ';
473 if (curd(1,0) == '(') nex = ' ';
474 break;
475 case 'O':
476 if ((iscrate(curd(0,-1))) && (iscrate(curd(0,-2))))
477 {
478 nexd(0,-1)=' ';
479 nexd(0,-2)=' ';
480 }
481 break;
482 }
483 if (iscrate(cur))
484 {
485 if (curd(1,0) == ')')
486 {
487 int bx=0; int flag=0;
488 while ((iscrate(curd(bx,0))) && (issupport(curd(bx,1))))
489 {
490 if (curd(bx-1,0) <= ' ')
491 {
492 flag = 1;
493 }
494 bx--;
495 }
496 if (flag)
497 {
498 bx=0;
499 while ((iscrate(curd(bx,0))) && (issupport(curd(bx,1))))
500 {
501 nexd(bx-1,0) = curd(bx,0);
502 bx--;
503 }
504 nex = ')'; nexd(1,0) = ' ';
505 }
506 }
507 if (curd(-1,0) == '(')
508 {
509 int bx=0; int flag=0;
510 while (iscrate(curd(bx,0)) && (issupport(curd(bx,1))))
511 {
512 if (curd(bx+1,0) <= ' ')
513 {
514 flag=1;
515 }
516 bx++;
517 }
518 if (flag)
519 {
520 bx=0;
521 while ((iscrate(curd(bx,0))) && (issupport(curd(bx,1))))
522 {
523 nexd(bx+1,0) = curd(bx,0);
524 bx++;
525 }
526 nex = '('; nexd(-1,0)= ' ';
527 }
528 }
529 if ((curd(-1,0)=='C') ||
530 (curd(1,0)=='C') ||
531 (curd(0,-1)=='C') ||
532 (curd(0,1)=='C')) nex = ' ';
533 }
534 if ((curd(-1,0)=='F') ||
535 (curd(1,0)=='F') ||
536 (curd(0,-1)=='F') ||
537 (curd(0,1)=='F')) nex = ' ';
538 }
539 }
540 #if __BORLANDC__
541 delay (deldur);
542 #endif
543 memcpy(pg, pg2, LINEWIDTH * PAGEHEIGHT * sizeof(cell));
544 }
545 if (fi) fclose (fi);
546 if (fo) fclose (fo);
547 if (fs) fclose (fs);
548 if (debug) printf ("%c[22;1H", 27);
549 #if CURSOROFF
550 __asm
551 {
552 mov al,0x01
553 mov cx,oldcursor
554 int 0x10
555 }
556 #endif
557 exit (0);
558 }
559
560 int isramp(c)
561 char c;
562 {
563 return ((c=='/')||(c=='\\'));
564 }
565
566 int isblock(c)
567 char c;
568 {
569 return ((c=='='));
570 }
571
572 int issupport(c)
573 char c;
574 {
575 return ((c=='=')||iscrate(c)||(c=='(')||(c==')')||(c==';')||
576 (c=='/')||(c=='\\')||(c==':')||(c=='*')||(c==',')||
577 (c=='>')||(c=='<')||(c=='O')||(c=='W')||(c=='M')||
578 (c=='A')||(c=='V')||(c=='~')||(c=='.'));
579 }
580
581 int iscrate(c)
582 char c;
583 {
584 return ((c=='0')||(c=='1')||(c=='2')||(c=='3')||
585 (c=='4')||(c=='5')||(c=='6')||(c=='7')||
586 (c=='8')||(c=='9')||(c=='a')||(c=='b')||
587 (c=='c')||(c=='d')||(c=='e')||(c=='f'));
588 }
589
590 int ctoh(c)
591 char c;
592 {
593 if((c>='0') && (c<='9')) return (c-'0'); else return ((c-'a')+10);
594 }
595
596 char htoc(i)
597 int i;
598 {
599 if((i>=0) && (i<=9)) return ((char)(i+'0')); else return ((char)(i+'a')-10);
600 }