ICFP Contest 2006
Team: Abstraction Anonymous

um.cpp

Download

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include <arpa/inet.h>
  6. #include <sys/types.h>
  7. #include <sys/mman.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10.  
  11. // begin C++ pain
  12. #include <queue>
  13.  
  14. using namespace std;
  15.  
  16. #define A(inst) ((inst >> 0x6) & 0x7)
  17. #define B(inst) ((inst >> 0x3) & 0x7)
  18. #define C(inst) (inst & 0x7)
  19. #define A13(inst) ((inst >> 25) & 0x7)
  20. #define DATA(inst) (inst & 0x1ffffff)
  21. #define OP(inst) (inst >> 28)
  22. #define REG(num) (registers[num])
  23. #define REGA(inst) (REG(A(inst)))
  24. #define REGB(inst) (REG(B(inst)))
  25. #define REGC(inst) (REG(C(inst)))
  26. #define REGA13(inst) (REG(A13(inst)))
  27.  
  28. #define MEMSIZ (1024 * 1024 * 32)
  29.  
  30. typedef unsigned int platter;
  31.  
  32. platter registers[8] = {0,0,0,0,0,0,0,0};
  33. platter * arrays[MEMSIZ];
  34. size_t siz_arrays[MEMSIZ];
  35. size_t num_array = 1;
  36. platter finger = 0;
  37. int last_free = 0;
  38.  
  39. int main(int argc, char *argv[]) {
  40. int lastloc = 0, i;
  41. platter cur;
  42. platter * temp;
  43. struct stat x;
  44. queue<int> free_list;
  45.  
  46. stat(argv[1], &x);
  47. temp = (platter *) mmap(NULL, x.st_size,
  48. PROT_READ | PROT_WRITE, MAP_PRIVATE,
  49. open(argv[1], O_RDONLY, 0600), (off_t) 0);
  50. arrays[0] = (platter *) malloc(x.st_size);
  51. memcpy(arrays[0], temp, x.st_size);
  52. munmap(temp, x.st_size);
  53.  
  54. siz_arrays[0] = x.st_size;
  55. while(1) {
  56. cur = htonl(arrays[0][finger++]);
  57.  
  58. switch(OP(cur)) {
  59. // condmove
  60. case 0:
  61. if (REGC(cur) != 0) {
  62. REGA(cur) = REGB(cur);
  63. }
  64. break;
  65. // index
  66. case 1:
  67. REGA(cur) = arrays[REGB(cur)][REGC(cur)];
  68. break;
  69. // amend
  70. case 2:
  71. assert(arrays[REGA(cur)] != 0);
  72. arrays[REGA(cur)][REGB(cur)] = REGC(cur);
  73. break;
  74. // add
  75. case 3:
  76. REGA(cur) = REGB(cur) + REGC(cur);
  77. break;
  78. // mult
  79. case 4:
  80. REGA(cur) = REGB(cur) * REGC(cur);
  81. break;
  82. // div
  83. case 5:
  84. REGA(cur) = REGB(cur) / REGC(cur);
  85. break;
  86. // not_and
  87. case 6:
  88. REGA(cur) = ~ (REGB(cur) & REGC(cur));
  89. break;
  90.  
  91. // halt
  92. case 7:
  93. exit(0);
  94. break;
  95.  
  96. // alloc
  97. case 8:
  98. // try and pop a location off the stack, otherwise start counting up
  99. if (!free_list.empty()) {
  100. i = free_list.front();
  101. free_list.pop();
  102. } else {
  103. for (i = lastloc+1;
  104. arrays[i] != NULL && i != lastloc;
  105. i = (i + 1) % MEMSIZ) ;
  106. }
  107. // this tracks the last insertion instead
  108. /* for (i = last_free;
  109. arrays[i] != NULL && i != last_free-1;
  110. i = (i + 1) % MEMSIZ) ; */
  111. // this version walks forward in the array
  112. /* for (i = lastloc+1;
  113. arrays[i] != NULL && i != lastloc;
  114. i = (i + 1) % MEMSIZ) ; */
  115. //assert(i != lastloc);
  116. //assert(i != last_free-1);
  117. // move last_free somewhere random, for fun
  118. //last_free = rand() % MEMSIZ;
  119.  
  120. lastloc = i;
  121. arrays[i] = (platter *) calloc(REGC(cur), sizeof(platter));
  122. siz_arrays[i] = REGC(cur);
  123. REGB(cur) = i;
  124. break;
  125. // abandon
  126. case 9:
  127. free(arrays[REGC(cur)]);
  128. arrays[REGC(cur)] = 0;
  129. //last_free = REGC(cur);
  130. free_list.push(REGC(cur));
  131. break;
  132. // out
  133. case 10:
  134. if (REGC(cur) < 256) {
  135. putchar(REGC(cur));
  136. fflush(stdout);
  137. }
  138. break;
  139. // in
  140. case 11:
  141. REGC(cur) = getchar();
  142. break;
  143. // load
  144. case 12:
  145. if (REGB(cur) != 0) {
  146. free(arrays[0]);
  147. arrays[0] = (platter *) calloc(siz_arrays[REGB(cur)], sizeof(platter));
  148. assert(arrays[0] != 0);
  149. assert(arrays[REGB(cur)] != 0);
  150. memcpy(arrays[0], arrays[REGB(cur)],
  151. siz_arrays[REGB(cur)] * sizeof(platter));
  152. siz_arrays[0] = siz_arrays[REGB(cur)];
  153. }
  154. finger = REGC(cur);
  155. break;
  156. // data
  157. case 13:
  158. REGA13(cur) = DATA(cur);
  159. break;
  160. default:
  161. fprintf(stderr, "Died!\n");
  162. exit(1);
  163. }
  164. }
  165. }
  166.  

Hell is other programming languages. -- Sartran
Hell is that programming language! -- Dan
Ordinarily, one would enrich this language with more powerful means of computation. Instead I take a different tack... -- Harmonious Monk