神秘的语言LMCode

第一部分
第二部分
第三部分
第四部分
第五部分

本文致力于基于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 0
ideone.com

并使用无条件跳转命令跳过了向前几个步骤的同一程序,〜>〜?>〜>〜>〜!

我们得到一个数组5 5 0 0 0 0 0 0 0 0 0
ideone.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] = 3data_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--; } 

我们将编写一个显示100的偶数的程序。

我们将数字102加载到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

为了将两个数字AB相乘,您需要将BA乘以B。

在循环中,在每次迭代中,我们将从A减去1,并且当A不为零时,将B加到B。

LMCode程序} >>> ^ <+>〜<<< ^>-<〜{>>> ^。 将数字A +1B相乘,即 必须故意减少一个因素。

这是因为循环只会在-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的转移将55相乘。

首先将必要的值放在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汇编程序仿真器的文章

Source: https://habr.com/ru/post/zh-CN427629/


All Articles