Skip to content

Instantly share code, notes, and snippets.

@nsmaciej
Last active February 18, 2020 11:34
Show Gist options
  • Save nsmaciej/3053a735ea76cae8518a86bb1178602a to your computer and use it in GitHub Desktop.
Save nsmaciej/3053a735ea76cae8518a86bb1178602a to your computer and use it in GitHub Desktop.
/* ____ _ ____
* / __ )_________ _(_)___ _________ _/ / /
* / __ / ___/ __ `/ / __ \/ ___/ __ `/ / /
* / /_/ / / / /_/ / / / / / /__/ /_/ / / /
* /_____/_/ \__,_/_/_/ /_/\___/\__,_/_/_/
*
* Copyright 2017 Maciej Goszczycki
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef char C; typedef void V; typedef int I; typedef unsigned char UC; typedef const char CC;
#define B break
#define M case
#define R return
#define SL strlen
#define P printf
#define F(v, s, l) for (int v = s; v < l; v++)
#define W(e) while((e))
#define CL(x) "\033[1m\033[91m" x "\033[0m"
V die(CC *b) { fprintf(stderr, "%s\n", b); exit(1); }
I has(CC *a, C v) { I l=SL(a); F(i, 0, l) if(a[i]==v) R 1; R 0; }
I reloc(UC **p, I s, I r) { *p = realloc(*p, s + r); memset(*p + s, 0, r); R r; }
V call(I d, V **p) { /* https://filippo.io/making-system-calls-from-assembly-in-mac-os-x/ */
V *c = p[0] + 0x2000000; if(d) P("Syscall: %p(%p, %p, %p)\n", c, p[1], p[2], p[3]);
asm volatile ("movq %0, %%rax\n" "movq %1, %%rdi\n" "movq %2, %%rsi\n" "mov %3, %%rdx\n" "syscall\n"
:: "m" (c), "m" (p[1]), "m" (p[2]), "m" (p[3]) : "%rax", "%rdi", "%rsi", "%rdx"); }
C* reap(CC *p) {
I c = 255; I s = c; FILE *f = fopen(p, "r"); if (!f) die("file error"); C *b = malloc(s); I r = 0; I d;
W(d = fread(b + r, 1, c - 1, f)) { r += d; b = realloc(b, s += c); }
r += d; b[r + 1] = 0; R b; }
I* bjmp(CC *m) {
I r = SL(m); I *j = calloc(r, sizeof(int)); I *s = calloc(r, sizeof(int)); I p = 0;
F(i, 0, r) {
if (m[i] == '[') s[p++] = i;
else if (m[i] == ']') { p--; if (p < 0) die("unmatched loop close"); j[i] = s[p]; j[s[p]] = i; }
}
if (p) die("missing loop close"); free(s); R j; }
V debp(CC *m, I r, UC *t, I p, I s) {
I l = SL(m);
F(i, 0, l) if (i == r) P(CL("%c"), m[i]); else P("\033[2m%c\033[0m", m[i]);
F(i, 0, p) P("%d ", t[i]); P(CL("%d")" ", t[p]);
I nz = 0; F(i, p + 1, s) if(t[i]) nz = i; if (nz) F(i, p + 1, nz + 1) P("%d ", t[i]);
P("\n\n"); }
V run(I d, I u, CC *m) {
I c = 255; UC *t = malloc(sizeof(int) * c); I s = c; I p = 0; I r = SL(m); I *j = bjmp(m); I i = 0;
W(i < r) {
switch (m[i]) {
M '+': t[p]++; B;
M '-': t[p]--; B;
M '>': p++; if (p >= s) s += reloc(&t, s, c); B;
M '<': p--; if (p < 0) die("negative pointer"); B;
M '[': if (!t[p]) i = j[i]; B;
M ']': if (t[p]) i = j[i]; B;
M '#': debp(m, i, t, p, s); B;
M '!': if (p + 8 >= s) s += reloc(&t, s, c); call(d, (V*)t+p); B;
M '&': if (p + 8*3 >= s) s += reloc(&t, s, c); *(void**)(t+p) = (void*)t+p; B;
default: i++; continue;
}
if (d) debp(m, i, t, p, s); if(u) getchar(); i++;
} }
I main(I c, C *v[]) {
if (c < 2) die("no file");
C *p = reap(v[1][0] == '-' ? "/dev/stdin" : v[1]);
if (c > 2) run(has(v[2],'d'), has(v[2],'s'), p); else run(0, 0, p);
free(p); R 0; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment