diff options
| author | 2025-08-07 20:10:31 +0330 | |
|---|---|---|
| committer | 2025-08-07 20:10:31 +0330 | |
| commit | 2447ad82249a7d2bc3e472e1e556c3de98ed4774 (patch) | |
| tree | 2e6d4bab26711407d98ce044d8ccc0be0effdc02 /pu.c | |
| parent | comment (diff) | |
repl demo
Diffstat (limited to 'pu.c')
| -rw-r--r-- | pu.c | 211 |
1 files changed, 174 insertions, 37 deletions
@@ -1,9 +1,16 @@ +#define _XOPEN_SOURCE 700 #include <stdio.h> #include <stdlib.h> -#include <unistd.h> #include <string.h> +#include <unistd.h> + #pragma clang diagnostic ignored "-Wreturn-type" #pragma clang diagnostic ignored "-Wc23-extensions" +#pragma clang diagnostic ignored "-Wnull-character" +#pragma clang diagnostic ignored "-Wimplicit-int" + +#define CLAY_IMPLEMENTATION +#include "clay.h" // clang-format off #define S 65536 @@ -67,7 +74,7 @@ int emu() { int size = m[ 3 ], i = 0; for (; i < size; i++) putchar(m[ ptr++ ]); - write(STDOUT_FILENO, &m[ ptr ], size); + while (size--) putchar(m[ ptr++ ]); } // 1: input character @@ -87,36 +94,7 @@ int emu() { char R_backup[] = "hlt\0 ar1\2 ar2\3 ar3\4 ar4\5 ar5\6 ar6\7 ar7\x8 ar8\x9 r1a\xA r2a\xB r3a\xC " "r4a\xD r5a\xE r6a\xF r7a\20 r8a\21 mem\22 aca\23 add\24 sub\25 not\26 clr\27"; -int main(int argc, char **argv) { - if (access("t", F_OK)) { - // patch the instruction table incase you removed it. - printf("you've deleted t! i'll write it again for you.\n\n"); - FILE *fp = fopen("t", "w+"); - fwrite(R_backup, 1, sizeof(R_backup), fp); - fclose(fp); - memcpy(R, R_backup, sizeof(R_backup)); - } - - if (argc == 1) { - printf("Usage:\n %s <filename>", argv[ 0 ]); - exit(1); - } - - // read code - FILE *fp = fopen(argv[ 1 ], "r"); - fseek(fp, 0, SEEK_END); - int sz = ftell(fp); - rewind(fp); - char code[ sz + 1 ]; - fread(code, 1, sz, fp); - code[ sz ] = 0; - fclose(fp); - - // set pc - m[ 7 ] = 1024; - // assemble - char *fail_point = as(code, &m[ 1024 ]); - +void error_debug(char *fail_point, char *code, int sz) { if (fail_point != 0) { int error_pos = (int) (fail_point - code); int i; @@ -132,7 +110,14 @@ int main(int argc, char **argv) { } fprintf( - stderr, "Assembly failed at line %d, column %d (position %d):\n", line, col, error_pos); + stderr, + "\x1b[1m\x1b[31merror:\x1b[0m " + "\x1b[1massembly failed\x1b[0m " + "at \x1b[36mline %d\x1b[0m, \x1b[36mcolumn %d\x1b[0m " + "(\x1b[33mposition %d\x1b[0m):\n", + line, + col, + error_pos); int line_start = error_pos; while (line_start > 0 && code[ line_start - 1 ] != '\n') { line_start--; } @@ -142,17 +127,169 @@ int main(int argc, char **argv) { line_end++; } - fprintf(stderr, " "); + fprintf(stderr, " \x1b[1m"); for (i = line_start; i < line_end; i++) { fputc(code[ i ], stderr); } - fprintf(stderr, "\n"); + fprintf(stderr, "\x1b[0m\n"); fprintf(stderr, " "); - for (i = line_start; i < error_pos; i++) { fputc(' ', stderr); } - fprintf(stderr, "^ parsing stopped here\n"); + for (i = line_start; i < error_pos; i++) { + fputc((code[ i ] == '\t') ? '\t' : ' ', stderr); + } + fprintf(stderr, "\x1b[1m\x1b[31m^\x1b[0m \x1b[90mparsing stopped here\x1b[0m\n"); + } +} +int main(int argc, char **argv) { + if (access("t", F_OK)) { + // patch the instruction table incase you removed it. + printf("you've deleted `t`! i'll write it again for you.\n\n"); + FILE *fp = fopen("t", "w+"); + fwrite(R_backup, 1, sizeof(R_backup), fp); + fclose(fp); + memcpy(R, R_backup, sizeof(R_backup)); + } + + if (argc == 1) { + printf( + "Usage:\n %s run <filename>: Execute a file\n %s repl: Open in REPL mode", + argv[ 0 ], + argv[ 0 ]); exit(1); } + if (argc == 2 && !strcmp(argv[ 1 ], "repl")) { + printf("\npu repl\n" + "| code is inserted at address 1024\n" + "| submit RUN to execute the code.\n" + "| submit CLEAR to erase history.\n" + "| submit SAVE to write contents to repl.pu\n" + "| submit LOAD to fetch contents from repl.pu\n" + "\n"); + + char *code = malloc(1); + *code = '\n'; + size_t size = 0; + + while (1) { + printf("%li > ", size); + char *line; + size_t _len; + size_t len = getline(&line, &_len, stdin); + + if (len == 1) continue; + + if (len == 4 && strncmp(line, "run", 3) == 0) { + memset(m, 0, 8); + m[ 7 ] = 1024; + emu(); + continue; + } + + if (len == 5 && strncmp(line, "save", 4) == 0) { + FILE *fd = fopen("repl.pu", "w+"); + fwrite(code, 1, size, fd); + fclose(fd); + printf("saved %li bytes.\n", size); + + continue; + } + + if (len == 5 && strncmp(line, "load", 4) == 0) { + FILE *fp = fopen("repl.pu", "r"); + fseek(fp, 0, SEEK_END); + int sz = ftell(fp); + rewind(fp); + char *saved = malloc(sz + 1); + fread(saved, 1, sz, fp); + saved[ sz ] = 0; + fclose(fp); + + free(code); + code = saved; + size = sz; + printf("loaded %i bytes.\n", sz); + + goto SKIP_STRAIGHT; + } + + if (len == 6 && strncmp(line, "clear", 5) == 0) { + printf("-- code cleared\n"); + free(code); + code = malloc(1); + size = 0; + continue; + } + + if (len == 7 && strncmp(line, "status", 6) == 0) { + printf( + "\nregisters\n" + "r1: %i r2: %i\n" + "r3: %i r4: %i\n" + "r5: %i r6: %i\n" + "r7: %i pc: %i\n\n", + m[ 0 ], + m[ 1 ], + m[ 2 ], + m[ 3 ], + m[ 4 ], + m[ 5 ], + m[ 6 ], + m[ 7 ]); + + continue; + } + + char *old_code = malloc(size); + memcpy(old_code, code, size); + + code = realloc(code, size += len); + memcpy(&code[ size - len ], line, len); + + SKIP_STRAIGHT: + + char *exit_code = as(code, &m[ 1024 ]); + + #define COLOR_RED "\e[0;31m" + #define COLOR_RESET "\e[0m" + + if (exit_code != 0) { + printf(COLOR_RED "\n"); + error_debug(exit_code, code, size); + printf("\n" COLOR_RESET); + + free(code); + code = old_code; + size -= len; + continue; + } + + free(old_code); + } + + exit(0); + } + + if (argc == 3 && strcmp(argv[ 1 ], "run") != 0) { + printf("Invalid mode - Only supported modes are 'run' and 'repl'\n"); + } + + // read code + FILE *fp = fopen(argv[ 2 ], "r"); + fseek(fp, 0, SEEK_END); + int sz = ftell(fp); + rewind(fp); + char code[ sz + 1 ]; + fread(code, 1, sz, fp); + code[ sz ] = 0; + fclose(fp); + + // set pc + m[ 7 ] = 1024; + // assemble + char *fail_point = as(code, &m[ 1024 ]); + + error_debug(fail_point, code, sz); + // run emulation emu(); } |
