Skip to content

Instantly share code, notes, and snippets.

@ghassanpl
Last active June 2, 2024 21:32
Show Gist options
  • Save ghassanpl/f6773652e678c7cd0d95ce2e15a2256c to your computer and use it in GitHub Desktop.
Save ghassanpl/f6773652e678c7cd0d95ce2e15a2256c to your computer and use it in GitHub Desktop.
woops
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TYPE_VALUEARRAY 0
#define TYPE_POINTERARRAY 1
typedef struct value
{
long Type, Rank, Dimensions[3], Elements[2];
}*Value;
#define SingleArgumentFunction(f) Value f(Value w)
#define TwoArgumentFunction(f) Value f(Value a, Value w)
#define copy(d,s,n) memcpy(d,s,(n)*4)
long *AllocNWords(long n)
{
return (long*)malloc(n * 4);
}
long CalculateElements(long r, long* d)
{
long z = 1;
for (long i = 0; i < r; i++)
z = z*d[i];
return z;
}
Value CreateValue(long t, long rank, long* dimensions)
{
Value z = (Value)AllocNWords(5 + CalculateElements(rank, dimensions));
z->Type = t;
z->Rank = rank;
copy(z->Dimensions, dimensions, rank);
return z;
}
SingleArgumentFunction(iota)
{
long n = *w->Elements;
Value z = CreateValue(TYPE_VALUEARRAY, 1, &n);
for (long i = 0; i < n; i++)
z->Elements[i] = i;
return z;
}
TwoArgumentFunction(plus)
{
long r = w->Rank;
long *d = w->Dimensions;
long n = CalculateElements(r, d);
Value z = CreateValue(TYPE_VALUEARRAY, r, d);
for (long i = 0; i < n; i++)
z->Elements[i] = a->Elements[i] + w->Elements[i];
return z;
}
TwoArgumentFunction(from)
{
long r = w->Rank - 1;
long *d = w->Dimensions + 1;
long n = CalculateElements(r, d);
Value z = CreateValue(w->Type, r, d);
copy(z->Elements, w->Elements + (n * *a->Elements), n);
return z;
}
SingleArgumentFunction(box)
{
Value z = CreateValue(TYPE_POINTERARRAY, 0, 0);
*z->Elements = (long)w;
return z;
}
TwoArgumentFunction(cat)
{
long an = CalculateElements(a->Rank, a->Dimensions);
long wn = CalculateElements(w->Rank, w->Dimensions);
long n = an + wn;
Value z = CreateValue(w->Type, 1, &n);
copy(z->Elements, a->Elements, an);
copy(z->Elements + an, w->Elements, wn);
return z;
}
TwoArgumentFunction(find)
{
return 0;
}
TwoArgumentFunction(rsh)
{
long r = a->Rank ? *a->Dimensions : 1;
long n = CalculateElements(r, a->Elements);
long wn = CalculateElements(w->Rank, w->Dimensions);
Value z = CreateValue(w->Type, r, a->Elements);
copy(z->Elements, w->Elements, wn = n>wn ? wn : n);
if (n -= wn)
copy(z->Elements + wn, z->Elements, n);
return z;
}
SingleArgumentFunction(sha)
{
Value z = CreateValue(TYPE_VALUEARRAY, 1, &w->Rank);
copy(z->Elements, w->Dimensions, w->Rank);
return z;
}
SingleArgumentFunction(id)
{
return w;
}
SingleArgumentFunction(size)
{
Value z = CreateValue(TYPE_VALUEARRAY, 0, 0);
*z->Elements = w->Rank ? *w->Dimensions : 1;
return z;
}
void PrintInt(long i)
{
printf("%d ", i);
}
void PrintNewline()
{
printf("\n");
}
void PrintValue(Value w)
{
long r = w->Rank;
long *d = w->Dimensions;
long n = CalculateElements(r, d);
for (long i = 0; i < r; i++)
PrintInt(d[i]);
PrintNewline();
if (w->Type == TYPE_POINTERARRAY)
{
for (long i = 0; i < n; i++)
{
printf("< ");
PrintValue((Value)w->Elements[i]);
}
}
else
{
for (long i = 0; i < n; i++)
PrintInt(w->Elements[i]);
}
PrintNewline();
}
char Operators[] = "+{~<#,";
Value(*DoubleArgumentFunctions[])(Value, Value) = {
0,plus,from,find,0,rsh,cat
};
Value(*SingleArgumentFunctions[])(Value) = {
0,id,size,iota,box,sha,0
};
Value Variables[26];
long IsLetter(long a)
{
return a >= 'a' && a <= 'z';
}
long IsOperator(long a)
{
return a<'a';
}
Value ExecuteExpression(long* e)
{
long a = *e;
if (IsLetter(a))
{
if (e[1] == '=')
return Variables[a - 'a'] = ExecuteExpression(e + 2);
a = (long)Variables[a - 'a'];
}
if (IsOperator(a))
return SingleArgumentFunctions[a](ExecuteExpression(e + 1));
else if (e[1])
return DoubleArgumentFunctions[e[1]]((Value)a, ExecuteExpression(e + 2));
else
return (Value)a;
}
Value ParseNoun(long c)
{
Value z;
if (c<'0' || c>'9')
return 0;
z = CreateValue(TYPE_VALUEARRAY, 0, 0);
*z->Elements = c - '0';
return z;
}
long ParseVerb(long c)
{
long i = 0;
for (; Operators[i];)
if (Operators[i++] == c)
return i;
return 0;
}
long *Parse(char *s)
{
long a;
long n = strlen(s);
long *e = AllocNWords(n + 1);
char c;
for (long i = 0; i < n; i++)
{
c = s[i];
if (a = (long)ParseNoun(c))
e[i] = a;
else if (a = ParseVerb(c))
e[i] = a;
else
e[i] = c;
}
e[n] = 0;
return e;
}
int main()
{
char s[99];
while (gets_s(s))
PrintValue(ExecuteExpression(Parse(s)));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment