ラベル バグ の投稿を表示しています。 すべての投稿を表示
ラベル バグ の投稿を表示しています。 すべての投稿を表示

2015年8月24日月曜日

V3.10のバグ

V3.10(まで)の不具合です。すべてV3.40で解決されました。もうないだろうと思っていてもまだまだ出てくるもので(T_T)/

・forに対応するnextが存在しないままプログラムが終わっていると、落ちる
例えば、
for i=0 to 2
//  next
はnextがないので、本来はエラーが発生するはずですが、落ちます。エラー処理で発生行を特定しようとするのですが、この場合、エラー発生行が存在しないのでこうなります。for側にてエラーを発生させれば良さそうですが、現在の処理では無理なので。
V3.10まででの回避策は、対応するnextをちゃんと記述することです。

・whileに対応するendwhileが存在しないままプログラムが終わっていると、落ちる
・repeatに対応するuntilが存在しないままプログラムが終わっていると、落ちる
・switchに対応するendswitchが存在しないままプログラムが終わっていると、落ちる
・funcに対応する endfuncが存在しないままプログラムが終わっていると、落ちる
・enum/fenum対応する endenumが存在しないままプログラムが終わっていると、落ちる
   forと同様の理由で発生します。

・10次元配列を宣言するとシステムエラーが発生する
 9次元までしか使えませんでした。また、エラーメッセージが正しくありませんでした。

・新規作成からファイルを保存しようとすると、ファイル名入力欄に「.!」と表示されている
  それを消してからファイル名を入力してください。

・デバッグ処理が残っている
 内部的にデバッグ用処理が有効のまま残ってました。
 実行には関係ありません。

・cardInit()でカードパターンファイル名がSHIFT-JISに対応してない
  V3.10まででは、UTF-8で指定していれば問題ありません。

・行番号付きプログラムが正しく読めない
 正確には、読み込めますが行番号が削除されません。
 V3.10で改行コードがCRのみのファイルに対応した時のエンバグです。
 サンプルではrandomWalk.basが実行できません。
 なお、行番号のあるなしは1行目で判断します。1行目に行番号がない場合、2行目以降に行番号があっても削除されません。それは仕様です。

・設定の旧表示互換がONにならない
 V3.10でのエンバグですが、潜在的にプログラムに問題がありました。
 英語版ではもう1つ、X68互換関数のON/OFFが変更できませんでした。

・プログラムソースの1文字目がサロゲートペア文字の場合、フォント選択画面で文字が表示されない
 正しく動くプログラムでは事実上ありえないけど。

・symbolt()でサロゲートペア文字を含めた時、正しく表示されない

・一部外部関数で、実行時エラーが発生しているはずなのに無視されてしまう
 X68互換関数は、内部的にはX-BASICで書いた処理を手動でObjective-Cにコンパイルしたような記述になっていますが、その中で呼び出している外部関数内でエラーが発生した時、無視されます。外部関数はエラーチェックを言語コア側に任せているため、コアを通さず呼び出した場合にはエラーがチェックされなかったわけです。

・テキスト文字が小さくなりすぎることがある
ディセンダーや文字表示のゴミ対策のため、文字が小さくなることが多くなりました。
計算式を見直し、できるだけV3.00以前と同じくらいになるようにしました。
ただし、行数が減る場合があります。

・beep2()のfloadonlyが無効
 毎回ファイルを読みに行ってた

・removeTouchArea()してもタッチエリアが開放されたように見えない(もしくはタイミングがずれて開放されるようにみえる)

・bitmapImgLoad()/bitmapTileImgLoad()に引数指定時の動作がおかしい
 引数とり込み処理がおかしかった。
 全部省略した時のみ正常動作したはず。

・print 整数数字時の前のスペースの入り方が/68と異なる
/68 iOS
"A";100;"B" A 100 B
"A";-100;"B" A-100 B A -100 B
実はぺけ-BASICと同じ。
floatはあってた(ぺけ-BASICは異なる)

・print "〜"; // とすると表示後改行が入ってしまう
 print "〜"; /* や
 print "〜";://なら改行は入らない

・最終桁で全角文字を表示するとき、先に改行されない
 今までは表示してから改行してた(故に、右端1文字は欠けることがあった)

・スプライト関数が無効の時、互換関数内のスプライト関係関数を呼び出すと異常になる
呼び出し先のスプライト関数が無効になっているのだから、それを使う関数も無効にしなければいけませんでした。

・enumの値を式を使って記述するとき、一部演算子を2つ以上連続で使っているとエラーになる
 たとえば、
enum
 C= 1+2+4// OK
 D= 1 or 2 and 4// エラーが発生する
 E= (1 or 2) and 4 // OK
endenum
となります。or/andだけではなく、比較演算子やshlなど複数あります。
 修正を試みましたが、中間コードコンパイルの核に関わる部分で、単純な修正では無理だとわかり ました。そのため、これは仕様とします。
 ()をつけると大丈夫ですので、そういう記述をおねがいします。

・ファンクションキーの表示座標が実は間違っていた
 今回clearance引数の追加に伴い処理を見なおした時に発覚しました。
 ファンクションキーを多段表示した時に間が空きすぎるのはそのためでした。

・bitmapOpen(fdirect=ON)で落ちることがある
 クリアサイズを求める変数が不定になっててエリアをオーバーしてクリアしてしまうことがありました。グラフィックを実行すると落ちることがあるのはほとんどこれが原因ではないかと。

・全くの初回起動時、V3.0以降で追加された設定が初期化されてない
 だから使えなくなっていました。

・サンプルのloadFromURL_zipExpand.basがエラーを発生する
これはサンプルのバグではなく、それが読み込もうとしているサーバー側のファイルの問題でした。すでに修正されています。

・zipExpand()で、Windows環境下で作られたZip内の日本語ファイル名ファイルが展開できない
Zip内のファイル名の文字コードは作られた環境に依存するようです。Windows上で作ったものはSHIFT-JISでした。ZipライブラリがUTF8にしか対応してなかったので自動判別して展開できるようにしました。

・jpegHeader()が正しい情報を返せないことがある
 想定外の格納され方をされていたためです。
 X68時代に作ったヘッダー解析処理では、現在の画像に対応しきれてませんでした。

・pngHeader()が正しい情報を返せないことがある
 PNGファイルはiOS内部に入れられるときヘッダーが改変される(多分リソース内のみ)ようで、情報の位置がずれてました。それに対応しました。

・motionGetRotation()/compassGetData()/symbol(,ht)/fontSize(,wy)/getWidth(,fontWx,fontWy)でfloat変数に値を返すときに落ちることがある

・モーション関数を使った後にメモリが確保されたままになっている
モーション関数を使ったプログラムを何度も実行するとメモリエラーが発生する可能性があります。

・motionEnd()を呼び出さないでendするとモーション機能が動いたままになってしまう

・emailSend()でzip圧縮した時のファイル作成日時がおかしい
これは使っていたライブラリ(ZipArchive)のバグでした。

・str$(正の数字)で前にスペースが入る
例えばstr$(1)=" 1"(len=2)になります。X-BASIC/68では前のスペースは外れるので"1"(len=1)です。これは浮動小数点数値でも同じです。なお、負数の場合は前に"-"が入ります。

2015年7月16日木曜日

v3.00のバグと仕様について

X-BASIC for iOS v3.00には、以下のように不具合のように見える「仕様」があります。

(1)エラーをタップしてジャンプするとき、その行が画面に出てこない
これはiOS8のバグだと思います。
エラー行をUITextView:scrollRangeToVisible:というメッセージを使い画面内に入るように画面スクロールさせていますが、このスクロールが途中で止まってしまうことがあります。そうなった時はもう1回タップしてください。たいがいは2回もタップすると表示される範囲にスクロールされます。

(2)エディタの「編集」と「リスト」を切り替えた時、両者の表示位置が一致してない。
基本的にはUITextViewに自由に行スクロールする機能がないことが原因ですが、(1)のバグも一因ではあります。
UITextViewではないエディタモジュールがあればいいのですけど。まあ、エディタの問題は、これからはprogloaderがあるので、外部エディタを使っていただければとm(_ _)m。

(3)fopen()のリターン値がX-BASIC/68と異なる
X-BASIC/68のプログラムを移植した時、fopen()でエラーが出る場合の原因は間違いなくこれです。
iOS版は正常が>=1でエラーが0ですが、/68は正常が>=0でエラーが-1です。
開発時に参照した文献が間違っていたことと、その後テストのために移植したプログラムがリターン値でエラーチェックをしていなかったため発見が遅れ、その間にサンプルでこのリターン値で数多く作ってしまった為、現状そのままになってしまっています。
要望が多ければ/68に合わせますし、それはそれで移植したプログラムに不具合が出てきそうなので、fopenX68()を新設するかもしれません。->V3.10で/68に合わせて変更しました。


(4)ファイル名またはディレクトリ名にサロゲートペア文字を入れると正しく処理されない
Objective-Cライブラリの問題であり、表示と違ってめったにありえないことなので対処しないことにしました。おそらく、Mac/iOS上でフォルダの指定を可能にしているほとんどのプログラムが同様の問題を抱えていると思います。


以下は不具合です。すべてV3.10で修正済みです

(1)改行コードが&h0dのBASICプログラムが読み込めない。
テストしたファイルの中にこれがなかったので確認出来てませんでした。
XcodeというかMac上は&h0aだし、X68/Windowsは&h0d,&h0aなので。 X1で作られたものが&h0dのみでした。
とりあえずの回避方法は、何かしらのプログラムで改行コードを置き換えてください。 たいていのエディタは改行コード指定ができるでしょう。 V3.10で修正済みです。
なお、freads()はちゃんと&h0dに対応しています。

(2)freads()で、最大文字列長を超える文字列を読み込んだ時に落ちる(と思う)
(3)freads()で、EOF(&h1a)を読み込んでも読み取りが終了しない
         なので、&h1aの後ろにデータが有った場合、それも読み込んでいた。
    (&h1aは単なる1バイトデータとみなされていた。)
(4)freads()で改行なしでファイルが終了する場合のリターン値が/68と異なっていた
   「例」TEST&h1aというファイルを読んだ場合
     /68  st="TEST",リターン値=-1(エラーが返る)
        iOS  st="TEST",リターン値=4(読み込めた文字列長が返っていた)
       次回のfreads()で-1が返った。
  freads()は/68でも細かい仕様が未公開だったので、この際調べたら差異がありました。

(2)UTF16で4バイトになる文字が正常表示できない
これはiOSというかObjective-Cライブラリのバグに近い仕様が原因です。例えば
 ♣▒🐓🍅

という絵文字群は、UTF16で前2文字が2バイト、後ろ2文字が4バイトです。
(後ろ2文字は環境によっては表示されないかもしれません。)
(Objective-Cの内部文字コードはUTF16です。)

それぞれのlengthを取ると([@"〜" length]),全て1になるべきが、
文字lengthUTF8UTF16
1E2 99 A326 63
1E2 96 9225 92
🐓2F0 9F 90 93D8 3D DC 13
🍅2F0 9F 8D 85D8 3C DF 45
となります。後ろ2文字の長さが異常です。また、characterAtIndexで1文字取り出しても2バイトごとの取り出しになります。

これらはサロゲートペアという文字です。サロゲートペアは一部の文字を4バイトに拡張することで扱える文字範囲を拡大したものだそうです。先のlengthやcharacterAtIndex、substringWithRange:NSMakeRange(i, 1)はそれに対応できていません。

このため、それらを使って1文字づつ表示しようとしているX-BASICの内部処理では正常に表示できませんでした。

なお、X-BASIC for iOSのutf8Mid$()など文字列切り出し関数群やutf8Len()は正しく動作しています(これらは独自に開発した処理を使っている)。

(3)font()で等幅でないフォントを指定した時=全角を含め1文字1桁のとき、幅が広いフォントを表示した時文字が重なってしまう
サロゲートペアで表示される文字の中には、普通の文字に比べ幅広い文字が存在していました。最も幅の広そうなフォントで計算するようにしました。

(4)同指定時、文字を重ねた時に、前の文字の一部が残ることがある。
1文字分の領域幅を消さなければいけないのに、フォントの幅で処理してました。
ただし、縦幅に関してはV3.00で対応したディセンダーの問題でもあるので、width()でディセンダーを有効にすることで対処できます。
→これに関してはV3.10でも完全に修正しきれてません(横方向は直ったけど縦方向が)。(5)の修正を急ぐためです。

(5)RUN直後に落ちることがある
外部関数設定処理に問題があり、ワークを破壊してました。動いていたほうがむしろ奇跡です。次バージョン開発中にこれが顕著になり、散々調べた結果ようやく原因が特定出来ました。malloc()で確保したワーク内の破壊はProfileでもわからないので時間がかかりました。

(6)keyRepeatTime()でリピートなし及び即時リピートの設定ができない
引数の処理に問題がありました。

(7)font()でpointSizeの指定が無視されている
これも引数の処理に問題がありました。常に省略時と同じになってたはずです。

特に(5)が致命的なので、これを直した+αのV3.10を公開しました。また、fopen()のリターン値もX68に合わせて変更しました。fopen()を使ったプログラムを作成されている方は、ご注意ください(互換モードは用意してあります)。



2015年7月15日水曜日

X-BASIC for iOS V2.96のバグ

X-BASIC for iOS V2.96までで発見されたバグは、以下の通りです。
  1. E付き浮動小数点数数字をstr$()すると落ちることがある
  2. 文字列用usingの中に'.'があるとエラーが発生するか落ちる
  3. 文字列長が設定値−1文字までしか設定できない
  4. 長めの文字列にコード変換系関数を使った時、落ちることがある
  5. スプライトのパターン0を定義した時、画面左上に表示されてしまう(消せない)
  6. テキスト画面で属性付き表示をすると描画カスが残ることがある
  7. YES/NOを引数にする関数が、正しい値を受け取れてなかった(誤動作した)
  8. YES/NOをリターン値にする関数が、正しい値を返してなかった
  9. 実行時に0除算すると落ちる
  10. using "〜"の後ろに:なしに// または /*でコメントを記述した時usingフォーマットエラーになる
  11. 変数名がenum定数と同名の時にもエラーが発生しない
  12. 正のfloat値をprintした時、数値の前にスペースが入らない
  13. wait()中にBreakすると、次回RUN以後wait()がすぐ帰ってくるようになる 
  14. motionGetRotation()/compassGetData()が正しい値を引数の変数に返さない
  15. loadFromURL()でエラーが発生時の処理がおかしい
  16. エディタで行番号とソースがずれる
  17. iOS8でアクションシート表示中に設定を押すと、以後一切の操作ができなくなってしまう
  18. 「編集」「リスト」切り替えすると、ソースコードの最後に空行が+1行されてしまう
  19. 編集中のプログラムをリストから削除して、再起動した時に「新規作成」と表示されない
  20. iOS8で、再起動時、前回選択していたソースを忘れることがある
  21. iOS8(iOS7でもなるかも)で外部キーボードモードの時、検索のキャンセルを押しても検索枠が消えない
  22. 同一グラフィックページに対するbitmapImgLoad()を短期間に呼び出すと、描画が遅れるまたは欠けることがある
最後の1つ以外はV3.00で解決されました。
最後の1つは高速描画の弊害なので、今のところ解決手段が見つかってません。

上記のバグのため動かないサンプルがありました。
 また、サンプル自体のバグも修正してあります。

・・・

V3.00では64ビット化に合わせてソース全体の見直しをしました(内部バッファー制御を一新しています)。またサンプルをもう一度全部実行しなおしていきました。SHARPのX-BASIC(/68) Ver2.0マニュアルも実家で発見したので、そこにあったサンプルも取り込みました。
その過程で多数のバグが発見されました。
すべてiOS版のみのバグです。

これで言語系のバグはほぼとれたのでは、と思います。まだ残ってましたのでV3.1で修正してます。

次バージョンではデバッグ系を強化したいと思ってます。
MZ-80K(SP-5030)レベルの簡易MMLも実装したいんだけど、出来るかどうか。

追伸:
X1-BASICからの移植をしやすいようにもしようかな思ってますが、 実家にあったはずのマニュアルが見当たりません。
「不要なのであげてもいいよ」という方がいらっしゃればお知らせください (PDFでも可)。

2014年1月24日金曜日

ぺけ-BASICの外部関数のバグについて&ぺけ-BASIC v0.02.002

X-BASIC for iOSの元になったぺけ-BASICは、外部関数にもバグがいるようです(教えていただきました)。

X-BASIC for iOSは、本体こそぺけ-BASICのソースを解析した結果を元に作っていますが、外部関数はX-BASIC/68の仕様を元に完全に一から書き上げたので、気がつきませんでした。

関数名 dskf()
バグ 大容量メディアに対して使った場合、リターン値が正しくないことがある。
詳細 この関数はDOSコールの_DSKFREの返す値を
使用可能なクラスタ数.w * クラスタ当りのセクタ数.w * セクタ当りのバイト数.w
と乗算してリターン値を作っていますが、ここで使っている68000の命令がすべてmulu.w =.w*.w->.l演算であるため、3つ目の乗算で.lで得られた値の.w部分のみ使ってしまい、 このバグが発生します。
要するに、使用可能なクラスタ数.w * クラスタ当りのセクタ数.w が16ビットで収まらない ような大容量デバイスに対して使用すると、バグります。
iOS版での状況 iOS版には存在しない関数です。

関数名 fread()/fwrite()
バグ リターン値が、X-BASIC/68は読み書き出来た「要素数」であるのに対し、 ぺけ-BASICではバイト数が返ってきています。
詳細 これはDOS _READ/_WRITEのリターン値をそのまま返しているためで、 リターン値を要素サイズで割る処理が抜けています。
iOS版での状況 iOS版は/68と同じく要素数を返します。 ちなみに、Cの関数であるfread()/fwrite()も要素数を返します。

これら3つの外部関数とfloat変数の初期化バグ、および一部エラーが発生した時に OSがトラップを発生させるバグを修正したぺけ-BASICを一応作りましたので、ご入用の方は、「こちら」からどうぞ。

2014/01/26追記:
このバージョンで、68000機上で「未宣言変数があると落ちる」と言う報告をいただいています。
(68030では発生しないらしい。)
この問題は、オリジナル版をうちの環境でアセンブルした物でも発生するので、開発環境の差異による問題かもしれません。現在調査中です。しばらくお待ちください。
(直せない可能性も有り。)

2014/01/27追記:
どうやらこの問題はオリジナルからあるようです(と言うか、オリジナルでも発生しました)。
ワークエリアが足りない時も落ちます。
なので、私の追加した部分以外にも調査の手を広げる必要があるので、さらに時間がかかりそうです。(今余り時間が取れないので。というか、食が足りてなくてやる気が出ない方が強いかも。
差し入れ絶賛募集中。酒類も可^_^;)

2014/01/27追記2:
とか書きながら、ビール飲みつつ解析してたらバグを突き止められて修正。
ご褒美、絶賛受付中(^_^;)

2014/01/31追記:
まだトラップが発生するという報告があります。
68030では発生せず68000だけということですが、当方では68000でも発生せず原因不明です。

2014/02/05追記:
問題はBASIC本体側ではなく、FM音源ドライバを組み込んでいないのにMUSIC.FNCを組み込んでいたためわかりました。と言うことで、ここの公開版は問題なしです。
でも、起動時や正常終了時にはエラーが発生せず、エラー時のみ引っかかるのかは、さらなる解析が必要そう。

2013年7月2日火曜日

V2.2のバグとその回避法

X-BASIC for iOS v2.2に以下のバグが発見されました。

1. print/printsで先頭文字が全角の時、それ以下に半角文字があっても全て全角幅で表示されてしまう

これはV2.2でのみ発生します。
当面の回避法は、print/prints()の表示文字列中、全角と半角を分離してください。

print "ABCあいう"
 ↓
print "ABC";"あいう"


2. 単項演算子と2項演算子を含む式で「システムエラー」もしくは「式の型が異なる」が発生する
「例1」
   if a>=-128 and a<=-1 then {
   }

 「例2」
  a=(a>=-1 or a<=128)

回避するには、負数を()でくくります。
「例1」
   if a>=(-128) and a<=(-1) then {
   }
「例2」
  a=(a>=(-1) or a<=128)

 もしくはifを個別に分割します。
   if a>=-128 then {
       if a<=-1 then {
       }
   }

・・・ではありますが、いずれもV2.3で修正済みですので、バージョンアップするのが一番手っ取り早いです(^_^)。

この他の、V2.2までに発生していてるバグは以下の通りです。
  1. dim floatに{}で初期値を指定するとエラーになる
  2. 配列を引数に持つ関数の中で、子関数にその配列を渡すときエラーが発生する
  3. 配列の2次元目以降の要素番号チェックが正しくない
  4. 外部関数内で発生したエラーのメッセージが表示されない
  5. 配列要素番号が(通しで)32767を超えると動作が異常になるかエラーが発生する 
  6. グローバルもしくはローカルの変数領域が64KB以上必要なとき、うまく確保できない
  7. emailSend()で添付ファイルをzipで圧縮するとき、正しいzipファイルが生成されない 
  8. randomize()がrandomise()になってる(綴りミス)
  9. 実行時エラーの指す行がずれている
4番まではV2.3で修正されました。5~8はV2.4で修正されました。
実行時エラーは小規模プログラムでは直りましたが、大規模プログラムでは 大幅にずれる問題が解決できていません。


2013年6月16日日曜日

V2.1のバグとその回避方法

X-BASIC for iOS V2.1に以下のバグが発見されました。
  1. vpriority()が即時反映されない
  2. tBackgroundAlpha()/gBackgroundAlpha()/kBackgroundAlpha()が即時反映されない
  3. gTransform()で変形をかけた状態で終了した時、次回の実行時に画面サイズがおかしくなる
  4. inputで入力中の文字が表示されない
  5. dim floatに{}で初期値を指定するとエラーになる
  6. 配列を引数に持つ関数の中で、子関数にその配列を渡すときエラーが発生する
  7. 配列の2次元目以降の要素番号チェックが正しくない
  8. 外部関数内で発生したエラーのメッセージが表示されない
  9. 実行時エラーの指す行がずれている

最後の5つ以外はV2.2で修正されますが、当面の回避策は以下の通りです。
  1. vpriority()を設定した後に以下の関数を呼び出すことで即時反映されます。
    func allPageUpdate(page;int)
      print " ";:// ここはテキスト表示に問題ないように変更すること
      apage(GPAGE0):line(0,0,0,0,0)
      apage(GPAGE1):line(0,0,0,0,0)
      apage(GPAGE2):line(0,0,0,0,0)
      apage(GPAGE3):line(0,0,0,0,0)
      apage(page)
    endfunc
    例えば、vpriority(page,GPAGE0,GPAGE1,GPAGE2,TPAGE):allPageUpdate(page)
  2. 関数呼び出し後、それぞれの画面を書き換える関数を呼び出すと同時に反映されます。
    たとえば、tBackgroundAlpha():print " "など。
  3. プログラム終了時にgTransform()として変形を解除しておけば回避できます。
  4. これはV2.1で画面表示を高速化したことによるエンバグです。回避策がありません。V2.2をお待ちください。
  5. (要素番号)=で1つ1つ代入してください
  6. これは回避策がありません。V2.3をお待ちください。
  7. 要素番号チェックは自前で行ってください。
  8. これは回避策がありません。V2.3をお待ちください。
  9. ほとんどの場合、実行時エラーは1つ下の行を指しています。その下の行がコメント行の場合は、さらにその下を指します。



また、以下は仕様です。
  • 内部関数で配列を引数にする時、そのサイズ指定にenum定数を使えない
    「例」func f(masu(WW,WW);int):// エラー発生
これは、以下の理由に依ります。
  1. 内部関数の名前と引数の登録は、コンパイルの前処理で行われている
  2. enum定数の決定はコンパイル中に行われる
  3. このため、内部関数定義中は定数が未定
これを解決するのは極めて難しく、使われる頻度と実装やデバッグの労力を考えた結果、 「仕様として制限する」ことにしました。 あしからず、ご了承ください。

どうしても即値で記述するのが嫌なら、要素数そのものを省略すればいいでしょう。
   「例」func f(masu(,);int)
(次元を表す ',' は省略不可。)

2013年5月8日水曜日

V1.71のバグについて

現在までにわかっている、X-BASIC for iOSのバグをお知らせします。

・usingを使わないfloat表示が正しくないことがある
・usingを使いfloatを表示するときで、小数桁を0桁にした時、小数→整数位で四捨五入されない
・iOSバージョンに小数位があるとき(iOS6.1など)、getSystemversion()の返してくるiOSバージョンがおかしい
・keyRepeatTime()で正しく設定されない

以上は、内部的にfloatとdoubleの受け違い、または変換時の有効桁欠損が原因です。


・3.5インチデバイス(iPod touch/iPhoneの3/4)で画面下部が少し切れている
 このため、ファンクションキーが表示されません。
 4インチと間違っていました。

・tborder()が次にprintで何か表示するまで表示されない
tborder(〜):print " "とすることで回避出来ます。

・float配列を使うと落ちることがある
・circle()でのstartAngle/endAngle指定が効いてない
・プログラムの選択を繰り返すと落ちることがある

・いくつかのサンプルBASICプログラムが正常動作しない

現在審査中のV2.0では修正されます。
しばらくお待ちください。

2013年4月23日火曜日

ぺけ-BASICのバグについて(見つけ次第更新)

X-BASIC for iOSの開発に際しては、「ぺけ-BASIC」を大いに参考にさせていただきました。

中間コードにコンパイルしてから実行するという構造もそこからいただきました。

「ぺけ-BASIC」は物理的に速くないX68000上で、出来るだけ速くX-BASICを動かそうとする優秀なプログラムですが、いかんせんオールアセンブラな上にメンテナンス性が考慮されてない記述だったため、解析はきわめて難しいものでした。
(68000というMPUやアセンブラHASに強く依存する記述や、定数化してない即値記述が非常に多いなど。)

原作者の方が「バグ取り以外はしない」とおっしゃられていましたが、実際のところ「それ以外出来ない」状況にあったというのが真実でしょう。
少しでもいじろうもんなら他の部分に影響を与える、そんな、ある意味「絶妙なバランス」でした。

今回の開発ではX-BASIC/68だけでなくぺけ-BASIC上でも動作確認をしましたが、
いろいろとバグを発見しました。今更ではありますが、ここに公開しておきます。
もちろん、iOS版ではすべて解消しています。
  • floatの変数初期化サイズが足りていない
    要するに宣言しただけでは0.0にならないと言うことです。
    float変数を使う場合、明示的に初期化しないと正しくない結果をもたらします。

  • float定数のみ f1 * -f2で「無効な命令が発生する」
    「例」4.321*-5.01
    X-BASIC/68はOK
    int/charはOK

  • 単項演算子が連続すると式エラーが出る
    not -/-notなど
    float/int/charすべて
    X-BASIC/68はOK
    ()を付ければ回避できる

  • usingの結果および書式指定の方法がX-BASIC/68と異なる
    "+##"の結果
    "\.#"の結果(整数部なしで\をつける)
    ^^^^^指定時に,を付けたらエラーになる
    X-BASIC/68ぺけ
    -^^^^^^^^^^-
    +****+

  • printの数値表示時の桁位置が違う
    X-BASIC/68符号(+の時は空白)+数値+空白1文字
    ぺけ空白+符号付き数値+空白

  • e表現floatが使えない
    3.14e10など

  • then {またはelse {の後に:/*と書くとエラーになる
    コメントを書く場合、:なしで/*と書かなければならない
    内部的にはマルチステートメントの処理に問題がある
    X-BASIC/68でもelse {で発生する。

  • tan(pi(1.0/2.0))の計算結果がおかしい
    6.2184311638237E+015となってしまう。
    正解は1.6331239353195E+016
    X-BASIC/68も同じなので、XM6 typeG/xm6i、もしくはfloat2.xのバグかもしれない。ちなみに、sin()/cos()で計算すると正しい。
    sin(pi/2)/cos(pi/2)=1.6331239353195E+016
    以下も正しい。
    tan(pi/4)=1
    tan(pi/8)=0.4142...
  • 配列を引数に持つ関数の中で、子関数にその配列を渡すときエラーが発生する
    func testFunc(n;int,s(4,1);str)

    subFunc(s) :// ここでエラーが発生する
    endfunc
    func subFunc(s(4,1);str)

    endfunc
    引数配列の要素数は省略が可能=呼び出し時に確定されるため、コンパイル時には未定のままになっています。 ところが、その確定処理が抜けているためエラーが発生しています。
    なお、要素数を省略してない場合もエラーになります。

  • 関数の引数名が関数名と同じだったとき、func文で変数二重宣言エラーが発生する
    関数の引数名は関数名と同じにしないでください。
    なおこれはX-BASIC/68では発生しませんが、ぺけ-BASICで発生します。
    バグというより仕様です。両者の数少ない非互換部分の1つです。

  • func message(n;  int , rt;  int)のように、引数型を示す;の後にスペースを入れると内部エラーが発生する。
    スペースを取るとOK。X-BASIC/68では発生しない。

  • using "~"の後ろにスペースを置くとエラーが発生する
    using "###";a /* OK
    using "###" ;a /* エラー
    X-BASIC/68では発生しない。

  • 0除算をしてもエラーが発生しないことがある
    例えば、以下の時にそうなります。
    print "1/0=";1/0 /* エラーが発生するはずなのに1と表示される
    /*
    int a=0
    int b=0*(1-1#/(a*a))
    print "b=";b  /* 2147483647と表示される
    /* ちなみに
    print 0*(1-1#/(a*a)) /* #NANと表示される
    int b=0*(1-1/(a*a))  /* とするとエラーが発生する
    どういう条件ではエラーが発生しないのかまでは突き止めてませんが、どうも整数はエラーになっても実数演算で0になるときはエラーにならないような感じです。
    なお、X-BASIC/68ではすべてエラーになります。

以下は、ソース内に見つけた不具合らしき部分です。実動作では確認してません。
  • 以下の物が32767個を超えると異常動作を起こす
    変数の個数(グローバル/ローカル別)
    ラベル最大数
    行番号の実利用数
  • 行番号に65535を使うと異常動作する
  • func で配列引数を取った時、dim(n,m の後に)以外の文字があると其の分ワークが無駄に消費される
    たぶん暴走はしないけど、おかしい
  • 配列の初期化
    {}の個数が宣言した要素数より多い時、中間コードエリアを破壊する
    一応後でエラーを出す処理は入っているが、そこまで行くまでに(メモリ内容を破壊して)異常動作を起こす可能性がある
  • 関数で配列引数のとき3次元以上の配列を与えてもエラーが発生しない
    次元判定に使うレジスタを間違っている
  • 配列への代入がおかしい
    レジスタの参照を間違っているので。
    たぶん ぺけ-BASIC はたまたま動いてるだけ。
  • 文字列定数加算をしたとき
    その合計サイズが256バイトを超えるとワークを破壊する
    その領域を別の文字列変数がすでに使っている場合、その内容が化ける
    加算を繰り返すと其の都度新しいワークを割り付けるため、メモリ不足に陥りやすい
  • 拡張配列を関数の引数にしたとき、要素数テーブルを過剰にクリアしてしまう
  • 配列宣言で、閉じ括弧がなくソースが終わったときにハングアップする。
    多次元配列で,の後がなくソースが終わったときも同様。
なんにしても、動作を考える上でぺけ-BASICが参考になったのは紛れもない事実です。
この場で感謝いたします。

ーーーーーーーーーーーーーーーーーーーーーーーー
おまけ
X-BASIC/68のバグ。

・引数なし関数の定義をするとき、func f( ) とカッコ内にスペースが有るとき、呼び出し側で「式の記述が間違っています」エラーが発生する

f() :/* ここで発生

引数なしの時は ()としなければならない。
 ぺけーBASICでは発生しない。

・プログラムファイルの終端を&h1aだけで判断しているため、それがないファイルを読み込ませた時、プログラムにゴミが入ることがある。
変な行が途中に入ってエラーが発生する事が多い。
これはバグというより「仕様」。