Skip to content

Instantly share code, notes, and snippets.

@niconii
Forked from typeswitch-dev/daiyon.c
Last active January 3, 2022 23:37
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 niconii/8c82fab2178eb6eae32d792583c036a5 to your computer and use it in GitHub Desktop.
Save niconii/8c82fab2178eb6eae32d792583c036a5 to your computer and use it in GitHub Desktop.
第四 (Daiyon) — a Japanese & Forth inspired postfix language

daiyon

based on the code from this tweet by @typeswitch-dev

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <locale.h>
#include <wchar.h>
FILE *in; long M[1<<24]={0}, *D, *R, H=0x130000, IP=0, T;
long getu() { return (int)getwc(in); }
void putu(long c) { putwc(c, stdout); }
int main(int argc, char** argv) {
setlocale(LC_ALL, ""); 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 L'「': *--D = H; while ((OP = getu()) != L'」')
{ assert(OP>0); M[H++]=OP; } M[H++]=0; break; /* quote */
case L'だ': M[D[1]] = D[0]; D += 2; break; /* is */
case L'出': case 0: IP = *R++; break; /* exit */
case L'写': D--; D[0] = D[1]; break; /* dup */
case L'捨': D++; break; /* drop */
case L'移': T=D[0]; D[0]=D[1]; D[1]=T; break; /* swap */
case L'足': D[1] += D[0]; D++; break; /* add */
case L'引': D[1] -= D[0]; D++; break; /* sub */
case L'掛': D[1] *= D[0]; D++; break; /* mul */
case L'割': D[1] /= D[0]; D++; break; /* div */
case L'残': D[1] %= D[0]; D++; break; /* mod */
case L'同': D[1] = (D[1] == D[0]); D++; break; /* equal */
case L'下': D[1] = (D[1] < D[0]); D++; break; /* less */
case L'一': *--D = 1; break; /* one */
case L'読': *--D = getu(); break; /* read */
case L'書': putu(*D++); break; /* write */
case L'数': printf("%ld ", *D++); break; /* count */
case L'字': *--D = IP?M[IP++]:getu(); break; /* char */
case L'此': *--D = H; break; /* here */
case L'で': H = *D++; break; /* at */
case L'記': 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
字#「無」だ
字0「十掛」だ
字1「0一足」だ
字2「0二足」だ
字3「0三足」だ
字4「0四足」だ
字5「0五足」だ
字6「0六足」だ
字7「0七足」だ
字8「0八足」だ
字9「0九足」だ
字行「#10書」だ
#12345数行
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment