银色月光下

漫漫长夜

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  4 Posts :: 7 Stories :: 0 Comments :: 0 Trackbacks

常用链接

留言簿(12)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

c_toy, 是一个以 c语法为借鉴的 动态类型 脚本语言,集成了部分流行脚本语言的特性,虽然之前有做过一些不同的,语法解析, 虚拟机,但都半途而废,我需要把我对动态语言的理解,付诸实现.
 
作为动态语言,它看起来更像是 javascript, 但不管是 javascript, c_toy, 你们都得管c 喊爹!
1. 基本语句
  •  print = std.sys.print; 
  •  for(i=0; i<10; ++i){
  •      print (i);
  •  }

  •  

     

    看看出错的情况,

    编译时错误 



     运行时错误



    这不是错误


     


     

    2.函数,斐波那契 数列的迭代方式

  • function fab(t){
  •     r1, r2 = 1, 1;//像是lua, python的多变量赋值,如果是那个swap的例子就比较有趣了,
  •     for(i = 2; i<t; ++i){
  •         rt, r2 = r2, r1+r2;
  •         r1 = rt;
  •     }
  •     return r2;
  • };
  • print(fab(10) );


  •  

    3.函数用法,斐波那契 函数的递归方式
  • fab = function(t){
  •     if(t == 1)return 1;
  •     else if(t==2) return 1;
  •     else return fab(t-1)+fab(t-2);
  • };
  • std.sys.print(fab(10) );


  •  

    4.闭包函数first class, 作为一个现代脚本语言, 怎可缺少
    对于闭包,虽然一开始,我想携带整个环境,但我最后使用逃逸变量分析, 这相对来说高效一点,
  • bind1st = function(fbin, p1) //这个。。。是c++里 std::bind1st,
  • {
  •     return function(p2){return fbin(p1, p2); };
  • };
  •  
  • add = function(a, b){return a+b;};
  • std.sys.print(bind1st(add, 3)(4) );


  •  



    5.  coroutine,协程也是有的,相对于lua的非对称形式,这种方式使用起来简单些,如python,
    通过yield这个关键字, 你还可return重置函数状态,
  • f = function()
  • {
  •     yield print("step 1");
  •     yield print("step 2");
  •     yield print("step 3");
  •     return print("end of call");
  • };
  • f(); f(); f();f();f();

  •  



    6. 内置数据结构,数组(栈),表,没有指针,语言级别的数据结构,安全又方便,
        t = [1, 22, 3]; t [1] = 22;
        print(t[2]);
        push(t, 4);    pop(t);pop(t);pop(t);
        print(size(t) ); //
        m = m{ "key1":[1, 2, "text"], 3:"a" };
        print(m["key1"] );
        print("所有数据类型支持打印", m,  t); //print是可变参数的函数哦, 


     ( m{...},这样的语法形式看起来有些。。。但,LR的方法似乎很难 直接使用 m = {}, 的形式而不和其它语法规则冲突,

    所以 [] 表示数组, 而 m{ 表示 map );


    7. 模块化,注意 module, export, using, global, 这几个关键字
    //文件A, 
    module test.A
    export _1, _2
    _1 = "A._1";
    _2 = "A._1";
    //文件B, 
    module test.B
    export print
    using test
    print = function()
    {
        std.sys.print(A._1, A._2);
    }
    //文件user,
    using test.B;
    print();//将打印出 A._1, A._2;

    8. 嵌入,它是一个以c/c++为宿主的脚本语言...
    两种嵌入方式,一种是 lua like, 和下面一种方式等价, of couse, 效率更高!
    typedef u32 (*f_proto)(st_vm* rt);//想想 lua 的 c function的形式, 
    另一种,for c++,我为什么提供这个接口,一,为了容易用, 二, c_toy已经放入我的 ModuleCPP的组件库里,这是标准的使用方式,我迟些
    struct i_functor//嵌入接口, to override by user
    {
        virtual void on_eval(i_context* ctx) = 0;
    };
    看看i_context,
    struct i_context
    {
        virtual long in_size() = 0;
        virtual bool to_int(long idx, int&) = 0;
        virtual bool to_bool(long idx, bool&) = 0;
        virtual bool to_string(long idx, char* buff, long max_sz) = 0;
        virtual const char* to_printable_string(long idx) = 0;
        virtual void begin_push() = 0;
        virtual void push_bool(bool) = 0;
        virtual void push_int(int) = 0;
        virtual void push_string(const char* str) = 0;
        virtual void push_lightuserdata(void*) = 0;
    };
    是的, lua用户很熟悉吧,
    8. 调试

    单步,断点,VM查看是基本的调试手段
    ...
    //debug running
        virtual void debug_step(bool is_step) = 0;
        virtual void debug_set_break(long idx, bool open_close) = 0;
        virtual void debug_clear_breaks() = 0;
        virtual bool debug_run() = 0;
        virtual bool debug_continue() = 0;
    ...
    //vm states
        virtual long get_local_size() = 0;
        virtual const char* get_local_value_string(long idx) = 0;
        virtual long get_eval_size() = 0;
        virtual const char* get_eval_value_string(long idx) = 0;
        virtual long get_ref_size() = 0;
        virtual const char* get_ref_value_string(long idx) = 0;
        virtual long get_pc() = 0;
        virtual const char* get_current_code_string() = 0;
    ...

    //而且,也需要查看源码和byte code之间的映射
    ...
        virtual long get_code_size() = 0;
        virtual const char* get_code_string(long idx) = 0;//byte code
        virtual long get_src_line_size() = 0;
        virtual const char* get_src_line_string(long ln) = 0;//源码
        virtual long src_to_code(long ln, long& left) = 0;//return right// source <-> bytecode的映射
        virtual long code_to_src(long ln) = 0;
    ...
    10. 完整演示一个的求素数算法
  • module demo.sieve
  • export test

  • using std.core //for push/pop...
  • using std.sys //for print

  • p = [2];//生成的素数就放在这, 初始素数为2
  • n_gen = function(){ for(i = 3; true; ++i){yield i;} };//自然数生成器
  • is_p = function(num){//判断是否素数
  •      sz = std.core.size(p);
  •      for(i = 0; i<sz; ++i){
  •           if(num%p[i]==0) return false;
  •      }
  •      return true;
  • };

  • p_gen = function(){//素数生成器
  •     yield(p[0]);
  •     for(;true;){
  •         n = n_gen();
  •         if(is_p(n ) ){
  •              std.core.push(p, n);
  •              yield n;
  •         }
  •     }
  • };
  • for(i = 0; i<100; ++i){//前100位素数
  •     std.sys.print(p_gen() );
  • }

  •  


     


    最后,是一个扩展实现的 c_toy绘图


     

    posted on 2012-02-20 20:00 lichking 阅读(515) 评论(0)  编辑 收藏 引用 所属分类: 编程语言

    只有注册用户登录后才能发表评论。
    网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理