BrainFuck 解释器(C语言实现)

简介: 码农的业余休闲活动就是去学习一门冷门的语言或者研究一项非主流的技术。BrainFuck 是一门小巧的编程语言,顾名思义,阅读这门语言的代码就像在强奸你的大脑一样。事实证明开发它的解释器比读懂它的 Hello World 要快。BrainFuck只有八条指令: 指令 含义 等价的C代码 > 指针加一 ++ptr; < 指针减一

码农的业余休闲活动就是去学习一门冷门的语言或者研究一项非主流的技术。BrainFuck 是一门小巧的编程语言,顾名思义,阅读这门语言的代码就像在强奸你的大脑一样。事实证明开发它的解释器比读懂它的 Hello World 要快。

BrainFuck只有八条指令:

指令 含义 等价的C代码
> 指针加一 ++ptr;
< 指针减一 --ptr;
+ 指针指向的字节的值加一 ++*ptr;
- 指针指向的字节的值减一 --*ptr;
. 输出指针指向的单元内容(ASCII码) putchar(*ptr);
, 输入内容到指针指向的单元(ASCII码) *ptr = getchar();
[ 如果指针指向的单元值为零,向后跳转到对应的]指令的次一指令处 while (*ptr) {
] 如果指针指向的单元值不为零,向前跳转到对应的[指令的次一指令处 }

解释器代码如下:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define TOKENS "><+-.,[]"

#define CODE_SEGMENT_SIZE 30000
#define STACK_SEGMENT_SIZE 1000
#define DATA_SEGMENT_SIZE 30000

typedef void (*Callback)(void);

struct {
  char cs[CODE_SEGMENT_SIZE];   /* Code Segment */
  long ip;                      /* Instruction Pointer */

  char ss[STACK_SEGMENT_SIZE];  /* Stack Segment */
  long sp;                      /* Stack Pointer */

  char ds[DATA_SEGMENT_SIZE];   /* Data Segment */
  long bp;                      /* Base Pointer */

  Callback fn[128];
} vm;

void vm_forward() {
  vm.bp = (vm.bp + 1) % DATA_SEGMENT_SIZE;
}

void vm_backward() {
  vm.bp = (vm.bp + DATA_SEGMENT_SIZE - 1) % DATA_SEGMENT_SIZE;
}

void vm_increment() {
  vm.ds[vm.bp]++;
}

void vm_decrement() {
  vm.ds[vm.bp]--;
}

void vm_input() {
  vm.ds[vm.bp] = getchar();
}

void vm_output() {
  putchar(vm.ds[vm.bp]);
}

void vm_while_entry() {
  if (vm.ds[vm.bp]) {
    vm.ss[vm.sp] = vm.ip - 1;
    vm.sp++;
  } else {
    int c = 1;
    for (vm.ip++; vm.cs[vm.ip] && c; vm.ip++) {
      if (vm.cs[vm.ip] == '[') {
        c++;
      } else if (vm.cs[vm.ip] == ']') {
        c--;
      }
    }
  }
}

void vm_while_exit() {
  if (vm.ds[vm.bp]) {
    vm.sp--;
    vm.ip = vm.ss[vm.sp];
  }
}

void setup() {
  int c;
  int i;

  memset(&vm, 0, sizeof(vm));
  vm.fn['>'] = vm_forward;
  vm.fn['<'] = vm_backward;
  vm.fn['+'] = vm_increment;
  vm.fn['-'] = vm_decrement;
  vm.fn['.'] = vm_output;
  vm.fn[','] = vm_input;
  vm.fn['['] = vm_while_entry;
  vm.fn[']'] = vm_while_exit;

  for (i = 0; (c = getchar()) != EOF;) {
    if (strchr(TOKENS, c)) {
      vm.cs[i] = c;
      i++;
    }
  }
}

void run() {
  while (vm.cs[vm.ip]) {
    vm.fn[vm.cs[vm.ip]]();
    vm.ip++;
  }
}

int main(int argc, char* argv[]) {
  if (argc > 1) {
    freopen(argv[1], "r", stdin);
  }

  setup();
  run();

  return 0;
}

Hello world:

brainfuc$ cat helloword.bf
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
brainfuc$ ./bf helloword.bf
Hello World!
brainfuc$


目录
相关文章
|
6月前
|
存储 C语言
brainfuck原理及C语言实现
brainfuck原理及C语言实现
69 0
|
C语言
造轮子之-C语言实现ArrayList
造轮子之-C语言实现ArrayList
|
C语言
C语言实现学生成绩管理系统
本文提供一例C语言实现的命令行学生信息管理系统,供初学者参考。
293 0
|
存储 Linux C语言
生产者消费者模式保姆级教程 (阻塞队列解除耦合性) 一文帮你从C语言版本到C++ 版本, 从理论到实现 (一文足以)
生产者消费者模式保姆级教程 (阻塞队列解除耦合性) 一文帮你从C语言版本到C++ 版本, 从理论到实现 (一文足以)
生产者消费者模式保姆级教程 (阻塞队列解除耦合性) 一文帮你从C语言版本到C++ 版本, 从理论到实现 (一文足以)
|
存储 C语言
c语言实现扫雷(含循环递归展开)
本笔记通过c语言实现扫雷小游戏(包含递归展开) 游戏实现逻辑位于test.c文件,整个游戏头文件位于game.h,游戏进程的具体操作于game.c中实现。
150 0
c语言实现扫雷(含循环递归展开)
|
C语言
c语言实现三子棋(内含阅读思路,简单易实现)
本文如果按顺序来阅读可能不太好接受,建议阅读顺序为,由test.c的逻辑顺序读下去,遇见具体函数的实现跳转到game.c中来理解
114 0
c语言实现三子棋(内含阅读思路,简单易实现)
|
SQL 关系型数据库 MySQL
C语言连接并实现对MySQL的增删改查
C语言访问数据库并不如Java、Python那般容易。本文介绍C语言连接并实现对MySQL的增删改查的方法。
442 0
|
C语言
c语言实现二进制八进制十进制和十六进制的相互转化
c语言实现二进制八进制十进制和十六进制的相互转化
258 0
|
C语言
c语言实现简单学生管理系统
该学生管理系统的实现是通过分文件的方式来写的,infor.h文件为头文件,源文件infor.c实现源文件test.c中封装函数,建议读者在做较大的系统是分文件来实现,可以提高代码的运行效率。
136 0
|
搜索推荐 C语言
【指针进阶三】实现C语言快排函数qsort&回调函数
【指针进阶三】实现C语言快排函数qsort&回调函数
79 0
【指针进阶三】实现C语言快排函数qsort&回调函数