Guest User

applicant.c

a guest
Aug 2nd, 2026
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.33 KB | Source Code | 0 0
  1. #include <ncurses.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <applicant.h>
  5. #include <string.h>
  6.  
  7. struct applicant {
  8.     unsigned char program[PROGRAM_LENGTH];
  9.     unsigned char memory[MEMORY_CAPACITY];
  10.     unsigned char programCursor, memoryCursor;
  11.     unsigned char accum;
  12.     unsigned char bufferCount;
  13.     struct {
  14.         bool more:1;
  15.         bool less:1;
  16.         bool zero:1;
  17.     } flags;
  18.     unsigned char** buffers;
  19.     buffsz_t* bufferSizes;
  20.     void* flushReceiver;
  21.     void (*flushcallback)(void* restrict receiver, applicant* restrict applicant, int bufferid);
  22. };
  23.  
  24. applicant* spawnApplicant() {
  25.     applicant* applicant = malloc(sizeof(struct applicant));
  26.     *applicant = (struct applicant) {
  27.         .programCursor = 0,
  28.         .memoryCursor = 0,
  29.         .bufferCount = 0,
  30.         .accum = 0,
  31.         .bufferSizes = NULL,
  32.         .buffers = NULL,
  33.         .flushcallback = NULL,
  34.         .flushReceiver = NULL,
  35.         .flags = {false, false, false},
  36.     };
  37.     for (int i = 0; i < PROGRAM_LENGTH; i++) {
  38.         applicant->program[i] = (unsigned char) (rand() % 256);
  39.     }
  40.     memset(applicant->memory, 0x00, MEMORY_CAPACITY);
  41.     return applicant;
  42. }
  43. applicant* mutateApplicant(applicant* src) {
  44.     applicant* applicant = malloc(sizeof(struct applicant));
  45.     *applicant = (struct applicant) {
  46.         .programCursor = 0,
  47.         .memoryCursor = 0,
  48.         .bufferCount = 0,
  49.         .accum = 0,
  50.         .bufferSizes = NULL,
  51.         .buffers = NULL,
  52.         .flushcallback = NULL,
  53.         .flushReceiver = NULL,
  54.         .flags = {false, false, false},
  55.     };
  56.     for (int i = 0; i < PROGRAM_LENGTH; i++) {
  57.         applicant->program[i] = src->program[i];
  58.         if (rand() % 256 > 240) {
  59.             applicant->program[i] = rand() % 256;
  60.         }
  61.     }
  62.     memset(applicant->memory, 0x00, MEMORY_CAPACITY);
  63.     killApplicant(&src);
  64.     return applicant;
  65. }
  66. applicant* cloneApplicant(applicant* src) {
  67.     applicant* applicant = malloc(sizeof(struct applicant));
  68.     *applicant = (struct applicant) {
  69.         .programCursor = 0,
  70.         .memoryCursor = 0,
  71.         .bufferCount = 0,
  72.         .accum = 0,
  73.         .bufferSizes = NULL,
  74.         .buffers = NULL,
  75.         .flushcallback = NULL,
  76.         .flushReceiver = NULL,
  77.         .flags = {false, false, false},
  78.     };
  79.     for (int i = 0; i < PROGRAM_LENGTH; i++) {
  80.         if (src) {
  81.             applicant->program[i] = src->program[i];
  82.         } else {
  83.             applicant->program[i] = rand() % 256;
  84.         }
  85.     }
  86.     memset(applicant->memory, 0x00, MEMORY_CAPACITY);
  87.     return applicant;
  88. }
  89. void applicantSetFlushCallback(void* receiver, applicant* applicant, void (*flushcallback)(void* restrict, struct applicant* restrict, int)) {
  90.     applicant->flushReceiver = receiver;
  91.     applicant->flushcallback = flushcallback;
  92. }
  93. void killApplicant(applicant** papplicant) {
  94.     if (!papplicant) return;
  95.     if (!*papplicant) return;
  96.     if ((*papplicant)->buffers) {
  97.         free((*papplicant)->buffers);
  98.         (*papplicant)->buffers = NULL;
  99.     }
  100.     if ((*papplicant)->bufferSizes) {
  101.         free((*papplicant)->bufferSizes);
  102.         (*papplicant)->bufferSizes = NULL;
  103.     }
  104.     if (*papplicant) free(*papplicant);
  105.     *papplicant = NULL;
  106. }
  107.  
  108. void applicantConnectBuffer(applicant* applicant, unsigned char* buffer, buffsz_t length) {
  109.     if (applicant == NULL) return;
  110.     int new_count = applicant->bufferCount + 1;
  111.     applicant->buffers = realloc(
  112.         applicant->buffers,
  113.         sizeof(char*) * new_count
  114.     );
  115.     applicant->bufferSizes = realloc(
  116.         applicant->bufferSizes,
  117.         sizeof(buffsz_t) * new_count
  118.     );
  119.  
  120.     if (
  121.         !(applicant->bufferSizes && applicant->buffers)
  122.     ) {
  123.         printf("Failed to alloc buffers\n");
  124.         return;
  125.     }
  126.     int id = applicant->bufferCount;
  127.     applicant->bufferCount = new_count;
  128.     applicant->bufferSizes[id] = length;
  129.     applicant->buffers[id] = buffer;
  130. }
  131. void flushBuffer(applicant* applicant, int bufferid) {
  132.     applicant->flushcallback(applicant->flushReceiver, applicant, bufferid);
  133. }
  134. unsigned char applicantGetAccum(applicant* applicant) {
  135.     if (!applicant) return 0x00;
  136.     return applicant->accum;
  137. }
  138. unsigned char applicantGetTop(applicant* applicant) {
  139.     if (!applicant) return 0x00;
  140.     return applicant->memory[(applicant->memoryCursor - 1) % MEMORY_CAPACITY];
  141. }
  142. unsigned char applicantGetMemoryCursor(applicant* applicant) {
  143.     if (!applicant) return 0x00;
  144.     return applicant->memoryCursor % MEMORY_CAPACITY;
  145. }
  146. unsigned char applicantGetProgramCursor(applicant* applicant) {
  147.     if (!applicant) return 0x00;
  148.     return applicant->programCursor % MEMORY_CAPACITY;
  149. }
  150. unsigned char applicantGetProgramAt(applicant* applicant, char at) {
  151.     if (!applicant) return 0x00;
  152.     return applicant->program[at % PROGRAM_LENGTH];
  153. }
  154. void applicantStep(applicant* applicant) {
  155.     // get command
  156.     enum ApplicantOpcode command = applicant->program[applicant->programCursor] % APPLICANT_OPCODE_MAX;
  157.     // get argcount (max 2)
  158.     int argcount = 0;
  159.     switch (command) {
  160.     case APPLICANT_OPCODE_INCREMENT: // INC -> INCREMENTS accum VALUE 0
  161.     case APPLICANT_OPCODE_DECREMENT: // DEC -> DECREMENTS accum VALUE 0
  162.     case APPLICANT_OPCODE_RAND: // RAND puts RAND value to accum 0
  163.     case APPLICANT_OPCODE_ADD: // accum + TOP MEM VAL 0
  164.     case APPLICANT_OPCODE_SUB: // accum - TOP MEM VAL 0
  165.     case APPLICANT_OPCODE_CMP: // accum - TOP -> FLAGS 0
  166.     case APPLICANT_OPCODE_POP: // TOP MEM VAL ->> accum 0
  167.         argcount = 0; break;
  168.     case APPLICANT_OPCODE_JMP: // jmp to addr 1
  169.     case APPLICANT_OPCODE_PUSH: // PUSH VAL -> PUTS VALUE TO MEMORY 1
  170.     case APPLICANT_OPCODE_FLUSH: // FLUSH ID Flushes buffer with id. FOR Input - resets it, confirms read. For Output - sends it 1
  171.         argcount = 1; break;
  172.     case APPLICANT_OPCODE_READ_BUFFER: // RB ID N -> PUSH TO MEMORY AT N 2
  173.     case APPLICANT_OPCODE_WRITE_BUFFER: // WB ID N -> POP FROM MEMORY AT N 2
  174.         argcount = 2; break;
  175.     default: argcount = 0; break;
  176.     }
  177.     // collect args
  178.     unsigned char args[2] = {0, 0};
  179.     for (char i = 0; i < argcount; i++) {
  180.         args[i] = applicant->program[(applicant->programCursor + i) % PROGRAM_LENGTH];
  181.     }
  182.     // act
  183.     switch (command) {
  184.     case APPLICANT_OPCODE_PUSH:
  185.         applicant->memory[applicant->memoryCursor++] = args[0];
  186.         applicant->memoryCursor %= MEMORY_CAPACITY;
  187.         break;
  188.     case APPLICANT_OPCODE_POP:
  189.         applicant->accum = applicant->memory[--applicant->memoryCursor];
  190.         break;
  191.         return;
  192.     case APPLICANT_OPCODE_JMP:
  193.         if (applicant->programCursor == (args[0] % PROGRAM_LENGTH))
  194.             applicant->programCursor = (applicant->programCursor + 1) % PROGRAM_LENGTH;
  195.         else {
  196.             applicant->programCursor = (args[0] % PROGRAM_LENGTH);
  197.         }
  198.         return;
  199.     case APPLICANT_OPCODE_RAND:
  200.         applicant->accum = rand() % 256;
  201.         break;
  202.     case APPLICANT_OPCODE_INCREMENT:
  203.         applicant->accum++;
  204.         break;
  205.     case APPLICANT_OPCODE_DECREMENT:
  206.         applicant->accum--;
  207.         break;
  208.     case APPLICANT_OPCODE_ADD:
  209.         applicant->accum += applicant->memory[applicant->memoryCursor];
  210.         break;
  211.     case APPLICANT_OPCODE_SUB:
  212.         applicant->accum -= applicant->memory[applicant->memoryCursor];
  213.         break;
  214.     case APPLICANT_OPCODE_FLUSH:
  215.         flushBuffer(applicant, args[0]);
  216.         break;
  217.     case APPLICANT_OPCODE_WRITE_BUFFER:
  218.         if (applicant->bufferCount > 0) {
  219.             int clampeda = args[0] % applicant->bufferCount;
  220.             int clampedb = args[1] % applicant->bufferSizes[clampeda];
  221.             if (applicant->bufferSizes[clampeda] > 0) {
  222.                 applicant->buffers[clampeda][clampedb] = applicant->memory[--applicant->memoryCursor];
  223.                 if (applicant->memoryCursor < 0) {
  224.                     applicant->memoryCursor = MEMORY_CAPACITY - applicant->memoryCursor;
  225.                 }
  226.             }
  227.         }
  228.         break;
  229.     case APPLICANT_OPCODE_READ_BUFFER:
  230.         if (applicant->bufferCount > 0) {
  231.             int clampeda = args[0] % applicant->bufferCount;
  232.             int clampedb = args[1] % applicant->bufferSizes[clampeda];
  233.             if (applicant->bufferSizes[clampeda] > 0) {
  234.                 applicant->memory[applicant->memoryCursor++] = applicant->buffers[clampeda][clampedb];
  235.                 applicant->memoryCursor %= MEMORY_CAPACITY;
  236.             }
  237.         }
  238.         break;
  239.     case APPLICANT_OPCODE_CMP: {
  240.         signed char diff = applicant->accum - applicant->memory[applicant->memoryCursor - 1];
  241.         applicant->flags.zero = (diff == 0);
  242.         applicant->flags.more = (diff > 0);
  243.         applicant->flags.less = (diff < 0);
  244.     } break;
  245.     case APPLICANT_OPCODE_JZ: // jmp if flags.zero
  246.         if (applicant->flags.zero) {
  247.             applicant->programCursor = args[0] % PROGRAM_LENGTH;
  248.             return;
  249.         }break;
  250.     case APPLICANT_OPCODE_JM: // jmp if flags.more
  251.         if (applicant->flags.more) {
  252.             applicant->programCursor = args[0] % PROGRAM_LENGTH;
  253.             return;
  254.         }break;
  255.     case APPLICANT_OPCODE_JL: // jmp if flags.less
  256.         if (applicant->flags.less) {
  257.             applicant->programCursor = args[0] % PROGRAM_LENGTH;
  258.             return;
  259.         }break;
  260.  
  261.     case APPLICANT_OPCODE_MAX:
  262.       break;
  263.     }
  264.     // offset
  265.     applicant->programCursor = (applicant->programCursor + argcount + 1) % PROGRAM_LENGTH;
  266. }
  267. const char* applicantOpcodeToString(enum ApplicantOpcode opcode) {
  268.     switch (opcode % APPLICANT_OPCODE_MAX) {
  269.     case APPLICANT_OPCODE_INCREMENT: return "INC";
  270.     case APPLICANT_OPCODE_DECREMENT: return "DEC";
  271.     case APPLICANT_OPCODE_RAND: return "RAND";
  272.     case APPLICANT_OPCODE_ADD: return "ADD";
  273.     case APPLICANT_OPCODE_SUB: return "SUB";
  274.     case APPLICANT_OPCODE_CMP: return "CMP";
  275.     case APPLICANT_OPCODE_POP: return "POP";
  276.     case APPLICANT_OPCODE_JMP: return "JMP";
  277.     case APPLICANT_OPCODE_JZ: return "JZERO";
  278.     case APPLICANT_OPCODE_JM: return "JMORE";
  279.     case APPLICANT_OPCODE_JL: return "JLESS";
  280.     case APPLICANT_OPCODE_PUSH: return "PUSH";
  281.     case APPLICANT_OPCODE_FLUSH: return "FLUSH";
  282.     case APPLICANT_OPCODE_READ_BUFFER: return "RB";
  283.     case APPLICANT_OPCODE_WRITE_BUFFER: return "WB";
  284.     default:
  285.         return "";
  286.     }
  287. }
Advertisement
Add Comment
Please, Sign In to add comment