diff options
| author | 2025-08-12 20:27:34 +0330 | |
|---|---|---|
| committer | 2025-08-12 20:27:34 +0330 | |
| commit | 15914727d83a6f46ad724e126179713d935e5e6f (patch) | |
| tree | 2f601872b7575e4f3c0ca8c366fb2a1e1ea1b4fb /pu2/pu2.c | |
| parent | ir2 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.c | 216 |
1 files changed, 109 insertions, 107 deletions
@@ -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 |
