#include <cstdio>
#include <vector>
#include <cstring>
#include "./getch.h"
#define Ar reg[cr[0]]
#define Br reg[cr[1]]
#define Cr reg[cr[2]]
#define ui32 unsigned int
using namespace std;
int main(int argc, char** argv){
bool created = false;
int startsz = 1024;
vector<ui32*> arrays;
vector<int> sz;
unsigned int reg[8];
memset(reg,0,32);
unsigned int cr[3];
unsigned char buf[4];
FILE * fp = fopen(argv[1],"r");
int count = 0;
arrays.push_back(new ui32[startsz]);
sz.push_back(startsz);
while(fread(buf, 1, 4, fp)){
unsigned int c = 0;
for(int i = 0; i < 4; i++){
c = (c<<8)|buf[i];
}
arrays[0][count]=c;
count++;
sz[0]=count;
if(count>=startsz){
ui32 * tmp = new ui32[startsz];
memcpy(tmp,arrays[0],sz[0]*4);
delete[] arrays[0];
arrays[0] = new ui32[startsz*2];
memcpy(arrays[0],tmp,sz[0]*4);
if(memcmp(tmp,arrays[0],startsz*4)){
printf("fix your expand code!\n");
}
delete[] tmp;
startsz*=2;
//printf("sz[0] %i\n",sz[0]);
}
}
//printf("sz[0] %i\n",sz[0]);
int expos = 0;
int op=0;
while(expos < sz[0]){
memset(cr,0,12);
op = (arrays[0][expos]>>28)&15;
if(op>13 || op<0){
printf("Invalid OPCODE %d\n",op);
return 1;
}
if(op<13){
cr[0] = (arrays[0][expos]>>6)&7;
cr[1] = (arrays[0][expos]>>3)&7;
cr[2] = (arrays[0][expos]>>0)&7;
expos++;
switch(op){
case 0:
if(Cr)
Ar = Br;
break;
case 1:
Ar = arrays[Br][Cr];
break;
case 2:
arrays[Ar][Br]=Cr;
break;
case 3:
Ar = Br+Cr;
break;
case 4:
Ar = Br*Cr;
break;
case 5:
Ar = Br/Cr;
break;
case 6:
Ar = ~(Br&Cr);
break;
case 7:
return 0;
break;
case 8:
created=false;
for(int i = 0; i < arrays.size();i++){
if(sz[i]==0&&!created){
created = true;
arrays[i]=new ui32[Cr];
memset(arrays[i],0,Cr*4);
Br = i;
sz[i]=Cr;
}
}
if(!created){
Br = arrays.size();
arrays.push_back(new ui32[Cr]);
memset(arrays[Br],0,Cr*4);
sz.push_back(Cr);
}
break;
case 9:
delete[] arrays[Cr];
sz[Cr]=0;
break;
case 10:
printf("%c",(unsigned char)Cr);
break;
case 11:
Cr = mygetch();
break;
case 12:
expos=Cr;
sz[0] = sz[Br];
if(Br==0)
break;
delete[] arrays[0];
arrays[0] = new ui32[sz[Br]];
memcpy(arrays[0],arrays[Br],sz[Br]*4);
break;
}
//printf("Op: %d\n",op);
}
else{
cr[0] = (arrays[0][expos]>>25)&7;
Ar = (arrays[0][expos]&0x01ffffff);
expos++;
}
}
}