プチコン4 まとめWiki

SBDBGLIB & SB++

パンくずリスト

2020年5月18日投稿 / 投稿者 : うつりきまぐれ (りょうたんぽ) / タグ : 投稿プログラム うつりきまぐれ ツール ライブラリ

概要

これは SBDBG をラップして自分のプログラムから取り敢えず文字列からコンパイル・実行できるようにしたライブラリです。 OTY_SBDBG が別にダウンロードされている必要があります。SBDBGLIB には SBDBG.LIB というライブラリがあり、初期化用 DEF で別スロットに読み込みます。

また、このライブラリには私が適当に、ただ勿論便利になるよつに考えた上位互換言語 SB++ を解釈するように SBDBG を改造して読み込む機能があります。というかこちらの方がメインです。元々 SBDBG を直接改造して独自構文を組み込んでいましたが、変更点がわかりづらいのとまたアップデートに対応するため、プログラムからソースコード操作で改変する形にしました。

ところで普通に SB++ を SB にトランスパイルできないことにいま気がつきました。配布された SB++ プログラムを実行するときも SBDBGLIB と OTY_SBDBG がいるというのは鬱陶しいですね...

つかいかた

ライブラリを読み込む

  1. LOAD ”SBDBGLIB/SBDBG.LIB”,1
  2. EXEC 1
  3. SBDBG_INIT 2,#TRUE

SBDBG_INIT の第1引数は SBDBG を読み込むスロット、第2引数は SB++ を有効にするかを示します。

プログラムを実行

  1. DIM SUCCESS=SBDBG_EXEC(”BEEP 70”)

SBDBG_EXEC はプログラムをコンパイルして実行します。パースかコンパイルの時点でエラーが起きた場合は #FALSE 実行が正常に終了した場合は #TRUE を返します。

SB++ の構文

DEF 式

DEF 式 (DEF expression) は、式中に DEF を記述できる機能です。式中の DEF が評価されると別スロットにランダムな名前の DEF が生成されて、その名前が返されます。

DEF 式は次のように使います。

  1. DIM FUNC=DEF HELLO
  2.  ? ”こんにちは”
  3. END

ここで FUNC は文字列変数なので CALL で呼び出したり SPFUNC などに指定することができます。また DEF 式は変数に代入せずに、そのまま引数の中に記述することもできます。

ただし一部のケースでは DEF「文」として解釈されないように、それ自体を囲む括弧がないとエラーとなることがあります。下の例では SPFUNC の2番目の引数が省略されて、次に DEF「文」が続いていると構文解析の都合上解釈されてしまいます。

CALL や RETURN などや SPFUNC などの引数に直接 DEF 式を記述するときは括弧が必須です。ただし (括弧を伴う) 関数の引数に指定する場合や変数に直接代入する場合は曖昧さがないので括弧は必須ではありません。

  1. ’これはエラー
  2. SPFUNC SP,DEF
  3.  ...
  4. END
  5. ’こうする
  6. SPFUNC SP,(DEF
  7.  ...
  8. END)
再帰呼び出し

DEF 式での名前はその内側でのみ参照できます。また、DEF 式内ではその DEF 名と同じ名前のローカルな文字列変数が、その DEF を指すようにセットされています。

また SELF という名前のローカル変数が同様にその DEF を指すため、匿名 DEF でも再帰呼び出しが可能です。( 匿名 DEF については次の項を参照 ) 従って、DEF 式内で SELF という名前の変数を宣言するとエラーとなります。

  1. DIM FACT=DEF F(X)
  2.  IF X==1 THEN RETURN 1
  3.  RETURN X*CALL(F,X−1)
  4. END
  5. ’同じ
  6. DIM FACT2=DEF(X)
  7.  IF X==1 THEN RETURN 1
  8.  RETURN X*CALL(SELF,X−1)
  9. END
  10. ?CALL(FACT,5)
匿名 DEF

再帰呼び出しの必要がなければ、DEF の直後の名前は省略できます。その場合、関数の括弧や可変長引数や OUT は DEF キーワードの直後に書きます。

  1. DIM F1=DEF()
  2.  RETURN ”こんにちは”
  3. END
  4. ? CALL(F1)
  5. DIM SUM=DEF * OUT S
  6.  S=0
  7.  DIM I
  8.  FOR I=0 TO DEFARGC()−1
  9.   S=S+DEFARG(I)
  10.  NEXT
  11. END

引数が 1 で OUT 引数が 0 の匿名 DEF 式は想定通りに動作しません。これは、引数をもたず名前をもつ DEF 式とも解釈されるあいまいな構文になるためです。

  1. DIM F=DEF A
  2.  ...
  3. END

この場合は後者の解釈となります。A は DEF 名で、引数はありません。前者のような DEF 式は _ のようなダミーの名前をつけます。この名前は被っていても問題ないので、使用することのないダミーの名前は一律 _ で構わないと思います。

変数のキャプチャ

DEF 式は、DEF の外側の変数を参照できます。

  1. DIM NAME$=”吉野”
  2. DIM GREET=(DEF _ GREET$
  3.  ? GREET$;”, ”;NAME$;”!”
  4. END)
  5. CALL GREET,”ハロー”

上の例のように DEF 式が通常の DEF 内にある場合に、その DEF 内のローカル変数を参照できます。

注意点として、キャプチャ変数が1つ以上あると DEF 式の動作が非常に重いです。タイミングを考えて使いましょう。

完全にグローバルな変数は保存されず、DEF 式の呼び出しの時点の最新の値となります。DEF 式の外のローカル変数の値は保存されて、DEF 式が呼び出されるときに復元されます。ただし、現在の実装は DEF 式が呼び出されるたびにその値が復元されるので、以下のように DEF 式の外のローカル変数を変更して、また次回の呼び出しまで保持されることを意図するプログラムは正しい動作をしません。これはバグなので後に修正します。

  1. DEF BATTERY()
  2.  DIM S=100
  3.  RETURN (DEF(X)
  4.   S=S−X
  5.   IF S<0 THEN
  6.    ?”バッテリーがきれた”
  7.   ENDIF
  8.   RETURN S
  9.  END)
  10. END
  11. DIM USE=BATTERY()
  12. ? USE(30) ’ 70
  13. ? USE(58) ’ 42 (!?)
  14. ? USE(10) ’ 90 (!?)
  15. ? USE(26) ’ 74 (!?)
暗黙的な CALL

DEF 式を直接呼び出すたびに CALL が伴うのは煩わしいですね... そこで 暗黙的な CALL (Implicit CALL) という機能があります。

これは、文字列変数が存在し、その変数が命令や関数であるかのように呼ばれている場合、自動的に CALL に変換する機能です。

  1. DIM HELLO=DEF
  2.  ? ”こんにちは”
  3. END
  4. HELLO
  5. DIM FACT=DEF F(X)
  6.  IF X==1 THEN RETURN 1
  7.  RETURN X*F(X−1)
  8. END
  9. ? FACT(5)

それぞれの DEF 式の呼び出し、また再帰に暗黙的な CALL が使用されています。たとえば最後の行は ? CALL(FACT,5) に変換されます。

UFCS

UFCS (Unified Function Call Syntax) とはD言語に同名の機能があります。これは FUNC(OBJ,A,B) を OBJ.FUNC(A,B) と書けるというものです。これがそのまま SB++ にあります。

  1. ? ”あかさたなはまやらわ!”.MID$(2).LEN().SQR()

あんまり意味のないことをしてますが、幾らでもチェーンできます。括弧のネストが減り、視線の方向と処理の流れが一致するため見やすいコードになると思います。

バグ情報

DEF 内のローカル変数

以下のプログラムは USE 呼び出しのたびに S が 100 にリセットされてしまいます。そのうち直します。

公開キー

プチコン4 公開キー
4JK3483AV
選択肢 投票
ダウンロードしたよ  0 
なんだこれ  0 
まあいいんじゃない?  0 
めっちゃいいかも?  1 
だめだなぁ  0 
そんなことよりプチコンバータ  1 
投票によってタイムスタンプが更新されないようにしました

コメント

この作品に対するコメントがあれば一言どうぞ〜。


メニュー 【4】

過去シリーズWiki

ヘルプ

リンク

最近の更新

最近の人気ページ

オンライン情報

  • 現在同時に 2 人がこのサイトを見ています
  • このページはこれまでに 551 回、本日は 2 回、昨日は 0 回閲覧されました

ページの先頭に戻る

表示モード : [ スマホ・3DS対応表示 | クラシック表示 ]
PukiWiki 1.4.7 Copyright © 2001-2006 PukiWiki Developers Team. License is GPL. Based on "PukiWiki" 1.3 by yu-ji
ページの処理時間 : 0.027 秒 | このページの最終更新 : 2020/05/23 (土) 14:29:31 (554d) | ログイン
Copyright(C) 2011-2019 プチコンまとめWiki