Mercurial > repo
view interps/egobf/src/optimize.c @ 12518:2d8fe55c6e65 draft default tip
<int-e> learn The password of the month is release incident pilot.
author | HackEso <hackeso@esolangs.org> |
---|---|
date | Sun, 03 Nov 2024 00:31:02 +0000 |
parents | 859f9b4339e6 |
children |
line wrap: on
line source
#include <stdlib.h> #include <stdio.h> #include <string.h> #include "egobfi.h" #include "optimize.h" #define NEXT pptr++; CHKPSZ(pptr) int optaddto(int cur); void optimize() { /* optimize optimizes a chunk of code at ipptr */ int cnt, a; struct bfi *cur; while (iprog[ipptr]) { switch(iprog[ipptr]) { case '+': case '-': cnt = 0; while (iprog[ipptr] == '+' || iprog[ipptr] == '-') { if (iprog[ipptr] == '+') cnt++; else cnt--; ipptr++; } cur = prog + pptr; cur->cmd = ADD; cur->arg1 = cnt; NEXT break; case '>': case '<': cnt = 0; while (iprog[ipptr] == '>' || iprog[ipptr] == '<') { if (iprog[ipptr] == '>') cnt++; else cnt--; ipptr++; } cur = prog + pptr; cur->cmd = RHT; cur->arg1 = cnt; NEXT break; case '[': /* special case 1: zero */ if (iprog[ipptr + 2] == ']' && (iprog[ipptr + 1] == '-' || (iprog[ipptr + 1] == '+' && wrapping)) ) { prog[pptr].cmd = ZRO; NEXT ipptr += 3; break; } /* start a suboptimize */ a = pptr; NEXT ipptr++; optimize(); /* check for addto */ if (pptr == a + 5 && optaddto(a)) { ipptr++; break; } /* make the jump */ cur = prog + a; cur->cmd = LPO; cur->arg1 = pptr; cur = prog + pptr; cur->cmd = LPC; cur->arg1 = a; NEXT ipptr++; break; case ']': /* this optimization session is over */ return; case '.': /* not much we can optimize here ... */ prog[pptr].cmd = OUT; NEXT ipptr++; break; case ',': /* here neither ... */ prog[pptr].cmd = INP; NEXT ipptr++; break; case '#': /* still no optimizations! */ prog[pptr].cmd = DBG; NEXT ipptr++; break; default: ipptr++; break; } } /* if we finished making the optimized program, this is the end */ prog[pptr].cmd = FIN; pptr = 0; } int optaddto(int cur) { /* a = pptr of LPO, pptr = pptr of LPC */ struct bfi *a = prog + cur; /* two types of add-tos: >x +x <x -x -x >x +x <x */ if (a[1].cmd == RHT && a[3].cmd == RHT && a[1].arg1 == a[3].arg1 * -1) { if (a[2].cmd == ADD && a[4].cmd == ADD && a[4].arg1 == -1) { /* YAY! */ a->cmd = ADDTO; a->arg1 = a[1].arg1; a->arg2 = a[2].arg1; pptr = cur + 1; return 1; } } else if (a[2].cmd == RHT && a[4].cmd == RHT && a[2].arg1 == a[4].arg1 * -1) { if (a[1].cmd == ADD && a[3].cmd == ADD && a[1].arg1 == -1) { /* YAY! */ a->cmd = ADDTO; a->arg1 = a[2].arg1; a->arg2 = a[3].arg1; pptr = cur + 1; return 1; } } return 0; }