aboutsummaryrefslogtreecommitdiff
path: root/pu.c
diff options
context:
space:
mode:
authorGravatar Moon Flower <moon@coffin.ir> 2025-08-07 20:10:31 +0330
committerGravatar Moon Flower <moon@coffin.ir> 2025-08-07 20:10:31 +0330
commit2447ad82249a7d2bc3e472e1e556c3de98ed4774 (patch)
tree2e6d4bab26711407d98ce044d8ccc0be0effdc02 /pu.c
parentcomment (diff)
repl demo
Diffstat (limited to 'pu.c')
-rw-r--r--pu.c211
1 files changed, 174 insertions, 37 deletions
diff --git a/pu.c b/pu.c
index 4e93a31..7678e5d 100644
--- a/pu.c
+++ b/pu.c
@@ -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();
}