Giraffe+ 0.5.20.351

Downloadページへ

前リリースからの変化

  • パーサを少し最適化
  • スクリプトのオブジェクトからC++の変数への暗黙の型変換の仕様を少し変更
  • 標準入力をイベント化
  • Object.max, min, Numbers.max_limit, min_limitを定義
  • ダブルクオーテド空文字列(ようするに"")をパースできなくってたのを修正
  • Iostreamを実装
  • String.parse_into_xmlを定義
  • Interpreter.constantsに保持される名のメソッドはパース時に実行されるようにした
  • LITERALを最後の引数を返すメソッドとしてInterpreter.constantsに定義
  • ダブルクオーテド文字列において\(バックスラッシュ)に続く連続する空白文字(TAB or SPACE)を無視するようにした
  • __FILE__をパース時にパース中のファイル名に置き換えることにした
  • LocaleオブジェクトとしてC++のstd::localeクラスを定義
  • std::isspace(T, std::locale)等を数値オブジェクトのメソッドとして定義
  • RegexとStringオブジェクトのsplitメソッドを、引数が空文字列の場合に空文字列をひとつ含む配列を返すようにした
  • gc.dllを少し最適化
  • Alt+S, Alt+T, Alt+Rの逆順ソートスクリプトをsettings/keyに置いておいた

パーサを少し最適化

ch_pをorしてたのをchset_pにした。

スクリプトのオブジェクトからC++の変数への暗黙の型変換の仕様を少し変更

asの仕様の変更です。テスト

const外し

今までは、例えば、asをint constのオブジェクトに対してしていた場合、constを外すためにcopyした値を返してました。それを、asの場合はどうせC++へ値渡しされるのだからと、危険な感じもしますが、reinterpret_castして返すようにしました。

参照

asをint constオブジェクトに対してやった場合だけ失敗とするようにしました。asをint constのオブジェクトにするのは可能です。doubleを値渡しすることになりします。複数のクラスを継承している場合、親への参照キャスト時に、asの戻り値と引数が違うアドレスを指すためにエラーになる問題への対応です。
これにより、文字列の出力を参照渡しして得るC++関数に、as_Stringを持つオブジェクト、例えばRegex等を渡してもエラーにならなくなりました。自動的に検出されないバグとなります。

ようするになにがどうなったのか

無駄な安全性より効率性と利便性を選びました。

標準入力をイベント化

Giraffe.Event.Stdin(strOut)です。引数のstrOutはその時点でのCoutの未出力文字列です。

input:: ''
'文字列入力'.out input.in

とすれば「文字列入力」という文字列が引数になり、戻り値の文字列がCinに解釈されてinputの値になります。Cinの解釈が介入するため、さまざまな問題があります。実用品ではないと考えてください。

問題

数値を求められたのに非数値を入力したり、スペースを含む文字列を与えたりした場合、Cinが入力をバッファリングすることになります。そうなると、次のCin.<<もしくはObject.in使用前に入力バッファのクリアをしないと、次のそれらはGiraffe.Event.Stdinを介さず、そのバッファ値から入力を得ることになります。
これはistreamの仕様のようなものです。

StdinDialog

設定ダイアログのsetup/StdinDialogで、標準入力要求時に入力ダイアログが出るようになります。少し遊んでみると欠陥が理解できます。

Object.max, min, Numbers.max_limit, min_limitを定義

それぞれ、std::max, min, std::numeric_limits::max, minです。

ダブルクオーテド空文字列(ようするに"")をパースできなくってたのを修正

たぶん、"#{}"実装時になってたんだと思います。空文字列にはシングルクオートを使いがちなので今まで気付きませんでした。

Iostreamを実装

Ios, Istream, Ostream, Iostream, Streambuf, Ifstream, Ofstream, Fstream, Filebuf, Istringstream, Ostringstream, Stringstream, Stringbufで全部です。面倒だったので放置してましたが、やってみればすぐに終わりました。さすがにテストは書いてませんが。
ios_baseとbasic_iosIosにまとめました。定数は、Ios.fmtflags等、typedef名のオブジェクトに持たせています。skipws等、マニピュレータは普通にメソッドになってます。

バグ的仕様

Istream.getを定義してしまっているため、Object.getがIstreamから呼べません*1。次のバージョンでget_にでもリーネームすることになると思います。それか、Object.getをObject.@get等、C++の名前と被らない名前も定義し、省略記法はそちらを呼ぶようにするとか、そんな感じでしょうか。

実用性

元々C++のiostream自体がいまいち使い勝手のいいものでもないので、あまり使ってみようと思わないほうが良いです。iostreamを利用した何かを利用するためのものです。

String.parse_into_xmlを定義

gs.exeにあったやつです。文字列をスクリプトとしてパースし、そのパースツリーをXMLにして返します。

Interpreter.constantsに保持される名のメソッドはパース時に実行されるようにした

今まではメソッドであろうと、そのものを値としてリテラル化してましたが、実行するようにしました。これにより、旧言語で出来ていたのに新言語で出来なくなっていたパース時実行ができるようになりました。

LITERALを最後の引数を返すメソッドとしてInterpreter.constantsに定義

リテラル文字列を生成したい場面があります。例えばスクリプトのアイコンを他アイテムのアイコンと合わせたい場合

LITERAL& '他アイテム名'.compose_executee.Target

などとできます。

ダブルクオーテド文字列において\(バックスラッシュ)に続く連続する空白文字(TAB or SPACE)を無視するようにした

複数行文字列のインデントを出来るようにしました。

__FILE__をパース時にパース中のファイル名に置き換えることにした

フルパスへの変換等は無く、パースを求められたファイル名そのままになります。ちなみに、$0はRegexが使用済みです。

LocaleオブジェクトとしてC++のstd::localeクラスを定義

使いそうにないですが、一応。std::locale::global等、スタティック関数もLocale.global等で普通にアクセスできます。

std::isspace(T, std::locale)等を数値オブジェクトのメソッドとして定義

Localeを省略した場合、カレントグローバルロケールが使われます。いい加減なテスト & BOOST_PPを使った実装

RegexとStringオブジェクトのsplitメソッドを、引数が空文字列の場合に空文字列をひとつ含む配列を返すようにした

戻り値の配列はsize > 0を保証されるべきなので。

gc.dllを少し最適化

スレッド数の制限を、std::listを使って解除していましたが、スレッドIDによるルックアップが結構あるみたいなのでstd::mapに変更しました。とはいえ、スレッド数が常に何百もあるわけではないので、あまり意味があるとも思えませんが。

Alt+S, Alt+T, Alt+Rの逆順ソートスクリプトをsettings/keyに置いておいた

こっちのほうが使い勝手がいいですが、昇順では不自然なのでデフォルトにはしてません。

*1:実は今気付いた。