original C prototype
[maximus:kjhf.git] / prototype / machine.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 <stdio.h>
9 #include <stdlib.h>
10 #include "machine.h"
11 #include "fbitstream.h"
12 #include "parser.h"
13
14 static void *zero = 0;
15 static void *one = &one;
16
17 struct machine *machine(char *c, FILE *g, FILE *i, FILE *o) {
18   struct machine *m = malloc(sizeof(struct machine));
19   m->input = fibitstream(i);
20   m->output = fobitstream(o);
21   m->data = space(fibitstream(g));
22   m->dataPtr = cursor(m->data);
23   m->code = parse(c);
24   m->codePtr = m->code;
25   m->running = 1;
26   return m;
27 }
28
29 struct machine *step(struct machine *m) {
30   int bit = m->dataPtr->cell->data != zero;
31   enum opcode op = m->codePtr->op;
32   /* fputc("+^<>/\\,;|#"[op], stderr); */
33   switch (op) {
34   case (oHalt):      m->running = 0; break;
35   case (oFlip):      m->dataPtr->cell->data = !bit ? one : zero; break;
36   case (oUp):        m->dataPtr = up       (m->dataPtr, 0); break;
37   case (oLeft):      m->dataPtr = left     (m->dataPtr); break;
38   case (oRight):     m->dataPtr = right    (m->dataPtr); break;
39   case (oDownLeft):  m->dataPtr = downLeft (m->dataPtr); break;
40   case (oDownRight): m->dataPtr = downRight(m->dataPtr); break;
41   case (oInput):     m->input = m->input->get(m->input);
42                      m->dataPtr->cell->data = m->input->bit ? one : zero;
43                      break;
44   case (oOutput):    m->output = m->output->put(m->output, bit);
45                      if (m->input->end) { m->dataPtr->cell->data = zero; }
46                      break;
47   default:           break;
48   }
49   m->codePtr = m->codePtr->next[bit];
50   return m;
51 }
52