2008年12月26日

Get Windows Information in REBOL 2.x

寫了一段REBOL 2.x程式, 可以用來進行許多OS相關的判斷.

Kernel32.DLL: load/library %Kernel32.dll

MultiByteToWideChar: make routine! [
CodePage [ int ] ; 65001 for UTF-8
Flags [ int ]
MultiByteStr [ char* ]
MultiByteLen [ int ]
WideCharStr [ char* ]
WideCharLen [ int ]
return: [ int ]
] Kernel32.DLL "MultiByteToWideChar"

User-profile: dirize to-rebol-file get-env "Userprofile"

make-sure-c-string: func [ str [ string! ] ] [
if #"^@" <> last str [ append str #"^@" ]
]

get-wide-str: func [ str [string!] /local tmp ans ] [
make-sure-c-string str
insert/dup tmp: copy "" #" " 2 * length? str
MultiByteToWideChar 65001 0 str -1 tmp length? tmp
ans: copy/part tmp any [
attempt [ skip find tmp "^@^@^@" 3 ]
attempt [ skip find tmp "^@^@" 2 ]
tail tmp
]
]

GetWindowsDirectory: make routine! [
Buffer [ char* ]
Size [ int ]
return: [ int ]
] Kernel32.DLL "GetWindowsDirectoryA"

insert/dup buffer: copy "" #" " 200

GetWindowsDirectory buffer length? buffer
OS-drive: rejoin [ %/ copy/part buffer find buffer ":\" "/" ]

make-elements: func [name count type /local result][
if not word? type [type: type?/word type]
result: copy "^/"
repeat i count [
append result join name [i " [" type "]" newline]
]
to block! result
]

OS-VERSION-INFO-EX: make struct! OS-VERSION-INFO-EX-SPEC: compose/deep [
OSVersionInfoSize [ int ]
MajorVersion [ int ]
MinorVersion [ int ]
BuildNumber [ int ]
PlatformId [ int ]
(make-elements 'ch 128 #"@")
ServicePackMajor [ short ]
ServicePackMinor [ short ]
SuiteMask [ short ]
ProductType [ char ]
Reserved [ char ]
] none

OS-VERSION-INFO-EX/OSVersionInfoSize: 148 + 8

GetVersionEx: make routine! [
VersionInfo [ struct! [ (OS-VERSION-INFO-EX-SPEC) ]]
return: [ integer! ]
] Kernel32.dll "GetVersionExA"

GetSystemDefaultLCID: make routine! [
return: [ integer! ]
] Kernel32.dll "GetSystemDefaultLCID"

GetLastError: make routine! [
return: [ int ]
] Kernel32.DLL "GetLastError"

if zero? GetVersionEx OS-VERSION-INFO-EX [
alert rejoin [ {Error When Calling "GetVersionEx". Error Code =} GetLastError ]
exit
]

os-ver: rejoin [OS-VERSION-INFO-EX/MajorVersion "." OS-VERSION-INFO-EX/MinorVersion]
;SP?: OS-VERSION-INFO-EX/ServicePackMajor

sp: to-string copy/part at third OS-VERSION-INFO-EX 21 128
sp: copy/part sp find sp #"^@"

Win-Vista?: Win-2003?: Win-XP?: Win-2000?: false
OS?: switch/default os-ver [
"6.0" [ Win-Vista?: true "Win-Vista"]
"5.2" [ Win-2003?: true "Win-2003" ]
"5.1" [ Win-XP?: true "Win-XP" ]
"5.0" [ Win-2000?: true "Win-2000" ]
] [ none ]

SP0?: SP1?: SP2?: SP3?: SP4?: false

sp?: switch sp [
"" [ SP0?: true 0 ]
"Service Pack 1" [ SP1?: true 1 ]
"Service Pack 2" [ SP2?: true 2 ]
"Service Pack 3" [ SP3?: true 3 ]
]

HOME-Ed?: not zero? (OS-VERSION-INFO-EX/SuiteMask and 512)
EMBEDDED-Ed?: not zero? (OS-VERSION-INFO-EX/SuiteMask and 64)

zh-TW?: zh-CN?: zh-HK?: zh-MO?: zh-SG?: ja-JP?: ko-KR?: vi-VN?: th-TH?: false

lang?: switch/default skip to-hex GetSystemDefaultLCID 4 [
#0404 [
zh-TW?: true "zh-TW"
]
#0804 [
zh-CN?: true "zh-CN"
]
#0c04 [
zh-HK?: true "zh-HK"
]
#1404 [
zh-MO?: true "zh-MO"
]
#1004 [
zh-SG?: true "zh-SG"
]
#0411 [
ja-JP?: true "ja-JP"
]
#0412 [
ko-KR?: true "ko-KR"
]
#042a [
vi-VN?: true "vi-VN"
]
#041e [
th-TH?: true "th-TH"
]
] [ none ]

2008年12月25日

利用Delect設計方言

REBOL具有豐富的Literal,除了可以提高程式的「可讀性」和「可寫性」之外,也可以方便設計方言(dialect,也就是所謂的DSL)。這一點是其他語言遠比不上REBOL的。

以往,設計REBOL方言的方式,是利用Parse函數。在REBOL 3.0之後,又多了一個方式,就是利用Delect。Delect是DEcode diaLECT的意思。REBOL內部的方言,許多都是利用Delect做出來的。

大多數的方言,都會定義一些關鍵字(keyword)。每個關鍵字後面可以有0到多個參數。有些時候,這些參數出現的次序無所謂,因為透過型別就可以推測出參數的意義。例如:「Circle 100x100 50」與「Circle 50 100x100」,雖然100x100和50的出現次序不同,但是都可以讓我們認為這是要表達一個「圓心在100x100」,半徑是50的圓。所以處理這類方言的時候,值的次序不重要,重要的是值的型別,這種方言用Delect設計會相當容易。

良好的方言,應該要方便學習與使用。放寬參數的次序,可以幫助使用者學習與使用方言。以上面的Circle例子來說,使用者就不需要牢記,到底是先寫半徑再寫圓心,還是先寫圓心再寫半徑。

關於Delect的用法,請見DocBase的這篇說明。我以後也會寫文章說明Delect的詳細用法。

2008年12月2日

REBOL 3.0 alpha 18

這個版本新加入三名核心測試成員。未來在修正完畢他們所找到的Bug之後,將會更廣泛地釋出,讓更多人試用。關於2008/11與2008/12的進展與規劃,請見這篇文章。

2008年12月1日

文法剖析器


昨天晚上整理磁碟機,找到一個很久以前用REBOL寫的一個程式:「文法剖析器」。我希望在REBOL 3.0釋出之後,能有時間重寫這個程式,並完善它。

RebTalk

REBOL語言設計者Carl今天對GUI Test World釋出新版的REBOL 3.0,並開發了一個名為RebTalk的Reblet程式。這是REBOL 3.0的第一個Reblet。