Emmental言語の紹介と記録

,

http://esolangs.org/wiki/Emmental

良い言語である。 (面倒なだけの部分を機械に投げ付けてしまえば)けっこう書き易い。 grassとsedを足して割った感じ。

introduction

状態としては、stackとqueueをそれぞれ持ち、動的に操作できる関数空間を持つ。 命令は使い易さと簡潔さを意識して選ばれており、条件分岐は縮約命令 $\lfloor log x \rfloor$ ~とeval ?を主に用い、関数を呼び分ける形で行う。 関数定義のためのquoteによる特徴的な見ためを持つ。

詳細に関してはwiki等を見て。

examples

drop命令

準備として、; #0 !として$0$番目の関数をnopにする。 : -としてstack topを$0$にし、?により$0$番目の関数を呼ぶことでこれを消費し、全体としてdrop操作となる。

not命令

例えば~ #8 + ~ #3 -とする。 $256$種類の値を$0,1$の$2$種類に分ける必要があるが、非可逆操作でこの用途に使えるのは実質的に$log x$ ~のみであり、これを使う。 $0, 1, \dots, 255$をまず$8 = [0], 0 = [1] = [2], \dots, 7 = [128] = \dots = [255]$の$8$種の同値類に分割し、これをずらして再度分割することにより、$0, 1$のみに潰す。

if文

分岐が可能な命令はeval ?のみである。 例えば、上で示したnot等を使い$0,1$を作り、関数$0$と関数$1$をそれぞれ分岐先として定義し、?により呼び分けることで実現できる。

while文

末尾再帰のようにすればよい。if文で直接制御してもよいが、再帰関数自体を動的にnopで塗り替えることもできる。

criticism

if文やwhile文の分だけ関数定義がnestすることになる。 この際、toplevelとそれ以外で諸々の挙動に差があり、綺麗でない。 具体的には、

  • ;命令はtoplevelでのみ使える
    • '; $=$ #59;は同値であるので、ひとつ内側では'';#35#53#57とする必要がある
  • ?を介さない直接の関数呼び出しが不透明
    • その関数内で動的に定義された関数を呼ぶには?が必要
    • !命令により定義された関数が実際の環境に反映されるのが、そのscopeを抜けた時点であるのが原因

fizzbuzz

書いた。

quoted

wikiのそれと同様のquoteによる記法で書いて翻訳させた。以下のような規則。

  • 'A $\to$ #65
  • ''A $=$ '#'6'5 $\to$ #35#54#53
  • '''A $\to$ #35#51#53#35#53#52#35#53#51

中規模のものを書きたいなら、例えば以下のような拡張されたquotationと、commentの記法を定めるとよさそう。

  • '(ABC) $=$ 'A'B'C $\to$ #65#66#67
  • '(A'(BC)D) $=$ 'A''B''C'D $\to$ #65#35#54#54#35#54#55#68
; #32!                         NOP
; ':'-'3'2'? '$ !              DROP
; '~'#'8'+'~'#'3'- 'c !        NEGATE LOGICALLY
; '#'1'0'. 'a !                PRINT NEWLINE

; ''f'.''i'.''z'.''z'. 'f !    PRINT FIZZ
; ''b'.''u'.''z'.''z'. 'b !    PRINT BUZZ
; ''0'+'. 'p !                 PRINT DIGIT
; 'v'^'$ 'r !                  ROTATE QUEUE

MEMORY ON QUEUE
#1^$    FIZZ
#1^$    BUZZ
#0^$    TEN
#1^$    ONE
#1^$    COUNT

;
    MEMORY ON FUNCTION AREA
    ''; '''p''? ''n '!
    ''; '''; '''n ''! ''N '!

    FIZZ
    'v
    ''; ''f''N ''$''#''1 '#'1 '!
    '';        ''#''1''+ '#'0 '!
    ':'#'3'-'c'? '^'$

    BUZZ
    'v
    ''; ''b''N ''$''#''1 '#'1 '!
    '';        ''#''1''+ '#'0 '!
    ':'#'5'-'c'? '^'$

    TEN
    'v
    '';            '#'1 '!    SKIP IF ZERO
    ''; '':'''n''? '#'0 '!
    ':'c'? '^'$

    ONE
    'v
    ':''n'?
    ''; ''$''#''0 ''r''r''r''v ''#''1''+ ''^''$ '#'1 '!    CARRY
    ''; ''#''1''+                               '#'0 '!
    ':'#'9'-'c'? '^'$

    'a    NEWLINE

    'v
    ''; ''';'''l''! '#'1 '!    REMOVE FUNCTION L
    ''; ''#''1''+   '#'0 '!
    ':'#'1'0'0'-'c'? '^'$
    ''l'?    NEXT LOOP
'l!
l    BEGIN LOOP

raw

組込みでない関数がdefaultでは何もしない関数として扱われる(仕様?処理系依存?)ようなので、大文字で書いたCOMMENTはそのままにしていてもよい。

; #32!
; #58#45#51#50#63 #36 !
; #126#35#56#43#126#35#51#45 #99 !
; #35#49#48#46 #97 !

; #35#49#48#50#46#35#49#48#53#46#35#49#50#50#46#35#49#50#50#46 #102 !
; #35#57#56#46#35#49#49#55#46#35#49#50#50#46#35#49#50#50#46 #98 !
; #35#52#56#43#46 #112 !
; #118#94#36 #114 !


#1^$
#1^$
#0^$
#1^$
#1^$

;

    #35#53#57 #35#51#53#35#52#57#35#52#57#35#53#48#35#54#51 #35#49#49#48 #33
    #35#53#57 #35#51#53#35#53#51#35#53#55 #35#51#53#35#52#57#35#52#57#35#52#56 #35#51#51 #35#55#56 #33


    #118
    #35#53#57 #35#49#48#50#35#55#56 #35#51#54#35#51#53#35#52#57 #35#49 #33
    #35#53#57        #35#51#53#35#52#57#35#52#51 #35#48 #33
    #58#35#51#45#99#63 #94#36


    #118
    #35#53#57 #35#57#56#35#55#56 #35#51#54#35#51#53#35#52#57 #35#49 #33
    #35#53#57        #35#51#53#35#52#57#35#52#51 #35#48 #33
    #58#35#53#45#99#63 #94#36


    #118
    #35#53#57            #35#49 #33
    #35#53#57 #35#53#56#35#51#53#35#52#57#35#52#57#35#52#56#35#54#51 #35#48 #33
    #58#99#63 #94#36


    #118
    #58#35#49#49#48#63
    #35#53#57 #35#51#54#35#51#53#35#52#56 #35#49#49#52#35#49#49#52#35#49#49#52#35#49#49#56 #35#51#53#35#52#57#35#52#51 #35#57#52#35#51#54 #35#49 #33
    #35#53#57 #35#51#53#35#52#57#35#52#51                               #35#48 #33
    #58#35#57#45#99#63 #94#36

    #97

    #118
    #35#53#57 #35#51#53#35#53#51#35#53#55#35#51#53#35#52#57#35#52#56#35#53#54#35#51#51 #35#49 #33
    #35#53#57 #35#51#53#35#52#57#35#52#51   #35#48 #33
    #58#35#49#48#48#45#99#63 #94#36
    #35#49#48#56#63
#108!
l

書き易いから上記でもって満足してしまっているが、漏らしている面白さがあれば教えてほしい。