Skip to content

Instantly share code, notes, and snippets.

@typeswitch-dev
Last active October 12, 2023 23:25
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save typeswitch-dev/ac86d7e32167c1e5bf311c796cedc1a8 to your computer and use it in GitHub Desktop.
Save typeswitch-dev/ac86d7e32167c1e5bf311c796cedc1a8 to your computer and use it in GitHub Desktop.
第四 (Daiyon) — a Japanese & Forth inspired postfix language
#include <stdio.h>
#include <string.h>
#include <assert.h>
FILE *in; long M[1<<24]={0}, *D, *R, H=0x130000, IP=0, T;
long getu() { long t, h = getc(in); if (h < 0xC0) return h;
t = ((h&0x1F) << 6) | (getc(in) & 0x3F); if (h < 0xE0) return t;
t = ( t << 6) | (getc(in) & 0x3F); if (h < 0xF0) return t;
t = ( t << 6) | (getc(in) & 0x3F); return t & 0x1FFFFF; }
void putu(long c) { if (c < 0x80) { putchar(c); return; }
if (c < 0x7FF) { putchar(0xC0|(c>>6)); } else {
if (c < 0x10000) { putchar(0xE0|(c>>12)); } else {
putchar(0xF0 | (c>>18)); putchar(0x80 | ((c>>12) & 0x3F)); }
putchar(0x80 | ((c>>6) & 0x3F)); } putchar(0x80 | (c & 0x3F)); }
int main(int argc, char** argv) { D = M + 0x120000; R = D + 0x1000;
for (int i = 1; i < argc; i++) { in = fopen(argv[i], "r");
assert(in); long OP = getu(); while(OP >= 0) { switch (OP) {
case 0xFF3B: *--D = H; while ((OP = getu()) != 0xFF3D)
{ assert(OP>0); M[H++]=OP; } M[H++]=0; break; /* []quote */
case 0x3060: M[D[1]] = D[0]; D += 2; break; /* だ is */
case 0x51fa: case 0: IP = *R++; break; /* 出 exit */
case 0x5199: D--; D[0] = D[1]; break; /* 写 dup */
case 0x6368: D++; break; /* 捨 drop */
case 0x787b: T=D[0]; D[0]=D[1]; D[1]=T; break; /* 移 swap */
case 0x8db3: D[1] += D[0]; D++; break; /* 足 add */
case 0x5f15: D[1] -= D[0]; D++; break; /* 引 sub */
case 0x639b: D[1] *= D[0]; D++; break; /* 掛 mul */
case 0x5272: D[1] /= D[0]; D++; break; /* 割 div */
case 0x6b8b: D[1] %= D[0]; D++; break; /* 残 mod */
case 0x540c: D[1] = (D[1] == D[0]); D++; break; /* 同 equal */
case 0x4e0b: D[1] = (D[1] < D[0]); D++; break; /* 下 less */
case 0x4e00: *--D = 1; break; /* 一 one */
case 0x8aad: *--D = getu(); break; /* 読 read */
case 0x66f8: putu(*D++); break; /* 書 write */
case 0x6570: printf("%ld ", *D++); break; /* 数 count */
case 0x5b57: *--D = IP?M[IP++]:getu(); break; /* 字 char */
case 0x6b64: *--D = H; break; /* 此 here */
case 0x3067: H = *D++; break; /* で at */
case 0x8a18: M[H++] = *D++; break; /* 記 note */
default: if (OP < 128) break; /* ignore ascii */
*--R = IP; IP=M[OP]; assert(IP); /* perform call */
} OP = IP ? M[IP++] : getu(); } } }
Numbers. The interpreter only defines the number 1,
so we need to define some more to do anything useful.
字無[一一引]だ "nil" 0 = 1 - 1
字二[一一足]だ "two" 2 = 1 + 1
字三[一二足]だ "three" 3 = 1 + 2
字四[二写足]だ "four" 4 = 2 + 2
字五[四一足]だ "five" 5 = 4 + 1
字六[二三掛]だ "six" 6 = 2 * 3
字七[六一足]だ "seven" 7 = 6 + 1
字八[二四掛]だ "eight" 8 = 2 * 4
字九[三写掛]だ "nine" 9 = 3 * 3
字十[二五掛]だ "ten" 10 = 2 * 5
字百[十写掛]だ "hundred" 100 = 10 * 10
字千[十百掛]だ "thousand" 1000 = 10 * 100
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment