diff options
Diffstat (limited to 'pu2/pu2.c')
| -rw-r--r-- | pu2/pu2.c | 123 |
1 files changed, 111 insertions, 12 deletions
@@ -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; |
