經過這段時間的努力,LuckyScript終于初步具備了我所希望它具有的一些特性,發文慶賀下,雖然總體來說還是個比較簡陋的東西,但作為本人本命年的吉祥物,我不想對它再要求太多了,由于還沒有經過仔細測試,Bug還比較多,所以暫時不會發布,現在只是把它所已經具有的一些特性介紹下,沒什么意外的話,不會再有改動了,以后改進的方向主要是效率方面,說到這里,我得表達下對Lua開發組的崇敬之情,前幾天同事發給我一個專業測試網站的報告
http://shootout.alioth.debian.org/u32/benchmark.php?test=all&lang=all&box=1,里面列出了世界上各種比較流行的語言的效率測試,看過Lua跟c的效率對比后,自己偷偷測試了下LuckyScript..結果可想而知,很簡單的測試,雖然我還沒有優化,雖然我用面象對象的方法組織工程,但這絕不該成為程序效率差別人一個數量級的理由,所以今后會把對LuckyScript效率的改進作為重點.
語法基本上與C++保持一致,沒太多好說的
一.數據定義
關鍵字:var,class,func,new
就如你猜想的那樣,var用于定義變量,class用于定義類,new 用于創建類,在LuckyScript中變量可以是所有東西,無論是數值,函數還是類,都可以賦給一個變量,除非顯式指定需要值復制,不然所有指向一個對象的變量間的賦值都只是傳遞引用,稍后你會看到這樣做的作用,下面的一段LuckyScript代碼能很好的告訴你數據定義的方式.
class Test


{
}

func TestFunc()


{

}

func main


{
var t = new Test();

var array[3] =
{2,"str",3};
var b = t;
}
二、宏定義
LuckyScript支持帶參數的宏定義,如:
#define add(a,b) \
(a + b)

func Main()


{
var sum = add(2,3);
}
三、語句
關鍵字:if,else,while,switch,case,default,for,break,continue
不要懷疑,跟C++完全一致,用法沒有任何區別,恩..也許是有一點區別的,還是以代碼說明問題
var k = 0;

for(var i = 0;i < 10;i ++)


{
for(var j = 0;j < 1000000;j ++)

{
k = k + 1;
}
}
上面的代碼被我用來測試自己腳本跟Lua的效率,循環1000萬次加法操作,恩..測試結果是lua花了0.369秒,luckyScript花了8.902秒,so,相差30倍左右..言歸正傳,在這段代碼中,不要認為i跟j的作用域就是在一個for循環內,我可以付責任地告訴你,在函數返回前,它都是有效的,所以如果你想在這個函數內接下來的代碼中copy這段代碼繼續Happy的循環的話,就會得到i跟j重復定義的錯誤,同理,while跟if也是一樣,另外,為了保持代碼的整潔,LuckyScript強制規定if,while,for后面必須跟著配對的大括號,同時操作數跟操作符之間必須隔開,也就是說,如果你把i ++換成i++也是會得到一個語法錯誤滴
四、跟OO有關的一些東西
關鍵字:class,public,private,protected
1.類定義
在LuckyScript中,你不可以象C++那樣定義自己的構造函數,或者說,LuckyScript中根本就沒有構造函數的概念,但你仍然可以指定類中變量的初始值,如下面代碼所示:
class Test


{
public:
var a;
var b;
};

main


{
var t = new Test(2,3);
}
2、3分別被賦給了Test中的a、b,賦值的順序跟定義的順序保持一致,public,private,protected聲明的作用跟你想的一樣
2、類嵌套
在一個類中允許包含另一個類作為成員變量,可以多層嵌套
class Test1


{
public:
var a;
};
class Test2


{
public:
var b = Test1();
};
class Test3


{
public:
var c = Test2();
};

func main()


{
var t = new Test3();

t.c.b.a = 2;//合法
}
3.繼承
LuckyScript支持單繼承方式,在類成員變量的作用域方面LuckyScript仍然跟C++保持一致,子類可以引用父類的protected成員,但不可以引用父類的private成員,恩..照例貼上一段代碼
class Base


{
public:
var a;
protected:
var b;
private:
var c;
};

class Test : public Base


{
public:
func test()

{
a = 2;\\合法
b = 2;\\合法
c = 2;\\錯誤
}
};
4、操作符重載
LuckyScript支持重載操作符,但這種重載類似于函數調用,在表達式中可能不能得到我們期望的結果,如:
class TestObj


{
public:
func operator + (var otherObj)

{
var retObj = new TestObj();
retObj.mVal = mVal + otherObj.mVal;

return retObj;
}

func operator * (var otherObj)

{
var retObj = new TestObj();
retObj.mVal = mVal * otherObj.mVal;

return retObj;
}


private:
var mVal;
};

func Main()


{
var t1 = new TestObj(2);
var t2 = new TestObj(3);

var t3 = t1 + t2;//相當于t1.operator + (t2),是正確的
var t4 = t1 * t2 + t3;//相當于t1.operator * (t2.operator + (t3)),這大概不是我們想要的結果
}
在對象參與的表達式中,優先級是從右到左的,跟操作符優先級沒關系,你可以認為這是個BUG,但修改它會帶來更多BUG,所以我就讓它這樣了。。有點諷刺的是,主程序對象的操作符重載卻是正常的,也可以作為正常的因子加入表達式中。
5、多態
看到這個標題,你可能會覺得有點奇怪,剛剛似乎沒看到有virtual之類的關鍵字啊..你沒看錯,但在LuckyScript中,這種聲明是多余的,讓我們考慮下面這樣一段代碼:
class Dog


{
public:
func doSomething()

{
print("Wang Wang Wang");
newLine();
}
};

func doSomething(var animal)
{
animal.doSomething();
}

func main
{
var d = new Dog();
doSomething(d);
}
在一門號稱無類型的語言中,上面的代碼是不是看起來很自然,很合理,既然是無類型,那就應該就可以傳遞任何東西,遺憾的是,雖然似乎很合理,但大多數情況下我們都會得到一個函數參數類型不匹配的錯誤,這是一個相當令人郁悶的錯誤(至少在我看來如此),既然無類型,又何來類型不匹配呢?本著為用戶服務的精神,我讓上面這段代碼在LuckyScript中是合法的,既然所有對象都可以傳遞,那么要實現多態的特性也是輕而易舉的了,如:
class Dog


{
public:
func doSomething()

{
print("Wang Wang Wang");
newLine();
return 0;
}
};

class Cat


{
public:
func doSomething()

{
print("Miao Miao Miao");
newLine();
return 0;
}
};

class Value


{
public:
func doSomething()

{
return 10;
}
};

class Test


{
public:
func doSomething(var animal)

{
value = animal.doSomething();
return value;
}
private:
var value;
};

func Main()


{
var cat = new Cat();
var dog = new Dog();
var value = new Value();
var animal = new Test();

animal.doSomething(cat);
animal.doSomething(dog);

print(animal.doSomething(value));
newLine();
}
得到運行結果:

如你所想的那樣,實現這個特性并不像腳本代碼本身看起來那么輕松自然,因為在函數調用前,我們都無法知道animal到底是個什么東西,自然也就無從判斷animal.doSomething()的合法性,所以,一個很直觀的辦法就是為每個不同的調用生成一個版本的函數代碼,就象模板一樣,我就是這樣做的,是的,這個方法既不高效也不巧妙,或許你有更好的idea?
五、一些預定義的命令
__Pause命令,當遇到這個命令時,腳本會無條件保留現場并返回,下次再執行的時候會從暫停的地方開始執行。
__Exit命令,跟C的exit一樣,會直接結束腳本的運行。
六、與宿主程序的交互
基本思想跟lua差不多,用戶可以往腳本添加自己的數據,以棧來互相傳遞數據,這塊還有很多東西在考慮中,所以暫時不寫,留待以后補充
PS:LuckyScript是支持垃圾回收的,所以別奇怪為什么有new沒有delete
posted on 2009-03-13 18:08
清風 閱讀(1925)
評論(7) 編輯 收藏 引用 所屬分類:
LuckyScript