したらばTOP ■掲示板に戻る■ 全部 1-100 最新50 | |
レス数が1スレッドの最大レス数(1000件)を超えています。残念ながら投稿することができません。

おちゃめくらぶ掲示板

1416御茶目菜子:2012/12/09(日) 23:56:01
1画面プログラムは取捨選択が重要
11月23日にプチコンでテキストエディタ「PETIT EDITOR」を作りMEM$の編集をしたり短い
プログラムを作ったりができるようになったのだけどそれを活用できるようなプログラムを
作ってないので作ろうと思ったにょ。
テキストエディタがあるならやっぱりプログラミングということで1画面のリストサイズに
収まるプログラミング言語のインタープリタを作ることにしたにょ。
そこでターゲットとなったのが難解プログラミング言語にょ。
難解プログラミング言語は多くの種類があるけどシンプルなものが多いため小さいサイズで
実現が可能なものも多いにょ。
その中でターゲットに選んだのがBrainfuckにょ。

これは、命令そのものがシンプルだけど奥が深いためにょ。
このBrainfuckはインタープリタそのものは簡単にできるにょ。
ということで、可読性重視で最小限の機能のみを搭載したものをプチコンで作ってみたにょ。

ACLS:CLEAR
MAX=30000:DIM P(MAX)
L=LEN(MEM$)-1
FOR I=0TO L
P$=MID$(MEM$,I,1)
 IF P$==">"THEN C=C+1:IF C>=MAX THEN C=0
 IF P$=="<"THEN C=C-1:IF C<0 THEN C=MAX-1
 IF P$=="+"THEN P(C)=P(C)+1:IF P(C)>255 THEN P(C)=0
 IF P$=="-"THEN P(C)=P(C)-1:IF P(C)<0 THEN P(C)=255
 IF P$=="."THEN ?CHR$(P(C));
 IF P$==","THEN GOSUB @GETCHAR
 IF P$=="["THEN GOSUB @WHILE
 IF P$=="]"THEN GOSUB @WEND
NEXT
END

@GETCHAR
K$=INKEY$()
IF K$==""THEN @GETCHAR
P(C)=ASC(K$):RETURN

@WHILE
IF P(C) THEN RETURN
N=0
FOR J=I TO L
 P$=MID$(MEM$,J,1)
 IF P$=="]" THEN N=N-1
 IF P$=="[" THEN N=N+1
 IF !N THEN I=J:J=L
NEXT
RETURN

@WEND
IF !P(C) THEN RETURN
N=0
FOR J=I TO 0STEP -1
 P$=MID$(MEM$,J,1)
 IF P$=="]" THEN N=N-1
 IF P$=="[" THEN N=N+1
 IF !N THEN I=J:J=0
NEXT
RETURN

可読性重視であるため無駄が多いけどリスト短縮をすれば容易に一画面に収まりそうにょ。
ただし、ここで1つ問題があるにょ。
それは、すでにプチコンではえいださんがBrainfuckのインタープリタを作っているという
ことにょ。
いくら1画面というサイズであっても遙か前に作られたものより劣るものであったら作る
意味は半減してしまうにょ。
しかし、このえいださんが作ったインタープリタは初代プチコンが発売されて間もない頃
(昨年5月)であるためプチコンmkIIのホームメニューには対応してないという点があるにょ。
そして、私が参考として他者が作ったjavascriptで動作するBrainfuckのインタープリタを
いくつか試してみたけどえいださんが作ったものにはポインタの値が分からないというのが
やはり個人的にはかなり気になったにょ。
あと操作性の面も気になったにょ。

というわけで、作るものの方向性は決まったにょ。
「mkIIのホームメニューに対応させる」「実行中の様子を分かりやすくする」「操作性を
良くする」という点を重視することになったにょ。
ホームメニューに対応させるには1回ごとにRUNをするのではなく繰り返して実行を可能にする
必要があるにょ。
そのためCLEARは最初にしか使用できず、初期化を行うためリストがやや長くなるにょ。
それとえいださんと同じくMEMリソースファイルをロードして実行させるだけではなく直接
入力も可能にしようと思ったにょ。
えいださんは起動時にその両者を振り分けを行っていたけどホームメニューに対応するため
にはそれではいけないにょ。
メニューで選択というのもプログラムが長くなってしまうため厳しいにょ。

そこで考えたのが自動選択にょ。
同じ入力場面でファイル名を入力すればロード、コードを入力すればそのコードを実行という
ものにょ。
これは幸いにしてBrainfuckは命令で使う文字ががプチコンのファイル名で使える文字と
被ってないため単純にASC関数で判断可能にょ。
しかし、問題はASC(A$)とした時にはNullの場合だとエラーになってしまうにょ。
LINPUTではなくINPUTにすればそんな問題はないけどINPUTではBrainfuckで「,」を使う
必要性があるためできないにょ。
それと、PETIT EDITORで非常に優れていると私が感じている点である空打ちによる実行は
INPUTではなくLINPUTを使わないと実現できないからね。
空入力の際にASC(A$)がエラーになるという問題はあらかじめN$にCHR$(0)を入れておいて
ASC(A$+N$)とすることで克服できたにょ。
これによって、Aボタンの空打ちで「前回入力したコードを再度実行」というえいださんの
インタープリタでは実現されてない機能も実現することができたにょ。

次に実行中の様子の分かりやすさだけどやはり大きいのはポインタの値の表示にょ。
これは別に難しいことはなく現在の値を表示するだけにょ。
しかし、1画面プログラムにおいては多数のものを表示するとLOCATEだけでも馬鹿にならなく
なってしまうにょ。
また、カーソルはGFILLで描画しているけど実行中のコードとポインタの2カ所にカーソルを
描画しなくてはならないためGFILL命令が2つ必要になるというのも1画面プログラムでは
辛くなるところだけどそれよりも辛いのがカーソルの座標を求めなくてはならないという
ことにょ。
2カ所のカーソルのX、Y座標、つまり4つの座標において固定ステップの整数化が必要になって
くるにょ。
単なる整数化であれば、FLOOR (A) は 0OR A で済むのだけどこれが32単位で整数化(つまり、
32、64、96・・・)であれば (0OR A/32)*32 とする必要があるにょ。
これでは1行に収まらない行が出てきたため 0OR A よりもさらに短縮できる整数化の方法を
用いているにょ。

操作性においては、実行速度可変式が絶対条件にょ。
えいださんのBrainfuckインタープリタはウエイトを0〜9フレームに設定できるけど初期値が
4になっているのだけどボタンの長押し対策がされてないためそれより速くしようものならば
すぐに0に達してしまうにょ。(一番使えそうな1〜3が設定するのが困難)
ということで、1画面でボタンの長押し対策をするのは大変だし、速度を一気に変えたい場合
にはボタンを何度も押すのは不便であるため各ボタンに速度を割り振ることにしたにょ。
これによって実行速度は自由に変えられるようになったにょ。
また、上記の空打ちで前回実行したコードがそのまま実行できるというのは非常に大きいにょ。
やはり、1回実行するたびにロードしなおしなんて非常に面倒だし、(コードの直接実行の
画面だけではなく)ロード画面のファイル名入力行に前回実行されたコードが表示されて
いるためRUNをして、そのコードを削除して、ファイル名を入力というのを1回ごと行うのは
私には耐えられなかったにょ。
ということで、操作性においては十分なできになったと思うにょ。

そうしてできたのが、このPetit Brainfuckにょ。
http://ww5.tiki.ne.jp/~ochame/petitcom/2page.htm#brainfuck
http://www.youtube.com/watch?v=QA4aqgKYQ48
ただし、上記の3つのポイントがクリアできた反面で「,」命令の搭載は見送りで多重ループは
不可になったにょ。
これは現在可能なリスト短縮テクニックを駆使してもどうにもならなかったけど「,」命令を
使う機会はあまりないし、追加は非常に容易であるため問題ないにょ。(操作性や画面表示
関係はそう簡単にはいかない)
また多重ループにおいてはMEMリソースを使う以上は255文字が限界となるため多重ループが
不可欠になるような複雑な処理は書けないだろうと判断したのでそれほど問題はないと
思われるにょ。
個人的にはこの命令の一部が非実装となったデメリットよりも上記の3つをクリアできた
メリットの方が遙かに大きく感じるにょ。

とはいえ、やっぱり多重ループを使いたいとか言う人は自分で実装するのも1つの手にょ。
そのための解説ページも作ったにょ。
http://ww5.tiki.ne.jp/~ochame/petitcom/brainfuck.htm
このページにはBrainfuck入門やサンプルコードなども書いているため参考になるのでは
ないかと思われるにょ。




掲示板管理者へ連絡 無料レンタル掲示板