aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar moon <moon@coffin.ir> 2025-08-23 14:06:35 +0330
committerGravatar moon <moon@coffin.ir> 2025-08-23 14:06:35 +0330
commit4bccfb47a63461e53925faebca7132e262ebd9da (patch)
tree5c4340ec8f2efa304cfef306235f8c1f181f7a22
parentif statements are now supported! (diff)
while loops!
-rw-r--r--pu2/code.i217
-rw-r--r--pu2/pu2.c123
-rw-r--r--pu2/pu2.out.c7
3 files changed, 123 insertions, 24 deletions
diff --git a/pu2/code.i2 b/pu2/code.i2
index 06d1c54..22ab74f 100644
--- a/pu2/code.i2
+++ b/pu2/code.i2
@@ -1,3 +1,5 @@
+
+
/*
testing grounds for the ir2 assembler
@@ -21,17 +23,14 @@ macro putchar(1) {
system();
}
-@10 = 0;
+@90 = 5;
-// if statement!!
-if (@10) {
- puts(["hi"], [2]);
-}
+while (@90) {
+ @90--;
-putchar([10]);
-puts([" hello world"], [15]);
-putchar([10]);
-putchar([10]);
+ puts(["hello"], [5]);
+ putchar([10]);
+}
exit(0);
diff --git a/pu2/pu2.c b/pu2/pu2.c
index 7640039..c097873 100644
--- a/pu2/pu2.c
+++ b/pu2/pu2.c
@@ -310,6 +310,7 @@ int ir2_depth = 0;
bool has_jump_warned = false;
bool has_useless_if_warned = false;
+bool has_false_while_warned = false;
string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label_delegated_t forward_refs[ 1 << 10 ]) {
char T;
@@ -366,7 +367,11 @@ string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label
swap();
mem_in_a(mem_index);
op(sub);
+ swap();
+ imm(mem_index);
store();
+
+ continue;
}
if(*I == '+' && I[1] == '+') { // increment
@@ -377,7 +382,11 @@ string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label
swap();
mem_in_a(mem_index);
op(add);
+ swap();
+ imm(mem_index);
store();
+
+ continue;
}
char extra_op = '=';
@@ -406,7 +415,7 @@ string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label
} else if (extra_op == '&') {
perform_op(and);
} else if (extra_op == '!') {
- // @1 != @2;
+ // @1 != @2; (@1 = !@2)
mem_in_a(mem2_index);
op(not);
swap();
@@ -431,20 +440,20 @@ string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label
swap();
mem_in_a(mem_index);
op(sub);
+ swap();
+ imm(mem_index);
store();
} else if (extra_op == '&') {
imm(imm);
swap();
mem_in_a(mem_index);
op(and);
- store();
- } else if (extra_op == '!') {
- // @1 != 5;
- imm(imm);
- op(not);
swap();
imm(mem_index);
store();
+ } else if (extra_op == '!') {
+ // @1 != 5; (@1 = !5;)
+ imm_in_mem(mem_index, !imm);
}
}
@@ -721,22 +730,23 @@ string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label
int *Code_B = Code;
int *Data_B = Data;
+ // completely eliminate code generated in useless if statement
+ int m2[S/4];
+ Data = Code = m2;
+
// get new I location
string new_I = _ir2(I, macros, labels, forward_refs);
I = new_I;
// restore values
Code = Code_B;
Data = Data_B;
-
- continue;
- }
-
- else {
+ } else {
// just... i mean, i guess run the code..?
string new_I = _ir2(I, macros, labels, forward_refs);
I = new_I;
- continue;
}
+
+ continue;
}
bool was_negated = false;
@@ -769,6 +779,95 @@ string _ir2(string I, macro_t macros[ 1 << 9 ], label_t labels[ 1 << 10 ], label
continue;
}
+ else if (strncmp("while", I, 5) == 0 && !isalnum(I[5])) {
+ I += 5;
+ space; checkskip('(', "expected open paren for while loop"); space;
+ ir2_depth++;
+
+ if (isdigit(*I)) {
+ int value = strtol(I, &I, 10); space;
+
+ checkskip(')', "expected closing paren after while loop argument"); space;
+ checkskip('{', "expected opening bracket for while loop body"); space;
+
+ if (!value) {
+ // non-running while loop
+
+ if(!has_false_while_warned) {
+ has_false_while_warned = true;
+ printf("warn: dead code inside while loop\n");
+ }
+
+ // just skip over everything inside
+
+ int *Code_B = Code;
+ int *Data_B = Data;
+
+ // completely eliminate code generated in useless while loop
+ int m2[S/4];
+ Data = Code = m2;
+
+ // get new I location
+ string new_I = _ir2(I, macros, labels, forward_refs);
+ I = new_I;
+ // restore values
+ Code = Code_B;
+ Data = Data_B;
+ } else {
+ // run forever!
+
+ int start = Code - m;
+
+ string new_I = _ir2(I, macros, labels, forward_refs);
+ I = new_I;
+
+ imm_in_mem(7, start); // always jump back to the start
+ }
+
+ continue;
+ }
+
+ bool was_negated = false;
+ if (*I == '!') {
+ was_negated = true;
+ I++; space;
+ }
+
+ checkskip('@', "expected memory address for while loop expression (hint: only simple conditions are supported)");
+ if (!isdigit(*I)) run_err(I, "expected memory index");
+ int mem_index = strtol(I, &I, 10); space;
+ checkskip(')', "expected closing paren after while loop condition"); space;
+ checkskip('{', "expected opening bracket for while loop body"); space;
+
+ mem_in_a(mem_index);
+ if (!was_negated) op(not);
+ op(a2u);
+ imm(0xDEAD10C4); // DEADLOCK - placeholder for the patchback
+ int* patchback = Code - 1;
+ swap();
+ imm(7);
+ op(str);
+
+ int start_index = Code - m;
+
+ // handle the code stuff
+ string new_I = _ir2(I, macros, labels, forward_refs);
+ I = new_I;
+
+ *patchback = Code - m; // patch the jump instruction
+
+ // check the condition and jump back if true
+ mem_in_a(mem_index);
+ if (was_negated) op(not);
+ op(a2u);
+ imm(start_index);
+ swap();
+ imm(7);
+ op(str);
+
+ continue;
+ }
+
// macro call, maybe?
else if (isalpha(*I)) {
string old_I = I;
diff --git a/pu2/pu2.out.c b/pu2/pu2.out.c
index f35a7ab..8bc9f52 100644
--- a/pu2/pu2.out.c
+++ b/pu2/pu2.out.c
@@ -153,7 +153,7 @@ void __attribute__((hot, aligned(64))) pu2() {
static int s1, s2, s3;
static const __attribute__((aligned(64))) void *PRECOMPUTED_TABLE[]
- = { &&C_ZERO, &&C_ONE, &&C_TWO, &&C_THREE, &&C_FOUR,
+ = { &&PU2_END, &&C_ONE, &&C_TWO, &&C_THREE, &&C_FOUR,
&&C_FIVE, &&C_SIX, &&C_SEVEN, &&C_EIGHT, &&C_NINE,
&&C_TEN, &&C_ELEVEN, &&C_TWELVE, &&C_THIRTEEN, &&CB_FOURTEEN,
&&CB_FIFTEEN, &&CB_SIXTEEN, &&CB_SEVENTEEN, &&CB_EIGHTEEN, [32] = 0 };
@@ -166,8 +166,8 @@ void __attribute__((hot, aligned(64))) pu2() {
__builtin_prefetch(M + 1, 0, 3);
goto *PRECOMPUTED_TABLE[ inst.c ];
- C_ZERO:
- goto PU2_END;
+// C_ZERO:
+// goto PU2_END;
C_ONE:
#ifndef PU2_NO_ASM
asm("mov %1, %0" : "=r"(a) : "r"(inst.v));
@@ -183,6 +183,7 @@ void __attribute__((hot, aligned(64))) pu2() {
#endif
goto PU2_START;
C_THREE:
+ // if (unlikely(a == 7)) printf("conditional jmp %i (%i) [a=%i b=%i u=%i]\n", M - M2, u, a, b, u);
if (likely(u)) {
if (unlikely(a == 7)) M = M2 + (b >> 1);
m[ a ] = b;