aboutsummaryrefslogtreecommitdiff
path: root/pu2/pu2.c
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 /pu2/pu2.c
parentif statements are now supported! (diff)
while loops!
Diffstat (limited to 'pu2/pu2.c')
-rw-r--r--pu2/pu2.c123
1 files changed, 111 insertions, 12 deletions
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;