aboutsummaryrefslogtreecommitdiff
path: root/pu2/pu2.c
diff options
context:
space:
mode:
authorGravatar Moon Flower <moon@coffin.ir> 2025-08-12 20:27:34 +0330
committerGravatar Moon Flower <moon@coffin.ir> 2025-08-12 20:27:34 +0330
commit15914727d83a6f46ad724e126179713d935e5e6f (patch)
tree2f601872b7575e4f3c0ca8c366fb2a1e1ea1b4fb /pu2/pu2.c
parentir2 initial release! (diff)
ir2 prototype! includes strings and DATA segment and other stuffs :3
Diffstat (limited to 'pu2/pu2.c')
-rw-r--r--pu2/pu2.c216
1 files changed, 109 insertions, 107 deletions
diff --git a/pu2/pu2.c b/pu2/pu2.c
index 66794bc..66fefbf 100644
--- a/pu2/pu2.c
+++ b/pu2/pu2.c
@@ -1,63 +1,5 @@
-#include <ctype.h>
+#include "pu2.out.c"
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#pragma clang diagnostic ignored "-Wparentheses"
-#pragma clang diagnostic ignored "-Wreturn-type"
-#pragma clang diagnostic ignored "-Wempty-body"
-
-// pu2!
-// maybe compacter? idk
-// last cpu: 167 chars
-
-// NOTE: if you want the cpu to
-// crash or do something when an invalid opcode is met,
-// replace the `8` in the code with whatever behavior you desire.
-// you can use ({...}) to insert normal code, or use __builtin_trap() for a SIGTRAP
-
-// clang-format off
-#define S 1<<20
-#define H !--c
-#define J while
-m[S],c,v,a,b,u;pu2(){J(c=m[m[7]++],v=m[m[7]++],c){H?a=v:H?a=m[b]:H?u?m[a]=b:0:H?v=a,a=b,b=v:H?a+=b:H?a-=b:H?a=a&&b:H?a=!a:H?u=1:8;u=v;}}
-// clang-format on
-
-// there's just memory. no, really
-// ok actually there's two registers called a and b
-// 0 HLT: halt
-// 1 IMM: a = imm
-// 2 LOD: a = m[b]
-// 3 STR: m[a] = b (only happens if acc != 0)
-// 4 SWP: swap a and b
-// 5 ADD: a += b
-// 6 SUB: a -= b
-// 7 AND: a &&= b
-// 8 NOT: a = !a
-// 9 ACC: u = imm
-
-// NOTE: Memory indexes less than 1024 should be considered as temporary/compute memory, and
-// programs should be written at index 1024 and upwards.
-//
-// NOTE: Memory index 7 is the program
-// counter, in which the current instruction is read from m[m[7]] at each cycle
-
-// -------------------------
-
-// yeehaw baby it's time for as2
-// E is the error code loc. zero it before calling as2
-// Y is macro storage. extend as needed
-// set O for output before running. keep in mind, it gets modified whilst as2 is running.
-// therefore, i recommend you store a copy somewhere!
-
-// clang-format off
-char*C="hltimmlodstrswpaddsubandnotacc",*Y[1<<10],*E,*L,i;*O;as2(char*I){J(c=*I++){if(c==35){J(*++I-10);c=*I++;}L=C;(!isspace(c)?c-39?c-125?c-123?c-64?({i=0,I--;J(i++,*L)strncmp(L,I,3)?L+=3:({I+=3;*O++=i-1;*O++=i-2?0:strtol(I,&I,10);goto Q;});E=I;return 1;Q:;}):as2(Y[strtol(I,&I,10)]):({Y[strtol(I,&I,10)]=I+1;J(*I++-125);}):({break;}):({*O++=1;*O++=*I++;}):0);}}
-// clang-format on
-
-#undef S
-#undef H
-#undef J
-
-#ifndef __WRAPPER
typedef char *string;
@@ -139,7 +81,6 @@ emu() {
int ptr = m[ 2 ];
int size = m[ 3 ], i = 0;
- for (; i < size; i++) putchar(m[ ptr++ ]);
while (size--) putchar(m[ ptr++ ]);
}
@@ -167,30 +108,6 @@ struct {
} opcode = {
0, 1, 2, 3, 4, 5, 6, 7, 8,9
};
-
-#define emit(OP, VAL) ({ *(*O)++ = (OP); *(*O)++ = (VAL); })
-#define store() ({ emit(opcode.acc, 1); emit(opcode.str, 0); })
-#define run_err(result) \
- ({ \
- printf("\n"); \
- error_debug((result), ERR_code, strlen(ERR_code)); \
- printf("\nir2 error message: %s\n", ERR); \
- printf("\n"); \
- exit(1); \
- })
-
-#define checkskip(char, message) \
- ({ \
- if (!*I) { \
- ERR = (message); run_err(I); \
- } \
- if (*I++ != (char) ) { \
- ERR = (message); ERR_code=init_I; run_err(I-1); \
- } \
- })
-#define scanword() ({ slice VAR = { 0, I}; while (isalnum(*I)) VAR.len++, I++; VAR; })
-#define memslice slice __attribute__((cleanup(clean_slice_ref)))
-#define readd() ({ if(used == new.len) new.ref = realloc(new.ref, new.len *= 2); })
// clang-format on
typedef unsigned char byte;
@@ -211,10 +128,88 @@ typedef struct {
clean_slice_ref(slice *val) { free(val->ref); }
+#define static_len(G) (sizeof(G) / sizeof((G)[ 0 ]))
+
+#define emit(OP, VAL) \
+ ({ \
+ *Code++ = (OP); \
+ *Code++ = (VAL); \
+ })
+#define store() \
+ ({ \
+ emit(opcode.acc, 1); \
+ emit(opcode.str, 0); \
+ })
+#define run_err(result) \
+ ({ \
+ printf("\n"); \
+ error_debug((result), ERR_code, strlen(ERR_code)); \
+ printf("\nir2 error message: %s\n", ERR); \
+ printf("\n"); \
+ exit(1); \
+ })
+
+#define checkskip(char, message) \
+ ({ \
+ if (!*I) { \
+ ERR = (message); \
+ run_err(I); \
+ } \
+ if (*I++ != (char) ) { \
+ ERR = (message); \
+ ERR_code = init_I; \
+ run_err(I - 1); \
+ } \
+ })
+#define scanword() \
+ ({ \
+ slice VAR = { 0, I }; \
+ while (isalnum(*I) || *I == '_') VAR.len++, I++; \
+ VAR; \
+ })
+#define memslice slice __attribute__((cleanup(clean_slice_ref)))
+#define readd() ((used == new.len) ? (new.ref = realloc(new.ref, new.len *= 2)) : 0)
+#define scanvalue() \
+ ({ /* value scanner! numbers, characters, strings. */ \
+ int value; \
+ if (isdigit(*I)) { \
+ value = strtol(I, &I, 10); \
+ } else if (*I == '\'') { \
+ I++; \
+ value = *I++; \
+ checkskip('\'', "couldn't find closing quote on character"); \
+ } else if (*I == '"') { \
+ string str_start = ++I; \
+ bool T = false; \
+ size_t str_len = 0; \
+ while (*I != '"' || T) { \
+ if (*I == '\\') { \
+ T = !T; \
+ if (!T && I[ 1 ] == '"') str_len--; \
+ } \
+ str_len++; \
+ I++; \
+ } \
+ I++; \
+ str_len++; \
+ int *dest_start = Data -= str_len; \
+ int y; \
+ for (y = 0; y < str_len-1; y++) { dest_start[ y ] = str_start[ y ]; } \
+ Data[ -1 ] = 0; \
+ value = Data - m; \
+ } else { \
+ ERR = "expected value (number, character, string)"; \
+ run_err(I); \
+ } \
+ value; \
+ })
+
T;
string ERR;
string ERR_code;
-_ir2(string I, int **O, entry macros[ 1 << 9 ]) {
+int *Code = &m[ 4000 ];
+int *Data = &m[ static_len(m) - 1 ]; // grows downwards
+_ir2(string I, entry macros[ 1 << 9 ]) {
string init_I = I;
ERR = "all good";
@@ -249,15 +244,8 @@ _ir2(string I, int **O, entry macros[ 1 << 9 ]) {
emit(opcode.swp, 0);
emit(opcode.imm, mem_index);
store();
- } else if (isdigit(*I) || *I == '\'') {
- int imm;
- if (*I == '\'') {
- I++;
- imm = *I++;
- checkskip('\'', "couldn't find closing quote on character");
- } else {
- imm = strtol(I, &I, 10);
- }
+ } else {
+ int imm = scanvalue();
emit(opcode.imm, imm);
emit(opcode.swp, 0);
@@ -276,7 +264,7 @@ _ir2(string I, int **O, entry macros[ 1 << 9 ]) {
skip_space(&I);
// parse macro stuff
- if (!isalpha(*I)) {
+ if (!isalpha(*I) && *I != '_') {
ERR = "expected letter at macro name";
run_err(I - 1);
}
@@ -367,7 +355,11 @@ _ir2(string I, int **O, entry macros[ 1 << 9 ]) {
skip_space(&I);
checkskip(';', "expected semicolon after system blob");
- _ir2("@0 = 2; exit();", O, macros);
+ emit(opcode.imm, 2);
+ emit(opcode.swp, 0);
+ emit(opcode.imm, 0);
+ store();
+ emit(opcode.hlt, 0);
continue;
}
@@ -491,31 +483,43 @@ _ir2(string I, int **O, entry macros[ 1 << 9 ]) {
new.ref[ used ] = 0;
- _ir2(new.ref, O, macros);
+ _ir2(new.ref, macros);
continue;
}
}
}
-ir2(string I, int **O) {
+ir2(string I) {
entry macros[ 1 << 9 ];
- _ir2(I, O, macros);
+ _ir2(I, macros);
}
+string op_names[] = { "hlt", "imm", "lod", "str", "swp", "add", "sub", "and", "not", "acc" };
+
main() {
- int *out = &m[ 1024 ];
size_t o_size;
- ir2(read_file("code.i2", &o_size), &out);
- m[ 7 ] = 1024;
+ ir2(read_file("testing.i2", &o_size));
+ m[ 7 ] = 4000;
- // size_t res_size = out - &m[ 1024 ];
+ size_t res_size = Code - &m[ 4000 ];
+ // --- BYTES PRINTING ---
// for(i = 0; i < res_size; i++) {
- // printf("%i ", m[1024+i]);
+ // printf("%X%X ", m[4000+i]>>4, m[4000+i]&0b1111);
+ // if(i % 8 == 7) printf("\n");
// }
// fflush(stdout);
// printf("\n\n");
+ // --- OPCODES PRINTING ---
+ // for (i = 0; i < res_size; i++) {
+ // int op = m[ 4000 + i++ ];
+ // int data = m[ 4000 + i ];
+
+ // printf("%s(%i);\n", op_names[ op ], data);
+ // }
+ // printf("\n\n");
+
emu();
}
@@ -532,7 +536,7 @@ main2(int argc, char **argv) {
char *contents = read_file(filename, &file_size);
E = 0;
- O = &m[ 1024 ];
+ K = &m[ 1024 ];
as2(contents);
if (E != 0) {
@@ -543,5 +547,3 @@ main2(int argc, char **argv) {
m[ 7 ] = 1024;
emu();
}
-
-#endif \ No newline at end of file