Last active
October 12, 2023 23:25
-
-
Save typeswitch-dev/ac86d7e32167c1e5bf311c796cedc1a8 to your computer and use it in GitHub Desktop.
第四 (Daiyon) — a Japanese & Forth inspired postfix language
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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(); } } } | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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