Label: ♦chinese ♦news

[245] 道语言近期开发进展概要

Comment

道语言近期开发进展概要


除了不少错误修复和一些优化外, 近期的道语言开发实现了一些新语言特性。 下面简要地介绍一下这些特性:
  • 基于哈希的关联表:
    这种数据类型作为一种关联表,同样使用类型名 map 。 哈希表的构造方式跟如python,javascript等其它流行语言里的 哈希表/字典类型的构造方式一样,如:
    h  =  {'abc'  :  123,  'def'  :  456}
    h  =  {  :  }# 空哈希表

    测试显示基于哈希的关联表在插入与查找等操作上效率可以显著地高于 基于红黑树的关联表。现在道语言虚拟机内部的一些键值查找也改为 基于哈希的关联表了。
  • 使用array/list/tuple/map{ expression(s) }构造数据:
    使用这种语法可以是被构造数据的类型更加显而易见。 花括号里的表达式要么是枚举的数据元素,要么是一组 基于初值,增量,元素个数描述的数值:
    a  =  array{1,  2,  3}# 向量
    a  =  array{1  :  3}# 向量
    a  =  array{1  :  2  :  3}# 向量
    b  =  array{1,  2;  3,  4}# 2X2矩阵
    c  =  list{1,  2,  3}
    d  =  list{1  :  2}# 数组
    e  =  tuple{123,  'abc'}
    f  =  map{'BB'=>22,  'AA'=>11}# 有序键值
    g  =  map{'BB'  :  22,  'AA'  :  11}# 无序键值
  • 支持定义类似python缩进语法的宏支持
    有关细节可在这里找到:http://daovm.net/space/dao/thread/224

    有关例子在这里找到:demo/macro/scoping_by_indentation.dao

    随同缩进语法新增的另外两个新特性是:支持在语法宏的目标语法表达式里构造字符串; 和支持源语法模式在目标表达式里的多重使用。 这两项特性可用来写出一个独特的quine程序(一种重构并输出本身程序的源代码的程序): http://daovm.net/space/dao/thread/235
  • 更完善的运算符重载:
    现在道语言对运算符重载的支持比较完整了。 需要指出的是,重载单目或双目算术或布尔运算符的方法 必须是静态方法,即不需要类实例来调用该方法。

    单目运算符的重载有两种方式:
    class  Integer
    {
        ...
        staticoperator  !(C  :  Integer,  A  :  Integer  ){
            C.value  =  !  A.value;
            returnC;
        }
        staticoperator  !(A  :  Integer  ){
            return  Integer{  !  A.value};
        }
    }
    对于 C = !A ,当 C A 的类型都为 Integer C 的引用计数为一时, 第一个重载方法将被调用,否则调用第二个重载方法。 这样的处理是为了重用临时对象,避免构造新的对象。 这两种方法都必须返回结果对象。

    类似地,双目运算符的重载方式有三种:
    class  Integer
    {
        ...
        staticoperator  +=(C  :  Integer,  B  :  Integer  ){
            C.value  +=  B.value;
            returnC;
        }
        staticoperator  +(C  :  Integer,  A  :  Integer,  B  :  Integer  ){
            C.value  =  A.value  +  B.value;
            returnC;
        }
        staticoperator  +(A  :  Integer,  B  :  Integer  ){
            return  Integer{A.value  +  B.value};
        }
    }
    这里的第一种重载方法将被用于 C += B C = C + B 。 对于第二和第三种重载方法的调用,情况类似于上面介绍的单目运算符的 重载,这两种方法之间的选择将取决于 C 及其引用计数。

    类实例或c数据类型的等于和不等于比较将基于两对象的内存地址, 除非这两种比较的运算符被重载。 类实例或c数据类型一般不支持大于,大于等于或小于,小于等于比较操作, 除非这些运算符被重载。不过,在这些重载方法里, 跟被重载运算符相同的运算符将使用两对象的内存地址作比较:
    class  Integer
    {
        ...
        staticoperator  >(A  :  Integer,  B  :  Integer  ){
            b  =  A  >  B;  # 基于A和B内存地址的比较!
            return  Integer{A.value  >  B.value};
        }
    }
  • 接口绑定:
    一个接口类型就是一个成员方法的集合,使用接口类型将方便 某些情况下,既可以使用不同类的实例,也可以是不同类型的C数据对象, 只要它们兼容同样的接口。接口类型可以绑定到能提供所有接口方法 的类或C数据类型。类或C数据类型与接口类型的兼容性的检查,在运行 时将基于该类型是否有某接口类型的捆绑。接口类型的捆绑既可以在 编译时完成也可在运行时进行。

    例子:
    interfaceAA
    {
        routine  Meth(  a  =  0);
        operator[](  index  :  int)=>int;
        operator.name()=>string;

        routine  __for_iterator__(  iter  :  for_iterator  );
        operator[](  iter  :  for_iterator  );
    }
    routine  Test(  o  :  AA)
    {
        o.Meth(123);
        io.writeln(  o[1]);
        io.writeln(  o.name  );
        for(  i  in  o  )io.writeln(i)
    }

    classBB
    {
        routine  Meth(  a  =  0){io.writeln(  a  )}
        operator[](  index  :  int){return  index  }
        operator.name(){return'BB'}

        routine  __for_iterator__(  iter  :  for_iterator  ){
            iter.valid  =  1;
            iter.iterator  =  0;
        }
        operator[](  iter  :  for_iterator  ){
            id  =  (int)iter.iterator;
            iter.valid  =  id  +  1  <  5;
            iter.iterator  =  id  +  1;
            return  id;
        }
    }
    classCC  :  BB
    {
    }

    bindAAtoBB;

    Test(BB());
    Test(CC());

    for(  i  inCC())io.writeln(i)
    此例子也可在这里找到:demo/interface.dao
    bindAAtoany
    将允许接口 AA 在运行时被捆绑到任意兼容的类或C类型上。
  • Meta fields (元/附加/动态成员?)和基于原型(prototype)的编程:
    array, list, map, tuple, cdata 和类实例支持meta成员,这种成员的添加与访问 需要使用meta成员访问符 -> 。 关联表可以作为名为 __proto__ 的特殊meta成员添加到那些对象里, 这样当查找某对象的meta成员时,如果不存在,查找将在其名为 __proto__ 的 meta成员里继续。

    meta成员没有静态的类型检查。一个对象的普通成员和meta成员互不干扰。
    a  =  {'name'  :  'Test'}
    b  =  a->name;
    a->name  =  'New';
    io.writeln(  b,  a,  std.about(a));

    a->meth  =  routine(self  :  map<string,string>  )
    {
            for(  it  inself)io.writeln(  it  )
    }
    a->meth();

    c  =  {'index'  :  123}
    c->__proto__  =  a;
    io.writeln(  c->name,  c  );

    class  Test{}
    t  =  Test();

    t->value  =  123;
    io.writeln(  t->value);

    t->__proto__  =  c;

    io.writeln(  t->name,  t->index  );
    此例子也可在这里找到:demo/meta_field.dao
  • 新的for-in迭代循环支持
    任何定义了如下成员方法的类型都可以被用在 for-in 循环里:
    routine  __for_iterator__(  iter  :  for_iterator  );
        operator[](  iter  :  for_iterator  );
    这里 for_iterator 是一个简单的内置迭代子类型, 它本质上是个定义为 tuple<valid:int,iterator:any> 的元组类型。 方法 __for_iterator__() 用于循环前初始化迭代子。 在每次循环时,重载操作符 [] 将被用来获得与迭代子关联的元素, 并且适当地更新迭代子的状态。 当迭代子的 valid 成员被置零时,循环将被终止。 参考上面接口绑定中的例子。

重要的内部实现更新:
  • 更小的DString结构,减少需要的内存分配次数;
  • 更好的函数调用栈处理;
  • 基于哈希的成员或键值查找;
  • 重新实现异常类为cdata类型;
  • 推迟的C类型的成员设置;
  • 更好的浮点数异常处理;
  • 静态成员方法的显示申明(使用 static 关键词);
  • 更好的参数传递处理;
  • 类型匹配结果的缓存;
  • 重载函数检查结果的缓存;
  • 改善的道语言C接口。

一些小的改动:
  • 闭包的up-value的直接访问;
  • variable := expression 作为 variable : any = expression 的简写;
  • 字符串正则表达式模式单元 {{text}} ,用来逐字匹配text;
  • 字符串模式匹配方法 mpack() ,用来将匹配的模式组的子字符串聚合返回;
  • std.setlocale()

autobind.dao的完善:
  • 支持C++名字空间;
  • 支持C回调函数;
  • 支持使用C++类实例作为缺省参数;
  • 更好的虚函数支持。

Comments

Change picture:

Choose file:

123 4
56 78910 11
121314151617 18
192021222324 25
2627282930

klabim: ... Ok, I found it. It can be so easy by reading the documentation :- ). I have overseen the keyword glob ... (Aug.21,18:09)

klabim: sharing vars between scripts Hi, how can I share a variable between 2 scripts in an embedded environment? For example: script 1: ... (Aug.21,17:55)

This site is powered by Dao
Copyright (C) 2009,2010, daovm.net.
Webmaster: admin@daovm.net