This? Oh.. Well... This is a interpreter for my wired assembly like instructions. I got bored. So I made this. I don't know why. I just did. It was definitely a waste of time. And now I'm sharing it with you. So you can waste your time too.
I think I bested my self when it comes to unorganized code. This is a mess. I'm sorry.
This is a complex shit show and I'm too lazy to write tests.
I'm like YandareDev but like... less spaghetti.
Compile cass.c with gcc. Then run it with the file you want to interpret as the first argument. For example:
gcc cass.c -o cass
./cass <file>-dor--debug- Shows you a nice debug screen-r <amount>or--registers <amount>- Specifies max amount of registers ($0 is not counted)-S <amount>or--register-size <amount>- Specifies how much bits a register can hold-s <amount>or--speed <amount>- How many instructions to execute per second (max 100)-Vor--version- Print the version of the program-vor--verbose- Print all the normally ignored warnings and errors--strict- Exit with an error if there are any runtime warnings-hor--help- Prints the help message
Well... open up instructions.c
Instructions are defined like this:
void newInstructionFunc(int* PC char* args[])And you also need to define the instruction info:
struct Instruction newInstruction = {"newInstruction", argCount, (int[]){...argType}, (void*)newInstructionFunc};Finally, increment INSTRUCTION_COUNT at the end of the file.
and append your instruction to the instructions array.
This one takes in a single argument of the type label and jumps to that label.
void jmpFunc(int* PC, int args[]) { *PC = args[0]; }
struct Instruction jmp = {"jmp", 1, (int[]){LABEL}, (void*)jmpFunc};This one takes in two arguments. The first one is the type register and the second one is the type number. It then moves the number into the register.
void movFunc(int* PC, int args[]) {
int reg1 = args[0];
int reg2 = args[1];
registers[reg1] = registers[reg2];
}
struct Instruction mov = {"mov", 2, (int[]){REGISTER, NUMBER}, (void*)movFunc};There are 4 types of arguments types:
0orREGISTER- Register1orNUMBER- Number2orLABEL- Label3orDATA_POINTER- Data pointer
Depending on type of argument it will give you a different value.
// The register is the index of the register
int regIndex = args[n];
int registerValue = registers[regIndex]; // The value of the register // The number is already an int
int num = args[n]; // The label is the PC index of the label
int labelIndex = args[n];
// You can set *PC to this value to jump to the label
*PC = labelIndex;int dataPointerIndex = args[n];
//You can get the data from the data list with these functions:
char* dataString = getDataString(dataList, dataPointerIndex);
int dataInt = getDataInt(dataList, dataPointerIndex);That's it. Okay Have fun!