2Bのインタープリターを作成する


12

通訳を書く 2Bの

好き David Cattの難解な言語2Bが。各セルがバイトの独立したテープ(「サブテープ」)であるテープにメモリが保存されています。通訳を書いてください!

言語仕様

公式の仕様はここにあります。この仕様で"は、範囲内の数値0-90と解釈される10)を_意味し、任意の長さの文字列を意味します。各セルはの範囲の値を格納し、0-255オーバーフロー/アンダーフローはBFと同じように折り返します。(ありがとう@MartinBüttner)。テキストを数字0-255に変換するには、ASCIIコードを使用します。私はこれについて詳細を見つけることができないので、テープの長さは255最小であるべきだと言いますが、そうでない場合は編集してください。

+-------------+----------------------------------------------------------------------------------------------------------------------------------------+
| Instruction |                                                              Description                                                               |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------+
| 0           | Zeroes the current cell and clears the overflow/underflow flag.                                                                        |
| {           | If the current cell is zero, jump to the matching }.                                                                                   |
| }           | A placeholder for the { instruction.                                                                                                   |
| (           | Read a byte from the input stream and place it in the current cell.                                                                    |
| )           | Write the value of the current cell to the console.                                                                                    |
| x           | Store the value of the current cell in a temporary register.                                                                           |
| o           | Write the value of the temporary register to the console.                                                                              |
| !           | If the last addition overflowed, add one to the current cell. If the last subtraction underflowed, subtract one from the current cell. |
| ?           | Performs a binary NOT on the current cell.                                                                                             |
| +"          | Adds an amount to the current cell.                                                                                                    |
| -"          | Subtracts an amount from the current cell.                                                                                             |
| ^"          | Moves the subtape up a number of times.                                                                                                |
| V"          | Moves the subtape down a number of times.                                                                                              |
| <"          | Moves the tape left a number of times.                                                                                                 |
| >"          | Moves the tape right a number of times.                                                                                                |
| :_:         | Defines a label of name _.                                                                                                             |
| *_*         | Jumps to a label of name _.                                                                                                            |
| ~_~         | Defines a function of name _.                                                                                                          |
| @_@         | Calls a function of name _.                                                                                                            |
| %           | Ends a function definition.                                                                                                            |
| #_#         | Is a comment.                                                                                                                          |
| [SPACE]     | Is an NOP.                                                                                                                             |
| [NEWLINE]   | Is treated as whitespace and removed.                                                                                                  |
| [TAB]       | Is treated as whitespace and removed.                                                                                                  |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------+

テスト

+0+0+0+0+0+0+0+2)+0+0+9)+7))+3)-0-0-0-0-0-0-0-9)+0+0+0+0+0+0+0+0+7)-8)+3)-6)-8)-7-0-0-0-0-0-0)

出力すべき Hello world!


+1:i:{()*i*}

cat改行なしでプログラムを並べ替えます。


+1:loop:{@ReadChar@*loop*}@PrintHello@@WriteAll@(~ReadChar~(x-0-3<2o^1>1+1>1%~PrintHello~+0+0+0+0+0+0+0+2)-1+0+0+0)+7))+3)+1-0-0-0-0-0-0-0-0)%~WriteAll~<1x:reverse:{<1v1>1-1*reverse*}o-1:print:{-1<1)^1>1*print*}%

最初に名前を受け入れ、次にを押すとReturn、出力する必要がありますHello name名前は入力されたものです)。

そのプログラムの功績はDavid Cattにあります。


私は完全なテストプログラムに取り組んでいます。

ルール

  • 標準的な抜け穴は禁止されています
  • 通訳者は、コメントを除き、すべての仕様を満たす必要がありますが、コメントは必須ではありません。

得点

  • これはなので、最少バイトが勝ちます!
  • インタープリターがコメントを処理する場合は-10バイト。

リーダーボード

これは、通常のリーダーボードと言語ごとの勝者の概要の両方を生成するスタックスニペットです。

回答が表示されるようにするには、次のマークダウンテンプレートを使用して、見出しから回答を開始してください。

# Language Name, N bytes

N提出のサイズはどこですか。スコアを改善する場合、古いスコアを打つことで見出しに残すことができます。例えば:

# Ruby, <s>104</s> <s>101</s> 96 bytes


4
いい案!ここでいくつかの考え:サブテープあたりのセルの数と、実装で使用するサブテープの数を定義してください(または、ある種の適応/無限であるかどうかを指定してください)。入力文字列を0〜255の数値に変換する方法 おそらくASCIIコード?
flawr

回答:


4

Python2、748 736 731 709 704 691バイト

これは楽しい小さな挑戦でした。このコードをさらに短くすることができると確信しています(多分後でそれを行うでしょう)。

from sys import*
w=stdout.write
p=open(argv[1],'r').read()
c,r,s,x,y,t,o=0,0,256,0,0,0,0
g=[[0]*s]*s
e=lambda d:p.find(d,c+1)
def h(i,j=0,k=0):global c,x,y;c+=1;n=1+(int(p[c])-1)%10;l=g[x][y]+n*i;g[x][y]=l%s;o=l/s;x=(x+n*j)%s;y=(y+n*k)%s
a="g[x][y]"
b="[p[c+1:i]]"
l={}
f={}
d={'0':a+"=0",'{':"if "+a+"<1:c=e('}')",'(':"i=stdin.read(1);"+a+"=ord(i)if i else 0",')':"w(chr("+a+"))",'x':"t="+a,'o':"w(chr(t))",'!':a+"+=o",'?':a+"=0if "+a+"else 1",'+':"h(1)",'-':"h(-1)",'^':"h(0,1)",'V':"h(0,-1)",'<':"h(0,0,-1)",'>':"h(0,0,1)",':':"i=e(':');l"+b+"=i;c=i",'*':"i=e('*');c=l"+b,'~':"i=e('~');f"+b+"=i;c=e('%')",'@':"i=e('@');r=i;c=f"+b,'%':"c=r"}
while c<len(p):
    if p[c]in d:exec d[p[c]]
    c+=1

この実装では、ラベルと関数を呼び出す前に宣言(実装)する必要があります。与えられた2つのテストでは完全に機能しますが、残念ながら、言語の作成者が作成した「SayHi.2b」プログラムでは機能しません(関数の宣言の順序を変更した後でも)。この問題は、テープおよびサブテープシステムの理解方法に関係していると思われます。メインテープに沿って移動する場合、対応するサブテープの位置は0にリセットされますか?現時点では、メインテープ上を移動する場合でも、サブテープ上の位置を維持しています。

より読みやすいバージョンは次のとおりです。

#!/usr/bin/python

import sys
w=sys.stdout.write
p=open(sys.argv[1],'r').read()
c,r,s,x,y,t,o=0,0,256,0,0,0,0
# c is the current index in the program string
# r is the return index (for functions)
# s is the size of the tape, subtapes and modulo for ints (max int will be 255)
# x and y are the coordinates in the grid
# t is the temporary register
# o is overflow
g=[[0]*s]*s # initialise a grid 256x256 with 0

e=lambda d:p.find(d,c+1)
def n():global c;c+=1;i=int(p[c]);return i if i>0 else 10 # get the number specified
def h(i):j=g[x][y]+i;g[x][y]=j%s;o=j/s # handle addition and substraction
def m(i,j):global x,y;x=(x+i)%s;y=(y+j)%s # move current cell

a="g[x][y]" # string of current cell
b="[p[c+1:i]]" # key for label or function
l={} # dictionary of labels
f={} # dictionary of functions
d={'0':a+"=0",
   '{':"if "+a+"<1:c=e('}')",
   '(':"i=sys.stdin.read(1);"+a+"=ord(i)if i else 0",
   ')':"w(chr("+a+"))",
   'x':"t="+a,
   'o':"w(chr(t))",
   '!':a+"+=o",
   '?':a+"=0if "+a+"else 1",
   '+':"h(n())",
   '-':"h(-n())",
   '^':"m(n(),0)",
   'V':"m(-n(),0)",
   '<':"m(0,-n())",
   '>':"m(0,n())",
   ':':"i=e(':');l"+b+"=i;c=i",
   '*':"i=e('*');c=l"+b,
   '~':"i=e('~');f"+b+"=i;c=e('%')",
   '@':"i=e('@');r=i;c=f"+b,
   '%':"c=r",
   '#':"c=e('#')"
   }

while c<len(p): # loop while c is not EOF
    # print c, p[c]
    if p[c]in d:exec d[p[c]] # execute code kept as a string
    c+=1 # increment index

編集:コメント処理(-10バイト)を考慮し、1つのエラーで修正します。この実装はネストされた関数呼び出しをサポートしていません(必要な機能であれば実装できます)

Edit2:ハンドラー関数を変更して、加算、減算、セル移動を行いました。より多くのラムダ!:D(「読みやすいバージョン」は現在同期していない可能性があります)

Edit3:コメントを処理するのに5バイトかかることを実感しました(-10を考慮すると)。だから私はちょうどそれを削除しました、それは今では不完全に感じるのは残念です。

Edit4:ハンドラh()内でnの定義をラムダからvarに移動しました


たくさんの人と一緒+a+に参加したほうがいいかもしれないa?また、変数に割り当てる必要がなくなります。
マルティセン

辞書全体の文字列を結合することはできず、文字列ごとに個別に結合する価値がないことを除いてはまあ。文字列をaに割り当てることは、コードにとって実際には役に立たないバイトを獲得するためのトリックです。
バジルヘンリー

私は実際にそれを指定しなかったので、関数の順序について文句を言うことはできないと思いますが、SayHi.2bファイルを機能させようとします。シフト時にサブテープをゼロにリセットするように変更するとどうなりますか?
JimBobOH
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.