diff --git a/2011/richards/README.md b/2011/richards/README.md index 41b0272e1..9faa94e4d 100644 --- a/2011/richards/README.md +++ b/2011/richards/README.md @@ -48,7 +48,7 @@ This is an implementation of the classic UNIX [dc](https://en.wikipedia.org/wiki/Dc_(computer_program)) command, the [reverse Polish](https://en.wikipedia.org/wiki/Reverse_Polish_notation) calculator. Actually it's a pretty bad implementation, since it only implements -32-bit integers (well, sizeof(int)-sized integers). It only implements the +32-bit integers (well, `sizeof(int)`-sized integers). It only implements the commands `+`, `-`, `*`, `/`, `p` (only for numbers), register stacks, macros and comparisons. Wow, you'd think I could've done better in 2K of code. @@ -64,7 +64,7 @@ stack grows down and integers are at least 32-bit. You will probably get warnings while compiling the code. In particular: -* If your system requires the inclusion of alloca.h to use alloca, use the +* If your system requires the inclusion of `alloca.h` to use alloca, use the compile flag `-DAH`. * If your system cannot use `mmap()`, use the compile flag `-DNM`. @@ -76,7 +76,7 @@ You will probably get warnings while compiling the code. In particular: * GCC likes to complain about `while (a = b)` (assignments as a condition). -* I don't return from `main()`, even though it's declared to return int. +* I don't return from `main()`, even though it's declared to return `int`. Platforms on which all known/tested optimization levels work with no additional flags: diff --git a/2011/richards/richards.alt.c b/2011/richards/richards.alt.c new file mode 100644 index 000000000..f504ba28b --- /dev/null +++ b/2011/richards/richards.alt.c @@ -0,0 +1,206 @@ +#ifdef AH +#include +#endif +#include +#include +#include +#include +#include +#include +#ifndef NM +#include +#endif +#define vo volatile +#define A(x,y,z) O(x,y,z##1)O(x,y,z##2)O(x,y,z##3) +#define B(x,y) A(x,y,1)A(x,y,2)A(x,y,3) +#define C(x,y) B(x,y##1)B(x,y##2)B(x,y##3) +#define D(x) C(x,1)C(x,2)C(x,3) +#define E(x) D(x##1)D(x##2)D(x##3) +#define G E(1)E(2)E(3) +#define S d-> +#define M S a +#define R(x) ; S r(#x); +#define L(x,y) S l[x](d)R(y) +#define F(x) void l##x(vo dt d) { +#define Q(x); M--; *M=*M x M[1]; R(x) +#define O(x,y,z) x##y##z, +#define q typedef +#define H 9<<16 +#define I case +#define J(i) calloc(i,1) +#define W(c) e=memmove(e,x[(u)c],y[(u)c])+y[(u)c]; +#define N break; I +q char k; +q void o; +q int u; +q o(*f) (vo o *); +q struct { + u *a, **R, *m, h, c; + k **s; + f *l, *j, r; +} *dt; +u m[] = { G 0 } ; + +u n[H]; +dt st; +u sk[H]; +k *w; +o *x[H]; +u y[H]; +f j, e; +u l=256; +o g(u v) +{ + if (v > l) { + g(v / l); + g(l); + W('*') g(v % l); + W('+')} else { + W(m[v])} +} + +f K(k * p, dt d) +{ + k c, n = 0; + f r = (f) e; + W(1) + while ((c = *p)) { + switch (c) { + I '#': + while (*++p != 10); + N '[':c = 1; + S s[S c] = ++p; + for (; c; p++) { + if (*p == '[') + c++; + else if (*p == ']') + c--; + } + p[-1] = 0; + g(S c++); + N '!':n = 1; + c = *++p; + if (!(c & 1)) + I '<': I '>': + c ^= 2; + I '=':W(c) if (n) { + W('!') n = 0; + } + g(*++p); + W('|') p++; + N 's': I 'S': I 'l': + I 'L':g(*++p); + W(c) p++; + N '_':p++; + default: + if (isdigit(*p)) { + g(atoi(p)); + while (isdigit(*p)) + p++; + } else + p++; + W(c)} + } + W(2) return r; +} + +o t(vo dt d) +{ + S r("\01") Q(+)Q(-)Q(*) * M = -*M; + R(_)Q( ==) Q(<)Q(>) * M = !*M; + R(!)M[-1] ^= *M; + *M ^= M[-1] R(r) M[1] = *M; + M++ R(d) * S R[*M] = M[-1]; + M--; + R(s) * ++S R[*M] = M[-1]; + M--; + R(S) * M = *S R[*M]; + R(l) * M = *S R[*M]--; + R(L) L(1, /)L(2, p) L(3, x) L(4, |) +#undef O +#define O(x,y,z) *++M=S m[(x*S h+y)*S h+z]; S r(""); + G S l[0] (d); +} + +o T() +{ +} + +o rd(u v) +{ + o *a = 0, **b = &a, **c = b + 32; + x[v] = w; + for (; b < c && (*b < (o *)w || *b > (o *) T || *b == &v); b++); + if (b == c) { + jmp_buf *j = alloca(sizeof(*j)); + setjmp(*j); + rd(v); + } else { + y[v] = *b - (o*)w; + w = *b; + } +} + +q o(*rt) (u); +vo rt rs = rd; +o re(vo k * rec) +{ + static u i = 0; + *(st->a = sk + 9) = 0; + rs(*rec ? *rec : m[i++]); +} F(d) M--; + +*M /= M[1]; +} F(p) printf("%d\n", *M); +} F(x) u n = *M--; + +if (!S j[n]) +S j[n] = K(S s[n], d); +S j[n] (d); +} + +F(1) M -= 2; +if (M[1]) +{ +M++; +*M = *S R[M[1]]; +lx(d); +} +} +f *lib1[] = { T, T, T, T, T } ; +f *lib2[] = { T, ld, lp, lx, l1 } ; + +int main() +{ + u i; + k *b; + dt d = st = J(sizeof(*st)); + M = sk + 9; + S R = J(l * sizeof(k *)); + for (i = 0; i < l; i++) + S R[i] = J(H); + S m = n; + S s = J(H); + S l = (f *) lib1; + S j = J(H); + S r = (f) re; + for (i = 0; m[i]; i++) + n[m[i]] = i; + w = (k *) t; + t(d); + x[2] = w; + y[2] = (k *) T - w + 8; + S h = 100; + S l = (f *) lib2; + S r = (f) T; + j = e = +#ifdef NM + malloc(H); +#else + (f)mmap(NULL, H, -1, MAP_ANON | MAP_PRIVATE | MAP_JIT, -1, 0); + #define CONFIG_DYNAMIC_CODE_SIGNING + mprotect(e, H, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE|((vm_prot_t) 0x20)); +#endif + while (b = fgets(malloc(999), 999, stdin)) + ((f) K(b, d)) (d); +} diff --git a/bugs.md b/bugs.md index 02a5101ca..075810964 100644 --- a/bugs.md +++ b/bugs.md @@ -2480,7 +2480,9 @@ memory protections with the arm64 processor. workarounds but at this time he could not get it to work. He offers some earlier debugging sessions below as well as a resource from the author as well as some resources on Apple's website should anyone wish to take a crack at it. He might -address it later. +address it later but a starting point might be in +[richards.alt.c](2011/richards/richards.alt.c). + ### Debugging diff --git a/thanks-for-fixes.md b/thanks-for-fixes.md index 4e30adec0..b02b42594 100644 --- a/thanks-for-fixes.md +++ b/thanks-for-fixes.md @@ -3234,7 +3234,9 @@ least with the silicon chip (Intel has not been tested) and it is quite possibly an inherent problem in macOS to do with executing code in in memory/JIT and in particular with the silicon chip. See [bugs.md](/bugs.md) for more details and a document from Apple about how it might be fixed if anyone is brave enough to -try. +try. If they do they might want to look also at +[richards.alt.c](2011/richards/richards.alt.c), for whatever it might or might +not be worth. ## [2011/vik](2011/vik/vik.c) ([README.md](2011/vik/README.md]))