Tenshi中关于数据结构部分的设计

Tenshi脚本语言的设计

太阳神上 posted @ 2008年4月11日 14:56 in Tenshi with tags Tenshi , 1288 阅读

  已經有好幾個星期没寫博客了,這幾個星期裏也没什麽事。不過我的那個Tenshi語言有了很大的進展,基于glib-2.0的解釋器已經實現了表達式的堆棧處理代碼,而整體的框架也搭建得差不多了。不過還是有很多方面的問題没有解决,很多設計上還遠不穩定,中間又改了很多。

  其中一個很重要的問題就是數據結構的處理,由于C語言的標准并没有標准的容器,要想管理符號表之類的東西要麽自己寫,要麽用第三方的庫。我一直想找一個通用性强,效率又高的庫。GNU的庫本來是最好不過了,它的glib裏有我想要的所有容器,充分地滿足了我的要求,不過它的庫是都是動態庫,而且要運行我的程序,居然要四個動態庫,如在Windows中需要libglib-2.0.dll,libgmodule-2.0.dll,iconv.dll和intl.dll。雖然都不大,可是却不是我需要的,後來找了一個CTL(C Template Library),也就是用C語言的宏來實現類似C++模板類,雖然文件很小,但功能實在是太少,後來又找了個ylib,這個很不錯,還是國人的作品,作者對C++的STL很熟悉,這個庫實際上就是C語言的STL,而且還是静態庫,滿足我的要求,可是那裏對哈希表的操作我一直没搞明白,所以後來想想還是用glib,後來基于glib的我寫得差不多了,後來發現本來我想用的很多功能glib能提供的我也不用花很大力氣,還是學學人家lua,完全的Ansi C,一點廢話都没有。而glib裏面的有些容器還是不符合我的要求,其實就容器而言,最好用的還是STL,可惜那是C++的東西,既然要用C語言實現,STL還是割愛好了。用C語言來實現數據結構總是不如C++的類來得方便。

  最終,我又决定,還是自己寫,去掉glib,不過glib給我的啓示還是很大的,我後來寫的函數大多都是類似glib的命名方式,如棧的壓棧操作,我定義為tns_stack_push,這種前輟+域+操作,并且以下劃綫分割,全用小寫字母,看起來很順眼。除了命名上的啓示外,還有一個很重要的Quark處理也是引自glib。

  關于Tenshi中的模塊處理,因為在Linux和Windows中關于動態庫的加載的系統調用是不同的,最早我是准備兩個不同的文件,在Makefile裏設置,如unix裏定義為module.unix.c,在Windows裏這個文件命名為module.win.c,後來我使用了條件編譯,這様就可以寫在同一個文件裏,再後來,我用宏來統一加載動態庫的接口,如打開動態庫的操作,我這様定義

  1. #ifdef unix
  2. #define tns_module_open(name) dlopen(name,RTLD_LAZY)
  3. #elif WIN32
  4. #define tns_module_open(name) LoadLibrary(name)
  5. #endif

  感覺這種處理是最簡單和最優雅的。以前看C語言的頭文件,發現預處理特彆多,覺得很惡心,現在也覺得這様做的必要性了。

  關于語言是動態類型還是静態類型的問題,因為現在主流的脚本語言都是動態類型的,所以最早的設計就是動態的,這様棧的數據一定包含有類型信息,後來,這種設計實際上增加了很多執行期的負擔,每次執行時都要進行類型檢查,後來我還是想出了一個折衷的方案,類似boo脚本的設計,變量本身是有類型的,這個類型一旦確定,就不能再更改,一切賦予它的值則必須兼容這種類型,我覺得變量的類型變來變去事實上加大了很多出錯的幾率,這使得寫起來容易,調試起來難,而事實上調試的時間遠比寫的時間長,所以在這方面我用的是静態類型,但是類似C的静態類型本身的缺點是在執行期就完全丢掉了類型信息,有時很不便,我有一種特彆的解决方案,即Tenshi脚本的函數調用分為兩種,一種可以在編譯成中間碼時就執行,而第二種要執行時才執行,而這二者對程序員是透明的,完全由庫决定。這是Tenshi脚本的一個很大的特色。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter