第一部分第二部分第三部分第四部分第五部分本文致力于基于
Little Man Computer架构的某种深奥语言
LMCode的解释器的创建。
实际上,这是
LMC的汇编器仿真器,仅在这里代替汇编器命令INP,STA,ADD,SUB,OUT,使用特殊命令。 字符。
要将数字加载到
command_mem命令的内存中,从一个命令过渡到
另一个命令,并输出结果,请使用
brainfuck命令。
- 让INP命令匹配
- OUT命令对应。
- ADD命令对应于+
- 子命令对应于-
- STA命令对应〜
- LDA命令对应于^
我们编写一个程序,将输入设备中的数字加载到电池中,将数字保存在内存中,将内存中的数字添加到电池中(数字的两倍),然后将翻倍的数字输出到输出设备。
在汇编器LMC中,该程序将如下所示(让初始单元格为20)
INP STA 20 ADD 20 OUT
在LMCode中,此程序将类似于
,〜+。在我们的LMCode机器中,代码存储器和数据存储器是分开的(哈佛体系结构),我们将创建
command_mem行以加载LMCode代码。
command_mem字符串将代表命令的内存。 我们还创建了一个
data_mem数据
数组 ,该
数组代表数据存储器。
我们将程序加载到
command_mem〜〜中 。 #include <stdio.h> int main(void) { int i=0; // int j=0; // int acc = 0; // char command_mem[100] = ",~+."; // int data_mem[10]={0}; // while (command_mem[i] != '\0') { if (command_mem[i]==',') // scanf("%d", &acc); if (command_mem[i]=='+') // data_mem acc=acc+data_mem[j]; // if (command_mem[i]=='~') // data_mem[j]=acc; // if (command_mem[i]=='.') // printf("Output: %d",acc); i++; // } // printf("\n"); // for (int k = 0; k<10; k++) printf("%d ", data_mem[k]); return 0; }
将数字
123装入输入设备时,我们得到数字
246 。
您可以在oline ide
ideone.com中签到添加命令
在处理符号
>时,我们将增加数据数组
data_mem的索引
j if(command_mem[i]=='>') j++;
在处理符号
<时,我们将减少数据数组
data_mem的索引
j if(command_mem[i]=='<') j--;
要按命令向前跳
? 我们将过渡到标签
!为此,我们将跳过
?之间的所有字符
。 和
! if(command_mem[i]=='?') { while(command_mem[i] != '!' ) { i++; } }
为了进行比较,我们编写了一个程序,在该程序中,用户使用命令将一个数字(例如
5 )与一个命令一起输入到连续五个单元格中
〜>〜>〜>〜>〜 #include <stdio.h> int main(void) { int i=0; // int j=0; // int acc = 0; // char command_mem[100] = ",~>~>~>~>~"; // int data_mem[10]={0}; // while (command_mem[i] != '\0') { if (command_mem[i]==',') // scanf("%d", &acc); if (command_mem[i]=='+') // data_mem acc=acc+data_mem[j]; // if (command_mem[i]=='~') // data_mem[j]=acc; // if (command_mem[i]=='.') // printf("Output: %d",acc); if(command_mem[i]=='>') // j++; if(command_mem[i]=='<') // j--; if(command_mem[i]=='?') { // ! while(command_mem[i] != '!') i++; } i++; // } // printf("\n"); // for (int k = 0; k<10; k++) printf("%d ", data_mem[k]); return 0; }
结果,我们得到一个数组
5 5 5 5 5 0 0 0 0 0 0ideone.com并使用无条件跳转命令跳过了向前几个步骤的同一程序
,〜>〜?>〜>〜>〜!我们得到一个数组
5 5 0 0 0 0 0 0 0 0 0ideone.com添加
pzflag标志PositiveZero-flag
仅当电池中的数字大于或等于零时,标志才会升起。
if(acc>=0){ pzflag=1;} else { pzflag=0;}
继续执行条件
pzflag == 1,我们将执行命令
{和
} if(command_mem[i]=='{') && (pzflag==1){ while(command_mem[i] != '}' ) i++; }
接下来,让两个数字存储在我们的内存中
data_mem [0] = 3和
data_mem [1] = 5我们将编写一个显示最大数量的程序。
#include <stdio.h> int main(void) { int i=0; // int j=0; // int acc = 0; int pzflag = 1; // acc>=0 char command_mem[100] = "^>-{^?}<^!."; // int data_mem[10]={0}; data_mem[0]=3; // data_mem[1]=5; while ( command_mem[i] != '\0') { if(command_mem[i]==',') // scanf("%d", &acc); if(command_mem[i]=='+') // data_mem acc=acc+data_mem[j]; // if(command_mem[i]=='-') // data_mem acc=acc-data_mem[j]; // if(command_mem[i]=='>') // j++; if(command_mem[i]=='<') // j--; if(command_mem[i]=='~') // data_mem[j]=acc; // if(command_mem[i]=='^') // data_mem acc=data_mem[j]; // if(command_mem[i]=='.') { // printf("Output: %d",acc); printf(" "); }; if(command_mem[i]=='?') { // ! while(command_mem[i] != '!') i++; } if (command_mem[i]=='{' && pzflag==1) { // acc>=0 while(command_mem[i] != '}') i++; } if(acc>=0){ // , acc>=0 pzflag=1; } else { pzflag=0; } i++; // } // printf("\n"); // for (int k = 0; k<10; k++) printf("%d ", data_mem[k]); return 0; }
ideone.com要返回,请添加变量
pz_prev 。
如果当前字符是
{ ,则“升旗”
pz_prev if (command_mem[i]=='}') pz_prev=1;
如果标签
}在命令
{之前,则需要跳回
if (command_mem[i]=='{' && pzflag==1 && pz_prev==1) { while(command_mem[i] != '}') i--; }
我们将编写一个显示
10到
0的偶数的程序。
我们将数字
10和
2加载到
data_mem数组中,然后,当
acc中的数字大于或等于零时,我们将从
10中减去
2并显示结果
#include <stdio.h> int main(void) { int i=0; // int j=0; // int acc = 0; int pzflag = 1; // acc>=0 int pz_prev=0; // acc>=0 char command_mem[100] = "}^.>-<~{"; // 10 0 int data_mem[10]={0}; data_mem[0]=10; // data_mem[1]=2; while ( command_mem[i] != '\0') { if(command_mem[i]==',') // scanf("%d", &acc); if(command_mem[i]=='+') // data_mem acc=acc+data_mem[j]; // if(command_mem[i]=='-') // data_mem acc=acc-data_mem[j]; // if(command_mem[i]=='>') // j++; if(command_mem[i]=='<') // j--; if(command_mem[i]=='~') // data_mem[j]=acc; // if(command_mem[i]=='^') // data_mem acc=data_mem[j]; // if(command_mem[i]=='.') { // printf("Output: %d",acc); printf(" "); }; if (command_mem[i]=='}') // ? pz_prev=1; if(command_mem[i]=='?') { // ! while(command_mem[i] != '!') i++; } if (command_mem[i]=='{' && pzflag==1 && pz_prev==0) { // while(command_mem[i] != '}') // acc>=0 i++; } if (command_mem[i]=='{' && pzflag==1 && pz_prev==1) { // while(command_mem[i] != '}') // acc>=0 i--; } if(acc>=0){ // , acc>=0 pzflag=1;} else { pzflag=0;} //printf("i=%d",i);printf(" "); i++; // } // printf("\n"); // for (int k = 0; k<10; k++) printf("%d ", data_mem[k]); return 0; }
ideone.com为了将两个数字
A和
B相乘,您需要将
B与
A乘以
B。在循环中,在每次迭代中,我们将从
A减去1,并且当
A不为零时,将
B加到B。
LMCode程序
} >>> ^ <+>〜<<< ^>-<〜{>>> ^。 将数字
A +1和
B相乘,即 必须故意减少一个因素。
这是因为循环只会在
-1为 acc时结束。
例如,将
5乘以
5 。
为此,首先将必要的值放在
data_mem中 data_mem[0]=4; data_mem[1]=1; data_mem[2]=5;
ideone.com添加无条件跳转。
为此,添加变量
prev 。
我们还添加
了条件
acc = 0时的 前进/后退过渡。 对于此类转换,请创建
zflag标志(ZeroFlag)和
z_prev变量。
条件
zflag == 1的转换将由命令
(和
)执行我们使用无条件转移和根据条件
zflag == 1的转移将
5和
5相乘。
首先将必要的值放在
data_arr中 data_arr[0]=5; data_arr[1]=1; data_arr[2]=5;
LMCode程序
!>>> ^ <+>〜<<< ^>-<〜(?)>>> ^。 对应于汇编程序
INP STA 20 INP STA 21 INP STA 22 LDA 23 ADD 22 STA 23 LDA 20 SUB 21 STA 20 BRZ 14 BRA 06 LDA 23 OUT HLT
C代码
#include <stdio.h> int main(void) { int i=0; // int j=0; // int acc = 0; int pzflag = 1; // acc>=0 int zflag =1; // acc==0 int pz_prev=0; // acc>=0 int z_prev=0; // acc==0 int prev=0; // char command_mem[100] ="!>>>^<+>~<<<^>-<~(?)>>>^."; int data_mem[10]={0}; data_mem[0]=5; // data_mem[1]=1; data_mem[2]=5; while ( command_mem[i] != '\0') { if(command_mem[i]==',') // scanf("%d", &acc); if(command_mem[i]=='+') // data_mem acc=acc+data_mem[j]; // if(command_mem[i]=='-') // data_mem acc=acc-data_mem[j]; // if(command_mem[i]=='>') // j++; if(command_mem[i]=='<') // j--; if(command_mem[i]=='~') // data_mem[j]=acc; // if(command_mem[i]=='^') // data_mem acc=data_mem[j]; // if(command_mem[i]=='.') { // printf("Output: %d",acc); printf(" "); }; if (command_mem[i]=='}') // ? pz_prev=1; if (command_mem[i]==')') // ? z_prev=1; if (command_mem[i]=='!') // ? prev=1; // if (command_mem[i]=='?' && prev==0) { while(command_mem[i] != '!') i++; } // if (command_mem[i]=='?' && prev==1) { while(command_mem[i] != '!') i--; } // acc=0 if (command_mem[i]=='(' && zflag==1 && z_prev==0) { while(command_mem[i] != ')') i++; } // acc=0 if (command_mem[i]=='(' && zflag==1 && z_prev==1) { while(command_mem[i] != ')') i--; } // acc>=0 if (command_mem[i]=='{' && pzflag==1 && pz_prev==0) { while(command_mem[i] != '}') i++; } // acc>=0 if (command_mem[i]=='{' && pzflag==1 && pz_prev==1) { while(command_mem[i] != '}') i--; } // if(acc>=0){ pzflag=1;} else { pzflag=0;} if(acc==0){ zflag=1;} else { zflag=0;} //printf("i=%d",i);printf(" "); i++; // } // printf("\n"); // for (int k = 0; k<10; k++) printf("%d ", data_mem[k]); return 0; }
ideone.com通常,不能创建标志,但是要立即代替标志检查电池中的数字等于多少。
让我们检查斐波那契数是如何计算的。
#include <stdio.h> int main(void) { int i=0; // int j=0; // int acc = 0; int pzflag = 1; // acc>=0 int zflag =1; // acc==0 int pz_prev=0; // acc>=0 int z_prev=0; // acc==0 int prev=0; // char command_mem[100] ="}>>^>+.~<+.~<<^>-<~{"; int data_mem[10]={0}; data_mem[0]=5; // data_mem[1]=1; data_mem[2]=1; while ( command_mem[i] != '\0') { if(command_mem[i]==',') // scanf("%d", &acc); if(command_mem[i]=='+') // data_mem acc=acc+data_mem[j]; // if(command_mem[i]=='-') // data_mem acc=acc-data_mem[j]; // if(command_mem[i]=='>') // j++; if(command_mem[i]=='<') // j--; if(command_mem[i]=='~') // data_mem[j]=acc; // if(command_mem[i]=='^') // data_mem acc=data_mem[j]; // if(command_mem[i]=='.') { // printf("Output: %d",acc); printf(" "); }; if (command_mem[i]=='}') // ? pz_prev=1; if (command_mem[i]==')') // ? z_prev=1; if (command_mem[i]=='!') // ? prev=1; // if (command_mem[i]=='?' && prev==0) { while(command_mem[i] != '!') i++; } // if (command_mem[i]=='?' && prev==1) { while(command_mem[i] != '!') i--; } // acc=0 if (command_mem[i]=='(' && zflag==1 && z_prev==0) { while(command_mem[i] != ')') i++; } // acc=0 if (command_mem[i]=='(' && zflag==1 && z_prev==1) { while(command_mem[i] != ')') i--; } // acc>=0 if (command_mem[i]=='{' && pzflag==1 && pz_prev==0) { while(command_mem[i] != '}') i++; } // acc>=0 if (command_mem[i]=='{' && pzflag==1 && pz_prev==1) { while(command_mem[i] != '}') i--; } // if(acc>=0){ pzflag=1;} else { pzflag=0;} if(acc==0){ zflag=1;} else { zflag=0;} //printf("i=%d",i);printf(" "); i++; // } // printf("\n"); // for (int k = 0; k<10; k++) printf("%d ", data_mem[k]); return 0; }
ideone.com我在
此处 esolang.org上发布了有关
LMCode语言的注释
PS
此处 有关娱乐的 Intel-4004汇编程序仿真器的文章