Skip to content

Instantly share code, notes, and snippets.

@madebyjeffrey
Created February 6, 2016 19:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save madebyjeffrey/b30fc9537bb21b9ef81c to your computer and use it in GitHub Desktop.
Save madebyjeffrey/b30fc9537bb21b9ef81c to your computer and use it in GitHub Desktop.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct a {
long t, r, d[3], p[2];
} *A;
long *ma(int n) {
return (long *) malloc(n * 4);
}
void mv(long *d, long *s, int n) {
for (long i = 0; i < n; ++i) {
d[i] = s[i];
}
}
int tr(int r, long *d) {
long z = 1;
{
long i = 0, _n = (r);
for (;
i < _n;
++i) {
z = z * d[i];
}
};
return
z;
}
A ga(int t, int r, long *d) {
A z = (A) ma(5 + tr(r, d));
z->t = t, z->r = r, mv(z->d, d, r);
return z;
}
A iota(A w) {
long n = *w->p;
A z = ga(0, 1, &n);
{
long i = 0, _n = (n);
for (; i < _n; ++i) { z->p[i] = i; }
};
return z;
}
A plus(A a, A w) {
long r = w->r, *d = w->d, n = tr(r, d);
A z = ga(0, r, d);
{
long i = 0, _n = (n);
for (; i < _n; ++i) { z->p[i] = a->p[i] + w->p[i]; }
};
return z;
}
A from(A a, A w) {
long r = w->r - 1, *d = w->d + 1, n = tr(r, d);
A z = ga(w->t, r, d);
mv(z->p, w->p + (n * *a->p), n);
return z;
}
A box(A w) {
A z = ga(1, 0, 0);
*z->p = (long) w;
return z;
}
A cat(A a, A w) {
long an = tr(a->r, a->d), wn = tr(w->r, w->d), n = an + wn;
A z = ga(w->t, 1, &n);
mv(z->p, a->p, an);
mv(z->p + an, w->p, wn);
return z;
}
void find(A a, A w) { }
A rsh(A a, A w) {
long r = a->r ? *a->d : 1, n = tr(r, a->p), wn = tr(w->r, w->d);
A z = ga(w->t, r, a->p);
mv(z->p, w->p, wn = n > wn ? wn : n);
if (n -= wn)mv(z->p + wn, z->p, n);
return z;
}
A sha(A w) {
A z = ga(0, 1, &w->r);
mv(z->p, w->d, w->r);
return z;
}
A id(A w) { return w; }
A size(A w) {
A z = ga(0, 0, 0);
*z->p = w->r ? *w->d : 1;
return z;
}
void pi(int i) { printf("%d ", i); }
void nl() { printf("\n"); }
void pr(A w) {
long r = w->r, *d = w->d, n = tr(r, d);
for (long i = 0; i < r; ++i) {
pi(d[i]);
}
nl();
if (w->t) {
for (long i = 0; i < n; ++i) {
printf("< ");
pr(w->p[i]);
}
} else {
for (long i = 0; i < n; ++i) {
pi(w->p[i]);
}
};
nl();
}
char vt[] = "+{~<#,";
A(*vd[])() = {0, plus, from, find, 0, rsh, cat},
(*vm[])() = {0, id, size, iota, box, sha, 0};
long st[26];
// boolean
int qp(a) { return a >= 'a' && a <= 'z'; }
// boolean
int qv(a) { return a < 'a'; }
A ex(long *e) {
long a = *e;
if (qp(a)) {
if (e[1] == '=')return st[a - 'a'] = ex(e + 2);
a = st[a - 'a'];
}
return qv(a) ? (*vm[a])(ex(e + 1)) : e[1] ? (*vd[e[1]])(a, ex(e + 2)) : (A) a;
}
// c is used like a char
A noun(int c) {
A z;
if (c < '0' || c > '9')return 0;
z = ga(0, 0, 0);
*z->p = c - '0';
return z;
}
int verb(int c) {
long i = 0;
for (; vt[i];)if (vt[i++] == c)return i;
return 0;
}
long *wd(char *s) {
long a, n = strlen(s), *e = ma(n + 1);
char c;
{
long i = 0, _n = (n);
for (; i < _n; ++i) { e[i] = (a = noun(c = s[i])) ? a : (a = verb(c)) ? a : c; }
};
e[n] = 0;
return e;
}
int main() {
char s[99];
while (gets(s))pr(ex(wd(s)));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment