original C prototype
[maximus:kjhf.git] / prototype / hyperspace.c
1 /*****************************************************************************
2 **
3 **  hyperfuck -- boolfuck in the hyperbolic plane
4 **  Copyright (C) 2010 Claude Heiland-Allen <claudiusmaximus@goto10.org>
5 **
6 */
7
8 #include <assert.h>
9 #include <stdlib.h>
10 #include "hyperspace.h"
11
12 /***    struct cell *cell(void)    *******************************************
13 **
14 **  create a new cell
15 **
16 */
17
18 struct cell *cell(void) {
19   struct cell *c = malloc(sizeof(struct cell));
20   c->up = c->left = c->right = c->downLeft = c->downRight = 0;
21   c->data = 0;
22   return c;
23 }
24
25 /***    struct space *space(struct bitstream *)    ***************************
26 **
27 **  create a new space
28 **
29 */
30
31 struct space *space(struct ibitstream *bs) {
32   struct space *s = malloc(sizeof(struct space));
33   s->above = bs;
34   s->top = cell();
35   return s;
36 }
37
38 /***    struct cursor *cursor(struct space *)    *****************************
39 **
40 **  create a new cursor
41 **
42 */
43
44 struct cursor *cursor(struct space *s) {
45   struct cursor *c = malloc(sizeof(struct cursor));
46   c->space = s;
47   c->cell = s->top;
48   return c;
49 }
50
51 /***    struct cursor *up(struct cursor *, int)    ***************************
52 **
53 **  move up
54 **
55 **  TOP                     LEFT                    RIGHT
56 **    left    right           (exists)                (as LEFT)
57 **    +---+   +---+
58 **    | N |   | N |
59 **    +-+-+   +-+-+
60 **    |O|       |O|
61 **    +++       +++
62 **
63 */
64
65 struct cursor *up(struct cursor *o, int wantRight) {
66   if (!o->cell->up) {
67     int r;
68     if (o->space->above->end) {
69       r = wantRight;
70     } else {
71       o->space->above = o->space->above->get(o->space->above);
72       r = o->space->above->bit;
73     }
74     o->cell->up = cell();
75     if (r) { o->cell->up->downRight = o->cell; }
76     else   { o->cell->up->downLeft  = o->cell; }
77     o->space->top = o->cell->up;
78   }
79   o->cell = o->cell->up;
80   return o;
81 }
82
83 /***    struct cursor *downLeft(struct cursor *)    **************************
84 **
85 **  move down left
86 **
87 **  TOP                     LEFT                    RIGHT
88 **    +---+                   +---+---+               (as LEFT)
89 **    | O |                   |???| O |
90 **    +-+-+                   +-+-+-+-+
91 **    |N|?|                     |?|N|?|
92 **    +++++                     +++++++
93 **
94 */
95
96 struct cursor *downLeft(struct cursor *o) {
97   if (!o->cell->downLeft) {
98     o->cell->downLeft = cell();
99     o->cell->downLeft->up = o->cell;
100     if (o->cell->downRight) {
101       o->cell->downRight->left = o->cell->downLeft;
102       o->cell->downLeft->right = o->cell->downRight;
103     }
104     if (o->cell->left && o->cell->left->downRight) {
105       o->cell->left->downRight->right = o->cell->downLeft;
106       o->cell->downLeft->left = o->cell->left->downRight;
107     }
108   }
109   o->cell = o->cell->downLeft;
110   return o;
111 }
112
113 /***    struct cursor *downRight(struct cursor *)    *************************
114 **
115 **  move down right
116 **
117 **  TOP                     LEFT                    RIGHT
118 **    +---+                   +---+---+               (as LEFT)
119 **    | O |                   | O |???|
120 **    +-+-+                   +-+-+-+-+
121 **    |?|N|                   |?|N|?|
122 **    +++++                   +++++++
123 **
124 */
125
126 struct cursor *downRight(struct cursor *o) {
127   if (!o->cell->downRight) {
128     o->cell->downRight = cell();
129     o->cell->downRight->up = o->cell;
130     if (o->cell->downLeft) {
131       o->cell->downLeft->right = o->cell->downRight;
132       o->cell->downRight->left = o->cell->downLeft;
133     }
134     if (o->cell->right && o->cell->right->downLeft) {
135       o->cell->right->downLeft->left = o->cell->downRight;
136       o->cell->downRight->right = o->cell->right->downLeft;
137     }
138   }
139   o->cell = o->cell->downRight;
140   return o;
141 }
142
143 /***    struct cursor *left(struct cursor *)    ******************************
144 **
145 **  move left
146 **
147 **  TOP                     LEFT                    RIGHT
148 **      +-------+             +---+---+               +---+---+
149 **      |   N   |             |???<###|               |???|###|
150 **      +-/-+-^-+             +-+\+^+-+               +-+-+/+^+
151 **    { | N | N | }           |?|N|O|                   |?|N|O|
152 **    { +-+\+^+-+ }           +++++++                   +++++++
153 **        |N|O|
154 **        +++++
155 **
156 */
157
158 struct cursor *left(struct cursor *o) {
159   if (!o->cell->left) {
160     if        (o->cell->up && o->cell->up->downRight == o->cell) { /* RIGHT */
161       o->cell = o->cell->up;
162       o = downLeft(o);
163       return o;
164     } else if (o->cell->up && o->cell->up->downLeft  == o->cell) { /* LEFT */
165       o->cell = o->cell->up;
166       o = left(o);
167       o = downRight(o);     
168       return o;
169     } else if (!o->cell->up) {                                     /* TOP */
170       struct cell *c;
171       int n = 0;
172       do {
173         c = o->cell;
174         o = up(o, 1);
175         n++;
176       } while (o->cell->downLeft == c);
177       o = downLeft(o);
178       while (n--) {
179         o = downRight(o);
180       }
181       return o;
182     } else {
183       assert(0); /* broken */
184     }
185   }
186   o->cell = o->cell->left;
187   return o;
188 }
189
190 /***    struct cursor *right(struct cursor *)    *****************************
191 **
192 **  move right
193 **
194 **  TOP                     LEFT                    RIGHT
195 **      +-------+             +---+---+               +---+---+
196 **      |   N   |             |###|???|               |###>###|
197 **      +-^-+-\-+             +^+\+-+-+               +-+^+/+-+
198 **    { | N | N | }           |O|N|?|                   |O|N|?|
199 **    { +-+^+/+-+ }           +++++++                   +++++++
200 **        |O|N|
201 **        +++++
202 **
203 */
204
205 struct cursor *right(struct cursor *o) {
206   if (!o->cell->right) {
207     if        (o->cell->up && o->cell->up->downRight == o->cell) { /* RIGHT */
208       o->cell = o->cell->up;
209       o = right(o);
210       o = downLeft(o);
211       return o;
212     } else if (o->cell->up && o->cell->up->downLeft  == o->cell) { /* LEFT */
213       o->cell = o->cell->up;
214       o = downRight(o);
215       return o;
216     } else if (!o->cell->up) {                                     /* TOP */
217       struct cell *c;
218       int n = 0;
219       do {
220         c = o->cell;
221         o = up(o, 0);
222         n++;
223       } while (o->cell->downRight == c);
224       o = downRight(o);
225       while (n--) {
226         o = downLeft(o);
227       }
228       return o;
229     } else {
230       assert(0); /* broken */
231     }
232   }
233   o->cell = o->cell->right;
234   return o;
235 }
236