[Home]ChrisHowlett/ICFP

ec2-3-143-4-181.us-east-2.compute.amazonaws.com | ToothyWiki | ChrisHowlett | RecentChanges | Login | Webcomic

/*****************************************************************************/
/* ICFP UM implementation. This relies on ulongs being 32 bits.              */
/*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

typedef unsigned long ulong;
typedef ulong platter;

platter reg[8];

typedef struct array
{
  ulong size;
  platter *platters;
} array;

array zero;

platter *finger;

#define ARRAY(index) ((index == 0) ? zero : (*((array *)index)))

int execute(void);

int main(int argc, char **argv)
{
  /***************************************************************************/
  /* Local variables.                                                        */
  /***************************************************************************/
  FILE *f;
  struct stat stats;
  ulong size;
  ulong reading;
  int ii;
  unsigned char read_byte;

  /***************************************************************************/
  /* Initialise registers.                                                   */
  /***************************************************************************/
  memset(reg, 0, 8 * sizeof(platter));

  /***************************************************************************/
  /* Open the file.                                                          */
  /***************************************************************************/
  if (argc != 2)
  {
    printf("Usage: um file.um\n");
    return 1;
  }
  if ((f = fopen(argv[1], "rb")) == NULL)
  {
    printf("Can't open input file for read\n");
    return 2;
  }

  /***************************************************************************/
  /* Check the file's size.                                                  */
  /***************************************************************************/
  fstat(fileno(f), &stats);
  size = stats.st_size;

  if (size % sizeof(platter) != 0)
  {
    printf("Bad file length\n");
    return 3;
  }

  /***************************************************************************/
  /* Allocate space in zero.                                                 */
  /***************************************************************************/
  zero.size = size / sizeof(platter);
  zero.platters = malloc(zero.size * sizeof(platter));

  /***************************************************************************/
  /* Read file into zero.                                                    */
  /***************************************************************************/
  read_byte = fgetc(f);
  finger = &(zero.platters[0]);
  for (reading = 0; reading < zero.size; reading++)
  {
    *finger = 0;

    for (ii = 0; ii < sizeof(platter); ii++)
    {
      *finger = (*finger << 8) + read_byte;
      read_byte = fgetc(f);
    }
    finger++;
  }

  /***************************************************************************/
  /* Set up finger.                                                          */
  /***************************************************************************/
  finger = &(zero.platters[0]);

  /***************************************************************************/
  /* Run it!                                                                 */
  /***************************************************************************/
  return execute();
}

int execute(void)
{
  /***************************************************************************/
  /* Local variables.                                                        */
  /***************************************************************************/
  ulong comm;
  unsigned char op,a,b,c;
  array *temp_array;
  int input;

  /***************************************************************************/
  /* Spin Cycle.                                                             */
  /***************************************************************************/
  while (1)
  {
    /*************************************************************************/
    /* Read op, and advance finger.                                          */
    /*************************************************************************/
    comm = *finger;
    finger++;
    op = (unsigned char)((comm & 0xF0000000) >> 28);
    c = (unsigned char)(comm & 0x00000007);
    b = (unsigned char)((comm >> 3) & 0x00000007);
    a = (unsigned char)((comm >> 6) & 0x00000007);

    /*************************************************************************/
    /* Do op.                                                                */
    /*************************************************************************/
    switch (op)
    {
      case 0:
        // Conditional Move
        if (reg[c] != 0)
        {
          reg[a] = reg[b];
        }
        break;

      case 1:
        // Array Index
        reg[a] = ARRAY(reg[b]).platters[reg[c]];
        break;

      case 2:
        // Array Amendment
        ARRAY(reg[a]).platters[reg[b]] = reg[c];
        break;

      case 3:
        // Addition
        reg[a] = reg[b] + reg[c];
        break;

      case 4:
        // Multiplication
        reg[a] = reg[b] * reg[c];
        break;

      case 5:
        // Division
        reg[a] = reg[b] / reg[c];
        break;

      case 6:
        // Nand
        reg[a] = ~(reg[b] & reg[c]);
        break;

      case 7:
        // Halt
        goto EXIT_LABEL;
        break;

      case 8:
        // Allocation
        temp_array = malloc(sizeof(array));
        temp_array->size = reg[c];
        temp_array->platters = malloc(reg[c] * sizeof(platter));
        memset(temp_array->platters, 0, reg[c] * sizeof(platter));
        reg[b] = (platter)temp_array;
        break;

      case 9:
        // Abandonment
        free(ARRAY(reg[c]).platters);
        free((array *)reg[c]);
        break;

      case 10:
        // Output
        putchar((unsigned char)reg[c]);
        break;

      case 11:
        // Input
        input = getchar();
        reg[c] = (input == EOF) ? 0xFFFFFFFF : input;
        break;

      case 12:
        // Load
        if (reg[b] == 0)
        {
          // Load zero
          finger = &(zero.platters[reg[c]]);
        }
        else
        {
          // Load other
          zero.platters = realloc(zero.platters, ARRAY(reg[b]).size * sizeof(platter));
          zero.size = ARRAY(reg[b]).size;
          memcpy(zero.platters,
                 ARRAY(reg[b]).platters,
                 zero.size * sizeof(platter));
          finger = &(zero.platters[reg[c]]);
        }
        break;

      case 13:
        // Orthography
        a = (unsigned char)((comm & 0x0E000000) >> 25);
        reg[a] = comm & 0x01FFFFFF;
        break;

      default:
        return 4;
    }
  }

EXIT_LABEL:
  return 0;
}





Pity me, for I have written this:

,..|.................................................................................................................................,
:L v                                                                                                                                 :
: *==================*  *==================*                                                                                         :
: !send [(N,E),(N,S)]!->!send [(N,E),(N,S)]!----+                                                                                    :
: *==================*  *==================*    |                                                                                    :
:  |                   +-+                      |                                                                                    :
:  v                   |                        |                                                                                    :
: *==============*     |  *==================*  |                                                                                    :
: !case N of S, E!-----#->!send [(Inl (), E)]!--#-------------------------------------------------------------------------------------
: *==============*     |  *==================*  |                                                                                    :
:  |                   |                        |                                                                                    :
:  v                   |                        |                                                                                    :
: *=======*            |                        |                                                                                    :
: !split N!---+        |                        |                                                                                    :
: *=======*   |        |     +------------------+                                                                                    :
:  |          |        |     |                                                                                                       :
:  v          +--------#-----#--------------------------------------+                                                                :
: *=======*            |     |                                      |                                                                :
: !split N!---------+  |     |                                      |                                                                :
: *=======*         |  |   +-#--------------------------------------#--------------------------------+                               :
:  |                |  |   | |                                      v                                v                               :
:  v                |  |   | |    *=============================*  *=====*  *==================*  *============*                     :
: *==============*  |  |   | |  +>!send [((W,(Inl(),Inl())), E)]!->!use L!->!send [(W,E),(W,S)]!->!send [(W,E)]!----------------------
: !case N of S, E!--#--#---+ |  | *=============================*  *=====*  *==================*  *============*                     :
: *==============*  |  |     +--#--------------------------------+            |                                                      :
:  |                |  +------+ +--------------------------+     |            |                                                      :
:  |                +-------+ +--+                         | +---#------------+                                                      :
:  |                        |    v                         | |   |                                                                   :
:  |  *===================* | *=====*  *==================*| |   |                                                                   :
---#->!send [(W,S), (W,E)]!-#>!use R!->!send [(W,E),(W,S)]!+ |   |                                                                   :
:  |  *===================* | *=====*  *==================*  |   |                                    *==================*           :
:  |      |                 |                           |    |   +----------------------------------->!send [(W,E),(W,S)]!+          :
:  |      v                 v                   +-------#----+                                        *==================*|          :
:  |  *=======*            *=======*  *=======* |       |      *==================*                        |              |          :
:  +->!split N!----------+ !split N!->!split W!-#-------#--+ +>!send [(W,E),(W,S)]!------------------------#----------+   |          :
:     *=======*          | *=======*  *=======* |       |  | | *==================*                        |          |   |          :
:      |       +---------#--+          |        v       +--#-+             |                               v          | +-+          :
: +----+       v         +-+           | *===========*     |               v           *=============*  *============*| |            :
: |         *===========*  |           +>!use multint!+    |              *=========*+>!case W of S,E!->!send [(N,E)]!#-#---+        :
: |R(i)   +>!use multint!+ |             *===========*|    |            +>!use eqint!+ *=============*  *============*| |   v        :
: |       | *===========*| |                          v    v            | *=========*              |                  | | *=====*    :
: |       |              | |               *===========*  *===========* | *==================*     v                +-#-#>!use L!-----
: |       +----------+   +-#-------------->!use plusint!->!use plusint!-#>!send [(W,S),(W,E)]!-+  *============*    | | | *=====*    :
: v                  |     |               *===========*  *===========* | *==================* +->!send [(W,S)]!    | | |            :
:*==================*|     | *=======*                                  |     |                   *============*    | | |            :
:!send [(N,E),(N,S)]!+     +>!split W!----------------------------------+     |                 +---+               | | |            :
:*==================*        *=======*                                        |                 v                   | | |            :
:                 |                 +----------------------------+            |        *=========*  *=============* | | |            :
:                 |                                              +------------#------->!use eqint!->!case W of E,S!-#-#-#-------------
:                 |                                                           |        *=========*  *=============* | | |            :
:                 |                                                           |                             |       | | |            :
:                 |                                                           |   +-------------------------#-------#-+ v            :
:                 +-------------------------------------------+               |   v                         |       |  *============*:
:                                                             |               | *================*          +-------#->!send [(N,S)]!:
:                                                             |               +>!send [((W,N),S)]!                  |  *============*:
:                                                             |                 *================*                  |        |       :
:                                                             |                  |                                  +---+    |       :
:                                                             |                  v                                      |    v       :
:                                                             |                 *================*  *==================*|   *=====*  :
:                                                             +---------------->!send [((W,N),E)]!->!send [(W,S),(W,E)]!+ +>!use L!---
:                                                                               *================*  *==================*  | *=====*  :
:                                                                                                                  +------+          :
,....................................................................................................................................,



ec2-3-143-4-181.us-east-2.compute.amazonaws.com | ToothyWiki | ChrisHowlett | RecentChanges | Login | Webcomic
This page is read-only | View other revisions | Recently used referrers
Last edited February 6, 2007 10:17 am (viewing revision 5, which is the newest) (diff)
Search: