Hatena::ブログ(Diary)

hogeなlog

プロフィール

hogelog

hogelog

小室 直(こむろ すなお)。電気通信大学2003年入学。2010年修士卒業。プログラミングとかしてます。

カレンダー
1984 | 01 |
2006 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 |
2010 | 01 | 06 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 05 | 08 | 09 | 10 | 12 |
2012 | 01 | 04 | 06 |

January 01(Sun), 1984

[] 構文を解析してから実行する子

#include <stdio.h>
#include <stdlib.h>
#define MAXCODE 30000
#define MAXMEM 30000
int mem[MAXMEM];
int pt = 0;
void (*optable[256])();
typedef void (*CodeType)();
char codebuf[MAXCODE];
void *code = codebuf;
int codept = 0;
#define codePrev(x) (codept-=sizeof(x))
#define codeNext(x) (codept+=sizeof(x))
#define codePoint() (codept)
#define codePointTo(x) (codept=(x))
#define codeValue(x) (*(x*)(code+codePoint()))
#define codeValueAt(x,p) (*(x*)(code+p))

void op_inc()
{
  ++mem[pt];
  codeNext(CodeType);
}
void op_dec()
{
  --mem[pt];
  codeNext(CodeType);
}
void op_next()
{
  ++pt;
  codeNext(CodeType);
}
void op_prev()
{
  --pt;
  codeNext(CodeType);
}
void op_get()
{
  mem[pt]=getchar();
  codeNext(CodeType);
}
void op_put()
{
  putchar(mem[pt]);
  codeNext(CodeType);
}
void op_zej()
{
  codeNext(CodeType);
  if(mem[pt]==0){
    codePointTo(codeValue(int));
  }
  else{
    codeNext(int);
  }
}
void op_goto()
{
  codeNext(CodeType);
  codePointTo(codeValue(int));
}
void evalCode()
{
  CodeType op;
  codePointTo(0);
  while((op=codeValue(CodeType))!=NULL){
    op();
  }
}
int readProgram(FILE *input, int blockStart)
{
  int c;
  while((c=fgetc(input))!=EOF){
    if(optable[c]==NULL) continue;
    codeValue(CodeType) = (CodeType)optable[c];
    if(c=='['){
      int startPt, endPt;
      startPt = codePoint();
      codeNext(CodeType);
      endPt = codePoint();
      codeNext(int);
      codeValueAt(int, endPt) = readProgram(input, startPt);
    }
    else if(c==']'){
      codeNext(CodeType);
      codeValue(int) = blockStart;
      codeNext(int);
      return codePoint();
    }
    else{
      codeNext(CodeType);
    }
    if(codePoint()>MAXCODE){
      fputs("too long code", stderr);
      exit(1);
    }
  }
  return codePoint();
}
void printProgram()
{
  codePointTo(0);
  while(codeValue(CodeType)!=NULL){
    CodeType op = codeValue(CodeType);
    printf("%3d: %p\n", codePoint(), op);
    codeNext(CodeType);
    if(op==(CodeType)op_zej||op==(CodeType)op_goto){
      printf("%3d: %d(int)\n", codePoint(), codeValue(int));
      codeNext(int);
    }
  }
  printf("%3d: end\n", codePoint());
}
void init()
{
  optable['+'] = op_inc;
  optable['-'] = op_dec;
  optable['>'] = op_next;
  optable['<'] = op_prev;
  optable[','] = op_get;
  optable['.'] = op_put;
  optable['['] = op_zej;
  optable[']'] = op_goto;
}
int main(int argc, char *argv[]){
  FILE *fp;
  if(argc>1){
    if((fp = fopen(argv[argc-1], "r")) == NULL){
      printf("cannot open file\n");
      return 1;
    }
  }
  else{
    fp = stdin;
  }
  init();
  readProgram(fp, -1);
#ifdef DEBUGPRINT
  printProgram();
#endif
  evalCode();
  return 0;
}
最近のコメント