|
|
Label: ♦english
♦news
|
[244] Summary of the recent development of Dao |
Comment |
fu
created at Sunday, 2010-06-06, 01:41:14
fu
modified at Sunday, 2010-06-06, 03:11:40
2 Replies, 1779 Hits
Summary of the recent development of Dao
Besides many bug fixings and some optimizations,
Dao has undergone some interesting developments to support some new features.
Here is a brief summary of these features:
- Hash data type:
Its type name is the same as map , but it is constructed
in the same way as hash in some other popular languages such as
Python and JavaScript etc, for example:
h = { 'abc' : 123, 'def' : 456 } h = { : }
Tests show significant speed improvement for insertion and lookup
over RB-Tree based map type. Many of the internal key value lookups
have been replaced by using hash.
- Data construction by array/list/tuple/map{ expression(s) }:
This syntax is support so that it can be used if one wants
the type of data is more apparent.
The expression(s) inside the braces are the enumerated
items or range specifications:
a = array{ 1, 2, 3 } a = array{ 1 : 3 } a = array{ 1 : 2 : 3 } b = array{ 1, 2; 3, 4 } 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 }
- Macro support for defining Python style indentation sensitive syntax:
Details can be found in http://daovm.net/space/dao/thread/224 .
An example is available from demo/macro/scoping_by_indentation.dao
Along with this new support, two extra supports are also implemented:
one for creating string literal in macros, the other for multiple uses of source patterns in target syntax. These two supports can be used to create a quine
program as show in http://daovm.net/space/dao/thread/235 .
- More support for operator overloading:
Now the support for operator overloading is nearly complete.
Overloaded methods for unary, binary arithmetic or boolean
operators must be static methods (namely they need no class instance to invoke).
Unary operators can be overloaded in two ways:
class Integer { ... static operator !( C : Integer, A : Integer ){ C.value = ! A.value; return C; } static operator !( A : Integer ){ return Integer{ ! A.value }; } }
Where the first will be invoked if, in C = !A ,
C and A have the right type of Integer
and C has reference count equal to one
(this is to reuse intermediate object and avoid creating new objects).
Otherwise, the second will be invoked if A has the right type.
In both case, the method has to return a result.
Similarly, binary operator can be overloaded in three ways:
class Integer { ... static operator +=( C : Integer, B : Integer ){ C.value += B.value; return C; } static operator +( C : Integer, A : Integer, B : Integer ){ C.value = A.value + B.value; return C; } static operator +( A : Integer, B : Integer ){ return Integer{ A.value + B.value }; } }
The first will be invoked for C += B or C = C + B .
Similar to the case for unary operators,
the choose between the second and third method will be based
on the availability of C from the stack and its reference count.
Equality and inequality comparison between class instances (or between cdata)
will be based on their raw pointers if operator == and !=
are not overloaded. Comparing by <, <=, >, >= is not allowed for
class instances and cdata, unless <, <= or >, >=
are overloaded. However inside the overloaded methods, such operations
will be based on row pointers of the operand objects, if the operation
has the same name as the overloaded operator:
class Integer { ... static operator >( A : Integer, B : Integer ){ b = A > B; return Integer{ A.value > B.value }; } }
- Interface binding:
See http://daovm.net/space/dao/thread/223 for details. Just to point out, interface supports operator overloading,
as shown in the following example.
Example:
interface AA { 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) }
class BB { 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; } } class CC : BB { }
bind AA to BB;
Test( BB() ); Test( CC() );
for( i in CC() ) io.writeln(i)
This example is available from demo/interface.dao .
- Meta fields and prototype-based programming:
Meta fields is supported for array, list, map, tuple, cdata and class instance etc.
Such fields can be set and got by meta field operator -> .
A special meta field __proto__ can be set to be a map,
for delegated field lookup. Meta fields do not subject to static type checking,
and do not interfere with the normal fields.
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 in self ) 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 );
This example is also available from demo/meta_field.dao .
- New support for for-in iteration:
Any type has the following methods can be used in for-in loop for interation:
routine __for_iterator__( iter : for_iterator ); operator[]( iter : for_iterator );
where for_iterator is the built-in simple iterator type,
which is essential a tuple type defined as tuple<valid:int,iterator:any> .
The method __for_iterator__() is called before the loop starts,
to initialize the iterator.
In each cycle of the loop, the overloaded operator [] is called
to obtain an item of the object, and update properly the iterator.
When the valid field become zero, the loop will stop.
See the above example in Interface binding.
Important internal changes worth mentioning:
- DString structure with reduced size and number of allocation operations;
- Better handling function call stack;
- Field (and other key-value) lookup by hash;
- Re-implementation of exception types as cdata;
- Deferred member setup for C types;
- Better float point exception handling;
- Explicit declaration of static methods by keyword static ;
- Better handling parameter passing;
- Caching type matching results;
- Caching results of overloaded function lookup;
- Some improvements in the C interfaces of Dao.
Some minor changes:
- Direct up-value lookup in closure;
- variable := expression as short for variable : any = expression ;
- Regex pattern {{text}} to literally matching the text;
- String's regex matching method mpack() for packing matched pattern groups as new string(s).
- std.setlocale()
Improvements in autobind.dao:
- Support C++ namespace;
- Support C callbacks;
- Support class instance as default parameter;
- Better support virtual functions.
Comments
Pompei2 commented at Monday, 2010-06-07, 08:47:39
Nice resume of the recent changes!
Besides what I already told you, I really like the customizable for-in iteration support. Good Job.
fu commented at Tuesday, 2010-06-08, 02:12:11
Hope more people will like it too:)
|
| | | 1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 |
fu: ...
I forgot to say something about the plan for the whole new year in my previous reply. Well, besides w ... (Jan.19,01:40)
fu: ...
Happy new dragon year (which will start from this sunday)!
Actually, it was a busy month (I wish th ... (Jan.18,22:46)
|