C 924 838 825 696 646 623
b
Talimatta belirtilen kayıt defterinde bir "işaretçi" (bayt-offset) depolar ve bu diziye daha sonra erişmek için sözde kodda bir diziyi aynı şekilde (ya da bir işaretçiyi yeniden oluşturmak için tersine) atadığı herhangi bir kaydı kullanır. Yine de test programını denemeniz gerekiyor ...
Düzenle: yorum eklendi.
Düzenleme: sabit talimat 12. bellekteki talimatı değil, işaretçiyi değiştirin. Sayım, tüm yorumlar, girintiler ve yeni satırlar kaldırılmış durumda.
Düzenleme: Sonuçları doğru yorumladığımı varsayarak şimdi çalışıyor gibi görünüyor. :) Son gerçekleştirme, 0 dizisine gerçekten de başlatılmamış bir kayıtta bulunabilen tutamaç 0 tarafından atıfta bulunulmasıydı . Çok bükülmüş küçük bir makine! :)
Düzenleme: hata ayıklama aygıtı write
yerine kullanmak için yeniden yazdı printf
.... Burada fikir hataları kaldırmaktır . :) Edit: putchar()
ve getchar()
ayrıca no-nos vardır sbrk
. Şimdi çalışıyor ve oldukça hızlı görünüyor.
#define O(_)*a=*b _*c;B
#define B break;case
#define U unsigned
U*m,r[8],*p,*z,f,x,*a,*b,*c;main(int n,char**v){U char
u[4];z=m=p=sbrk(4);f=n>1?open(v[1],0):0;\
while(read(f,u,4)){*m++=(((((*u<<8)|u[1])<<8)|u[2])<<8)|u[3];sbrk(4);}sbrk(4);\
for(;x=*p++,1;){c=r+(x&7);b=r+((x>>3)&7);a=r+((x>>6)&7);switch(x>>28){case
0:*c?*a=*b:0;B
1:*a=(*b?m+*b:z)[*c];B
2:(*a?m+*a:z)[*b]=*c;B
3:O(+)4:O(*)5:O(/)6:*a=~(*b&*c);B
7:return 0;case
8:*b=1+(U*)sbrk(4*(1+*c))-m;(m+*b)[-1]=*c;B
9:B
10:*u=*c;write(1,u,1);B
11:read(0,u,1);*c=*u;B
12:*b?memcpy(z=sbrk(4*(m+*b)[-1]),m+*b,4*(m+*b)[-1]):0;p=&z[*c];B
13:a=r+((x>>25)&7);*a=x&0x1ffffff;}}}
Sadece küçük endianlar için 611 karakterlik bir versiyon var.
#define O(_)*a=*b _*c;B
#define B break;case
#define U unsigned
U*m,r[8],*p,*z,f,x,*a,*b,*c;main(int n,char**v){U char
u[4];z=m=p=sbrk(4);f=n>1?open(v[1],0):0;while(read(f,u,4)){*m++=(((((*u<<8)|u[1])<<8)|u[2])<<8)|u[3];sbrk(4);}sbrk(4);for(;x=*p++,1;){c=r+(x&7);b=r+((x>>3)&7);a=r+((x>>6)&7);switch(x>>28){case
0:*c?*a=*b:0;B
1:*a=(*b?m+*b:z)[*c];B
2:(*a?m+*a:z)[*b]=*c;B
3:O(+)4:O(*)5:O(/)6:*a=~(*b&*c);B
7:return 0;case
8:*b=1+(U*)sbrk(4*(1+*c))-m;(m+*b)[-1]=*c;B
9:B
//10:*u=*c;write(1,u,1);B //generic
10:write(1,c,1);B //little-endian
//11:read(0,u,1);*c=*u;B //generic
11:read(0,c,1);B //little-endian
12:*b?memcpy(z=sbrk(4*(m+*b)[-1]),m+*b,4*(m+*b)[-1]):0;p=&z[*c];B
13:a=r+((x>>25)&7);*a=x&0x1ffffff;}}}
Girintili ve yorumlu (uzatılmış) yorumlu hata ayıklama cihazı ile.
//#define DEBUG 1
#include <fcntl.h> // open
#include <signal.h> // signal
#include <stdio.h> // putchar getchar
#include <string.h> // memcpy
#include <sys/types.h> // open
#include <sys/stat.h> // open
#include <unistd.h> // sbrk read
unsigned long r[8],*m,*p,*z,f,x,o,*a,*b,*c; // registers memory pointer zero file working opcode A B C
char alpha[] = "0123456789ABCDEF";
//void S(int x){signal(SIGSEGV,S);sbrk(9);} // autogrow memory while reading program
void writeword(int fd, unsigned long word){
char buf[8];
unsigned long m=0xF0000000;
int off;
for (off = 28; off >= 0; m>>=4, off-=4) {
buf[7-(off/4)]=alpha[(word&m)>>off];
}
write(fd, buf, 8);
write(fd, " ", 1);
}
int main(int n,char**v){
#ifdef DEBUG
int fdlog;
#endif
unsigned char u[4]; // 4-byte buffer for reading big-endian 32bit words portably
int cnt;
#ifdef DEBUG
fdlog = open("sandlog",O_WRONLY|O_CREAT|O_TRUNC, 0777);
#endif
z=m=p=sbrk(4); // initialize memory and pointer
//signal(SIGSEGV,S); // invoke autogrowing memory -- no longer needed
f=n>1?open(v[1],O_RDONLY):0; // open program
while(read(f,u,4)){ // read 4 bytes
*m++=(((((*u<<8)|u[1])<<8)|u[2])<<8)|u[3]; // pack 4 bytes into 32bit unsigned in mem
sbrk(4); // don't snip the end of the program
}
sbrk(4);
for(cnt=0;x=*p++,1;cnt++){ // working = *ptr; ptr+=1
c=r+(x&7); // interpret C register field
b=r+((x>>3)&7); // interpret B register field
a=r+((x>>6)&7); // interpret A register field
#ifdef DEBUG
{int i;write(fdlog,"{",1);for(i=0;i<8;i++)writeword(fdlog, r[i]);
write(fdlog,"} ",2);
}
write(fdlog, alpha+(x), 1);
write(fdlog, alpha+(x>>28), 1);
#endif
switch(o=x>>28){ // interpret opcode
case 0:
#ifdef DEBUG
write(fdlog, "if(rX)rX=rX\n", 12);
#endif
*c?*a=*b:0;
break; // Conditional Move A=B unless C==0
case 1:
#ifdef DEBUG
write(fdlog, "rX=rX[rX]\n", 10);
#endif
*a=(*b?m+*b:z)[*c];
break; // Array Index A=B[C]
case 2:
#ifdef DEBUG
write(fdlog, "rX[rX]=rX\n", 10);
#endif
(*a?m+*a:z)[*b]=*c;
break; // Array Amendment A[B] = C
case 3:
#ifdef DEBUG
write(fdlog, "rX=rX+rX\n", 9);
#endif
*a=*b+*c;
break; // Addition A = B + C
case 4:
#ifdef DEBUG
write(fdlog, "rX=rX*rX\n", 9);
#endif
*a=*b**c;
break; // Multiplication A = B * C
case 5:
#ifdef DEBUG
write(fdlog, "rX=rX/rX\n", 9);
#endif
*a=*b/ *c;
break; // Division A = B / C
case 6:
#ifdef DEBUG
write(fdlog, "rX=~(rX&rX)\n", 12);
#endif
*a=~(*b&*c);
break; // Not-And A = ~(B & C)
case 7:
#ifdef DEBUG
write(fdlog, "halt\n", 5);
#endif
return 0; // Halt
case 8:
#ifdef DEBUG
write(fdlog, "rX=alloc(rX)\n", 13);
#endif
*b=1+(unsigned long*)sbrk(4*(1+*c))-m;
(m+*b)[-1]=*c;
break; // Allocation B = allocate(C)
case 9:
#ifdef DEBUG
write(fdlog, "free(rX)\n", 9);
#endif
break; // Abandonment deallocate(C)
case 10:
#ifdef DEBUG
write(fdlog, "output(rX)\n", 11);
#endif
//putchar(*c);
//*u=u[1]=u[2]=' ';
u[3]=(char)*c;
write(fileno(stdout), u+3, 1);
break; // Output char from C to stdout
case 11:
#ifdef DEBUG
write(fdlog, "rX=input()\n", 11);
#endif
//x=getchar();*c=x;
read(fileno(stdin), u+3, 1);
*c=u[3];
break; // Input char from stdin into C
case 12:
#ifdef DEBUG
write(fdlog, "load(rX)[rX]\n", 13);
#endif
*b?memcpy(z=sbrk(4*(m+*b)[-1]),m+*b,4*(m+*b)[-1]):0;
p=&z[*c];
break; // Load Program copy the array B into the 0 array, Ptr=C
case 13:
#ifdef DEBUG
write(fdlog, "rX=X\n", 5);
#endif
a=r+((x>>25)&7);*a=x&0x1ffffff; // Orthography REG=immediate-25bit
}
}
}