RでBrainf*ck

Tsukuba.R#4での発表資料はこちら.

http://www.slideshare.net/mickey24/rbrainfck-1085191

とりあえずソースを載せておきます.

# R de Brainf*ck

brainfxxk <- function(code) {
  # local variables
  code <- strsplit(code,"")[[1]]
  len <- length(code)
  pc <- 1
  ptr <- 1
  mem <- rep(0, 128)

  buf <- ""

  # >
  inc_ptr <- function() {
    ptr <<- ptr + 1
  }

  # <
  dec_ptr <- function() {
    ptr <<- ptr - 1
  }

  # +
  inc_mem <- function() {
    mem[ptr] <<- mem[ptr] + 1
  }

  # -
  dec_mem <- function() {
    mem[ptr] <<- mem[ptr] - 1
  }

  # .
  putc <- function() {
    cat(intToUtf8(mem[ptr]))
  }

  # ,
  getc <- function() {
    if (nchar(buf) == 0) {
      buf <<- readline()
    }
    mem[ptr] <<- utf8ToInt(substring(buf, 1, 1))
    buf <<- substring(buf, 2)
  }

  # [
  wstart <- function() {
    if (mem[ptr] == 0) {
      count <- 1
      pc <<- pc + 1
      while (count > 0) {
        if (code[pc] == "[") { count <- count + 1; }
        if (code[pc] == "]") { count <- count - 1; }
        pc <<- pc + 1
      }
      pc <<- pc - 1
    }
  }
  
  # ]
  wend <- function() {
    if (mem[ptr] != 0) {
      count <- 1
      pc <<- pc - 1
      while (count > 0) {
        if (code[pc] == "[") { count <- count - 1; }
        if (code[pc] == "]") { count <- count + 1; }
        pc <<- pc - 1
      }
      pc <<- pc + 1
    }
  }

  # main loop
  while (pc <= len) {
    switch(code[pc],
           ">" = inc_ptr(),
           "<" = dec_ptr(),
           "+" = inc_mem(),
           "-" = dec_mem(),
           "." = putc(),
           "," = getc(),
           "[" = wstart(),
           "]" = wend()
           )
    pc <- pc + 1
  }
  cat("\n")
}

# Hello, world!
hello <- "+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+.";

brainfxxk(hello)