Bagian IBagian IIBagian IIIBagian ivBagian vArtikel ini dikhususkan untuk membuat juru bahasa dari beberapa bahasa
LMCode esoterik, yang didasarkan pada arsitektur
Little Man Computer .
Sebenarnya, ini adalah emulator assembler untuk
LMC , hanya di sini alih-alih perintah assembler INP, STA, ADD, SUB, OUT, yang khusus digunakan. karakter.
Untuk memuat nomor ke dalam memori perintah
command_mem , transisi dari perintah ke perintah, dan juga untuk menghasilkan hasilnya, perintah
brainfuck digunakan.
- Biarkan perintah INP cocok
- Perintah OUT sesuai .
- Perintah ADD sesuai dengan +
- perintah sub berhubungan dengan -
- Perintah STA berhubungan dengan ~
- Perintah LDA sesuai dengan ^
Kami menulis sebuah program yang memuat nomor dari perangkat input ke dalam baterai, menyimpan nomor dalam memori, menambahkan nomor dari memori ke baterai (menggandakan nomor), dan menampilkan nomor dua kali lipat ke perangkat output.
Dalam assembler LMC, program ini akan terlihat seperti ini (biarkan sel awal menjadi 20)
INP STA 20 ADD 20 OUT
Dalam LMCode, program ini akan terlihat seperti
, ~ +.Di mesin LMCode kami, memori kode dan memori data dipisahkan (arsitektur Harvard), kami akan membuat baris
command_mem untuk memuat kode LMCode. String
command_mem akan merepresentasikan memori dari perintah. Kami juga membuat
larik data
data_mem yang akan mewakili memori data.
Kami memuat program ke
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; }
Saat memuat nomor
123 ke perangkat input, kami mendapatkan nomor
246 .
Anda dapat memeriksa di oline ide
ideone.comTambahkan perintah untuk
- buka sel selanjutnya >
- buka sel sebelumnya <
Saat memproses simbol
> kita akan meningkatkan indeks
j dari array data
data_mem if(command_mem[i]=='>') j++;
Saat memproses simbol
<, kita akan mengurangi indeks
j dari data_mem array data
if(command_mem[i]=='<') j--;
Untuk melompat maju pada perintah
? Kami akan melakukan transisi ke label
!Untuk melakukan ini, kita akan melewati semua karakter di antara
? dan
! if(command_mem[i]=='?') { while(command_mem[i] != '!' ) { i++; } }
Sebagai perbandingan, kami menulis program di mana pengguna memasukkan angka, misalnya
5 , dengan perintah
, menjadi lima sel berturut-turut dengan perintah
~> ~> ~> ~> ~ #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; }
Hasilnya, kami mendapatkan array
5 5 5 5 5 0 0 0 0 0 0ideone.comdan program yang sama di mana beberapa langkah maju dilewati oleh perintah lompatan tanpa syarat
, ~> ~?> ~> ~> ~!Kami mendapatkan array
5 5 0 0 0 0 0 0 0 0 0ideone.comTambahkan
pzflag flag PositiveZero-flag
Bendera hanya akan dinaikkan jika angka dalam baterai lebih besar atau sama dengan nol.
if(acc>=0){ pzflag=1;} else { pzflag=0;}
Melangkah kedepan dengan syarat
pzflag == 1 kita akan menjalankan perintah
{ dan
} if(command_mem[i]=='{') && (pzflag==1){ while(command_mem[i] != '}' ) i++; }
Selanjutnya, biarkan dua angka disimpan dalam memori kita
data_mem [0] = 3 dan
data_mem [1] = 5Kami akan menulis sebuah program yang menampilkan angka maksimum.
#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.comUntuk melompat kembali, tambahkan
pz_prev variabel.
Jika karakter saat ini adalah
{ , maka "menaikkan bendera"
pz_prev if (command_mem[i]=='}') pz_prev=1;
Jika label
} mendahului perintah
{ , maka Anda perlu melompat kembali
if (command_mem[i]=='{' && pzflag==1 && pz_prev==1) { while(command_mem[i] != '}') i--; }
Kami akan menulis sebuah program yang menampilkan angka genap dari
10 hingga
0 .
Kami memuat angka
10 dan
2 ke dalam array
data_mem , kemudian, sementara angka dalam
acc lebih besar atau sama dengan nol, kami akan mengurangi
2 dari
10 dan menampilkan hasilnya
#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.comUntuk mengalikan dua angka
A dan
B , Anda harus menambahkan
B kali
A ke
B.Dalam loop, pada setiap iterasi, kita akan mengurangi satu dari
A , dan, sementara
A tidak nol, tambahkan
B ke B.
Program LMCode
} >>> ^ <+> ~ <<< ^> - <~ {>>> ^. mengalikan angka
A +1 dan
B , yaitu satu faktor harus sengaja dikurangi satu.
Ini karena loop hanya akan berakhir ketika
-1 dalam
acc .
Misalnya, kalikan
5 dengan
5 .
Untuk melakukan ini, pertama tempatkan nilai yang diperlukan dalam
data_mem data_mem[0]=4; data_mem[1]=1; data_mem[2]=5;
ideone.comTambahkan lompatan tanpa syarat
kembali .
Untuk melakukan ini, tambahkan variabel
prev .
Kami juga menambahkan transisi
maju / mundur dalam kondisi
acc = 0 . Untuk transisi seperti itu, buat bendera zflag (ZeroFlag) dan variabel
z_prev .
Transisi dengan syarat
zflag == 1 akan dilakukan oleh perintah
( dan
)Kami mengalikan
5 dan
5 menggunakan transisi tanpa syarat dan transisi sesuai dengan kondisi
zflag == 1 .
Pertama tempatkan nilai yang diperlukan dalam
data_arr data_arr[0]=5; data_arr[1]=1; data_arr[2]=5;
Program LMCode
! >>> ^ <+> ~ <<< ^> - <~ (?) >>> ^. sesuai dengan program assembler
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
Kode 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.comSecara umum, bendera tidak dapat dibuat, tetapi sebagai ganti mereka segera memeriksa apa nomor dalam baterai sama dengan.
Mari kita periksa bagaimana angka Fibonacci dihitung.
#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.comSaya memposting catatan tentang bahasa LMCode
di esolang.org
di siniPS Artikel tentang emulator assembler untuk Intel-4004
untuk hiburan di sini