#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #define KiB * 1024 #define MAX_NAMES 1024 #define STRING_LEN 64 #define IMAGE_SIZE 128 KiB char Labels[MAX_NAMES][STRING_LEN]; int32_t Pointers[MAX_NAMES]; int32_t np; char source[1 KiB]; int32_t target[IMAGE_SIZE]; int32_t here; void save() { FILE *fp; if ((fp = fopen("ngaImage", "wb")) == NULL) { printf("Unable to save the image!\n"); exit(2); } fwrite(&target, sizeof(int32_t), here, fp); fclose(fp); } int32_t lookup(char *name) { int32_t slice = -1; int32_t n = np; while (n > 0) { n--; if (strcmp(Labels[n], name) == 0) slice = Pointers[n]; } return slice; } void add_label(char *name, int32_t slice) { if (lookup(name) == -1) { strcpy(Labels[np], name); Pointers[np] = slice; np++; } else { printf("Fatal error: %s already defined\n", name); exit(0); } } void read_line(FILE *file, char *line_buffer) { int ch = getc(file); int count = 0; while ((ch != '\n') && (ch != EOF)) { line_buffer[count] = ch; count++; ch = getc(file); } line_buffer[count] = '\0'; } int32_t opcode_for(char *s) { if (strcmp(s, "..") == 0) return 0; if (strcmp(s, "li") == 0) return 1; if (strcmp(s, "du") == 0) return 2; if (strcmp(s, "dr") == 0) return 3; if (strcmp(s, "sw") == 0) return 4; if (strcmp(s, "pu") == 0) return 5; if (strcmp(s, "po") == 0) return 6; if (strcmp(s, "ju") == 0) return 7; if (strcmp(s, "ca") == 0) return 8; if (strcmp(s, "cc") == 0) return 9; if (strcmp(s, "re") == 0) return 10; if (strcmp(s, "eq") == 0) return 11; if (strcmp(s, "ne") == 0) return 12; if (strcmp(s, "lt") == 0) return 13; if (strcmp(s, "gt") == 0) return 14; if (strcmp(s, "fe") == 0) return 15; if (strcmp(s, "st") == 0) return 16; if (strcmp(s, "ad") == 0) return 17; if (strcmp(s, "su") == 0) return 18; if (strcmp(s, "mu") == 0) return 19; if (strcmp(s, "di") == 0) return 20; if (strcmp(s, "an") == 0) return 21; if (strcmp(s, "or") == 0) return 22; if (strcmp(s, "xo") == 0) return 23; if (strcmp(s, "sh") == 0) return 24; if (strcmp(s, "zr") == 0) return 25; if (strcmp(s, "en") == 0) return 26; if (strcmp(s, "ie") == 0) return 27; if (strcmp(s, "iq") == 0) return 28; if (strcmp(s, "ii") == 0) return 29; return 0; } void pass1(char *fname) { int inBlock = 0; char *buffer = (char *)source; unsigned int opcode; char inst[3]; FILE *fp; inst[2] = '\0'; here = 0; fp = fopen(fname, "r"); if (fp == NULL) { printf("Unable to load file\n"); exit(2); } while (!feof(fp)) { read_line(fp, buffer); if (strcmp(buffer, "~~~") == 0) { if (inBlock == 0) inBlock = 1; else inBlock = 0; } else { if (inBlock == 1) { if (buffer[1] == '\t' || buffer[1] == ' ') { switch (buffer[0]) { case 'i': memcpy(inst, buffer + 8, 2); opcode = opcode_for(inst); opcode = opcode << 8; memcpy(inst, buffer + 6, 2); opcode += opcode_for(inst); opcode = opcode << 8; memcpy(inst, buffer + 4, 2); opcode += opcode_for(inst); opcode = opcode << 8; memcpy(inst, buffer + 2, 2); opcode += opcode_for(inst); target[here++] = opcode; break; case 'r': target[here++] = -1; break; case 'd': target[here++] = atoi(buffer+2); break; case 'c': target[here++] = buffer[2]; break; case 's': opcode = 2; while (opcode < strlen(buffer)) target[here++] = buffer[opcode++]; target[here++] = 0; break; case ':': add_label(buffer+2, here); break; } } } } } fclose(fp); } void pass2(char *fname) { char *buffer; FILE *fp; int inBlock; inBlock = 0; buffer = (char *)source; here = 0; fp = fopen(fname, "r"); while (!feof(fp)) { read_line(fp, buffer); if (strcmp(buffer, "~~~") == 0) { if (inBlock == 0) inBlock = 1; else inBlock = 0; } else { if (inBlock == 1) { switch (buffer[0]) { case 'i': here++; break; case 'r': target[here++] = lookup(buffer+2); if (lookup(buffer+2) == -1) printf("Lookup failed: '%s'\n", buffer+2); break; case 'd': here++; break; case 'c': here++; break; case 's': here = here + strlen(buffer) - 1; break; case ':': break; } } } } fclose(fp); } int main(int argc, char **argv) { np = 0; if (argc > 1) { pass1(argv[1]); pass2(argv[1]); save(); printf("Wrote %d cells to ngaImage\n", here); } else printf("muri\n(c) 2017-2018 charles childers\n\n%s filename\n", argv[0]); return 0; }