TA的每日心情 | 郁闷 昨天 09:47 |
---|
签到天数: 1623 天 连续签到: 1 天 [LV.Master]伴坛终老
|
本帖最后由 nemon 于 2013-2-6 16:36 编辑
据《战国策.赵策》中《秦围赵之邯郸》记载,“周烈王崩,诸侯皆吊,齐后往。周怒,赴于齐曰:‘天崩地坼,天子下席。东藩之臣田婴齐后至,则斫之!’(齐)威王勃然怒曰:‘叱嗟,而母婢也!’卒为天下笑。”用现在的话简单说就是周烈王挂了,齐威王拖着到最后一个去吊孝,周怒了,说你一住东边欠发达地区的家臣还敢这么怠慢,欠扁!齐王咆哮了“尼玛是丫头!”后来这句话流传开来,逐渐演变,从“尔母婢也”扩展成“尔母X也”,白话变成了“你妈的......”,之后再由第二人称改为第三人称,再用汉语拼音第一个字母代替,最后成了“TMD”三个响当当的字母。鲁迅先生都曾经撰文《论‘他妈的’》以述“这话的分布,大概就跟着中国人足迹之所至罢”,“只要在中国过活的话,便总听得到他妈的”,于是总结这三个字为中国“国骂”。
不止中国有国骂,查百科看到各国风俗不同,在此一事上倒是不分伯仲。如果常看USA片,原声中F***恐怕是少不了的。不过大家都知道,骂并不都是表示侮辱,有时只是助词表示语气而已。对比一下fuckbrain和brainfuck,你会发现前者大概是"脑残"的意思而后者是一个很难读懂的摧残脑细胞的计算机语言。由于fuck在英语中是脏话,这种语言有时被称为brainf*ck或brainf***,甚至被简称为BF。BF语言只包括八个运算符,尽管如此,它是图灵完备的,像其它图灵机一样能够正确运行,可以完成任何计算任务。这种语言基于一个简单的机器模型,除了指令,这个机器还包括:一个以字节为单位、被初始化为零的数组、一个指向该数组的指针(初始时指向数组的第一个字节)、以及用于输入输出的两个字节流。下面是这八种状态的描述,其中每个状态由一个字符标识:
字符 | 含义 | > | 指针加一 | < | 指针减一 | + | 指针指向的字节的值加一 | - | 指针指向的字节的值减一 | . | 输出指针指向的单元内容(ASCII码) | , | 输入内容到指针指向的单元(ASCII码) | [ | 如果指针指向的单元值为零,向后跳转到对应的]指令的次一指令处 | ] | 如果指针指向的单元值不为零,向前跳转到对应的[指令的次一指令处 | 下面我们就来运行一个BF的解释器:
首先,打开串口做的控制台:
输入2,看一下现在的内存:
内存都是0,然后选3输入程序:
程序内容是,注意要在此基础上加@结尾:- >;+++++++++[<++++++++>;-]<.>;+++++++[<++++>;-]<+.+++++++..+++.[-]>;++++++++[<++++>;-]<.#>;+++++++++++[<+++++>;-]<.>;++++++++[<+++>;-]<.+++.------.--------.[-]>;++++++++[<++++>;-]<+.[-]++++++++++.
复制代码
然后选4,看一下输入的程序:
之后选5,运行程序,在两排减号之间是输出,
可以看到,和大多数语言的第一个例子一样,这个程序输出“Hello World!”
再按一次2看看内存。可以看到只用了第一个字节:
下面看代码,首先是brainfuck.h:- #ifndef BRAINFUCK_H
- #define BRAINFUCK_H
- #define BF_PROG_SIZE 500
- #define BF_MEMORY_SIZE 64
- #define BF_STACK_SIZE 16
- typedef void(*FB_OUT_CHAR)(char c);
- #define FUNC_FB_OUT_CHAR(funcname) void funcname(char c)
- //FUNC_FB_OUT_CHAR(out_char);
- typedef char(*FB_GET_CHAR)();
- #define FUNC_FB_GET_CHAR(funcname) char funcname()
- //FUNC_FB_GET_CHAR(out_char);
- void BrainFuckInterpret(unsigned char *pc_CmdLine,unsigned char *pc_Memory,FB_OUT_CHAR out_char, FB_GET_CHAR get_char);
- #endif //BRAINFUCK_H
复制代码 这是brainfuck.c,里面就是虚机的逻辑:
- #include "brainfuck.h"
- void BrainFuckInterpret(unsigned char *pc_CmdLine,unsigned char *pc_Memory,FB_OUT_CHAR out_char, FB_GET_CHAR get_char)
- {
- //unsigned char uc_Memory[BF_MEMORY_SIZE]={0};
- unsigned char *pc_PM=pc_Memory;
- unsigned char *pc_PC=(unsigned char *)pc_CmdLine;
- unsigned short us_CurrentStackCount=0;
- unsigned short us_tmpStackCount=0;
- unsigned char *uc_Stack[BF_STACK_SIZE]={0};
- /*
- for(us_tmpStackCount=0;us_tmpStackCount<BF_MEMORY_SIZE;us_tmpStackCount++)
- pc_Memory[us_tmpStackCount]=0;
- us_tmpStackCount=0;
- */
- while(*pc_PC)
- {
- switch(*pc_PC)
- {
- case '>': //指针加一
- pc_PM++;
- pc_PC++;
- break;
- case '<': //指针减一
- pc_PM--;
- pc_PC++;
- break;
- case '+': //指针指向的字节的值加一
- (*pc_PM)++;
- pc_PC++;
- break;
- case '-': //指针指向的字节的值减一
- (*pc_PM)--;
- pc_PC++;
- break;
- case '.': //输出指针指向的单元内容(ASCII码)
- out_char(*pc_PM);
- pc_PC++;
- break;
- case ',': //输入内容到指针指向的单元(ASCII码)
- (*pc_PM)=get_char();
- pc_PC++;
- break;
- case '[': //如果指针指向的单元值为零,向后跳转到对应的]指令的次一指令处
- if((*pc_PM)==0)
- {
- us_tmpStackCount=us_CurrentStackCount+1;
- pc_PC++;
- while(us_tmpStackCount>us_CurrentStackCount)
- {
- switch(*pc_PC++)
- {
- case '[':
- us_tmpStackCount++;
- break;
- case ']':
- us_tmpStackCount--;
- break;
- default:
- break;
- }
- }
- }
- else
- {
- us_CurrentStackCount++;
- uc_Stack[us_CurrentStackCount]=pc_PC;
- pc_PC++;
- }
- break;
- case ']': //如果指针指向的单元值不为零,向前跳转到对应的[指令的次一指令处
- if((*pc_PM)!=0)
- {
- pc_PC=uc_Stack[us_CurrentStackCount]+1;
- }
- else
- {
- us_CurrentStackCount--;
- pc_PC++;
- }
- break;
- default:
- pc_PC++;
- break;
- }
- }
- }
复制代码 最后是菜单项的定义和事件响应以及相关函数:- #include "brainfuck.h"
- //bf程序缓冲区
- unsigned char ucg_bf_file[BF_PROG_SIZE]={0};
- //bf内存缓冲区
- unsigned char ucg_bf_mem[BF_MEMORY_SIZE]={0};
- //打印一个字符
- FUNC_FB_OUT_CHAR(console_out_char)
- {
- printf("%c",c);
- }
- //读取一个字符
- FUNC_FB_GET_CHAR(console_get_char)
- {
- char c_char;
- uart_read(CONSOLE_UART, &c_char);
- while(c_char<32 || c_char>126)
- {
- uart_read(CONSOLE_UART, &c_char);
- }
- return c_char;
- }
- //事件响应
- void my_command_event(struct stCosnoleMenuRoot *stRt,unsigned int ui_ID)
- {
- char ac_buff[512]={0};
- unsigned int ui_l,ui_i,ui_j;
- printf("command 0x%x is be selected\r\n",ui_ID);
- switch(ui_ID)
- {
- case 0x11://iCnt=Cosnole_Add_A_Menu(&stMenu,0,0x11,"Clean Memory" ,MENU_TYPE_COMMAND,MENU_CHECK_TRUE,'1');//1
- printf("clearning...\r\n");
- for(ui_l=0;ui_l<BF_MEMORY_SIZE;ui_l++)ucg_bf_mem[ui_l]=0;
- printf("clearning done..\r\n");
- break;
- case 0x12://iCnt=Cosnole_Add_A_Menu(&stMenu,0,0x12,"Show Memory" ,MENU_TYPE_COMMAND,MENU_CHECK_TRUE,'2');//2
- printf("show memory:\r\n");
- printf("[address]");
- for(ui_l=0;ui_l<8;ui_l++)printf(" 0x%02x",ui_l);
- printf("\r\n");
- printf("-------------------------------------------------\r\n");
- for(ui_l=0;ui_l<BF_MEMORY_SIZE;ui_l++)
- {
- if(0==ui_l%8)printf("[0x%05x]",ui_l);
- printf(" 0x%02x",ucg_bf_mem[ui_l]);
- if(7==ui_l%8)printf("\r\n");
- }
- printf("memory show as above.\r\n");
- break;
- case 0x13://iCnt=Cosnole_Add_A_Menu(&stMenu,0,0x13,"Input Program" ,MENU_TYPE_COMMAND,MENU_CHECK_TRUE,'3');//3
- ui_l=inputLineFromConsole("Input the Prog:",ucg_bf_file,BF_PROG_SIZE);
- printf("the program has %d char.\r\n",ui_l);
- break;
- case 0x14://iCnt=Cosnole_Add_A_Menu(&stMenu,0,0x14,"Show Program" ,MENU_TYPE_COMMAND,MENU_CHECK_TRUE,'4');//4
- printf("Program is:\r\n");
- printf("%s\r\n",ucg_bf_file);
- printf("the program shown as above.\r\n");
- break;
- case 0x15://iCnt=Cosnole_Add_A_Menu(&stMenu,0,0x15,"Run Program " ,MENU_TYPE_COMMAND,MENU_CHECK_TRUE,'5');//5
- printf("Program is running...\r\n-------------------------------------\r\n");
- BrainFuckInterpret(ucg_bf_file,ucg_bf_mem,console_out_char,console_get_char);
- printf("\r\n-------------------------------------\r\n");
- printf("the program is done.\r\n");
- break;
- }
- show_current_menu(&stMenu);
- }
- //菜单项的定义
- ………………
- iCnt=Cosnole_Add_A_Menu(&stMenu,0,0x11,"Clean Memory" ,MENU_TYPE_COMMAND,MENU_CHECK_TRUE,'1');//1
- iCnt=Cosnole_Add_A_Menu(&stMenu,0,0x12,"Show Memory" ,MENU_TYPE_COMMAND,MENU_CHECK_TRUE,'2');//2
- iCnt=Cosnole_Add_A_Menu(&stMenu,0,0x13,"Input Program" ,MENU_TYPE_COMMAND,MENU_CHECK_TRUE,'3');//3
- iCnt=Cosnole_Add_A_Menu(&stMenu,0,0x14,"Show Program" ,MENU_TYPE_COMMAND,MENU_CHECK_TRUE,'4');//4
- iCnt=Cosnole_Add_A_Menu(&stMenu,0,0x15,"Run Program " ,MENU_TYPE_COMMAND,MENU_CHECK_TRUE,'5');//5
- ………………
复制代码
最后,再附一个fb的windows版的ide:
bfdev-1-4-7.rar
(330.83 KB, 下载次数: 7)
|
|