飴屋ぷろじぇくと

 ちょっとカテゴリを分けてみようかなっと。

--.--.--[--] スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

2014.10.09[木] FreeBASIC Compiler

公式
http://www.freebasic.net/
マニュアル(英語)
http://www.freebasic.net/wiki/wikka.php?wakka=DocToc
渡辺氏による上記の邦訳
http://makoto-watanabe.main.jp/freebasic/index.html

元々QuickBasic互換を目指してたとか。
マイナー言語に属するんだと思いますが、最近はオブジェクト指向とか後続の言語仕様を取り込みつつ、「もはやBASICではない」との批判も聞こえそうな勢いで進化中みたいです。
現状でも言語自体は結構強力で、「足りなければ作る」的なアプローチが出来ます。

さて。

UTAUでUNICODE問題が長年の懸案事項なんだけど
・VB6→表示がSJIS経由になるので日本語以外の多バイト文字が文字化けする。回避策はあるが完全対応は難しい
・C++→UNICODEは何とかなっても、そもそもGUIの構築が面倒い。その辺で気力がガリガリ削られる。
それで、FreeBASICではどうかなとお試し中。

問題のユニコードは[WString]という型があるけど、どうも扱い辛い。
C言語での固定配列やポインターみたいになっていて、

Dim w As WString * 32 '固定長のワイド文字列'
Dim x As WString Ptr  'ワイド文字列のポインタ'
x = Allocate(64)      '使うにはいちいちメモリを確保しなければならない'


「これじゃC言語じゃん」ってなる。お気楽文字列変数ってBASICの一番良いとこなのに。
で、いろいろやってみた結果、こんな感じで

[UString.bi]
Type UString
    sa(Any) As UShort
    Declare Constructor()
    Declare Constructor(w As WString)
    Declare Constructor(u As UString)
    Declare Operator Let (w As WString)
    Declare Operator Let (u As UString)
    Declare Operator Cast() ByRef As WString
    Declare Operator [](ByVal i As Integer) ByRef As UShort
    Declare Property Length As Integer
End Type


ショート型の可変長配列を文字列扱いするラッパーを作れば「ワイドでない"String"」と似たような扱いができることが判りました。
結合演算とかは

Dim a As UString
a = "文字列"
a = a + "ユニコード"


とかやると、わざわざ結合演算子を定義してなくとも、
勝手にWStringに変換して代入や結合をしてくれます。
このあたりは良くできてます。コンパイラが優秀ですね。
(「現状たまたま」なのかもしれないので油断できませんが)

まあとりあえず、こんな簡単なら言語仕様に入れてほしかった。

あとはMid関数のWString版にバグがありました。
多バイト文字が全部[?]に化けるもよう。
←WStringそのままでは化けませんでした。自作のUStringを自動変換期待してそのまま渡した場合だった。私のせい
どうもコミュニティが欧米中心のせいかユニコード対応が弱い気がします。
この辺、フォーラムに投稿すれば対応してくれるかもしれないけど、英語ってことでちょっと尻込み中。

なので対応が弱いかどうかは保留。

以下、実装
[UString.bas]
#include "UString.bi"

#Define s2w(s) *Cast(WString Ptr, @(s(0)))

Sub w2s(s() As UShort, w As WString)
    Dim ln As Long = Len(w)
    Redim s(0 To ln)
    Dim i as Long
    For i = 0 To ln
        s(i) = w[i]
    Next
End Sub

Operator UString.Cast() Byref As WString
    Return *Cast(WString Ptr, @(sa(0)))
End Operator

Constructor UString()
    Redim sa(0 To 0)
End Constructor

Constructor UString(w As WString)
    w2s sa(), w
End Constructor

Constructor UString(u As UString)
    This = u
End Constructor

Operator UString.Let (w As WString)
    w2s sa(), w
End Operator

Operator UString.Let (u As UString)
    Dim ln as Long = Ubound(u.sa)
    Redim sa(0 To ln)
    Dim i as Long
    For i = 0 To ln
        sa(i) = u.sa(i)
    Next
End Operator

Operator UString.[](ByVal i As Integer) ByRef As UShort
    Return sa(i)
End Operator

Property UString.Length As Integer
    Return UBound(sa)
End Property

Comment






(編集・削除用)

Trackback

http://utau2009.blog114.fc2.com/tb.php/18-fb63c554

この記事にトラックバック(FC2Blog User)

Copyright © 飴屋/菖蒲

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。