Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <ncurses.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include <applicant.h>
- #include <string.h>
- struct applicant {
- unsigned char program[PROGRAM_LENGTH];
- unsigned char memory[MEMORY_CAPACITY];
- unsigned char programCursor, memoryCursor;
- unsigned char accum;
- unsigned char bufferCount;
- struct {
- bool more:1;
- bool less:1;
- bool zero:1;
- } flags;
- unsigned char** buffers;
- buffsz_t* bufferSizes;
- void* flushReceiver;
- void (*flushcallback)(void* restrict receiver, applicant* restrict applicant, int bufferid);
- };
- applicant* spawnApplicant() {
- applicant* applicant = malloc(sizeof(struct applicant));
- *applicant = (struct applicant) {
- .programCursor = 0,
- .memoryCursor = 0,
- .bufferCount = 0,
- .accum = 0,
- .bufferSizes = NULL,
- .buffers = NULL,
- .flushcallback = NULL,
- .flushReceiver = NULL,
- .flags = {false, false, false},
- };
- for (int i = 0; i < PROGRAM_LENGTH; i++) {
- applicant->program[i] = (unsigned char) (rand() % 256);
- }
- memset(applicant->memory, 0x00, MEMORY_CAPACITY);
- return applicant;
- }
- applicant* mutateApplicant(applicant* src) {
- applicant* applicant = malloc(sizeof(struct applicant));
- *applicant = (struct applicant) {
- .programCursor = 0,
- .memoryCursor = 0,
- .bufferCount = 0,
- .accum = 0,
- .bufferSizes = NULL,
- .buffers = NULL,
- .flushcallback = NULL,
- .flushReceiver = NULL,
- .flags = {false, false, false},
- };
- for (int i = 0; i < PROGRAM_LENGTH; i++) {
- applicant->program[i] = src->program[i];
- if (rand() % 256 > 240) {
- applicant->program[i] = rand() % 256;
- }
- }
- memset(applicant->memory, 0x00, MEMORY_CAPACITY);
- killApplicant(&src);
- return applicant;
- }
- applicant* cloneApplicant(applicant* src) {
- applicant* applicant = malloc(sizeof(struct applicant));
- *applicant = (struct applicant) {
- .programCursor = 0,
- .memoryCursor = 0,
- .bufferCount = 0,
- .accum = 0,
- .bufferSizes = NULL,
- .buffers = NULL,
- .flushcallback = NULL,
- .flushReceiver = NULL,
- .flags = {false, false, false},
- };
- for (int i = 0; i < PROGRAM_LENGTH; i++) {
- if (src) {
- applicant->program[i] = src->program[i];
- } else {
- applicant->program[i] = rand() % 256;
- }
- }
- memset(applicant->memory, 0x00, MEMORY_CAPACITY);
- return applicant;
- }
- void applicantSetFlushCallback(void* receiver, applicant* applicant, void (*flushcallback)(void* restrict, struct applicant* restrict, int)) {
- applicant->flushReceiver = receiver;
- applicant->flushcallback = flushcallback;
- }
- void killApplicant(applicant** papplicant) {
- if (!papplicant) return;
- if (!*papplicant) return;
- if ((*papplicant)->buffers) {
- free((*papplicant)->buffers);
- (*papplicant)->buffers = NULL;
- }
- if ((*papplicant)->bufferSizes) {
- free((*papplicant)->bufferSizes);
- (*papplicant)->bufferSizes = NULL;
- }
- if (*papplicant) free(*papplicant);
- *papplicant = NULL;
- }
- void applicantConnectBuffer(applicant* applicant, unsigned char* buffer, buffsz_t length) {
- if (applicant == NULL) return;
- int new_count = applicant->bufferCount + 1;
- applicant->buffers = realloc(
- applicant->buffers,
- sizeof(char*) * new_count
- );
- applicant->bufferSizes = realloc(
- applicant->bufferSizes,
- sizeof(buffsz_t) * new_count
- );
- if (
- !(applicant->bufferSizes && applicant->buffers)
- ) {
- printf("Failed to alloc buffers\n");
- return;
- }
- int id = applicant->bufferCount;
- applicant->bufferCount = new_count;
- applicant->bufferSizes[id] = length;
- applicant->buffers[id] = buffer;
- }
- void flushBuffer(applicant* applicant, int bufferid) {
- applicant->flushcallback(applicant->flushReceiver, applicant, bufferid);
- }
- unsigned char applicantGetAccum(applicant* applicant) {
- if (!applicant) return 0x00;
- return applicant->accum;
- }
- unsigned char applicantGetTop(applicant* applicant) {
- if (!applicant) return 0x00;
- return applicant->memory[(applicant->memoryCursor - 1) % MEMORY_CAPACITY];
- }
- unsigned char applicantGetMemoryCursor(applicant* applicant) {
- if (!applicant) return 0x00;
- return applicant->memoryCursor % MEMORY_CAPACITY;
- }
- unsigned char applicantGetProgramCursor(applicant* applicant) {
- if (!applicant) return 0x00;
- return applicant->programCursor % MEMORY_CAPACITY;
- }
- unsigned char applicantGetProgramAt(applicant* applicant, char at) {
- if (!applicant) return 0x00;
- return applicant->program[at % PROGRAM_LENGTH];
- }
- void applicantStep(applicant* applicant) {
- // get command
- enum ApplicantOpcode command = applicant->program[applicant->programCursor] % APPLICANT_OPCODE_MAX;
- // get argcount (max 2)
- int argcount = 0;
- switch (command) {
- case APPLICANT_OPCODE_INCREMENT: // INC -> INCREMENTS accum VALUE 0
- case APPLICANT_OPCODE_DECREMENT: // DEC -> DECREMENTS accum VALUE 0
- case APPLICANT_OPCODE_RAND: // RAND puts RAND value to accum 0
- case APPLICANT_OPCODE_ADD: // accum + TOP MEM VAL 0
- case APPLICANT_OPCODE_SUB: // accum - TOP MEM VAL 0
- case APPLICANT_OPCODE_CMP: // accum - TOP -> FLAGS 0
- case APPLICANT_OPCODE_POP: // TOP MEM VAL ->> accum 0
- argcount = 0; break;
- case APPLICANT_OPCODE_JMP: // jmp to addr 1
- case APPLICANT_OPCODE_PUSH: // PUSH VAL -> PUTS VALUE TO MEMORY 1
- case APPLICANT_OPCODE_FLUSH: // FLUSH ID Flushes buffer with id. FOR Input - resets it, confirms read. For Output - sends it 1
- argcount = 1; break;
- case APPLICANT_OPCODE_READ_BUFFER: // RB ID N -> PUSH TO MEMORY AT N 2
- case APPLICANT_OPCODE_WRITE_BUFFER: // WB ID N -> POP FROM MEMORY AT N 2
- argcount = 2; break;
- default: argcount = 0; break;
- }
- // collect args
- unsigned char args[2] = {0, 0};
- for (char i = 0; i < argcount; i++) {
- args[i] = applicant->program[(applicant->programCursor + i) % PROGRAM_LENGTH];
- }
- // act
- switch (command) {
- case APPLICANT_OPCODE_PUSH:
- applicant->memory[applicant->memoryCursor++] = args[0];
- applicant->memoryCursor %= MEMORY_CAPACITY;
- break;
- case APPLICANT_OPCODE_POP:
- applicant->accum = applicant->memory[--applicant->memoryCursor];
- break;
- return;
- case APPLICANT_OPCODE_JMP:
- if (applicant->programCursor == (args[0] % PROGRAM_LENGTH))
- applicant->programCursor = (applicant->programCursor + 1) % PROGRAM_LENGTH;
- else {
- applicant->programCursor = (args[0] % PROGRAM_LENGTH);
- }
- return;
- case APPLICANT_OPCODE_RAND:
- applicant->accum = rand() % 256;
- break;
- case APPLICANT_OPCODE_INCREMENT:
- applicant->accum++;
- break;
- case APPLICANT_OPCODE_DECREMENT:
- applicant->accum--;
- break;
- case APPLICANT_OPCODE_ADD:
- applicant->accum += applicant->memory[applicant->memoryCursor];
- break;
- case APPLICANT_OPCODE_SUB:
- applicant->accum -= applicant->memory[applicant->memoryCursor];
- break;
- case APPLICANT_OPCODE_FLUSH:
- flushBuffer(applicant, args[0]);
- break;
- case APPLICANT_OPCODE_WRITE_BUFFER:
- if (applicant->bufferCount > 0) {
- int clampeda = args[0] % applicant->bufferCount;
- int clampedb = args[1] % applicant->bufferSizes[clampeda];
- if (applicant->bufferSizes[clampeda] > 0) {
- applicant->buffers[clampeda][clampedb] = applicant->memory[--applicant->memoryCursor];
- if (applicant->memoryCursor < 0) {
- applicant->memoryCursor = MEMORY_CAPACITY - applicant->memoryCursor;
- }
- }
- }
- break;
- case APPLICANT_OPCODE_READ_BUFFER:
- if (applicant->bufferCount > 0) {
- int clampeda = args[0] % applicant->bufferCount;
- int clampedb = args[1] % applicant->bufferSizes[clampeda];
- if (applicant->bufferSizes[clampeda] > 0) {
- applicant->memory[applicant->memoryCursor++] = applicant->buffers[clampeda][clampedb];
- applicant->memoryCursor %= MEMORY_CAPACITY;
- }
- }
- break;
- case APPLICANT_OPCODE_CMP: {
- signed char diff = applicant->accum - applicant->memory[applicant->memoryCursor - 1];
- applicant->flags.zero = (diff == 0);
- applicant->flags.more = (diff > 0);
- applicant->flags.less = (diff < 0);
- } break;
- case APPLICANT_OPCODE_JZ: // jmp if flags.zero
- if (applicant->flags.zero) {
- applicant->programCursor = args[0] % PROGRAM_LENGTH;
- return;
- }break;
- case APPLICANT_OPCODE_JM: // jmp if flags.more
- if (applicant->flags.more) {
- applicant->programCursor = args[0] % PROGRAM_LENGTH;
- return;
- }break;
- case APPLICANT_OPCODE_JL: // jmp if flags.less
- if (applicant->flags.less) {
- applicant->programCursor = args[0] % PROGRAM_LENGTH;
- return;
- }break;
- case APPLICANT_OPCODE_MAX:
- break;
- }
- // offset
- applicant->programCursor = (applicant->programCursor + argcount + 1) % PROGRAM_LENGTH;
- }
- const char* applicantOpcodeToString(enum ApplicantOpcode opcode) {
- switch (opcode % APPLICANT_OPCODE_MAX) {
- case APPLICANT_OPCODE_INCREMENT: return "INC";
- case APPLICANT_OPCODE_DECREMENT: return "DEC";
- case APPLICANT_OPCODE_RAND: return "RAND";
- case APPLICANT_OPCODE_ADD: return "ADD";
- case APPLICANT_OPCODE_SUB: return "SUB";
- case APPLICANT_OPCODE_CMP: return "CMP";
- case APPLICANT_OPCODE_POP: return "POP";
- case APPLICANT_OPCODE_JMP: return "JMP";
- case APPLICANT_OPCODE_JZ: return "JZERO";
- case APPLICANT_OPCODE_JM: return "JMORE";
- case APPLICANT_OPCODE_JL: return "JLESS";
- case APPLICANT_OPCODE_PUSH: return "PUSH";
- case APPLICANT_OPCODE_FLUSH: return "FLUSH";
- case APPLICANT_OPCODE_READ_BUFFER: return "RB";
- case APPLICANT_OPCODE_WRITE_BUFFER: return "WB";
- default:
- return "";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment