September 22,2009

boo 的 macro(1)

boo 的 macro 跟 C/C++ 的 macro 很類似,都是在編譯時期就被替代為實際的代碼。不過 C/C++ 只做簡單的替換,boo 的 macro 則是會在編譯時期時進行編譯並且執行、進行替換。
#
# dontimes.boo
#
import System
import Boo.Lang.Compiler

macro DoNTimes:
    n = DoNTimes.Arguments[0] as Ast.IntegerLiteralExpression
    print n.GetType().ToString() # n is IntegerLiteralExpression
    print DoNTimes.Body.GetType().ToString() # DoNTimes.Body is Block
    blocks = Ast.Block() # create new block add DoNTimes.Body n times.
    for i in range(Convert.ToInt32(n.ValueObject)):
        blocks.Add( DoNTimes.Body )
    return blocks

DoNTimes 3:
    print "foo"

print "Press any key to continue . . . "
Console.ReadKey(true)
使用 booi 來執行,你會看到下面的訊息,foo 被印了三次:
Boo.Lang.Compiler.Ast.IntegerLiteralExpression
Boo.Lang.Compiler.Ast.Block
foo
foo
foo
Press any key to continue . . .
那這跟用 for 迴圈來跑有什麼不同? 首先用 booc 來編譯:booc -t:exe dontimes.boo,在編譯的時候,你會發現第9行跟第10行的訊息被印了出來:
Boo.Lang.Compiler.Ast.IntegerLiteralExpression
Boo.Lang.Compiler.Ast.Block
這證明了 boo compiler 會在編譯時,把 macro 的部份先拿出來編譯,然後在編譯的時後去執行 macro,對程式碼進行替換。然後你會發現執行 dontimes 的時候,只印了 foo 三次。 用 reflector 來看,可以看到:
private static void Main(string[] argv)
{
    Console.WriteLine("foo");
    Console.WriteLine("foo");
    Console.WriteLine("foo");
    Console.WriteLine("Press any key to continue . . . ");
    Console.ReadKey(true);
}
代碼只有三行Console.WriteLine("foo");,這很清楚的說明了 booc 在編譯時,就把 macro 的內容替換進去了。


Posted by elleryq at 樂多Roodo! │17:36 │回應(0)引用(0)Boo
樂多分類:網路/3C 共同主題:.Net/Mono 工具:編輯本文
標籤:boo
Ads by Roodo! 

引用URL

http://cgi.blog.roodo.com/trackback/10000813