├── ChangeLog ├── Makefile.daomake ├── README ├── bundle.dao ├── credits.txt ├── dao.conf ├── demo ├── arrays.dao ├── class_forward_claration.dao ├── class_inheritance.dao ├── classes.dao ├── closures.dao ├── command_arguments.dao ├── concrete_interface.dao ├── concurrent │ ├── async_object.dao │ ├── channel_block.dao │ ├── channel_class.dao │ ├── critical.dao │ ├── future.dao │ ├── parallel_quicksort.dao │ ├── select_builtin.dao │ ├── select_custom.dao │ ├── select_mix.dao │ └── start.dao ├── defers.dao ├── deployment.dao ├── disjoint_union.dao ├── embedding │ ├── Makefile │ ├── README │ ├── dao_greeting.cpp │ ├── dao_greeting.h │ ├── dao_greeting2.cpp │ ├── dao_greeting3.cpp │ ├── fake_list.cpp │ ├── fake_number.cpp │ ├── fakelist.cpp │ ├── greeting.cpp │ ├── greeting.h │ ├── main.cpp │ └── mod_greeting.cpp ├── enums.dao ├── errors.dao ├── hello.dao ├── interface.dao ├── interface_forward_declaration.dao ├── lists.dao ├── maps.dao ├── mixins.dao ├── numbers.dao ├── object_operator.dao ├── resource.txt ├── routines.dao ├── strings.dao ├── tuples.dao ├── user_functional.dao ├── user_map_key.dao ├── user_type_casting.dao └── verbatim.dao ├── kernel ├── dao.h ├── daoBase.h ├── daoBytecode.c ├── daoBytecode.h ├── daoClass.c ├── daoClass.h ├── daoConst.c ├── daoConst.h ├── daoGC.c ├── daoGC.h ├── daoInferencer.c ├── daoInferencer.h ├── daoInterface.c ├── daoInterface.h ├── daoLexer.c ├── daoLexer.h ├── daoList.c ├── daoList.h ├── daoMain.c ├── daoMap.c ├── daoMap.h ├── daoNamespace.c ├── daoNamespace.h ├── daoNumtype.c ├── daoNumtype.h ├── daoObject.c ├── daoObject.h ├── daoOptimizer.c ├── daoOptimizer.h ├── daoParser.c ├── daoParser.h ├── daoPlatform.c ├── daoPlatform.h ├── daoProcess.c ├── daoProcess.h ├── daoRegex.c ├── daoRegex.h ├── daoRoutine.c ├── daoRoutine.h ├── daoStdlib.c ├── daoStdlib.h ├── daoStdtype.c ├── daoStdtype.h ├── daoStream.c ├── daoStream.h ├── daoString.c ├── daoString.h ├── daoTasklet.c ├── daoTasklet.h ├── daoThread.c ├── daoThread.h ├── daoType.c ├── daoType.h ├── daoValue.c ├── daoValue.h ├── daoVmcode.c ├── daoVmcode.h ├── daoVmspace.c └── daoVmspace.h ├── license.txt ├── makefile.dao ├── modules ├── auxlib │ ├── dao_api.c │ ├── dao_api.h │ ├── dao_aux.c │ ├── dao_aux.h │ ├── example.dao │ └── makefile.dao ├── debugger │ ├── dao_debugger.c │ └── makefile.dao ├── profiler │ ├── dao_profiler.c │ ├── dao_profiler.h │ └── makefile.dao └── stream │ ├── dao_stream.c │ ├── dao_stream.h │ └── makefile.dao ├── share ├── dao-logo.png ├── dao.vim ├── daohelp.vim └── release.sh ├── tests ├── WrongModule.dao ├── dao_CharType.c ├── dao_UserPodType.c ├── dao_UserType.c ├── examples.dao ├── makefile.dao ├── test_anonymous_routine.dao ├── test_arrays.dao ├── test_class.dao ├── test_class_inheritance.dao ├── test_class_mixin.dao ├── test_class_operator.dao ├── test_class_static_fields.dao ├── test_closure.dao ├── test_code_section.dao ├── test_concrete_interface.dao ├── test_coroutine.dao ├── test_decorator.dao ├── test_enum_symbol_def.dao ├── test_enum_symbol_type.dao ├── test_error_handling.dao ├── test_for.dao ├── test_if_else.dao ├── test_interface.dao ├── test_invar.dao ├── test_invar_class.dao ├── test_lexer.dao ├── test_maps.dao ├── test_misc.dao ├── test_multi_threading.dao ├── test_numbers.dao ├── test_operators.dao ├── test_parser.dao ├── test_regex_char_class.dao ├── test_routine.dao ├── test_strings.dao ├── test_switch.dao ├── test_tasklet.dao ├── test_tuples.dao ├── test_type.dao └── test_while.dao └── tools ├── autobind.dao ├── daomake ├── bootstrap │ └── Makefile ├── makefile.dao ├── packages │ ├── FindFFI.dao │ ├── FindFLTK.dao │ ├── FindGIR.dao │ ├── FindGLUT.dao │ ├── FindGLib.dao │ ├── FindGSL.dao │ ├── FindGraphicsMagick.dao │ ├── FindGraphicsMagickWand.dao │ ├── FindIconv.dao │ ├── FindLLVM.dao │ ├── FindMySQL.dao │ ├── FindOpenGL.dao │ ├── FindOpenGL3.dao │ ├── FindOpenGLES.dao │ ├── FindPostgreSQL.dao │ ├── FindReadLine.dao │ ├── FindSDL.dao │ └── FindSQLite.dao ├── platforms │ ├── beos.dao │ ├── bsd.dao │ ├── freebsd.dao │ ├── haiku.dao │ ├── ios.dao │ ├── linux.dao │ ├── macosx.dao │ ├── mingw.dao │ ├── minix.dao │ ├── openbsd.dao │ ├── unix.dao │ └── win32.dao └── source │ └── daoMake.c ├── daotest ├── makefile.dao └── source │ └── daoTest.c ├── doctools ├── codehl2html.dao ├── codehl2tex.dao ├── sdml.css ├── sdml2html.dao ├── sdml2pdf.dao ├── sdml2tex.dao └── sdml_parser.dao └── filetools ├── archive.dao └── bytecode.dao /Makefile.daomake: -------------------------------------------------------------------------------- 1 | 2 | PLATS = linux macosx freebsd openbsd mingw minix haiku ios 3 | 4 | # Set build mode: release, debug or profile; 5 | MODE ?= release 6 | 7 | # Set installation location: 8 | INSTALL ?= /usr/local 9 | 10 | # Set Dao root directory. 11 | # Not needed for in source building; 12 | # Required for out of source building. 13 | SRCDIR ?= . 14 | 15 | 16 | # Use STATIC=ON to turn on building statically linked Dao: 17 | STATIC ?= OFF 18 | 19 | # Use RESET=--reset to turn on resetting of file generation, 20 | # so that Makefiles will be overrided by force, and CacheFind*.dao 21 | # will be regenerated. 22 | RESET ?= 23 | 24 | # More options can be passed to DaoMake using: OPTIONS=... 25 | # 26 | # For example, one can use: OPTIONS="--option-THREAD OFF" 27 | # to turn off support for multithreading. 28 | # 29 | # Another example is to use: OPTIONS="--option-BUNDLE-SCRIPT example" 30 | # to enable single executable deployment. 31 | # And add "--option-BUNDLE-RESOURCES file1,file2" to the "OPTIONS" to specify 32 | # the files to be bundled into the executable. 33 | # 34 | OPTIONS ?= 35 | 36 | DAOMAKE_ARGS = --mode $(MODE) 37 | DAOMAKE_ARGS += --option-INSTALL-PATH $(INSTALL) 38 | DAOMAKE_ARGS += --option-STATIC $(STATIC) 39 | DAOMAKE_ARGS += $(RESET) $(OPTIONS) 40 | #DAOMAKE_ARGS += --option-CODEQUOTA ON 41 | 42 | all: 43 | @echo "Please choose a platform among ($(PLATS))!" 44 | 45 | $(PLATS) : 46 | cd $(SRCDIR)/tools/daomake/bootstrap && $(MAKE) $@ PLAT=$@ 47 | $(SRCDIR)/tools/daomake/bootstrap/daomake --platform $@ $(DAOMAKE_ARGS) $(SRCDIR) 48 | $(MAKE) 49 | 50 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Dao Programming Language 2 | http://daoscript.org 3 | 4 | Dao is a lightweight and optionally typed programming language 5 | with many interesting features. It includes features that can 6 | make concurrent programming much simpler. It has well designed 7 | interfaces for easy embedding and extending. 8 | 9 | The virtual machine and standard modules and tools of Dao are 10 | released under the Simplified BSD License. 11 | 12 | 13 | ================================================================ 14 | How to Build? 15 | ------------- 16 | 17 | The recommended way to compile Dao is to run the following from 18 | the shell: 19 | 20 | $ make -f Makefile.daomake PLATFORM 21 | 22 | where PLATFORM can be one of the followings: 23 | 24 | * linux 25 | * macosx 26 | * freebsd 27 | * openbsd 28 | * mingw 29 | * minix 30 | * haiku 31 | 32 | Then run the following to install: 33 | 34 | $ make install 35 | 36 | 37 | ================================================================ 38 | How to Customize Building? 39 | -------------------------- 40 | 41 | Build mode (release, debug or profile) and installation directory 42 | can be set by: 43 | 44 | $ make -f Makefile.daomake PLATFORM MODE=debug INSTALL=directory 45 | 46 | Out of source building can be done by executing the following 47 | from the build directory: 48 | 49 | $ make -f DAO-DIR/Makefile.daomake PLATFORM SRCDIR=DAO-DIR 50 | 51 | Please read Makefile.daomake for more options such as making 52 | static build etc. 53 | 54 | 55 | ================================================================ 56 | How to Contribute? 57 | ------------------ 58 | 59 | Contributions to the development of Dao are highly welcome. However, 60 | if you wish to contribute something to the official code base and/or 61 | documentations etc., you must agree to transfer the copyright of 62 | your contributions in whatever form to the copyright holder of the 63 | Dao programming language to avoid potential copyright issues. Your 64 | contribution will be properly credited. 65 | 66 | Of course, you can also contribute by testing and reporting bugs, 67 | developing modules, creating packages for popular Linux distributions, 68 | building and release binaries for some platforms, or even just spreading 69 | words for Dao:). All contributions in any form are highly appreciated! 70 | -------------------------------------------------------------------------------- /bundle.dao: -------------------------------------------------------------------------------- 1 | 2 | # Building system for single executable deployment: 3 | # 4 | # Given example.dao, the following will compile it into bytecodes, 5 | # and bundle the bytecodes with Dao runtime and loaded modules 6 | # into a single executable: 7 | # 8 | # make -f Makefile.daomake macosx OPTIONS="--option-BUNDLE-SCRIPT example" 9 | 10 | daovm_bundle = DaoMake::Option( "BUNDLE", "" ) 11 | 12 | if( daovm_bundle == "" ) return; 13 | 14 | bundler = DaoMake::Project( "DaoBundler" ) 15 | 16 | bundle_main = bundler.AddObjects( { "kernel/daoMain.c" } ) 17 | bundle_script = bundler.AddObjects( { std.path( $working ) / (daovm_bundle + ".dar.c") } ) 18 | 19 | bundle_main.AddDefinition( "DAO_WITH_STATIC_MODULES" ) 20 | bundle_script.AddIncludePath( "kernel" ) 21 | 22 | bundle = bundler.AddExecutable( daovm_bundle, bundle_main, bundle_script ) 23 | 24 | finders = DaoMake::ReadFile( daovm_bundle + ".dar.finders" ) 25 | 26 | bundle_finders = finders.split( "\n" ) 27 | 28 | # The path variable $(CMD_DIR) in the ".finders" file refers to the building directory, 29 | # which is the working directory for Dao to compile the program. And this script 30 | # should also be executed in the same directory. 31 | cmd_dir = std.path( $working ) 32 | dao_dir = DaoMake::GetEnv( "DAO_DIR" ) 33 | home_dir = DaoMake::GetEnv( "HOME" ) 34 | for( finder in bundle_finders ){ 35 | finder = finder.replace( "$(CMD_DIR)/", cmd_dir ) 36 | finder = finder.replace( "$(DAO_DIR)/", dao_dir ) 37 | finder = finder.replace( "$(HOME)/", home_dir ) 38 | fields = finder.split( "\t" ) 39 | if( fields.size() < 3 ) skip; 40 | 41 | if( DaoMake::IsFile( fields[1] ) ) std.load( fields[1] ) 42 | pro = DaoMake::FindPackage( fields[0] ) 43 | io.writeln( ">>>>> bundle:", pro, fields ) 44 | if( pro != none ) bundle.UseStaticLibrary( pro ) 45 | } 46 | 47 | # Linking to static library needs to be placed after the objects/libraries 48 | # with unresolved symbols in Linux: 49 | std.load( "FindDao.dao" ) 50 | daovm = DaoMake::FindPackage( "Dao" ) 51 | if( daovm != none ){ 52 | bundle.UseStaticLibrary( daovm, "dao" ) 53 | bundle.UseStaticLibrary( daovm, "dao_aux" ) 54 | } 55 | -------------------------------------------------------------------------------- /credits.txt: -------------------------------------------------------------------------------- 1 | 2 | Credits and Acknowledgements 3 | 4 | Since I started the development of Dao, I have received many valuable feedbacks, 5 | suggestions and bug reports from many people. Many thanks to them! 6 | 7 | Special thanks to the following contributors: 8 | * Danilov, Aleksey (Nightwalker, TheTrueNightwalker [at] gmail.com) 9 | Language improvements, modules, testing, bug reports and patches etc. 10 | * Beyer, Lucas (pompei2, pompei2 [at] gmail.com) 11 | CMake support, testing, bug reports and patches etc. 12 | * Oleg, Belousov (belousov.oleg [at] gmail.com) 13 | Testing, bug reports and patches etc. 14 | * Zhao, Zhiguo George (zhaozg [at] gmail.com) 15 | Testing, bug reports and patches etc. 16 | * dumblob (https://github.com/dumblob) 17 | Testing, bug reports and patches etc. 18 | 19 | -- Limin Fu 20 | -------------------------------------------------------------------------------- /dao.conf: -------------------------------------------------------------------------------- 1 | # Number of CPUs: 2 | # cpu = 1 3 | 4 | # Enable JIT: 5 | # jit = no 6 | 7 | # Enable safe execution mode: 8 | # safe = no 9 | 10 | # Number of spaces per tab: 11 | # tabspace = 8 12 | -------------------------------------------------------------------------------- /demo/arrays.dao: -------------------------------------------------------------------------------- 1 | 2 | var vec1 = [1, 2, 3] # array vector, or 1x3 matrix; 3 | var vec2 = [1.0; 2; 3] # array 3x1 matrix, or transposed vector; 4 | var mat1 = [1.0, 2; 3, 4] # array 2x2 matrix; 5 | var mat2 = [ [1, 2], [3, 4] ] # 2x2 matrix 6 | var mat3 = array{ 1, 2; 3, 4 } # 2x2 matrix 7 | var mat4 = array(5){ [1, 2, 3] } # 5x3 matrix; 8 | 9 | io.writeln( vec1 ) 10 | io.writeln( vec2 ) 11 | io.writeln( mat1 ) 12 | io.writeln( mat2 ) 13 | io.writeln( mat3 ) 14 | io.writeln( mat4 ) 15 | io.writeln( "number of elements:", %mat4 ) 16 | -------------------------------------------------------------------------------- /demo/class_forward_claration.dao: -------------------------------------------------------------------------------- 1 | 2 | class One 3 | 4 | class Another 5 | { 6 | routine Test( o : One ); 7 | } 8 | class One 9 | { 10 | var index = 123; 11 | 12 | routine Test1( dep :int ); 13 | routine Test2( dep :int ){ 14 | Test1( ++dep ) 15 | } 16 | routine Test1( dep :int ){ 17 | io.writeln( Test1, dep ); 18 | if( dep > 5 ) return 19 | Test2( ++dep ) 20 | } 21 | } 22 | 23 | routine Another::Test( o : One ) 24 | { 25 | io.writeln( o.index ); 26 | } 27 | 28 | var o = One(); 29 | var a = Another(); 30 | a.Test( o ); 31 | o.Test2(0) 32 | -------------------------------------------------------------------------------- /demo/class_inheritance.dao: -------------------------------------------------------------------------------- 1 | 2 | 3 | class AA 4 | { 5 | static glb = 1; 6 | const cst = 123; 7 | var obj = 456; 8 | var obj2 = 789; 9 | 10 | routine Meth(){ io.writeln( "AA::Meth()" ); return 123; } 11 | routine Meth( a ){ io.writeln( "AA::Meth(a)" ); return 123; } 12 | 13 | routine AA( i = 0 ){ io.writeln( "AA::AA( i = 0 )" ); } 14 | 15 | interface routine Virt(){ io.writeln( "AA::Virt()" ) } 16 | routine CallVirt(){ 17 | Virt() 18 | } 19 | } 20 | 21 | class BB : AA 22 | { 23 | const cst = "abc"; 24 | var obj = "abc"; 25 | var obj2 = "abc"; 26 | 27 | routine Meth(){ io.writeln( "BB::Meth()" ); return "abc"; } 28 | 29 | routine BB( i = 0 ){ io.writeln( "BB::BB( i = 0 )" ); } 30 | 31 | routine Virt(){ io.writeln( "BB::Virt()" ) } 32 | } 33 | 34 | class CC : BB 35 | { 36 | var obj2 = 0C; 37 | 38 | routine Virt(){ io.writeln( "CC::Virt()", self ) } 39 | } 40 | 41 | var c = CC(); 42 | 43 | io.writeln( c.cst == "abc" ? "ok" : "error" ); 44 | io.writeln( c.obj == "abc" ? "ok" : "error" ); 45 | io.writeln( c.obj2 == 0C ? "ok" : "error" ); 46 | io.writeln( c.Meth() == "abc" ? "ok" : "error" ); 47 | 48 | io.writeln( c.Meth(1) ); 49 | 50 | c.CallVirt(); 51 | var a: AA = c 52 | a.Virt() 53 | -------------------------------------------------------------------------------- /demo/classes.dao: -------------------------------------------------------------------------------- 1 | 2 | # Here is a simple class: 3 | class ClassOne 4 | { 5 | var index = 0; # instance variable with default value; 6 | var name : string 7 | var words : list = {} 8 | 9 | routine ClassOne( name :string, index = 0 ){ 10 | self.name = name; 11 | self.index = index; 12 | } 13 | } 14 | # Create a class instance: 15 | object = ClassOne( "abc" ) 16 | 17 | 18 | class Point3D 19 | { 20 | var x = 0.0; 21 | var y = 0.0; 22 | var z = 0.0; 23 | } 24 | # Create instance enumerating the members of the class, 25 | point = Point3D.{ 1, 2, 3 }; 26 | 27 | 28 | # The names of instance variables may also be specified in enumeration, 29 | point = Point3D. 30 | { 31 | y = 2, 32 | x = 1, 33 | z = 3, 34 | }; 35 | 36 | 37 | class Klass 38 | { 39 | const aClassConst = "KlassConst"; 40 | static aClassStatic = 123; 41 | } 42 | 43 | 44 | class MyNumber 45 | { 46 | private 47 | 48 | var value = 0; 49 | 50 | public 51 | 52 | routine MyNumber( v = 0 ){ 53 | value = v; 54 | } 55 | 56 | routine .value=( v ){ value = v } # setter; 57 | routine .value(){ return value } # getter; 58 | } 59 | 60 | num = MyNumber( 123 ) 61 | num.value = 456 62 | io.writeln( num.value ) 63 | 64 | -------------------------------------------------------------------------------- /demo/closures.dao: -------------------------------------------------------------------------------- 1 | 2 | # Anonymous functions and closures can be created using the same syntax 3 | # as defining a normal function but without function name. For example, 4 | # var rout = routine( a :int ){ io.writeln( a ) } 5 | # 6 | # In anonymous functions or closures, the default parameters can be 7 | # non-constant expressions that will be evaluated at the time of creation 8 | # of the anonymous function or closure. 9 | # 10 | # The only difference between anonymous functions or closures is that 11 | # anonymous functions do not access the local variables of the outer 12 | # scopes, while closures do. 13 | # 14 | # The outer variables accessed by a closure are captured at the time of the 15 | # creation of the closure, and become static variables of the closure. 16 | # 17 | # When an anonymous function or closure is parsed, the symbols are first 18 | # resolved locally, and then the local constants and variables of the outer 19 | # scopes are searched. The class members and global data are searched at last. 20 | 21 | var closures = {}; 22 | 23 | for(var i = 1 : 5 ){ 24 | var ls = { i }; 25 | var closure = routine(){ 26 | io.writeln( ls, i ) 27 | } 28 | closures.append( closure ) 29 | } 30 | 31 | for( closure in closures ) closure() 32 | 33 | routine Test() 34 | { 35 | var abc = "abc" 36 | var rout = routine(){ 37 | io.writeln( "outer closure", abc ) 38 | var rout = routine(){ 39 | io.writeln( "inner closure", abc ) 40 | } 41 | return rout; 42 | } 43 | return rout() 44 | } 45 | 46 | var rout = Test() 47 | rout() 48 | -------------------------------------------------------------------------------- /demo/command_arguments.dao: -------------------------------------------------------------------------------- 1 | 2 | routine main( index : int, name = "abc" ) 3 | { 4 | io.writeln( "main(index:int,name=\"abc\")", index, name ) 5 | return 0 6 | } 7 | 8 | routine main( name : string ) 9 | { 10 | io.writeln( "main(name:string)", name ) 11 | return 0 12 | } 13 | -------------------------------------------------------------------------------- /demo/concrete_interface.dao: -------------------------------------------------------------------------------- 1 | 2 | # Abstract interface: 3 | interface InterA 4 | { 5 | routine size()=>int 6 | routine serialize()=>string 7 | static routine statmeth()=>int 8 | } 9 | 10 | # Concrete interface for int: 11 | interface InterA for int 12 | { 13 | routine size(){ 14 | io.writeln( "InterA::size()", self ) 15 | self += 789; 16 | io.writeln( "InterA::size()", std.about(self) ) 17 | io.writeln( "InterA::size()", self.serialize() ); 18 | return self + 1; 19 | } 20 | routine serialize() => string { return "abc" + (string) (int) self; } 21 | static routine statmeth()=>int { return 456 } 22 | } 23 | 24 | var a: InterA = 123 # a: value type InterA; variable type InterA; 25 | var b = (InterA) 123; # b: value type InterA; variable type InterA; 26 | var c: InterA = 123 # c: value type InterA; variable type InterA; 27 | 28 | io.writeln( a.size() ) 29 | io.writeln( "value", (int) a, a.statmeth() ) 30 | 31 | var d: int = c 32 | 33 | # int is automatically converted to InterA, where InterA or InterA 34 | # is expected: 35 | var e: list> = { 123 } 36 | 37 | e.append(456) 38 | 39 | var f: list = { 678 } 40 | 41 | f.append(456) 42 | 43 | io.writeln( e, f ) 44 | 45 | 46 | 47 | 48 | interface InterB : InterA 49 | { 50 | routine []( index: int ) => int 51 | } 52 | 53 | interface InterB for int : InterA 54 | { 55 | routine []( index: int ) => int { 56 | return (self & (1<> index; 57 | } 58 | } 59 | 60 | var k = (InterB) 0x7ffeff; 61 | 62 | f.append( k ) 63 | 64 | io.writeln( f, k[1] ) 65 | 66 | var h = (InterA) k; 67 | io.writeln( std.about(h), h ) 68 | 69 | var m: InterA = k; 70 | io.writeln( std.about(m), m ) 71 | 72 | var s = (InterA) k; 73 | io.writeln( std.about(s), s ) 74 | -------------------------------------------------------------------------------- /demo/concurrent/async_object.dao: -------------------------------------------------------------------------------- 1 | #load os 2 | 3 | class Test !! 4 | { 5 | routine Task1( chan : mt::Channel ){ 6 | while(1){ 7 | var data = chan.receive() 8 | io.writeln( "Task1", data ) 9 | if( data.status == $finished ) break 10 | } 11 | } 12 | routine Task2(){ 13 | for(var i = 1 : 5 ){ 14 | io.writeln( "Task2", i ) 15 | #os.sleep(0.5); 16 | } 17 | } 18 | } 19 | 20 | var test = Test() 21 | 22 | var chan = mt::Channel(1) 23 | 24 | test.Task1( chan ) 25 | test.Task2() 26 | 27 | io.writeln( "Start to send message" ) 28 | 29 | for(var i = 1 : 5 ){ 30 | io.writeln( "sending", 100*i ) 31 | chan.send( 100*i ) 32 | #os.sleep(0.5) 33 | } 34 | chan.cap(0) 35 | 36 | routine main(){ 37 | for(var i=1:10){ 38 | io.writeln( "main()" ) 39 | #os.sleep(0.5) 40 | } 41 | return 0 42 | } 43 | -------------------------------------------------------------------------------- /demo/concurrent/channel_block.dao: -------------------------------------------------------------------------------- 1 | 2 | const N = 100000; 3 | 4 | var chan = mt::Channel(2) 5 | 6 | var produce = mt.start { 7 | var index = 0; 8 | io.writeln( "begin producing" ) 9 | while( ++index <= N ){ 10 | if( index % 100 == 0 ) io.writeln( "sending", index ) 11 | chan.send( index ) 12 | } 13 | io.writeln( "end producing" ) 14 | chan.cap(0) # set channel buffer size to zero to close the channel; 15 | } 16 | 17 | var consume = mt.start { 18 | io.writeln( "begin consuming" ) 19 | while(1){ 20 | var data = chan.receive() 21 | if( (int)data.data % 100 == 0 ) io.writeln( "received", data ); 22 | if( data.status == $finished ) break 23 | } 24 | io.writeln( "end consuming" ) 25 | } 26 | 27 | -------------------------------------------------------------------------------- /demo/concurrent/channel_class.dao: -------------------------------------------------------------------------------- 1 | 2 | const N = 100000; 3 | 4 | class Producer !! 5 | { 6 | routine Run( chan : mt::Channel ){ 7 | var index = 0; 8 | while( ++index <= N ){ 9 | if( index % 100 == 0 ) io.writeln( "sending", index ) 10 | chan.send( index ) 11 | } 12 | chan.cap(0) # set channel buffer size to zero to close the channel; 13 | } 14 | } 15 | 16 | class Consumer !! 17 | { 18 | routine Run( chan : mt::Channel ){ 19 | while(1){ 20 | var data = chan.receive() 21 | if( (int)data.data % 100 == 0 ) io.writeln( "received", data ); 22 | if( data.status == $finished ) break 23 | } 24 | } 25 | } 26 | 27 | var chan = mt::Channel(100) 28 | 29 | var producer = Producer() 30 | var consumer = Consumer() 31 | 32 | producer.Run( chan ) 33 | consumer.Run( chan ) 34 | -------------------------------------------------------------------------------- /demo/concurrent/critical.dao: -------------------------------------------------------------------------------- 1 | 2 | 3 | count = 0; 4 | mt.iterate( 10, 4 ){ [X,Y] 5 | io.writeln( "outside of critical section", Y ); 6 | mt.critical{[] # avoid redeclaring Y implicitly 7 | io.writeln( "in critical section", Y ); 8 | for( i = 1 : 100000 ) count += 1; 9 | } 10 | } 11 | io.writeln( count ); 12 | 13 | -------------------------------------------------------------------------------- /demo/concurrent/future.dao: -------------------------------------------------------------------------------- 1 | load os; 2 | 3 | class Test !! 4 | { 5 | routine Meth(){ 6 | for(var i = 1 : 5 ){ 7 | io.writeln( "@Test::Meth()", i ); 8 | #os.sleep(0.2); 9 | } 10 | } 11 | } 12 | 13 | var t = Test() 14 | 15 | mt.iterate( 4 ) { [X] 16 | io.writeln( "=========", "X"+(string)X ); 17 | var f = mt.start { 18 | for(var i = 1 : 5 ){ 19 | io.writeln( "start{}", i ); 20 | #os.sleep(0.01); 21 | } 22 | } 23 | #f.value(); # ERROR: cannot block inside code section methods; 24 | io.writeln( "---------", X ); 25 | } 26 | 27 | 28 | mt.iterate( 4 ) { [X] 29 | io.writeln( "=========", X ); 30 | t.Meth() #.wait( 5 ); # ERROR: cannot block inside code section methods; 31 | io.writeln( "---------", X ); 32 | } 33 | -------------------------------------------------------------------------------- /demo/concurrent/parallel_quicksort.dao: -------------------------------------------------------------------------------- 1 | load random 2 | 3 | routine QuickSort( data: array, first: int, last: int ) 4 | { 5 | var lower = first + 1; 6 | var upper = last; 7 | 8 | #io.writeln( first, last ); 9 | 10 | if( first >= last ) return; 11 | 12 | var val = data[first]; 13 | data[first] = data[ (first+last)/2 ]; 14 | data[ (first+last)/2 ] = val; 15 | 16 | var pivot = data[ first ]; 17 | 18 | while( lower <= upper ){ 19 | while( lower < last && data[lower] < pivot ) lower += 1; 20 | while( upper > first && pivot < data[upper] ) upper -= 1; 21 | if( lower < upper ){ 22 | val = data[lower]; 23 | data[lower] = data[upper]; 24 | data[upper] = val; 25 | upper -= 1; 26 | } 27 | lower += 1; 28 | } 29 | val = data[first]; 30 | data[first] = data[upper]; 31 | data[upper] = val; 32 | 33 | #{ 34 | if( first+1 < upper ) QuickSort( data, first, upper-1 ); 35 | if( upper+1 < last ) QuickSort( data, upper+1, last ); 36 | return; 37 | #} 38 | 39 | if( first+10000 < upper and upper+10000 < last ){ 40 | var fv1 = QuickSort( data, first, upper-1 ) !! 41 | QuickSort( data, upper+1, last ) 42 | fv1.wait(); 43 | }else{ 44 | if( first+1 < upper ) QuickSort( data, first, upper-1 ); 45 | if( upper+1 < last ) QuickSort( data, upper+1, last ); 46 | } 47 | } 48 | 49 | var a = [ 1, 3, 5, 4, 2, 6, 9, 7 ] 50 | a = array( 2000000 ){ random.rand( 10000000 ) } 51 | 52 | QuickSort( a, 0, a.size()-1 ); 53 | 54 | io.writeln( a[:5], a[a.size()-5:] ) 55 | -------------------------------------------------------------------------------- /demo/concurrent/select_builtin.dao: -------------------------------------------------------------------------------- 1 | load os 2 | load random 3 | 4 | const N = 10; 5 | const C = 1; 6 | 7 | var ichan = mt::Channel(C) 8 | var schan = mt::Channel(C) 9 | 10 | 11 | mt.start { 12 | var index = 0; 13 | io.writeln( "begin producing" ) 14 | while( ++index <= N ){ 15 | if( random.rand(2) ){ 16 | io.writeln( "sending integer:", index ); 17 | ichan.send( index ) 18 | }else{ 19 | io.writeln( "sending string: index_" + (string) index ); 20 | schan.send( "index_" + (string) index ) 21 | } 22 | os.sleep(0.5) 23 | } 24 | io.writeln( "end producing" ) 25 | ichan.cap(0) # set channel buffer size to zero to close the channel; 26 | schan.cap(0) 27 | } 28 | 29 | var chans = { ichan -> 0, schan -> 0 } 30 | 31 | io.writeln( "begin consuming" ) 32 | while( 1 ){ 33 | io.writeln( "before selecting" ); 34 | var data = mt::select( chans, 0.2 ) 35 | io.writeln( "received:", data ); 36 | if( data.status == $finished ) break 37 | } 38 | io.writeln( "end consuming" ) 39 | 40 | -------------------------------------------------------------------------------- /demo/concurrent/select_custom.dao: -------------------------------------------------------------------------------- 1 | load random 2 | 3 | const N = 100; 4 | 5 | var chans = { mt::Channel(1), mt::Channel(1) } 6 | 7 | mt.start { 8 | var index = 0; 9 | io.writeln( "begin producing" ) 10 | while( ++index <= N ){ 11 | if( random.rand(2) ){ 12 | io.writeln( "sending integer:", index ); 13 | chans[0].send( index ) 14 | }else{ 15 | io.writeln( "sending string: index_" + (string) index ); 16 | chans[1].send( "index_" + (string) index ) 17 | } 18 | } 19 | io.writeln( "end producing" ) 20 | chans[0].cap(0) # set channel buffer size to zero to close the channel; 21 | chans[1].cap(0) 22 | } 23 | 24 | var select = mt::Channel(1) 25 | 26 | mt.start { 27 | 28 | var f1 = mt.start { 29 | while(1){ 30 | var data = chans[0].receive(); 31 | if( data.status == $finished ) break 32 | select.send( (int) data.data ) 33 | } 34 | } 35 | 36 | var f2 = mt.start { 37 | while(1){ 38 | var data = chans[1].receive(); 39 | if( data.status == $finished ) break 40 | select.send( (string) data.data ) 41 | } 42 | } 43 | f1.wait() 44 | f2.wait() 45 | select.cap(0) # set channel buffer size to zero to close the channel; 46 | } 47 | 48 | io.writeln( "begin consuming" ) 49 | while(1){ 50 | var data = select.receive() 51 | io.writeln( "received", data ); 52 | if( data.status == $finished ) break 53 | } 54 | io.writeln( "end consuming" ) 55 | 56 | -------------------------------------------------------------------------------- /demo/concurrent/select_mix.dao: -------------------------------------------------------------------------------- 1 | load os 2 | load random 3 | 4 | const N = 10; 5 | const C = 1; 6 | 7 | var ichan = mt::Channel(C) 8 | var schan = mt::Channel(C) 9 | 10 | 11 | var fut = mt.start { 12 | var index = 0; 13 | io.writeln( "begin producing" ) 14 | while( ++index <= N ){ 15 | if( random.rand(2) ){ 16 | io.writeln( "sending integer:", index ); 17 | ichan.send( index ) 18 | }else{ 19 | io.writeln( "sending string: index_" + (string) index ); 20 | schan.send( "index_" + (string) index ) 21 | } 22 | #os.sleep(0.5) 23 | } 24 | io.writeln( "end producing" ) 25 | ichan.cap(0) # set channel buffer size to zero to close the channel; 26 | schan.cap(0) 27 | } 28 | 29 | var selects = { ichan => 0, schan => 0, fut => 0 } 30 | 31 | io.writeln( "begin consuming" ) 32 | while( 1 ){ 33 | io.writeln( "before selecting" ); 34 | var data = mt::select( selects, 0.2 ) 35 | io.writeln( "received:", data ); 36 | if( data.status == $finished ) break 37 | } 38 | io.writeln( "end consuming" ) 39 | 40 | -------------------------------------------------------------------------------- /demo/concurrent/start.dao: -------------------------------------------------------------------------------- 1 | load os; 2 | 3 | routine Test() 4 | { 5 | id = 123; 6 | name = "abc"; 7 | return mt.start { 8 | for( i = 1 : 10 ){ 9 | io.writeln( i ); 10 | os.sleep( 0.1 ); 11 | } 12 | # here id, name should have been copied, and it is safe to 13 | # access them even after Test() and its process is finished! 14 | io.writeln( id, name ); 15 | } 16 | } 17 | 18 | t = Test(); 19 | t.value(); # join 20 | 21 | Test(); 22 | Test(); 23 | 24 | io.writeln( "main thread done!" ); 25 | 26 | # All threads are automatically joined before program finishes! 27 | -------------------------------------------------------------------------------- /demo/defers.dao: -------------------------------------------------------------------------------- 1 | 2 | # A "defer" block is a block of code that can be executed when 3 | # a function returns normally or exits due to excpetions. Its 4 | # execution can be conditional or unconditional with respect 5 | # to exceptions: 6 | # -- "defer{block}" or "defer(){block}": unconditional exection, 7 | # when a function exits with or without exception; 8 | # -- "defer(none){block}": conditional execution, only when the 9 | # function exits without exception; 10 | # -- "defer(any){block}": conditional execution, when the function 11 | # exit with any exception(s); 12 | # -- "defer(type){block}": conditional execution, only when the 13 | # function exit with exception(s) matching to "type"; 14 | # -- "defer(type as name){block}": the same as "defer(type){block}" 15 | # except that the exception object will be accessible by "name". 16 | # 17 | # A defer block is compiled as a closure, so it can access outer 18 | # scope constants and variables in the same way as closures. 19 | # These outer scope variables are captured at the time the defer 20 | # block is reached in the normal execution. 21 | # 22 | # When a function exits, all the executable defer blocks that have 23 | # been reached in the normal execution will be executed in the reverse 24 | # order of being reached. Each conditional defer block can only be 25 | # activated once by one exception object, and the more recent exception 26 | # object is checked first if there are multiple exception objects. 27 | # 28 | # An exception object is suppressed once it is used to activate and 29 | # execute a conditional defer block. Such defer block must return 30 | # or not return value in the same way as the routine where the defer 31 | # is defined. The returned value by such defer will by used as the 32 | # new return value of the routine. 33 | # 34 | 35 | routine Test() 36 | { 37 | defer { 38 | io.writeln( "always executed" ) 39 | } 40 | defer( none ){ 41 | io.writeln( "defer( none )" ) 42 | } 43 | defer( Error as error ){ 44 | io.writeln( "defer( Exception::Error as error )" ) 45 | return 999 46 | } 47 | 48 | for(var i = 2 : 5 ) defer { io.writeln( "deferred", i ) } 49 | 50 | std.error( Error( "something" ) ) 51 | io.writeln( "returning" ); 52 | return 123 53 | } 54 | 55 | io.writeln( Test() ) 56 | -------------------------------------------------------------------------------- /demo/deployment.dao: -------------------------------------------------------------------------------- 1 | 2 | # make -f Makefile.daomake macosx MODE=debug OPTIONS="--option-BUNDLE-SCRIPT demo/deployment --option-BUNDLE-RESOURCES resource.txt" 3 | 4 | load aux 5 | load mixins 6 | 7 | var text = std::resource( "resource.txt" ) 8 | 9 | io.writeln( text ) 10 | -------------------------------------------------------------------------------- /demo/disjoint_union.dao: -------------------------------------------------------------------------------- 1 | 2 | #################################### 3 | # First example: 4 | #################################### 5 | 6 | var intstring : list = {}; 7 | 8 | intstring.append( 123 ); 9 | intstring.append( "abc" ); 10 | 11 | #intstring.append( {} ); # typing error 12 | 13 | io.writeln( intstring, intstring[0], intstring[1] ); 14 | 15 | 16 | 17 | #################################### 18 | # Second example: 19 | #################################### 20 | 21 | interface HasSizeMethod 22 | { 23 | routine Size()=>int; 24 | } 25 | class AA 26 | { 27 | routine Size()=>int{ return 10 } 28 | } 29 | class BB 30 | { 31 | routine Size()=>int{ return 20 } 32 | } 33 | 34 | routine Test( object: AA | BB | HasSizeMethod ) 35 | { 36 | # casting to an interface will invoke automatic binding: 37 | var object2 = (HasSizeMethod) object; 38 | io.writeln( object2.Size() ) 39 | } 40 | 41 | io.writeln( std.about( Test ) ); 42 | 43 | Test( AA() ) 44 | Test( BB() ) 45 | 46 | routine Test2( data: int|float|string ) 47 | { 48 | switch( data ) type { 49 | case int : io.writeln( "handling int", std.about( data ) ); 50 | case float : io.writeln( "handling float", std.about( data ) ); 51 | case string : io.writeln( "handling string", std.about( data ) ); 52 | } 53 | } 54 | 55 | Test2( 1 ); 56 | Test2( 1.0 ); 57 | Test2( "abc" ); 58 | 59 | 60 | 61 | #################################### 62 | # Third example: 63 | #################################### 64 | 65 | class FakeImage 66 | { 67 | var image = [1,2,3,4;5,6,7,8;11,12,13,14;15,16,17,18]; 68 | 69 | # instead of writing routine methods with all the combinations 70 | # such as tuple, tuple, ... 71 | # one can use disjoint union to simplify this. 72 | routine[]( i: int, js: none|tuple )=>array 73 | { 74 | # one can simply return image[i,js], but the following is for demonstration purpose: 75 | var j1 = 0; 76 | var j2 = image.dim(1) - 1; 77 | if( js == none ) return image[i,:]; 78 | if( js[0] != none ) j1 = js[0]; 79 | if( js[1] != none ) j2 = js[1]; 80 | return image[i,j1:j2]; 81 | } 82 | } 83 | 84 | var image = FakeImage(); 85 | io.writeln( image[1,1:] ); 86 | io.writeln( image[2,:1] ); 87 | 88 | 89 | 90 | #################################### 91 | # Fourth example: 92 | #################################### 93 | 94 | routine Sum( alist : list<@T> ) => @T 95 | { 96 | # reflect.trace(); 97 | return alist.sum(); 98 | } 99 | 100 | var s = Sum( { 1, 2, 3 } ); 101 | #s += "a"; # typing error 102 | io.writeln( s ); 103 | 104 | var s2 = Sum( { "a", "b", "c" } ); 105 | io.writeln( s2 ); 106 | 107 | -------------------------------------------------------------------------------- /demo/embedding/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CXX = g++ # -ggdb -fPIC -I. -shared 3 | 4 | # UNIX, MAC_OSX, or WIN32 must be defined for corresponding OS. 5 | CFLG = -DMAC_OSX -DDAO_DIRECT_API 6 | CFLG = -ggdb -DMAC_OSX -DDAO_DIRECT_API 7 | 8 | WRAP = dao_greeting.o dao_greeting2.o dao_greeting3.o 9 | 10 | all: greeting.o main.o $(WRAP) 11 | $(CXX) greeting.o main.o $(WRAP) -o greeting -ldao -ldl 12 | 13 | test: greeting.o main.o $(WRAP) 14 | $(CXX) greeting.o main.o $(WRAP) ../../dao.a -o greeting 15 | 16 | 17 | fake_list: fake_list.o 18 | $(CXX) fake_list.o -o fake_list -ldao -ldl 19 | 20 | fake_list.o: fake_list.cpp 21 | $(CXX) $(CFLG) -c fake_list.cpp -o fake_list.o 22 | 23 | 24 | fake_number: fake_number.o 25 | $(CXX) fake_number.o -o fake_number -ldao -ldl 26 | 27 | fake_number.o: fake_number.cpp 28 | $(CXX) $(CFLG) -c fake_number.cpp -o fake_number.o 29 | 30 | 31 | greeting.o: greeting.h greeting.cpp 32 | $(CXX) $(CFLG) -c greeting.cpp -o greeting.o 33 | 34 | main.o: main.cpp greeting.h 35 | $(CXX) $(CFLG) -c main.cpp -o main.o 36 | 37 | dao_greeting.o: dao_greeting.h dao_greeting.cpp 38 | $(CXX) $(CFLG) -c dao_greeting.cpp -o dao_greeting.o 39 | 40 | dao_greeting2.o: dao_greeting.h dao_greeting2.cpp 41 | $(CXX) $(CFLG) -c dao_greeting2.cpp -o dao_greeting2.o 42 | 43 | dao_greeting3.o: dao_greeting.h dao_greeting3.cpp 44 | $(CXX) $(CFLG) -c dao_greeting3.cpp -o dao_greeting3.o 45 | 46 | bind: 47 | autobind.dao greeting.h lang=cpp wrap_name=greeting del_tests="Greeting@self!=GetGreetingObject()" 48 | 49 | local-bind: 50 | ../../bin/dao ../../tools/autobind.dao greeting.h lang=cpp wrap_name=greeting 51 | 52 | bind-valgrind: 53 | valgrind --tool=memcheck --leak-check=full --dsymutil=yes ../../bin/dao ../../tools/autobind.dao greeting.h lang=cpp wrap_name=greeting 54 | 55 | clean: 56 | rm *.o 57 | -------------------------------------------------------------------------------- /demo/embedding/README: -------------------------------------------------------------------------------- 1 | 2 | To build: 3 | 4 | make bind 5 | make 6 | -------------------------------------------------------------------------------- /demo/embedding/fakelist.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | // If you want to use direct APIs of Dao, define the following 5 | // preprocessor option before EVERY including of dao.h. 6 | // Or add it in your Makefile or project compiling settings. 7 | //#define DAO_DIRECT_API 8 | #include 9 | 10 | static void dao_FakeList_FakeList( DaoContext *_ctx, DValue *_p[], int _n ); 11 | static void dao_FakeList_Iter( DaoContext *_ctx, DValue *_p[], int _n ); 12 | static void dao_FakeList_GetItem( DaoContext *_ctx, DValue *_p[], int _n ); 13 | 14 | static DaoFuncItem dao_FakeList_Meths[] = 15 | { 16 | { dao_FakeList_FakeList, "FakeList( size=0 )=>FakeList" }, 17 | { dao_FakeList_Iter, "__for_iterator__( self : FakeList, iter : for_iterator )" }, 18 | { dao_FakeList_GetItem, "[]( self : FakeList, iter : for_iterator )=>int" }, 19 | { NULL, NULL } 20 | }; 21 | static void Dao_FakeList_Delete( void *self ){} 22 | static DaoTypeBase FakeList_Typer = 23 | { "FakeList", NULL, NULL, dao_FakeList_Meths, {0}, {0}, Dao_FakeList_Delete, NULL }; 24 | DaoTypeBase *dao_FakeList_Typer = & FakeList_Typer; 25 | 26 | static void dao_FakeList_FakeList( DaoContext *_ctx, DValue *_p[], int _n ) 27 | { 28 | int size = _p[0]->v.i; 29 | DaoContext_PutCData( _ctx, (void*)(size_t)size, dao_FakeList_Typer ); 30 | } 31 | static void dao_FakeList_Iter( DaoContext *_ctx, DValue *_p[], int _n ) 32 | { 33 | int size = (int) DaoCData_GetData( _p[0]->v.cdata ); 34 | DaoTuple *it = _p[1]->v.tuple; 35 | DValue valid = DValue_NewInteger( size >0 ); 36 | DValue index = DValue_NewInteger( 0 ); 37 | DaoTuple_SetItem( it, valid, 0 ); 38 | DaoTuple_SetItem( it, index, 1 ); 39 | } 40 | static void dao_FakeList_GetItem( DaoContext *_ctx, DValue *_p[], int _n ) 41 | { 42 | int size = (int) DaoCData_GetData( _p[0]->v.cdata ); 43 | DaoTuple *it = _p[1]->v.tuple; 44 | DValue index = DaoTuple_GetItem( it, 1 ); 45 | DValue valid = DValue_NewInteger( (index.v.i+1) < size ); 46 | index.v.i += 1; 47 | DaoTuple_SetItem( it, valid, 0 ); 48 | DaoTuple_SetItem( it, index, 1 ); 49 | DaoContext_PutInteger( _ctx, index.v.i * 100 ); 50 | } 51 | 52 | const char* dao_source = 53 | "fl = FakeList(5)\n" 54 | "for( it in fl ) io.writeln( it )\n" 55 | ; 56 | 57 | int main( int argc, char *argv[] ) 58 | { 59 | DString *src; 60 | DaoVmSpace *vms; 61 | DaoNameSpace *ns; 62 | DaoVmProcess *vmp; 63 | 64 | // Search and load the Dao library. 65 | // DaoInitLibrary() can take a parameter which is the path 66 | // to the dynamic loading file of the Dao library. 67 | // If the parameter is NULL, the current path is searched, 68 | // then the path defined by environment variable DAO_DIR, 69 | // then $(HOME)/dao, and then the default system path: 70 | // /usr/local/dao/ or C:\dao\. 71 | // 72 | // With direct APIs, the example must be linked against the Dao library. 73 | // So if direct APIs are used, the following call is not necessary. 74 | #ifndef DAO_DIRECT_API 75 | if( DaoInitLibrary( NULL ) ==0 ) return 1; 76 | #endif 77 | 78 | // Initialize Dao library, and get the default DaoVmSpace object. 79 | // DaoVmSpace is responsible for handling interpreter settings, 80 | // paths and module loading etc. It is need to create several 81 | // other types of objects. 82 | vms = DaoInit(); 83 | 84 | // Get the main namespace of an DaoVmSpace object. 85 | // You can also call DaoNameSpace_New( vms ) to create one. 86 | ns = DaoVmSpace_MainNameSpace( vms ); 87 | 88 | // Get the main virtual machine process of an DaoVmSpace object. 89 | // You can also call DaoVmProcess_New( vms ) to create one. 90 | vmp = DaoVmSpace_MainVmProcess( vms ); 91 | 92 | // Prepare the Dao source codes: 93 | src = DString_New(1); 94 | DString_SetMBS( src, dao_source ); 95 | 96 | // Call the entry function to import the type wrapping FakeList 97 | // into the namespace ns. 98 | // 99 | // Calling to this function is not necessary, if and only if 100 | // the wrapping codes are compiled as dynamic loading library, 101 | // and there is a proper load statement in the Dao codes. 102 | // 103 | // Here the wrapping codes are compiled together with this 104 | // example, so this entry function must be called: 105 | DaoNameSpace_AddType( ns, dao_FakeList_Typer, 1 ); 106 | 107 | // Execute the Dao scripts: 108 | // Since the wrapped functions and types are imported into 109 | // namespace ns, it is need to access the wrapped functions and types 110 | // in the Dao scripts when it is executed: 111 | DaoVmProcess_Eval( vmp, ns, src, 1 ); 112 | 113 | DString_Delete( src ); 114 | DaoQuit(); // Finalizing 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /demo/embedding/greeting.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include"greeting.h" 6 | 7 | Greeting::Greeting( const char * msg ) 8 | { 9 | size = 0; 10 | message = NULL; 11 | if( msg ) SetMessage( msg ); 12 | } 13 | void Greeting::SetMessage( const char * msg ) 14 | { 15 | int n = strlen( msg ); 16 | if( message == NULL ){ 17 | message = (char*) malloc( n+1 ); 18 | size = n; 19 | }else if( size < n ){ 20 | free( message ); 21 | message = (char*) malloc( n+1 ); 22 | size = n; 23 | } 24 | strcpy( message, msg ); 25 | } 26 | void Greeting::PrintMessage() 27 | { 28 | if( message ) printf( "%s\n", message ); 29 | } 30 | void Greeting::DoGreeting( const char *name ) 31 | { 32 | printf( "C++: hi %s!\n", name ); 33 | } 34 | void Greeting::TestGreeting( Greeting *g, const char *name ) 35 | { 36 | g->DoGreeting( name ); 37 | } 38 | 39 | Greeting* GetGreetingObject() 40 | { 41 | static Greeting* singleton = new Greeting("Hello, from C++"); 42 | return singleton; 43 | } 44 | 45 | namespace CxxNS{ 46 | void Testing( Greeting *greeting, Bool bl ) 47 | { 48 | printf( "CxxNS::Testing(): %i\n", bl ); 49 | } 50 | void Testing( int a, Bool2 bl ) 51 | { 52 | printf( "CxxNS::Testing(): %i\n", bl ); 53 | } 54 | void Testing( Test *t, int b, const Test & o, const Test &g, int c ) 55 | { 56 | printf( "CxxNS::Testing(): %p\n", &o ); 57 | } 58 | int Testing2( Test *t, int b, const Test & o, const Test &g, int c ) 59 | { 60 | printf( "CxxNS::Testing(): %p\n", &o ); 61 | return 1; 62 | } 63 | } 64 | 65 | void Testing( CxxNS::Bool bl ) 66 | { 67 | printf( "Testing(): %i\n", bl ); 68 | } 69 | 70 | namespace CxxNS2{ 71 | void Testing( CxxNS::Test *test, CxxNS::Bool bl ) 72 | { 73 | printf( "CxxNS2::Testing(): %i\n", bl ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /demo/embedding/greeting.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | class otto 6 | { 7 | private: 8 | int a; 9 | public: 10 | otto(int b=123){ a = b; printf( "new otto\n" ); } 11 | virtual ~otto(){}; 12 | int geta(){ return a; } 13 | 14 | virtual void vtest(){} 15 | 16 | int& operator[](int i){ return a; } 17 | 18 | protected: 19 | virtual otto test(const otto &value){ 20 | printf( "call protected method\n" ); 21 | return otto(); 22 | } 23 | }; 24 | class otto2 : public otto 25 | { 26 | public: 27 | void vtest(){} 28 | }; 29 | 30 | class Greeting 31 | { 32 | int size; 33 | char *message; 34 | 35 | public: 36 | 37 | Greeting( const char * msg=NULL ); 38 | ~Greeting(){ if( message ) free( message ); } 39 | void SetMessage( const char * msg ); 40 | void PrintMessage(); 41 | 42 | // virtual function to be re-implemented by Dao class. 43 | virtual void DoGreeting( const char *name ); 44 | 45 | // This method will invoke g->DoGreeting( name ). 46 | // 47 | // When a Dao class is derived from this C++ class, 48 | // an instance (object) of that Dao class will contain 49 | // a parent object that is an instance of a wrapping 50 | // C++ class derived from Greeting (see dao_greeting.h). 51 | // 52 | // The derived Dao class may re-implement the above 53 | // virtual method. 54 | // 55 | // If g is an parent object of an Dao object, 56 | // a call to g->DoGreeting( name ) will execute the 57 | // virtual method re-implemented in Dao. 58 | void TestGreeting( Greeting *g, const char *name ); 59 | 60 | virtual void VirtWithDefault( const Greeting & g = Greeting() ){} 61 | 62 | class Null{}; 63 | Null TestNull( const Null & ){ return Null(); } 64 | }; 65 | class Greeting2 : public Greeting{}; 66 | 67 | class AutobindTest 68 | { 69 | public: 70 | // virtual void InternalTransformDerivative(const float in[3], float out[3], 71 | // float derivative[3][3]) = 0; 72 | // virtual void InternalTransformDerivative(const double in[3], double out[3], 73 | // double derivative[3][3]) = 0; 74 | }; 75 | 76 | Greeting* GetGreetingObject(); 77 | 78 | enum Enum1 { AA, BB, CC }; 79 | 80 | #ifdef TRUE 81 | #undef TRUE 82 | #undef FALSE 83 | #endif 84 | 85 | namespace CxxNS 86 | { 87 | enum Bool { FALSE, TRUE }; 88 | enum Enum2 { AA, BB, CC }; 89 | //namespace NestedNS { enum NestedEnum { DD, EE, FF }; } 90 | 91 | typedef Bool Bool2; 92 | 93 | class Test 94 | { 95 | public: 96 | 97 | int index; 98 | double value; 99 | 100 | void Print(){ printf( "%5i: %9f\n", index, value ); } 101 | }; 102 | /* reference a class from global scope */ 103 | void Testing( Greeting *greeting, Bool bl=FALSE ); 104 | void Testing( int a, Bool2 bl=FALSE ); 105 | void Testing( Test *t, int b=0, const Test & o = Test(), const Test & g=Test(), int c=0 ); 106 | int Testing2( Test *t, int b=0, const Test & o = Test(), const Test & g=Test(), int c=0 ); 107 | } 108 | 109 | typedef CxxNS::Test Test2; 110 | 111 | /* reference to a type and a constant from a namespace */ 112 | void Testing( CxxNS::Bool bl=CxxNS::FALSE ); 113 | 114 | namespace CxxNS2 115 | { 116 | /* cross referencing to members from another namespace */ 117 | void Testing( CxxNS::Test *test, CxxNS::Bool bl=CxxNS::FALSE ); 118 | } 119 | -------------------------------------------------------------------------------- /demo/embedding/mod_greeting.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define module_name Greeting 3 | #undef module_name 4 | 5 | #include"greeting.h" 6 | -------------------------------------------------------------------------------- /demo/enums.dao: -------------------------------------------------------------------------------- 1 | 2 | # C++ style definition of enum symbol types: 3 | enum Bool 4 | { 5 | False, 6 | True 7 | } 8 | 9 | 10 | io.writeln( Bool::False ) 11 | io.writeln( Bool.True ) 12 | 13 | 14 | switch( Bool.False ){ 15 | case Bool::False : io.writeln( "Bool::False" ) 16 | case Bool::True : io.writeln( "Bool::True" ) 17 | } 18 | 19 | # The following will also work without casting, 20 | # but it will be less efficient: 21 | switch( (Bool) $True ){ 22 | case Bool::False : io.writeln( "Bool::False" ) 23 | case Bool::True : io.writeln( "Bool::True" ) 24 | } 25 | 26 | 27 | # Symbols can be assigned to a variable of an 28 | # enum symbol type, as long as they are compatible: 29 | var bl : Bool = $True 30 | io.writeln( bl ) 31 | 32 | 33 | # The following is equivalent to: 34 | # enum CardSuit { Club, Diamond, Heart, Spade } 35 | type CardSuit = enum 36 | 37 | var card : CardSuit = $Spade 38 | card = CardSuit::Spade 39 | 40 | # In the following switch-case, the case constants $XYZ 41 | # can also be replaced with CardSuit::XYZ. Both will be 42 | # compiled into a jumping table, because the types of 43 | # "card" and switch case constants can be known/inferred 44 | # at compiling time: 45 | switch( card ){ 46 | case $Club: io.writeln( "Club card" ) 47 | case $Diamond: io.writeln( "Diamond card" ) 48 | case $Heart: io.writeln( "Heart card" ) 49 | case $Spade: io.writeln( "Spade card" ) 50 | } 51 | -------------------------------------------------------------------------------- /demo/errors.dao: -------------------------------------------------------------------------------- 1 | 2 | # The error handling in Dao is based defer blocks which can be executed 3 | # unconditionally or conditionally with respect to exceptions. 4 | # Please see the "Defer Blocks" demo for more details. 5 | # 6 | # In Dao, an exception or error can be raised by the standard method 7 | # std.error() which has three overloaded versions. The simplest version can 8 | # take a string as parameter to become the message of the error. 9 | # 10 | # To handle an error of certain type, one need to define a defer block 11 | # with the error type as its parameter. Such that the block will only 12 | # be executed when an error of that type actually happened. Then the 13 | # error object will be passed to the defer block for proper handling. 14 | # The error is suppressed by such defer block to allow program procede 15 | # normally (after returning to its caller). 16 | # 17 | # If the error can be recovered, one should handle it in the defer block 18 | # and return a value explicitly. This value will be used as the new return 19 | # value of the routine where the defer block is defined. 20 | # 21 | 22 | routine Test() 23 | { 24 | defer ( Error ){ 25 | io.writeln( "Error is handled! And a new value is returned!" ) 26 | return 456 27 | } 28 | io.writeln( "Test(): before error;" ) 29 | std.error( "some error" ) 30 | io.writeln( "Test(): after error;" ) 31 | return 123 32 | } 33 | 34 | io.writeln( Test() ) 35 | 36 | # Example to handle user defined exception type: 37 | class MyError : Error 38 | { 39 | routine (string)(){ return "MyError.{" + self.summary + "}" } 40 | } 41 | 42 | routine Test2() 43 | { 44 | defer ( MyError as error ) { 45 | io.writeln( "recovering from", error ) 46 | return none 47 | } 48 | 49 | io.writeln( "Test2(): before error;" ) 50 | std.error( MyError() ); 51 | io.writeln( "Test2(): after error;" ) 52 | } 53 | 54 | Test2() 55 | 56 | 57 | # To simplify the handling of panics, Dao support a special type 58 | # of code blocks that are executed in new stack frames. Such blocks 59 | # can be defined in the following ways: 60 | # std.exec { block } 61 | # std.exec ( value ) { block } 62 | # which are expressions that may return values. In the second case, 63 | # if the "block" raises an exception, the default "value" is returned 64 | # instead, and the exception is suppressed. 65 | 66 | var ls = { "A", "B", "C" } 67 | var it = "X"; 68 | 69 | std.exec { 70 | defer ( any ) { return "X" } 71 | it = ls[3] # Index out of range; 72 | } 73 | 74 | io.writeln( it ) 75 | 76 | 77 | # A simpler way to write the above codes: 78 | it = std.exec( "X" ){ ls[3] } 79 | 80 | io.writeln( it ) 81 | -------------------------------------------------------------------------------- /demo/hello.dao: -------------------------------------------------------------------------------- 1 | # This is a simple demo: 2 | io.write( "Hello Dao!\n" #{ comment inside codes #} ); 3 | 4 | #{ 5 | Here are multi-lines comments. 6 | Here are multi-lines comments. 7 | #} 8 | io.writef( "\nThis version is %s.\n", std.version(true) ) 9 | -------------------------------------------------------------------------------- /demo/interface.dao: -------------------------------------------------------------------------------- 1 | 2 | interface AA 3 | { 4 | routine Meth( a = 0 ); 5 | routine []( index: int )=>int; 6 | routine .name()=>string; 7 | 8 | routine for( iter: tuple ); 9 | routine []( iter: tuple )=>int; 10 | } 11 | routine Test( o: AA ) 12 | { 13 | io.writeln( "Test( o : AA )", std.about(o) ); 14 | o.Meth( 123 ); 15 | io.writeln( o[1] ); 16 | io.writeln( o.name ); 17 | for(var i in o ) io.writeln(i) 18 | } 19 | 20 | class BB 21 | { 22 | routine Meth( a = 0 ){ io.writeln( a ) } 23 | routine []( index: int ){ return index } 24 | routine .name(){ return "BB" } 25 | 26 | routine for( iter: tuple ){ 27 | iter[0] = true; 28 | iter[1] = 0; 29 | } 30 | routine []( iter: tuple ){ 31 | var id = iter[1]; 32 | iter[0] = iter[1] + 1 < 5; 33 | iter[1] += 1; 34 | return id; 35 | } 36 | } 37 | class CC : BB 38 | { 39 | } 40 | 41 | 42 | Test( BB() ); 43 | Test( CC() ); 44 | 45 | for(var i in BB() ) io.writeln(i) 46 | -------------------------------------------------------------------------------- /demo/interface_forward_declaration.dao: -------------------------------------------------------------------------------- 1 | 2 | interface InterAA; 3 | 4 | interface InterBB 5 | { 6 | routine TestBB( aa : InterAA ); 7 | routine Show(); 8 | } 9 | interface InterAA 10 | { 11 | routine TestAA( bb : InterBB ); 12 | routine Show(); 13 | } 14 | 15 | class One 16 | { 17 | routine TestAA( bb : InterBB ){ bb.Show() } 18 | routine Show(){ io.writeln( "One::Show()" ) } 19 | } 20 | 21 | class Another 22 | { 23 | routine TestBB( aa : InterAA ){ aa.Show() } 24 | routine Show(){ io.writeln( "Another::Show()" ) } 25 | } 26 | 27 | var o = One(); 28 | var a = Another(); 29 | o.TestAA( a ); 30 | a.TestBB( o ); 31 | -------------------------------------------------------------------------------- /demo/lists.dao: -------------------------------------------------------------------------------- 1 | 2 | var list1 = { 1, 2, 3 } # list 3 | var list2 = { 1.0, 2, 3 } # list 4 | var list3 = { 1 : 5 } # list 5 | var list4 = list{ 1 : 2 : 5 } # list 6 | 7 | io.writeln( list1 ) 8 | io.writeln( list2 ) 9 | io.writeln( list3 ) 10 | io.writeln( list4 ) 11 | io.writeln( "number of items:", %list4 ) 12 | -------------------------------------------------------------------------------- /demo/maps.dao: -------------------------------------------------------------------------------- 1 | 2 | # A map is created using "=>", 3 | var map1 = { "EE" => 5, "BB" => 2, "CC" => 3, "AA" => 1 } 4 | 5 | # A hash map is created using "->", 6 | var hash1 = { "EE" -> 5, "BB" -> 2, "CC" -> 3, "AA" -> 1 } 7 | 8 | io.writeln( std.about( map1 ) ) 9 | io.writeln( std.about( hash1 ) ) 10 | 11 | io.writeln( map1 ) 12 | io.writeln( hash1 ) 13 | io.writeln( "number of key/value pairs:", %hash1 ) 14 | 15 | io.writeln( map1["BB"] ) # get value by key; 16 | io.writeln( hash1["CC"] ) # get value by key; 17 | 18 | io.writeln( map1[ "AA" : "CC" ] ) # get sub map by slicing; 19 | io.writeln( map1[ "BB" : ] ) # get sub map by slicing; 20 | io.writeln( map1[ : "CC" ] ) # get sub map by slicing; 21 | 22 | 23 | # The "map" keyword is optional, 24 | var map2 = map{ "ABC" => 123, "DEF" => 456 } 25 | var hash2 = map{ "ABC" -> 123, "DEF" -> 456 } 26 | 27 | io.writeln( map2 ) 28 | io.writeln( hash2 ) 29 | io.writeln( map2.size() ) # get size; 30 | io.writeln( map2.keys() ) # get keys; 31 | io.writeln( map2.values() ) # get values; 32 | 33 | 34 | # With explicit type, the initializing float keys are 35 | # converted to integers automatically: 36 | var map3 : map = { 12.3 => "abc", 45.6 => "def" } 37 | 38 | io.writeln( map3 ) 39 | 40 | 41 | # Iterate over maps: 42 | for(var keyvalue in map1 ) io.writeln( keyvalue ) 43 | for(var keyvalue in hash1 ) io.writeln( keyvalue ) 44 | -------------------------------------------------------------------------------- /demo/mixins.dao: -------------------------------------------------------------------------------- 1 | 2 | class Base 3 | { 4 | var value = 456 5 | routine Meth2(){ io.writeln( self, value ) } 6 | } 7 | 8 | # 9 | # Classes to be used as mixin bases can be specified in a pair of brackets 10 | # following the class name. Only classes without parent classes can 11 | # be used as mixins. 12 | # 13 | class Mixin ( Base ) 14 | { 15 | var index = 123 16 | 17 | routine Meth(){ io.writeln( self, index, value ) } 18 | routine Meth2( a : string ){ io.writeln( self, index, value, a ) } 19 | } 20 | 21 | # 22 | # The "Base" class will be presented only once in "Klass": 23 | # 24 | class Klass ( Base, Mixin ) 25 | { 26 | var index = 123456 27 | routine Meth2( a : int ){ io.writeln( self, index, value, a ) } 28 | } 29 | 30 | var k = Klass() 31 | 32 | io.writeln( k.index ) 33 | 34 | k.Meth() 35 | k.Meth2() 36 | k.Meth2( "abc" ) 37 | k.Meth2( 789 ) 38 | 39 | 40 | -------------------------------------------------------------------------------- /demo/numbers.dao: -------------------------------------------------------------------------------- 1 | 2 | # Integer numbers: 3 | 4 | var I1 = 123 5 | var I2 = 0x123a 6 | var I3 :int = 789 7 | 8 | io.writeln( I1, I2, I3 ) 9 | io.writeln( "size of int:", %I1 ) 10 | io.writeln( std.about(I1), "\n" ) 11 | 12 | 13 | var F1 = .12 14 | var F2 = 12. 15 | var F3 = 12.5 16 | var F4 = 2e-3 17 | var F5 = 2E-3 18 | 19 | io.writeln( F1, F2, F3, F4, F5 ) 20 | io.writeln( "size of float:", %F1 ) 21 | io.writeln( std.about(F1), "\n" ) 22 | 23 | 24 | 25 | # Complex number (C suffix for the imaginary part): 26 | 27 | var C1 = 1C 28 | var C2 = 123C 29 | var C3 = 12.3C 30 | var C4 = C3.real; 31 | var C5 = C3.imag; 32 | 33 | io.writeln( C1, C2, C3, C4, C5 ) 34 | io.writeln( "size of complex:", %C1 ) 35 | io.writeln( std.about(C1), "\n" ) 36 | 37 | 38 | -------------------------------------------------------------------------------- /demo/object_operator.dao: -------------------------------------------------------------------------------- 1 | 2 | class Test{} 3 | 4 | var t1 = Test(); 5 | var t2 = Test(); 6 | var eq = t1 == t2; 7 | 8 | 9 | class Integer 10 | { 11 | var value = 0; 12 | 13 | routine Integer( v = 0 ){ value = v } 14 | 15 | static routine +( A : Integer, B : int ){ 16 | io.writeln( "Integer + int" ); 17 | return Integer( A.value + B ); 18 | } 19 | # no longer supported, now the first operand must be a user type: 20 | static routine +( A : int, B : Integer ){ 21 | io.writeln( "int + Integer" ); 22 | return Integer( A + B.value ); 23 | } 24 | static routine +( A : Integer, B : Integer ){ 25 | io.writeln( "Integer + Integer" ); 26 | return Integer( A.value + B.value ); 27 | } 28 | static routine +( C : Integer, A : Integer, B : Integer ){ 29 | io.writeln( "Integer = Integer + Integer" ); 30 | C.value = A.value + B.value; 31 | return C; 32 | } 33 | routine +=( B : Integer ){ 34 | io.writeln( "Integer += Integer" ); 35 | value += B.value; 36 | return self; 37 | } 38 | static routine -( A : Integer ){ 39 | io.writeln( "- Integer" ); 40 | return Integer( - A.value ); 41 | } 42 | static routine -( A : Integer, B : Integer ){ 43 | io.writeln( "Integer - Integer" ); 44 | return Integer( A.value - B.value ); 45 | } 46 | static routine <( A : Integer, B : Integer ){ 47 | io.writeln( "Integer < Integer" ); 48 | return Integer( A.value < B.value ); 49 | } 50 | static routine !( C : Integer, A : Integer ){ 51 | io.writeln( "routine !( C : Integer, A : Integer )" ); 52 | C.value = ! A.value; 53 | return C; 54 | } 55 | static routine !( A : Integer ){ 56 | io.writeln( "routine !( A : Integer )" ); 57 | return Integer( ! A.value ); 58 | } 59 | static routine <<( C: Integer, A: Integer, B: int ){ 60 | io.writeln( "routine <<( C: Integer, B: Integer, A: int )" ); 61 | C.value = A.value << B; 62 | return C 63 | } 64 | static routine <<( A: Integer, B: int ){ 65 | io.writeln( "routine <<( C: Integer, B: Integer, A: int )" ); 66 | return Integer( A.value << B ); 67 | } 68 | static routine ~( C : Integer, A : Integer ){ 69 | io.writeln( "routine ~( C : Integer, A : Integer )" ); 70 | C.value = ~ A.value; 71 | return C; 72 | } 73 | static routine ~( A : Integer ){ 74 | io.writeln( "routine ~( A : Integer )" ); 75 | return Integer( ~ A.value ); 76 | } 77 | static routine %( A : Integer ){ 78 | io.writeln( "routine %( A : Integer )" ); 79 | return % A.value; 80 | } 81 | #{ 82 | #} 83 | routine serialize(){ return value; } 84 | } 85 | 86 | 87 | var n1 = Integer(10); 88 | var n2 = Integer(20); 89 | # n3 = 1 + n2; # no longer supported, now the first operand must be a user type; 90 | var n4 = n1 + 2; 91 | var n5 = n1 + n2; 92 | var n6 = - n5; 93 | var n7 = n5 - n4; 94 | var n8 = n5 < n4; 95 | var n9 = n5 > n4; 96 | 97 | io.writeln( n4, n5, n6, n7, n8, n9 ); 98 | 99 | #{ 100 | n8 = Integer{10}; 101 | n9 = Integer{20}; 102 | #} 103 | n9 = ! n8 104 | io.writeln( n8, n9 ); 105 | n9 = ! n9 106 | io.writeln( n8, n9 ); 107 | 108 | n9.value = 10; 109 | n8.value = 20; 110 | io.writeln( "=======", n8, n9 ); 111 | for(var i = 1 : 2 ) n9 = n8 + n9 112 | io.writeln( "=======" ); 113 | n9 += n8 114 | 115 | var ls = { n8 + n9 } 116 | 117 | std.about( n8 + n9 ); 118 | 119 | invar n11 = Integer(10); 120 | #io.writeln( % n11 ) 121 | #io.writeln( n9 + n11 ) 122 | 123 | var k : any = n9 124 | io.writeln( "The following should raise an error!" ) 125 | io.writeln( k + n11 ) # Error 126 | -------------------------------------------------------------------------------- /demo/resource.txt: -------------------------------------------------------------------------------- 1 | Sample resource file! 2 | -------------------------------------------------------------------------------- /demo/routines.dao: -------------------------------------------------------------------------------- 1 | 2 | #{ 3 | # The following is a simple function that can take 3 parameters, 4 | # where the first can be of any type, the second can only be a 5 | # string, and the last can only be an optional integer with default 6 | # value 123. 7 | #} 8 | routine FunctionA( obj, name : string, index = 123 ) 9 | { 10 | io.writeln( obj, name, index ) 11 | } 12 | FunctionA( [], "abc" ) 13 | FunctionA( {}, "def", 456 ) 14 | 15 | 16 | #{ 17 | # If "..." is used as the last parameter in a function definition, 18 | # this function can take a variable number of parameters (up to 30). 19 | # (Such function is called variadic function). 20 | #} 21 | routine FunctionB( name : string, ... ) 22 | { 23 | io.writeln( name ) 24 | } 25 | FunctionB( "abc" ) 26 | 27 | 28 | #{ 29 | # To access the variadic part of the parameters inside a variadic 30 | # function, one has to define an alias for all the parameters using 31 | # the "as" keyword. So here, the "all" variable will be a tuple that 32 | # contains all the parameters passed to this function. 33 | #} 34 | routine FunctionC( name : string, ... as all ) 35 | { 36 | io.writeln( name, all ) 37 | } 38 | FunctionC( "abc", 123, [1,2] ) 39 | 40 | 41 | #{ 42 | # The variadic parameter "..." can also have an explicit type, 43 | # to ensure it only accepts parameters of that type. 44 | #} 45 | routine FunctionD( name : string, ... :int as all ) 46 | { 47 | io.writeln( name, all ) 48 | } 49 | FunctionD( "abc", 123, 456 ) # OK; 50 | # FunctionD( "abc", 123, [1,2] ) # ERROR; 51 | 52 | 53 | 54 | ############################### 55 | # Some tests: 56 | ############################### 57 | 58 | routine TestFunction( a : string, b = 123 ) 59 | { 60 | io.writeln( a, b ) 61 | } 62 | 63 | 64 | routine TestVariadicFunction( a : string, ... : int as all ) 65 | { 66 | io.writeln( a, all ) 67 | } 68 | 69 | 70 | ######################## 71 | ## Static Checking 72 | ######################## 73 | 74 | TestFunction( "abc" ) # Test default parameter; 75 | TestFunction( "abc", 456.5 ) # implicit conversion; 76 | 77 | # TestFunction() # ERROR: too few parameters; 78 | # TestFunction( "abc", 123, 456 ) # ERROR: too many parameters; 79 | 80 | TestVariadicFunction( "abc" ) # right parameter; 81 | TestVariadicFunction( "abc", 123 ) # right parameter; 82 | 83 | # TestVariadicFunction( 123 ) # ERROR: wrong first parameter; 84 | # TestVariadicFunction( "abc", "abc" ) # ERROR: wrong second parameter; 85 | 86 | 87 | ########################## 88 | ## Static Checking 89 | ## With function type only 90 | ########################## 91 | 92 | var TestFunction2 = TestFunction 93 | var TestVariadicFunction2 = TestVariadicFunction 94 | 95 | TestFunction2( "abc" ) # Test default parameter; 96 | TestFunction2( "abc", 456.5 ) # implicit conversion; 97 | 98 | # TestFunction2() # ERROR: too few parameters; 99 | # TestFunction2( "abc", 123, 456 ) # ERROR: too many parameters; 100 | 101 | TestVariadicFunction2( "abc" ) # right parameter; 102 | TestVariadicFunction2( "abc", 123 ) # right parameter; 103 | 104 | # TestVariadicFunction2( 123 ) # wrong first parameter; 105 | # TestVariadicFunction2( "abc", "abc" ) # wrong second parameter; 106 | 107 | 108 | ########################## 109 | ## Dynamic Checking 110 | ########################## 111 | 112 | var TestFunction3 : any = TestFunction 113 | var TestVariadicFunction3 : any = TestVariadicFunction 114 | 115 | TestFunction3( "abc" ) # Test default parameter; 116 | TestFunction3( "abc", 456.5 ) # implicit conversion; 117 | 118 | # TestFunction3() # ERROR: too few parameters; 119 | # TestFunction3( "abc", 123, 456 ) # ERROR: too many parameters; 120 | 121 | TestVariadicFunction3( "abc" ) # right parameter; 122 | TestVariadicFunction3( "abc", 123 ) # right parameter; 123 | 124 | # TestVariadicFunction3( 123 ) # wrong first parameter; 125 | # TestVariadicFunction3( "abc", "abc" ) # wrong second parameter; 126 | -------------------------------------------------------------------------------- /demo/strings.dao: -------------------------------------------------------------------------------- 1 | var mbs = "hello" 2 | var wcs = "道语言" 3 | 4 | # verbatim strings: 5 | var mbs2 = @[] some text @[] 6 | 7 | # C++ codes in MBS: 8 | var cpp = 9 | @[cpp x] 10 | class AA 11 | { 12 | int index; 13 | }; 14 | struct BB{}; 15 | @[cpp x] 16 | 17 | 18 | # Lua codes in MBS: 19 | var lua = 20 | @[lua] 21 | local a = 1; 22 | function Test() 23 | io.write( "Hello" ) 24 | end 25 | @[lua] 26 | 27 | # HTML codes in WCS: 28 | var html = 29 | @[html:123456] 30 | 31 | 32 | 33 | @[html:123456] 34 | 35 | io.writeln( mbs ); 36 | io.writeln( wcs ); 37 | io.writeln( mbs2 ); 38 | io.writeln( cpp ); 39 | io.writeln( lua ); 40 | io.writeln( html ); 41 | -------------------------------------------------------------------------------- /demo/tuples.dao: -------------------------------------------------------------------------------- 1 | 2 | var tup01 = ( 123, "abc" ) # tuple with unnamed items; 3 | var tup02 = ( index = 123, "abc" ) # first item is named as "index"; 4 | var tup03 = tuple{ 123, name = "abc" } 5 | 6 | io.writeln( tup01, tup02, tup03 ) 7 | 8 | 9 | var tup11 : tuple = (1, 2) 10 | var tup12 : tuple = (123, "abc") 11 | var tup13 : tuple = (1, 2, 3, "abc") 12 | 13 | io.writeln( tup11, tup12, tup13 ) 14 | io.writeln( "number of items:", %tup13 ) 15 | -------------------------------------------------------------------------------- /demo/user_functional.dao: -------------------------------------------------------------------------------- 1 | 2 | # A function that can be called with a code section. 3 | # The code section is expected to take an integer as parameter, 4 | # and return a string. 5 | routine Test()[X:int=>string] => string 6 | { 7 | io.writeln( "In functional method!" ); 8 | var s = yield( 123 ); # execute the code section; 9 | io.writeln( "Yielded value:", s ); 10 | return s; 11 | } 12 | 13 | Test { [X] 14 | io.writeln( "In code section:", X ); 15 | return "abc"; 16 | } 17 | 18 | routine Test( alist : list<@T> )[ item :@T, index :int => none|int ] =>list<@T> 19 | { 20 | yield( 55, 0 ); # invoke the code section of the caller; 21 | io.writeln( alist.collect{ [X] if( X < 33 ) return X } ); 22 | # call the list functional method with the caller"s code section; 23 | return alist.collect{ [X,Y] yield(X,Y) }; 24 | } 25 | 26 | var res = Test( {11,22,33,44} ){ [X] X > 22 } 27 | 28 | io.writeln( res, std.about(res) ); 29 | -------------------------------------------------------------------------------- /demo/user_map_key.dao: -------------------------------------------------------------------------------- 1 | 2 | class UserKey 3 | { 4 | var value = 0 5 | routine ==( other: UserKey ){ 6 | return value == other.value; 7 | } 8 | routine <( other: UserKey ){ 9 | return value < other.value; 10 | } 11 | routine (int)( hashing = false ){ 12 | io.writeln( 'Calling UserKey::(int)(hashing=false)', value ) 13 | return value 14 | } 15 | routine (string)(){ 16 | io.writeln( 'Calling UserKey::(string)()', value ) 17 | return (string)value 18 | } 19 | } 20 | 21 | var table = { UserKey.{0} -> 0 } 22 | var dt1 = UserKey.{ 123 } 23 | var dt2 = UserKey.{ 456 } 24 | var dt3 = UserKey.{ 123 } 25 | 26 | table[ dt1 ] = 1 27 | table[ dt2 ] = 1 28 | 29 | io.writeln( table.find( dt3 ) != none ) # true 30 | io.writeln( dt2 in table ); # true 31 | 32 | dt3.value += 100 33 | io.writeln( table.find( dt3 ) != none ) 34 | 35 | 36 | dt1.value += 100 37 | io.writeln( table.find( UserKey.{123} ) != none ) 38 | -------------------------------------------------------------------------------- /demo/user_type_casting.dao: -------------------------------------------------------------------------------- 1 | 2 | class Test 3 | { 4 | var value = { 123.2, 456.5 }; 5 | 6 | # conversion to int: 7 | routine (int) () { 8 | io.writeln( "casting to int" ); 9 | return value.sum(); 10 | } 11 | 12 | # conversion to float: 13 | routine (float) () { 14 | io.writeln( "casting to float" ); 15 | return value.sum(); 16 | } 17 | # conversion to string: 18 | routine (string) () { 19 | io.writeln( "casting to string" ) 20 | return value.reduce(""){ [x, y] y += (string)x }; # convert to string 21 | } 22 | routine (array) () { 23 | io.writeln( "casting to array" ); 24 | return array( %value ){ [i] value[i] } 25 | } 26 | routine (tuple) () { 27 | io.writeln( "casting to tuple" ); 28 | return (value[0], value[1]) 29 | } 30 | } 31 | 32 | var t = Test(); 33 | 34 | var a = (int)t; 35 | var b = (float)t; 36 | var c = (string)t; 37 | var v = (array)t; 38 | var v2 = (tuple)t; 39 | 40 | io.writeln( a, b, c, v2, std.about(v2) ) 41 | 42 | var e = Exception::Error( "testing" ); 43 | io.writeln( (string)e ); 44 | 45 | # a = (int)e; # error 46 | -------------------------------------------------------------------------------- /demo/verbatim.dao: -------------------------------------------------------------------------------- 1 | 2 | # A verbatim string is a string that can contain anything 3 | # without interpreting escape characters. 4 | 5 | # A pair of @[] can be used to quote a verbatim string: 6 | var str = @[] some text @[] 7 | 8 | # A delimiter can be placed in the squared brackets to make sure that 9 | # it can correctly mark the ending of the verbatim string. 10 | # A delimiter can contain letters, digits, underscores, blank spaces, 11 | # dots, colons, dashes, assignment marks. 12 | var cpp = 13 | @[cpp x] 14 | class AA 15 | { 16 | int index; 17 | }; 18 | struct BB{}; 19 | @[cpp x] 20 | 21 | 22 | # Lua codes in MBS: 23 | var lua = 24 | @[lua] 25 | local a = 1; 26 | function Test() 27 | io.write( "Hello" ) 28 | end 29 | @[lua] 30 | 31 | # HTML codes in WCS: 32 | var html = 33 | @[html:123456] 34 | 35 | 36 | 37 | @[html:123456] 38 | 39 | var random = 40 | @[=============] 41 | asdffd348234lks"djcnzxkWPOWI"Q23EW487503498*(S*(&)(*&QW39EQ8723049 42 | ASFJA 9384170(*&0(*AS&(A*S&)(*A&sADSUYasi[0A9S8-09a8-AS69876%A 43 | """""""asdfaoi0342sdlfkj(*&^98q73wrq)(&^%&^RFKJRYE" 44 | s8%S5$&A^5s4^a4" 45 | @[=============] 46 | 47 | io.writeln( str ); 48 | io.writeln( cpp ); 49 | io.writeln( lua ); 50 | io.writeln( html ); 51 | io.writeln( random ); 52 | -------------------------------------------------------------------------------- /kernel/daoBase.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Virtual Machine 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2006-2017, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef DAO_BASE_H 30 | #define DAO_BASE_H 31 | 32 | #include"daoPlatform.h" 33 | 34 | 35 | #define IntToPointer( x ) ((void*)(size_t)(x)) 36 | 37 | 38 | typedef struct DRoutines DRoutines; 39 | 40 | typedef struct DaoTypeTree DaoTypeTree; 41 | 42 | typedef struct DaoToken DaoToken; 43 | typedef struct DaoInode DaoInode; 44 | typedef struct DaoVmCodeX DaoVmCodeX; 45 | 46 | typedef struct DaoFuture DaoFuture; 47 | typedef struct DaoNameValue DaoNameValue; 48 | typedef struct DaoConstant DaoConstant; 49 | typedef struct DaoVariable DaoVariable; 50 | 51 | typedef struct DaoCnode DaoCnode; 52 | typedef struct DaoOptimizer DaoOptimizer; 53 | 54 | 55 | /* 56 | // Bit structure of the lookup index: 57 | // E2P2S4U8I16 = EEPPSSSSUUUUUUUUIIIIIIIIIIIIIIII 58 | // E: Error; P: Permission; S: Storage; U: Up/parent; I: Index 59 | */ 60 | #define LOOKUP_BIND( st, pm, up, id ) (((pm)<<28)|((st)<<24)|((up)<<16)|id) 61 | 62 | #define LOOKUP_BIND_LC( id ) ((DAO_LOCAL_CONSTANT<<24)|id) 63 | #define LOOKUP_BIND_GC( id ) ((DAO_GLOBAL_CONSTANT<<24)|id) 64 | #define LOOKUP_BIND_GV( id ) ((DAO_GLOBAL_VARIABLE<<24)|id) 65 | 66 | #define LOOKUP_PM( one ) (((one)>>28)&3) 67 | #define LOOKUP_ST( one ) (((one)>>24)&0xf) 68 | #define LOOKUP_UP( one ) (((one)>>16)&0xff) 69 | #define LOOKUP_ID( one ) ((unsigned short)((one)&0xffff)) 70 | 71 | #define LOOKUP_ISCST( one ) (LOOKUP_ST(one)&1) 72 | 73 | 74 | typedef struct DaoConfig DaoConfig; 75 | struct DaoConfig 76 | { 77 | short cpu; /* number of CPU */ 78 | short jit; /* enable JIT compiling */ 79 | short optimize; /* enable optimization */ 80 | short iscgi; /* is CGI script */ 81 | short tabspace; /* number of spaces counted for a tab */ 82 | }; 83 | 84 | extern DaoConfig daoConfig; 85 | 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /kernel/daoGC.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Virtual Machine 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2006-2017, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef DAO_GC_H 30 | #define DAO_GC_H 31 | 32 | #include"daoType.h" 33 | 34 | /* 35 | // The DaoCdata objects must be globally unique for the wrapped data. 36 | // Because relations regarding to the inheritance can only be set 37 | // when the wrappers are initialized at the first time. 38 | */ 39 | DAO_DLL DaoCdata* DaoWrappers_MakeCdata( DaoType *type, void *data, int owned ); 40 | 41 | 42 | #ifdef DAO_USE_GC_LOGGER 43 | DAO_DLL void DaoObjectLogger_Init(); 44 | DAO_DLL void DaoObjectLogger_Quit(); 45 | DAO_DLL void DaoObjectLogger_LogNew( DaoValue *object ); 46 | DAO_DLL void DaoObjectLogger_LogDelete( DaoValue *object ); 47 | DAO_DLL void DaoObjectLogger_PrintProfile(); 48 | #endif 49 | 50 | DAO_DLL int DaoGC_IsConcurrent(); 51 | DAO_DLL int DaoGC_Min( int n ); 52 | DAO_DLL int DaoGC_Max( int n ); 53 | 54 | DAO_DLL daoint DaoGC_GetCycleIndex(); 55 | 56 | DAO_DLL void DaoGC_Start(); 57 | DAO_DLL void DaoGC_Finish(); 58 | DAO_DLL void DaoGC_TryInvoke(); 59 | DAO_DLL void DaoGC_SetMode( int fullgc, int finalizing ); 60 | 61 | DAO_DLL void DaoCGC_Start(); 62 | 63 | DAO_DLL void DaoGC_IncCycRC( DaoValue *value ); 64 | DAO_DLL void DaoGC_IncRC( DaoValue *value ); 65 | DAO_DLL void DaoGC_DecRC( DaoValue *value ); 66 | DAO_DLL void DaoGC_Assign( DaoValue **dest, DaoValue *src ); 67 | DAO_DLL void DaoGC_Assign2( DaoValue **dest, DaoValue *src ); 68 | 69 | DAO_DLL void DaoGC_IncRCs( DList *values ); 70 | DAO_DLL void DaoGC_DecRCs( DList *values ); 71 | 72 | #define GC_IncRC( p ) DaoGC_IncRC( (DaoValue*)(p) ) 73 | #define GC_DecRC( p ) DaoGC_DecRC( (DaoValue*)(p) ) 74 | #define GC_Assign(dest,src) DaoGC_Assign( (DaoValue**)(dest), (DaoValue*)(src) ); 75 | 76 | 77 | DAO_DLL void DaoGC_LockData(); 78 | DAO_DLL void DaoGC_UnlockData(); 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /kernel/daoInferencer.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Virtual Machine 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2006-2017, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __DAO_INFERENCER_H__ 30 | #define __DAO_INFERENCER_H__ 31 | 32 | #include"daoBase.h" 33 | 34 | 35 | /* Instruction Node */ 36 | struct DaoInode 37 | { 38 | unsigned short code; /* Opcode; */ 39 | unsigned short a, b, c; /* Operands; */ 40 | unsigned short state; /* State; */ 41 | unsigned short level; /* Lexical level; */ 42 | unsigned short line; /* Line number in source file; */ 43 | unsigned int first; /* Index of the first token of the expression; */ 44 | unsigned short middle; /* The middle token, relative to "first"; */ 45 | unsigned short last; /* The last token, relative to "first"; */ 46 | 47 | unsigned int index; /* Index of the instruction; */ 48 | 49 | DaoInode *jumpTrue; 50 | DaoInode *jumpFalse; 51 | DaoInode *extra; 52 | 53 | DaoInode *prev; 54 | DaoInode *next; 55 | }; 56 | 57 | DaoInode* DaoInode_New(); 58 | 59 | void DaoInodes_Clear( DList *inodes ); 60 | 61 | void DaoRoutine_CodesToInodes( DaoRoutine *self, DList *inodes ); 62 | void DaoRoutine_CodesFromInodes( DaoRoutine *self, DList *inodes ); 63 | void DaoRoutine_SetupSimpleVars( DaoRoutine *self ); 64 | 65 | 66 | 67 | typedef struct DaoInferencer DaoInferencer; 68 | 69 | struct DaoInferencer 70 | { 71 | unsigned char tidHost; 72 | unsigned char silent; 73 | unsigned char error; 74 | 75 | unsigned short currentIndex; 76 | 77 | DaoRoutine *routine; 78 | DaoClass *hostClass; 79 | 80 | DList *inodes; 81 | DList *consts; 82 | DList *types; 83 | DList *types2; 84 | 85 | DList *rettypes; 86 | DList *typeMaps; 87 | DList *errors; 88 | DList *array; 89 | DList *array2; 90 | DList *defers; 91 | DList *routines; 92 | 93 | DMap *defs; 94 | DMap *defs2; 95 | DMap *defs3; 96 | DMap *rettypes2; 97 | DString *mbstring; 98 | 99 | DaoType *type_source; 100 | DaoType *type_target; 101 | int tid_target; 102 | int annot_first; 103 | int annot_last; 104 | 105 | DaoType *basicTypes[DAO_ARRAY]; 106 | }; 107 | 108 | DaoInferencer* DaoInferencer_New(); 109 | void DaoInferencer_Delete( DaoInferencer *self ); 110 | void DaoInferencer_Init( DaoInferencer *self, DaoRoutine *routine, int silent ); 111 | void DaoInferencer_Reset( DaoInferencer *self ); 112 | int DaoInferencer_DoInference( DaoInferencer *self ); 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /kernel/daoMap.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Virtual Machine 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2006-2017, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef DAO_MAP_H 30 | #define DAO_MAP_H 31 | 32 | #include"daoBase.h" 33 | 34 | #define DAO_HASH_SEED 0xda0 35 | 36 | #ifndef DAO_MAP_ITEM_TYPES 37 | #define DAO_MAP_ITEM_TYPES 38 | #endif 39 | 40 | enum KeySearchType 41 | { 42 | DAO_KEY_EQ, 43 | DAO_KEY_LE, 44 | DAO_KEY_GE 45 | }; 46 | 47 | typedef union 48 | { 49 | daoint pInt; 50 | void *pVoid; 51 | dao_complex *pComplex; 52 | DString *pString; 53 | DList *pList; 54 | DMap *pMap; 55 | DaoValue *pValue; 56 | DaoInteger *pInteger; 57 | DaoCstruct *pCstruct; 58 | DaoClass *pClass; 59 | DaoRoutine *pRoutine; 60 | DaoProcess *pProcess; 61 | DaoType *pType; 62 | DaoInode *pInode; 63 | DaoCnode *pCnode; 64 | DAO_MAP_ITEM_TYPES 65 | }DNodeData; 66 | 67 | struct DNode 68 | { 69 | unsigned int color : 1; 70 | unsigned int hash : 31; 71 | 72 | DNode *parent; 73 | DNode *left; 74 | DNode *right; 75 | 76 | DNodeData key; 77 | DNodeData value; 78 | }; 79 | 80 | typedef DMap DHash; 81 | 82 | struct DMap 83 | { 84 | DNode **table; /* Hash table, each entry is a tree; */ 85 | DNode *root; /* Root node; */ 86 | DNode *list; /* First node of the free list; */ 87 | size_t size; /* Size of the map; */ 88 | uint_t hashing; /* Hashing seed; */ 89 | uint_t tsize2rt; /* Square root of the table size; */ 90 | uint_t keytype : 4; /* Key type; */ 91 | uint_t valtype : 4; /* Value type; */ 92 | uint_t changes : 24; /* Changes that may change the tree structure(s); */ 93 | }; 94 | 95 | DAO_DLL DMap* DMap_New( short kt, short vt ); 96 | DAO_DLL DMap* DHash_New( short kt, short vt ); 97 | DAO_DLL DMap* DMap_Copy( DMap *dmap ); 98 | DAO_DLL void DMap_Assign( DMap *self, DMap *other ); 99 | 100 | DAO_DLL void DMap_Delete( DMap *self ); 101 | DAO_DLL void DMap_Clear( DMap *self ); 102 | DAO_DLL void DMap_Reset( DMap *self ); 103 | DAO_DLL void DMap_Erase( DMap *self, void *key ); 104 | DAO_DLL void DMap_EraseNode( DMap *self, DNode *node ); 105 | 106 | DAO_DLL DNode* DMap_Insert( DMap *self, void *key, void *value ); 107 | DAO_DLL DNode* DMap_Find( DMap *self, void *key ); 108 | DAO_DLL DNode* DMap_FindNode( DMap *self, void *key, int type ); 109 | DAO_DLL DNode* DMap_First( DMap *self ); 110 | DAO_DLL DNode* DMap_Next( DMap *self, DNode *node ); 111 | 112 | #define MAP_Insert( s, k, v ) DMap_Insert( (DMap*)(s), (void*)(daoint)(k), (void*)(daoint)(v) ) 113 | #define MAP_Erase( s, k ) DMap_Erase( (DMap*)(s), (void*)(daoint)(k) ) 114 | #define MAP_Find( s, k ) DMap_Find( (DMap*)(s), (void*)(daoint)(k) ) 115 | #define MAP_FindLE( s, k ) DMap_FindLE( (DMap*)(s), (void*)(daoint)(k) ) 116 | #define MAP_FindGE( s, k ) DMap_FindGE( (DMap*)(s), (void*)(daoint)(k) ) 117 | 118 | 119 | DAO_DLL unsigned int Dao_Hash( const void *key, int len, unsigned int seed ); 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /kernel/daoObject.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Virtual Machine 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2006-2017, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef DAO_OBJECT_H 30 | #define DAO_OBJECT_H 31 | 32 | #include"daoType.h" 33 | 34 | struct DaoObject 35 | { 36 | DAO_VALUE_COMMON; 37 | 38 | ushort_t isRoot : 1; 39 | ushort_t isNull : 1; 40 | ushort_t isAsync : 1; 41 | ushort_t isInited : 1; 42 | ushort_t unused : 12; 43 | ushort_t valueCount; 44 | 45 | DaoClass *defClass; /* definition class; */ 46 | DaoObject *rootObject; /* root object for safe down-casting; */ 47 | DaoValue *parent; /* parent object; */ 48 | DaoValue **objValues; /* instance variable values; */ 49 | }; 50 | 51 | DAO_DLL DaoObject* DaoObject_Allocate( DaoClass *klass, int value_count ); 52 | DAO_DLL DaoObject* DaoObject_New( DaoClass *klass ); 53 | DAO_DLL void DaoObject_Init( DaoObject *self, DaoObject *that, int offset ); 54 | DAO_DLL void DaoObject_Delete( DaoObject *self ); 55 | 56 | DAO_DLL int DaoObject_ChildOf( DaoObject *self, DaoValue *obj ); 57 | 58 | DAO_DLL DaoValue* DaoObject_CastToBase( DaoObject *self, DaoType *host ); 59 | DAO_DLL void DaoObject_SetParentCstruct( DaoObject *self, DaoCstruct *parent ); 60 | 61 | DAO_DLL int DaoObject_SetData( DaoObject *self, DString *name, DaoValue *value, DaoObject *objThis ); 62 | DAO_DLL int DaoObject_GetData( DaoObject *self, DString *name, DaoValue **data, DaoObject *objThis ); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /kernel/daoOptimizer.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Virtual Machine 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2006-2017, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __DAO_OPTIMIZER_H__ 30 | #define __DAO_OPTIMIZER_H__ 31 | 32 | #include"daoBase.h" 33 | 34 | 35 | enum DaoCnodeOperandType 36 | { 37 | DAO_OP_NONE, 38 | DAO_OP_SINGLE, 39 | DAO_OP_PAIR, 40 | DAO_OP_TRIPLE, 41 | DAO_OP_RANGE, 42 | DAO_OP_RANGE2 43 | }; 44 | 45 | 46 | /* Code Node */ 47 | struct DaoCnode 48 | { 49 | uchar_t type; /* use type of operands; */ 50 | uchar_t reachable; /* reachable status; */ 51 | ushort_t index; /* index of the node; */ 52 | ushort_t first; /* the only (SINGLE) or the first (PAIR/RANGE) used variable; */ 53 | ushort_t second; /* the second (PAIR) or the one-past-last (RANGE) used variable; */ 54 | ushort_t third; /* the third (TRIPLE) used variable; */ 55 | ushort_t lvalue; /* variable defined by the instruction; 0xffff for none; */ 56 | ushort_t lvalue2; /* C operand for SETF, SETI, SETDI, SETMI instructions; */ 57 | ushort_t exprid; /* expression id; 0xffff for none; */ 58 | int initvar; /* variable id; -1 for none; */ 59 | 60 | DList *ins; /* in nodes in the flow graph; */ 61 | DList *outs; /* out nodes in the flow graph; */ 62 | DList *kills; /* expressions that are killed by this one; */ 63 | 64 | DList *defs; /* definitions for this use node; */ 65 | DList *uses; /* uses for this definition node; */ 66 | 67 | DList *list; /* sorted list for the analysis results; */ 68 | }; 69 | 70 | DAO_DLL void DaoCnode_InitOperands( DaoCnode *self, DaoVmCode *code ); 71 | DAO_DLL int DaoCnode_FindResult( DaoCnode *self, void *key ); 72 | 73 | typedef void (*AnalysisInit)( DaoOptimizer*, DaoCnode* ); 74 | typedef int (*AnalysisUpdate)( DaoOptimizer*, DaoCnode*, DaoCnode* ); 75 | 76 | struct DaoOptimizer 77 | { 78 | DaoRoutine *routine; 79 | 80 | int reverseFlow; 81 | 82 | AnalysisInit init; 83 | AnalysisUpdate update; 84 | 85 | DList *nodes; /* all nodes (labels); */ 86 | DList *enodes; /* expression nodes (labels); */ 87 | DList *uses; /* nodes that use a variable; */ 88 | DList *refers; /* variables: 0, non-reference; 1, reference; */ 89 | 90 | DMap *exprs; /* all expressions; */ 91 | DMap *inits; /* init nodes; */ 92 | DMap *finals; /* final nodes; */ 93 | DMap *closes; /* closing nodes (for closing GOTO of code sections); */ 94 | 95 | DMap *tmp; 96 | DList *array; 97 | DList *array2; 98 | DList *array3; 99 | DList *nodeCache; 100 | DList *arrayCache; 101 | }; 102 | 103 | DAO_DLL DaoOptimizer* DaoOptimizer_New(); 104 | DAO_DLL void DaoOptimizer_Clear( DaoOptimizer *self ); 105 | DAO_DLL void DaoOptimizer_Delete( DaoOptimizer *self ); 106 | 107 | DAO_DLL void DaoOptimizer_DoLVA( DaoOptimizer *self, DaoRoutine *routine ); 108 | DAO_DLL void DaoOptimizer_DoRDA( DaoOptimizer *self, DaoRoutine *routine ); 109 | DAO_DLL void DaoOptimizer_DoVIA( DaoOptimizer *self, DaoRoutine *routine ); 110 | 111 | /* 112 | // Link Definition-Use and Use-Definition: 113 | // The results are stored in each node: 114 | // node->ins: node is the use, node->ins are the defintions; 115 | // node->outs: node is the defintion, node->outs are the uses; 116 | */ 117 | DAO_DLL void DaoOptimizer_LinkDU( DaoOptimizer *self, DaoRoutine *routine ); 118 | 119 | void DaoOptimizer_RemoveUnreachableCodes( DaoOptimizer *self, DaoRoutine *routine ); 120 | void DaoOptimizer_Optimize( DaoOptimizer *self, DaoRoutine *routine ); 121 | void DaoRoutine_UpdateRegister( DaoRoutine *self, DList *mapping ); 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /kernel/daoPlatform.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Virtual Machine 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2006-2017, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __DAO_PLATFORMS_H__ 30 | #define __DAO_PLATFORMS_H__ 31 | 32 | #ifndef DAO_KERNEL 33 | #define DAO_KERNEL 34 | #endif 35 | #include "dao.h" 36 | 37 | 38 | #ifdef WIN32 39 | 40 | # define DAO_DIR "C:\\dao" 41 | # define DAO_DLL_PREFIX "" 42 | # define DAO_DLL_SUFFIX ".dll" 43 | 44 | # define DAO_ENV_PATH_SEP ';' 45 | 46 | 47 | # include 48 | 49 | # ifdef _MSC_VER 50 | # include 51 | # else 52 | # include 53 | # endif 54 | 55 | # ifndef __GNUC__ 56 | # define strtoll _strtoi64 57 | # define wcstoll _wcstoi64 58 | # define snprintf _snprintf 59 | # define getcwd _getcwd 60 | # define stat _stat 61 | # define fstat _fstat 62 | # define fileno _fileno 63 | # endif 64 | 65 | 66 | #elif defined(UNIX) /* UNIX */ 67 | 68 | # define DAO_DIR "/usr/local" 69 | # define DAO_ENV_PATH_SEP ':' 70 | 71 | # include 72 | # include 73 | # include 74 | 75 | # define DAO_DLL_PREFIX "lib" 76 | 77 | # ifdef MACOSX 78 | # define DAO_DLL_SUFFIX ".dylib" 79 | # else /* UNIX */ 80 | # define DAO_DLL_SUFFIX ".so" 81 | # endif /* MACOSX */ 82 | 83 | 84 | #else /* other system */ 85 | 86 | # define DAO_DIR "" 87 | # define DAO_DLL_PREFIX "" 88 | # define DAO_DLL_SUFFIX ".unkown" 89 | # define DAO_ENV_PATH_SEP ':' 90 | 91 | #endif /* WIN32 */ 92 | 93 | 94 | #include 95 | #include 96 | #include 97 | #include 98 | #include 99 | 100 | 101 | DAO_DLL void Dao_NormalizePath( DString *path ); 102 | DAO_DLL int Dao_IsFile( const char *file ); 103 | DAO_DLL int Dao_IsDir( const char *file ); 104 | DAO_DLL FILE* Dao_OpenFile( const char *file, const char *mode ); 105 | 106 | DAO_DLL size_t Dao_FileChangedTime( const char *file ); 107 | 108 | DAO_DLL double Dao_GetCurrentTime(); 109 | 110 | DAO_DLL void* Dao_OpenDLL( const char *name ); 111 | DAO_DLL void* Dao_GetSymbolAddress( void *handle, const char *name ); 112 | 113 | DAO_DLL int DaoStream_SetScreenColor( DaoStream *self, const char *fgcolor, const char *bgcolor ); 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /kernel/daoRegex.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Virtual Machine 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2006-2017, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef DAO_REGEX_H 30 | #define DAO_REGEX_H 31 | 32 | #include"daoType.h" 33 | 34 | typedef struct DaoRgxItem DaoRgxItem; 35 | 36 | struct DaoRgxItem 37 | { 38 | uchar_t type; /* type of the pattern */ 39 | uchar_t config; 40 | short gid; 41 | short next; 42 | short jump; 43 | short from; 44 | short min; 45 | short max; 46 | daoint count; 47 | daoint pos; 48 | daoint offset; 49 | daoint posave; 50 | short fromsave; 51 | short length; /* length of the pattern */ 52 | short word; 53 | }; 54 | 55 | struct DaoRegex 56 | { 57 | char *source; 58 | daoint start; 59 | daoint end; 60 | DaoRgxItem *items; 61 | short count; /* total number of items; or free space in the buffer as input; */ 62 | short config; 63 | short attrib; 64 | short group; 65 | short indexed; 66 | char *wordbuf; 67 | int itemlen; /* in bytes */ 68 | int wordlen; /* in bytes */ 69 | int length; 70 | }; 71 | 72 | DAO_DLL DaoRegex* DaoRegex_New( DString *src ); 73 | #define DaoRegex_Delete( self ) dao_free( self ) 74 | DAO_DLL void DaoRegex_Copy( DaoRegex *self, DaoRegex *src ); 75 | 76 | /* compute the number of bytes needed for storing the compiled pattern */ 77 | DAO_DLL int DaoRegex_CheckSize( DString *src ); 78 | 79 | DAO_DLL int DaoRegex_Match( DaoRegex *self, DString *src, daoint *start, daoint *end ); 80 | DAO_DLL int DaoRegex_SubMatch( DaoRegex *self, int gid, daoint *start, daoint *end ); 81 | 82 | DAO_DLL int DaoRegex_Change( DaoRegex *self, DString *src, DString *target, int index ); 83 | DAO_DLL int DaoRegex_ChangeExt( DaoRegex *self, DString *input, DString *output, 84 | DString *target, int index, daoint *start2, daoint *end2 ); 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /kernel/daoStdlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Virtual Machine 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2006-2017, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef DAO_STDLIB_H 30 | #define DAO_STDLIB_H 31 | 32 | #include"daoType.h" 33 | 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /kernel/daoTasklet.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Virtual Machine 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2006-2017, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef DAO_TASKLET_H 30 | #define DAO_TASKLET_H 31 | 32 | #include"daoVmspace.h" 33 | 34 | 35 | enum DaoTaskletStatus 36 | { 37 | DAO_TASKLET_RUNNING , 38 | DAO_TASKLET_PAUSED , 39 | DAO_TASKLET_FINISHED , 40 | DAO_TASKLET_ABORTED 41 | }; 42 | 43 | 44 | /* 45 | // Channel for synchronous and asynchronous communication between tasklet. 46 | // 47 | // Each channel has a data buffer that holds data send to the channel. 48 | // Each buffer has a cap/capacity limit, and if the number of data items 49 | // has reached the cap, a sender will block when it sends data to this channel. 50 | // 51 | // Each time a receiver of a channel reads out one data item of the 52 | // channel buffer, which will effectively move the rest data items 53 | // forward and may cause one data item to enter the cap region. 54 | // When this happens, the sender of this data item will be unblocked. 55 | // 56 | // If the buffer cap is zero, it will effectively block any sender, 57 | // which is unblock only when the data item it sent has been read out. 58 | */ 59 | struct DaoChannel 60 | { 61 | DAO_CSTRUCT_COMMON; 62 | 63 | daoint cap; /* capacity limit of the channel; */ 64 | DList *buffer; /* DList; */ 65 | }; 66 | 67 | 68 | 69 | /* 70 | // Future value for tasklet. 71 | // 72 | // Each tasklet is represented by a future value. 73 | */ 74 | struct DaoFuture 75 | { 76 | DAO_CSTRUCT_COMMON; 77 | 78 | uchar_t state; 79 | uchar_t timeout; 80 | uchar_t aux1; 81 | uchar_t aux2; 82 | DaoValue *value; 83 | DaoValue *message; 84 | DaoValue *selected; 85 | DaoObject *actor; 86 | DaoProcess *process; 87 | DaoFuture *precond; /* the future value on which this one waits; */ 88 | }; 89 | 90 | DAO_DLL DaoFuture* DaoFuture_New( DaoNamespace *ns, DaoType *type, int vatype ); 91 | 92 | 93 | DAO_DLL void DaoVmSpace_AddTaskletCall( DaoVmSpace *self, DaoProcess *call ); 94 | 95 | #ifdef DAO_WITH_CONCURRENT 96 | 97 | DAO_DLL DaoChannel* DaoChannel_New( DaoNamespace *ns, DaoType *type, int dtype ); 98 | 99 | DAO_DLL void DaoFuture_ActivateEvent( DaoFuture *self, DaoVmSpace *vmspace ); 100 | 101 | DAO_DLL void DaoProcess_MarkActiveTasklet( DaoProcess *self, int active ); 102 | 103 | DAO_DLL void DaoProcess_ReturnFutureValue( DaoProcess *self, DaoFuture *future ); 104 | 105 | DAO_DLL int DaoVmSpace_GetThreadCount( DaoVmSpace *self ); 106 | DAO_DLL void DaoVmSpace_JoinTasklets( DaoVmSpace *self ); 107 | DAO_DLL void DaoVmSpace_StopTasklets( DaoVmSpace *self ); 108 | 109 | /* 110 | // If "proc" is not NULL, obtain (or create) a thread exclusively for 111 | // a tasklet that is identified by "proc" (virtual process). 112 | // The thread will become available to other tasklets only after this 113 | // tasklet is completed, namely, when proc->status = DAO_PROCESS_FINISHED 114 | // or proc->status = DAO_PROCESS_ABORTED after DaoProcess_Start(proc). 115 | // the virtual process "proc". 116 | */ 117 | DAO_DLL void DaoVmSpace_AddTaskletThread( DaoVmSpace *self, DThreadTask func, void *param, void *proc ); 118 | DAO_DLL void DaoVmSpace_AddTaskletJob( DaoVmSpace *self, DThreadTask func, void *param, void *proc ); 119 | DAO_DLL void DaoVmSpace_AddTaskletWait( DaoVmSpace *self, DaoProcess *wait, DaoFuture *future, double timeout ); 120 | 121 | #endif 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Dao Programming Language 2 | http://www.daovm.net 3 | 4 | Copyright (c) 2006-2014, Limin Fu 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, 8 | are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 25 | OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /modules/auxlib/dao_api.c: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Standard Modules 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2015, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /* 30 | // %s/\(\w\+\) \(\w\+\)( \(.*\) )/DAO_API( TIME, \1, \2, (\3) ) 31 | */ 32 | 33 | #ifdef DAO_API 34 | # undef DAO_API 35 | #endif 36 | 37 | #define DAO_API(Linkage,Type,Name,Signature) DAO_##Linkage##_DLL Type (*_##Name) Signature; Type (*_##Name) Signature = NULL 38 | 39 | 40 | #ifdef DAO_HAS_RANDOM 41 | #define DAO_RANDOM 42 | #include"../random/dao_random.h" 43 | #endif 44 | 45 | 46 | #ifdef DAO_HAS_STREAM 47 | #define DAO_STREAM 48 | #include"../stream/dao_stream.h" 49 | #endif 50 | 51 | 52 | #ifdef DAO_HAS_TIME 53 | #define DAO_TIME 54 | #include"../time/dao_time.h" 55 | #endif 56 | 57 | 58 | #ifdef DAO_HAS_DECIMAL 59 | #define DAO_DECIMAL 60 | #include"../decimal/dao_decimal.h" 61 | #endif 62 | 63 | 64 | #ifdef DAO_HAS_ZIP 65 | #define DAO_ZIP 66 | #include"../zip/dao_zip.h" 67 | #endif 68 | 69 | 70 | #ifdef DAO_HAS_CRYPTO 71 | #define DAO_CRYPTO 72 | #include"../crypto/dao_crypto.h" 73 | #endif 74 | 75 | 76 | #ifdef DAO_HAS_IMAGE 77 | #define DAO_IMAGE 78 | #include"../image/source/dao_image.h" 79 | #endif 80 | -------------------------------------------------------------------------------- /modules/auxlib/dao_api.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Standard Modules 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2015, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | 30 | 31 | #ifdef DAO_API 32 | # undef DAO_API 33 | #endif 34 | 35 | 36 | #ifdef DAO_API_INIT 37 | # define DAO_API(Linkage,Type,Name,Signature) _##Name = Name 38 | /* 39 | ; printf( "%i %p\n", __LINE__, & _##Name ) 40 | */ 41 | #else 42 | # define DAO_API(Linkage,Type,Name,Signature) DAO_##Linkage##_DLL Type (*_##Name) Signature 43 | #endif 44 | 45 | 46 | #ifdef DAO_HAS_RANDOM 47 | #include"../random/dao_random.h" 48 | #endif 49 | 50 | 51 | #ifdef DAO_HAS_STREAM 52 | #include"../stream/dao_stream.h" 53 | #endif 54 | 55 | 56 | #ifdef DAO_HAS_TIME 57 | #include"../time/dao_time.h" 58 | #endif 59 | 60 | 61 | #ifdef DAO_HAS_DECIMAL 62 | #include"../decimal/dao_decimal.h" 63 | #endif 64 | 65 | 66 | #ifdef DAO_HAS_ZIP 67 | #include"../zip/dao_zip.h" 68 | #endif 69 | 70 | 71 | #ifdef DAO_HAS_CRYPTO 72 | #include"../crypto/dao_crypto.h" 73 | #endif 74 | 75 | 76 | #ifdef DAO_HAS_IMAGE 77 | #include"../image/source/dao_image.h" 78 | #endif 79 | -------------------------------------------------------------------------------- /modules/auxlib/example.dao: -------------------------------------------------------------------------------- 1 | load aux; 2 | 3 | list1 = { 1.3, 2.5, 3.6 } 4 | list2 = { (any)(name=>'dao',year=>2006), (123+456$, 'abc'), [1.2, 3.4; 5.6, 7.8] } 5 | 6 | s1 = aux.serialize( list1 ); 7 | s2 = aux.serialize( list2 ); 8 | 9 | io.writeln( s2 ) 10 | io.writeln( s1, aux.deserialize( s1 ) ) 11 | io.writeln( s2, aux.deserialize( s2 ) ) 12 | 13 | map1 = { 'abc':123, 'def':{} } 14 | s3 = aux.serialize( map1 ); 15 | io.writeln( s3, aux.deserialize( s3 ) ) 16 | 17 | 18 | class Klass 19 | { 20 | var index = 123; 21 | var name = 'abc'; 22 | 23 | routine Klass( ){ index = 789; } 24 | routine Klass( i : int, s : string ){ index = i; name = s; } 25 | routine Klass( tup : tuple ){index = tup[0]; name = tup[1]; } 26 | routine serialize(){ return index, name } 27 | } 28 | object = Klass( 456, 'def' ); 29 | io.writeln( object.serialize() ); 30 | 31 | ss = aux.serialize( object ); 32 | io.writeln( ss ); 33 | object = (Klass)aux.deserialize( ss ) 34 | io.writeln( object, object.index, object.name ); 35 | 36 | ss = aux.serialize( { object } ); 37 | io.writeln( ss ); 38 | objects = aux.deserialize( ss ) 39 | object = objects[0] 40 | io.writeln( objects, object.index, object.name ); 41 | 42 | 43 | e = Exception( 'serialization test' ); 44 | ss = aux.serialize( e ); 45 | io.writeln( ss, std.about(ss) ); 46 | e = aux.deserialize( ss ) 47 | io.writeln( e, e.info ); 48 | 49 | class MyException : Exception 50 | { 51 | #use Exception; 52 | routine MyException( info = '' ) : Exception( info ){} 53 | } 54 | 55 | e2 = MyException( 'serialization test2' ); 56 | ss = aux.serialize( { e2 } ); 57 | io.writeln( ss ); 58 | 59 | e2 = aux.deserialize( ss )[0] 60 | io.writeln( e2, e2.info ); 61 | -------------------------------------------------------------------------------- /modules/auxlib/makefile.dao: -------------------------------------------------------------------------------- 1 | 2 | project = DaoMake::Project( "DaoAux" ) 3 | 4 | daovm = DaoMake::FindPackage( "Dao", $REQUIRED ) 5 | 6 | if( daovm == none ) return 7 | 8 | project.UseImportLibrary( daovm, "dao" ) 9 | project.AddIncludePath( "." ) # To be exported in FindDaoAux.dao 10 | project.SetTargetPath( "../../lib/dao/modules" ) 11 | 12 | project_objs = project.AddObjects( { "dao_aux.c", "dao_api.c" }, { "dao_aux.h", "dao_api.h" } ) 13 | 14 | if( DaoMake::IsDir( "modules/random" ) ) project_objs.AddDefinition( "DAO_HAS_RANDOM" ); 15 | if( DaoMake::IsDir( "modules/stream" ) ) project_objs.AddDefinition( "DAO_HAS_STREAM" ); 16 | if( DaoMake::IsDir( "modules/image" ) ) project_objs.AddDefinition( "DAO_HAS_IMAGE" ); 17 | if( DaoMake::IsDir( "modules/time" ) ) project_objs.AddDefinition( "DAO_HAS_TIME" ); 18 | if( DaoMake::IsDir( "modules/decimal" ) ) project_objs.AddDefinition( "DAO_HAS_DECIMAL" ); 19 | 20 | project_dll = project.AddSharedLibrary( "dao_aux", project_objs ) 21 | project_lib = project.AddStaticLibrary( "dao_aux", project_objs ) 22 | 23 | 24 | auxinc = DaoMake::MakePath( DaoMake::Variables[ "INSTALL_INC" ], "modules/auxlib" ) 25 | project.Install( auxinc, { "dao_aux.h", "dao_api.h" } ); 26 | findpkg = project.GenerateFinder( $TRUE ); 27 | 28 | # The Aux module compiled with the Dao project has been installed! 29 | #project.Install( DaoMake::Variables[ "INSTALL_MOD" ], project_dll ); 30 | #project.Install( DaoMake::Variables[ "INSTALL_MOD" ], project_lib ); 31 | project.Install( DaoMake::Variables[ "INSTALL_FINDER" ], findpkg ); 32 | -------------------------------------------------------------------------------- /modules/debugger/makefile.dao: -------------------------------------------------------------------------------- 1 | 2 | project = DaoMake::Project( "DaoDebugger" ) 3 | 4 | daovm = DaoMake::FindPackage( "Dao", $REQUIRED ) 5 | 6 | if( daovm == none ) return 7 | 8 | project.UseImportLibrary( daovm ) 9 | project.SetTargetPath( "../../lib/dao/modules" ) 10 | 11 | project_objs = project.AddObjects( { "dao_debugger.c" } ) 12 | project_dll = project.AddSharedLibrary( "dao_debugger", project_objs ) 13 | project_lib = project.AddStaticLibrary( "dao_debugger", project_objs ) 14 | 15 | 16 | project.GenerateFinder( $TRUE ); 17 | project.Install( DaoMake::Variables[ "INSTALL_MOD" ], project_dll ); 18 | project.Install( DaoMake::Variables[ "INSTALL_MOD" ], project_lib ); 19 | -------------------------------------------------------------------------------- /modules/profiler/dao_profiler.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Profiler 3 | // 4 | // Copyright (c) 2013, Limin Fu 5 | // All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without modification, 8 | // are permitted provided that the following conditions are met: 9 | // 10 | // * Redistributions of source code must retain the above copyright notice, 11 | // this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 25 | // OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef DAO_PROFILER_H 29 | #define DAO_PROFILER_H 30 | 31 | #include "daoValue.h" 32 | #include "daoStream.h" 33 | #include "daoRoutine.h" 34 | #include "daoProcess.h" 35 | #include "daoNamespace.h" 36 | #include "daoVmspace.h" 37 | 38 | 39 | typedef struct DaoxProfiler DaoxProfiler; 40 | 41 | struct DaoxProfiler 42 | { 43 | DaoProfiler base; 44 | 45 | DMutex mutex; 46 | DMap *profile; /* map> */ 47 | DMap *one; /* map */ 48 | }; 49 | 50 | DAO_DLL DaoxProfiler* DaoxProfiler_New(); 51 | DAO_DLL void DaoxProfiler_Delete( DaoxProfiler *self ); 52 | 53 | DAO_DLL dao_complex DaoProfiler_Sum( DMap *profile ); 54 | 55 | 56 | DAO_DLL void DaoRoutine_MakeName( DaoRoutine *self, DString *name, int max1, int max2, int max3 ); 57 | 58 | DAO_DLL int DaoProfiler_OnLoad( DaoVmSpace *vmSpace, DaoNamespace *ns ); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /modules/profiler/makefile.dao: -------------------------------------------------------------------------------- 1 | 2 | project = DaoMake::Project( "DaoProfiler" ) 3 | 4 | daovm = DaoMake::FindPackage( "Dao", $REQUIRED ) 5 | 6 | if( daovm == none ) return 7 | 8 | project.UseImportLibrary( daovm, "dao" ) 9 | project.SetTargetPath( "../../lib/dao/modules" ) 10 | 11 | project_objs = project.AddObjects( { "dao_profiler.c" }, { "dao_profiler.h" } ) 12 | project_dll = project.AddSharedLibrary( "dao_profiler", project_objs ) 13 | project_lib = project.AddStaticLibrary( "dao_profiler", project_objs ) 14 | 15 | 16 | project.GenerateFinder( $TRUE ); 17 | project.Install( DaoMake::Variables[ "INSTALL_MOD" ], project_dll ); 18 | project.Install( DaoMake::Variables[ "INSTALL_MOD" ], project_lib ); 19 | -------------------------------------------------------------------------------- /modules/stream/dao_stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | // Dao Standard Modules 3 | // http://daoscript.org 4 | // 5 | // Copyright (c) 2015,2016, Limin Fu 6 | // All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 11 | // * Redistributions of source code must retain the above copyright notice, 12 | // this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above copyright notice, 14 | // this list of conditions and the following disclaimer in the documentation 15 | // and/or other materials provided with the distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | 30 | #include"dao.h" 31 | 32 | #ifndef DAO_STREAM_DLL 33 | #ifdef DAO_STREAM 34 | # define DAO_STREAM_DLL DAO_DLL_EXPORT 35 | #else 36 | # define DAO_STREAM_DLL DAO_DLL_IMPORT 37 | #endif 38 | #endif 39 | 40 | 41 | #ifndef __DAO_MOD_STREAM_H__ 42 | #define __DAO_MOD_STREAM_H__ 43 | 44 | #include 45 | #include 46 | #include"daoStream.h" 47 | 48 | 49 | typedef struct DaoFileStream DaoFileStream; 50 | typedef struct DaoFileStream DaoPipeStream; 51 | typedef struct DaoStringStream DaoStringStream; 52 | 53 | 54 | struct DaoFileStream 55 | { 56 | DaoStream base; 57 | FILE *file; 58 | }; 59 | 60 | 61 | struct DaoStringStream 62 | { 63 | DaoStream base; 64 | dao_integer offset; 65 | }; 66 | #endif 67 | 68 | 69 | DAO_API( STREAM, DaoType*, DaoFileStream_Type, (DaoVmSpace *vmspace) ); 70 | DAO_API( STREAM, DaoType*, DaoStringStream_Type, (DaoVmSpace *vmspace) ); 71 | DAO_API( STREAM, DaoType*, DaoPipeStream_Type, (DaoVmSpace *vmspace) ) ; 72 | 73 | DAO_API( STREAM, DaoFileStream*, DaoFileStream_New, (DaoVmSpace *vmspace) ); 74 | DAO_API( STREAM, void, DaoFileStream_Delete, (DaoFileStream *self) ); 75 | DAO_API( STREAM, void, DaoFileStream_Close, (DaoFileStream *self) ); 76 | DAO_API( STREAM, void, DaoFileStream_InitCallbacks, (DaoFileStream *self) ); 77 | 78 | DAO_API( STREAM, DaoStringStream*, DaoStringStream_New, (DaoVmSpace *vmspace) ); 79 | DAO_API( STREAM, void, DaoStringStream_Delete, (DaoStringStream *self) ); 80 | 81 | DAO_API( STREAM, FILE*, DaoStream_GetFile, (DaoStream *self ) ); 82 | DAO_API( STREAM, DaoStream*, DaoProcess_PutFile, (DaoProcess *self, FILE *file) ); 83 | DAO_API( STREAM, DaoStream*, DaoProcess_NewStream, (DaoProcess *self, FILE *file) ); 84 | 85 | -------------------------------------------------------------------------------- /modules/stream/makefile.dao: -------------------------------------------------------------------------------- 1 | 2 | project = DaoMake::Project( "DaoStream" ) 3 | 4 | daovm = DaoMake::FindPackage( "Dao", $REQUIRED ) 5 | 6 | if( daovm == none ) return 7 | 8 | project.UseImportLibrary( daovm ) 9 | project.SetTargetPath( "../../lib/dao/modules" ) 10 | 11 | project_objs = project.AddObjects( { "dao_stream.c" } ) 12 | project_dll = project.AddSharedLibrary( "dao_stream", project_objs ) 13 | project_lib = project.AddStaticLibrary( "dao_stream", project_objs ) 14 | 15 | 16 | project.Install( DaoMake::Variables[ "INSTALL_MOD" ], project_dll ); 17 | project.Install( DaoMake::Variables[ "INSTALL_MOD" ], project_lib ); 18 | 19 | findpkg = project.GenerateFinder( $TRUE ); 20 | project.Install( DaoMake::Variables[ "INSTALL_FINDER" ], findpkg ); 21 | -------------------------------------------------------------------------------- /share/dao-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daokoder/dao/c322345dce03f627462dfd8e125cbad879c46786/share/dao-logo.png -------------------------------------------------------------------------------- /share/daohelp.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: Dao Help 1.0 3 | " Created based on the syntax file for Lua, C, C++ etc. 4 | " For version 5.x: Clear all syntax items 5 | " For version 6.x: Quit when a syntax file was already loaded 6 | if version < 600 7 | syntax clear 8 | elseif exists("b:current_syntax") 9 | finish 10 | endif 11 | 12 | syntax clear 13 | 14 | let b:current_syntax = "daohelp" 15 | 16 | syn case match 17 | 18 | syn match daoSpecial "@\[[0-9a-zA-Z_ .-:=()]*\]" 19 | 20 | syn region daoConstant start="\z(@\[red[0-9a-zA-Z_ .-:=()]*\]\)" end="\z1" 21 | syn region daoStructure start="\z(@\[green[0-9a-zA-Z_ .-:=()]*\]\)" end="\z1" 22 | syn region daoComment start="\z(@\[blue[0-9a-zA-Z_ .-:=()]*\]\)" end="\z1" 23 | 24 | 25 | "syncing method 26 | syn sync minlines=100 27 | 28 | " Define the default highlighting. 29 | " For version 5.7 and earlier: only when not done already 30 | " For version 5.8 and later: only when an item doesn't have highlighting yet 31 | if version >= 508 || !exists("did_daohelp_syntax_inits") 32 | if version < 508 33 | let did_daohelp_syntax_inits = 1 34 | command -nargs=+ HiLink hi link 35 | else 36 | command -nargs=+ HiLink hi def link 37 | endif 38 | 39 | HiLink daoConstant Constant 40 | HiLink daoComment Comment 41 | HiLink daoStructure Structure 42 | HiLink daoSpecial SpecialChar 43 | 44 | delcommand HiLink 45 | endif 46 | 47 | let b:current_syntax = "daohelp" 48 | 49 | finish 50 | 51 | let b:current_syntax = '' 52 | unlet b:current_syntax 53 | syntax include @Code syntax/dao.vim 54 | syntax region vbtCode matchgroup=vbt start="\z(@@\?\[\s*code\(\|[ .-:=()][0-9a-zA-Z_ .-:=()]*\)\]\)" end="\z1" contains=@Code 55 | hi link vbt Special 56 | 57 | let b:current_syntax = '' 58 | unlet b:current_syntax 59 | syntax include @Cpp syntax/cpp.vim 60 | syntax region vbtCpp matchgroup=vbt start="\z(@@\?\[\s*\(cpp\|cxx\)\(\|[ .-:=()][0-9a-zA-Z_ .-:=()]*\)\]\)" end="\z1" contains=@Cpp 61 | hi link vbt Special 62 | 63 | let b:current_syntax = '' 64 | unlet b:current_syntax 65 | syntax include @Lua syntax/lua.vim 66 | syntax region vbtLua matchgroup=vbt start="\z(@@\?\[\s*lua\(\|[ .-:=()][0-9a-zA-Z_ .-:=()]*\)\]\)" end="\z1" contains=@Lua 67 | hi link vbt Special 68 | 69 | let b:current_syntax = '' 70 | unlet b:current_syntax 71 | syntax include @Html syntax/html.vim 72 | syntax region vbtHtml matchgroup=vbt start="\z(@@\?\[\s*html\(\|[ .-:=()][0-9a-zA-Z_ .-:=()]*\)\]\)" end="\z1" contains=@Html 73 | hi link vbt Special 74 | 75 | let b:current_syntax = '' 76 | unlet b:current_syntax 77 | syntax include @Tex syntax/tex.vim 78 | syntax region vbtTex matchgroup=vbt start="\z(@@\?\[\s*tex\(\|[ .-:=()][0-9a-zA-Z_ .-:=()]*\)\]\)" end="\z1" contains=@Tex 79 | hi link vbt Special 80 | 81 | let b:current_syntax = "daohelp" 82 | 83 | -------------------------------------------------------------------------------- /share/release.sh: -------------------------------------------------------------------------------- 1 | make -f Makefile.daomake macosx 2 | 3 | mkdir Dao-$VERSION 4 | cd Dao-$VERSION 5 | fossil open --nested ../Dao.fossil 6 | fossil close 7 | cp ../manifest.uuid . 8 | 9 | mkdir -p doc 10 | cp -r ../doc/html doc/ 11 | 12 | cd modules 13 | fossil open --nested ../../modules/DaoModules.fossil 14 | fossil close 15 | 16 | cd ../tools 17 | fossil open --nested ../../tools/DaoTools.fossil 18 | fossil close 19 | 20 | cd ../../ && tar -zcf Dao-$VERSION.tgz Dao-$VERSION 21 | -------------------------------------------------------------------------------- /tests/WrongModule.dao: -------------------------------------------------------------------------------- 1 | 2 | #{ 3 | 4 | This script is wrong in Test::Meth(). If an application tries to load 5 | this script twice, it must produce the same error in Test::Meth(). 6 | If the second loading produces an error in Test::Test(), complaining 7 | the parameter type of m.append(), there must be a problem in specializing 8 | list and its methods, due to the possibility that the same namespace 9 | used to specialize list in the first loading is also used in the 10 | second loading. This is no longer the case in the current implementation 11 | of Dao, but regression tests must be done for this (see test_misc.dao). 12 | 13 | #} 14 | 15 | class Klass 16 | { 17 | } 18 | 19 | class Test 20 | { 21 | var m: list = {}; 22 | 23 | routine Test(){ 24 | m.append( Klass() ); 25 | } 26 | 27 | routine Meth(){ 28 | Test(1); 29 | } 30 | } 31 | 32 | t = Test(); 33 | -------------------------------------------------------------------------------- /tests/dao_CharType.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "dao.h" 4 | 5 | static void dao_isalnum( DaoProcess *proc, DaoValue *P[], int N ) 6 | { 7 | DaoProcess_PutInteger( proc, isalnum( DaoValue_TryGetInteger( P[0] ) ) ); 8 | } 9 | static void dao_isalpha( DaoProcess *proc, DaoValue *P[], int N ) 10 | { 11 | DaoProcess_PutInteger( proc, isalpha( DaoValue_TryGetInteger( P[0] ) ) ); 12 | } 13 | static void dao_isblank( DaoProcess *proc, DaoValue *P[], int N ) 14 | { 15 | DaoProcess_PutInteger( proc, isblank( DaoValue_TryGetInteger( P[0] ) ) ); 16 | } 17 | static void dao_iscntrl( DaoProcess *proc, DaoValue *P[], int N ) 18 | { 19 | DaoProcess_PutInteger( proc, iscntrl( DaoValue_TryGetInteger( P[0] ) ) ); 20 | } 21 | static void dao_isdigit( DaoProcess *proc, DaoValue *P[], int N ) 22 | { 23 | DaoProcess_PutInteger( proc, isdigit( DaoValue_TryGetInteger( P[0] ) ) ); 24 | } 25 | static void dao_isgraph( DaoProcess *proc, DaoValue *P[], int N ) 26 | { 27 | DaoProcess_PutInteger( proc, isgraph( DaoValue_TryGetInteger( P[0] ) ) ); 28 | } 29 | static void dao_islower( DaoProcess *proc, DaoValue *P[], int N ) 30 | { 31 | DaoProcess_PutInteger( proc, islower( DaoValue_TryGetInteger( P[0] ) ) ); 32 | } 33 | static void dao_isprint( DaoProcess *proc, DaoValue *P[], int N ) 34 | { 35 | DaoProcess_PutInteger( proc, isprint( DaoValue_TryGetInteger( P[0] ) ) ); 36 | } 37 | static void dao_ispunct( DaoProcess *proc, DaoValue *P[], int N ) 38 | { 39 | DaoProcess_PutInteger( proc, ispunct( DaoValue_TryGetInteger( P[0] ) ) ); 40 | } 41 | static void dao_isspace( DaoProcess *proc, DaoValue *P[], int N ) 42 | { 43 | DaoProcess_PutInteger( proc, isspace( DaoValue_TryGetInteger( P[0] ) ) ); 44 | } 45 | static void dao_isupper( DaoProcess *proc, DaoValue *P[], int N ) 46 | { 47 | DaoProcess_PutInteger( proc, isupper( DaoValue_TryGetInteger( P[0] ) ) ); 48 | } 49 | static void dao_isxdigit( DaoProcess *proc, DaoValue *P[], int N ) 50 | { 51 | DaoProcess_PutInteger( proc, isxdigit( DaoValue_TryGetInteger( P[0] ) ) ); 52 | } 53 | static void dao_tolower( DaoProcess *proc, DaoValue *P[], int N ) 54 | { 55 | DaoProcess_PutInteger( proc, tolower( DaoValue_TryGetInteger( P[0] ) ) ); 56 | } 57 | static void dao_toupper( DaoProcess *proc, DaoValue *P[], int N ) 58 | { 59 | DaoProcess_PutInteger( proc, toupper( DaoValue_TryGetInteger( P[0] ) ) ); 60 | } 61 | static void dao_isascii( DaoProcess *proc, DaoValue *P[], int N ) 62 | { 63 | DaoProcess_PutInteger( proc, isascii( DaoValue_TryGetInteger( P[0] ) ) ); 64 | } 65 | static void dao_toascii( DaoProcess *proc, DaoValue *P[], int N ) 66 | { 67 | DaoProcess_PutInteger( proc, toascii( DaoValue_TryGetInteger( P[0] ) ) ); 68 | } 69 | 70 | static DaoFunctionEntry charTypeMeths[]= 71 | { 72 | { dao_isalnum, "isalnum( ch : int ) => int" } , 73 | { dao_isalpha, "isalpha( ch : int ) => int" } , 74 | { dao_isblank, "isblank( ch : int ) => int" } , 75 | { dao_iscntrl, "iscntrl( ch : int ) => int" } , 76 | { dao_isdigit, "isdigit( ch : int ) => int" } , 77 | { dao_isgraph, "isgraph( ch : int ) => int" } , 78 | { dao_islower, "islower( ch : int ) => int" } , 79 | { dao_isprint, "isprint( ch : int ) => int" } , 80 | { dao_ispunct, "ispunct( ch : int ) => int" } , 81 | { dao_isspace, "isspace( ch : int ) => int" } , 82 | { dao_isupper, "isupper( ch : int ) => int" } , 83 | { dao_isxdigit, "isxdigit( ch : int ) => int" } , 84 | { dao_tolower, "tolower( ch : int ) => int" } , 85 | { dao_toupper, "toupper( ch : int ) => int" } , 86 | { dao_isascii, "isascii( ch : int ) => int" } , 87 | { dao_toascii, "toascii( ch : int ) => int" } , 88 | { NULL, NULL } 89 | }; 90 | 91 | DAO_DLL int DaoOnLoad( DaoVmSpace *vmSpace, DaoNamespace *ns ) 92 | { 93 | DaoNamespace_WrapFunctions( ns, charTypeMeths ); 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /tests/examples.dao: -------------------------------------------------------------------------------- 1 | 2 | #{ 3 | 4 | All tests are expressed as pairs of verbatim strings with tag "test": 5 | @[test(id)...], where "id" is optional and use only for error reporting. 6 | 7 | The first of each pair is considered as codes to be tested, and the second is 8 | the expected results to which the results of the first to be checked against. 9 | 10 | The expected results can be expressed in three forms (are checked in this order): 11 | 1. Value that should be produced by the test codes; 12 | 2. Raw printed output; 13 | 3. String pattern that should match the printed output; 14 | 15 | The first is checked only if the test codes do not print anything, 16 | and the expected result is not an empty string. 17 | 18 | #} 19 | 20 | 21 | # A positive test that produces a tuple (1,2): 22 | @[test(first)] 23 | a = 1 24 | b = ( a, 2 ) 25 | @[test(first)] 26 | @[test(first)] 27 | ( 1, 2 ) 28 | @[test(first)] 29 | 30 | 31 | # A positive test that prints "hello world!": 32 | @[test(second)] 33 | io.writeln( "hello world!" ) 34 | @[test(second)] 35 | @[test(second)] 36 | hello world! 37 | @[test(second)] 38 | 39 | 40 | # A negative test that should raise a parsing error: 41 | @[test(third)] 42 | a : array; # array type cannot contain string 43 | @[test(third)] 44 | @[test(third)] 45 | Invalid %s type %s form 46 | @[test(third)] 47 | -------------------------------------------------------------------------------- /tests/makefile.dao: -------------------------------------------------------------------------------- 1 | 2 | daotests = DaoMake::Project( "DaoTests" ) 3 | 4 | daovm = DaoMake::FindPackage( "Dao", $REQUIRED ) 5 | 6 | if( daovm == none ) return 7 | 8 | daotests.UseSharedLibrary( daovm ) 9 | 10 | chartype_objs = daotests.AddObjects( { "dao_CharType.c" } ) 11 | chartype_dll = daotests.AddSharedLibrary( "dao_CharType", chartype_objs ) 12 | 13 | chartype_dll.EnableDynamicLinking() 14 | 15 | 16 | usertype_objs = daotests.AddObjects( { "dao_UserType.c" } ) 17 | usertype_dll = daotests.AddSharedLibrary( "dao_UserType", usertype_objs ) 18 | 19 | usertype_dll.EnableDynamicLinking() 20 | 21 | 22 | podtype_objs = daotests.AddObjects( { "dao_UserPodType.c" } ) 23 | podtype_dll = daotests.AddSharedLibrary( "dao_UserPodType", podtype_objs ) 24 | 25 | podtype_dll.EnableDynamicLinking() 26 | 27 | 28 | daotests.AddTest( "Example", "examples.dao" ) 29 | 30 | daotests.AddTest( "Lexer", "test_lexer.dao" ) 31 | daotests.AddTest( "Parser", "test_parser.dao" ) 32 | 33 | daotests.AddTest( "Numbers", "test_numbers.dao" ) 34 | daotests.AddTest( "Strings", "test_strings.dao" ) 35 | 36 | test_enum = daotests.AddTest( "EnumSymbol", "test_enum_symbol_def.dao" ) 37 | test_enum.AddTest( "test_enum_symbol_type.dao" ) 38 | 39 | daotests.AddTest( "Arrays", "test_arrays.dao" ) 40 | 41 | daotests.AddTest( "Tuples", "test_tuples.dao" ) 42 | 43 | daotests.AddTest( "Maps", "test_maps.dao" ) 44 | 45 | test_decl = daotests.AddTest( "Declarations", "test_invar.dao" ) 46 | 47 | test_operator = daotests.AddTest( "Operators", "test_operators.dao" ) 48 | 49 | test_control = daotests.AddTest( "Controls", "test_if_else.dao" ) 50 | test_control.AddTest( "test_for.dao" ) 51 | test_control.AddTest( "test_while.dao" ) 52 | test_control.AddTest( "test_switch.dao" ) 53 | 54 | test_routine = daotests.AddTest( "Routine", "test_routine.dao" ) 55 | test_routine.AddTest( "test_anonymous_routine.dao" ) 56 | test_routine.AddTest( "test_closure.dao" ) 57 | test_routine.AddTest( "test_code_section.dao" ) 58 | #test_routine.AddTest( "test_decorator.dao" ) 59 | 60 | test_class = daotests.AddTest( "Class", "test_class.dao" ) 61 | test_class.AddTest( "test_class_inheritance.dao" ) 62 | test_class.AddTest( "test_class_static_fields.dao" ) 63 | test_class.AddTest( "test_class_operator.dao" ) 64 | test_class.AddTest( "test_class_mixin.dao" ) 65 | test_class.AddTest( "test_invar_class.dao" ) 66 | 67 | test_interface = daotests.AddTest( "Interface", "test_interface.dao" ) 68 | test_interface.AddTest( "test_concrete_interface.dao" ) 69 | 70 | test_regex = daotests.AddTest( "Regex", "test_regex_char_class.dao" ) 71 | test_regex.AddDependency( chartype_dll ) 72 | 73 | daotests.AddTest( "ErrorHandling", "test_error_handling.dao" ) 74 | 75 | misc = daotests.AddTest( "Misc", "test_misc.dao" ) 76 | misc.AddTest( "test_type.dao" ); 77 | misc.AddTest( "test_tasklet.dao" ); 78 | 79 | daovm_defs = daovm.MakeDefinitions() 80 | if( daovm_defs.find( "-DDAO_WITH_THREAD" ) >= 0 ) misc.AddTest( "test_multi_threading.dao" ); 81 | 82 | libdao_dll = daovm.FindTarget( "dao", $shared ); 83 | daotests.GetTargets( $test ).iterate { [test] 84 | test.AddDependency( libdao_dll ) 85 | } 86 | 87 | -------------------------------------------------------------------------------- /tests/test_anonymous_routine.dao: -------------------------------------------------------------------------------- 1 | 2 | 3 | @[test(code_01)] 4 | add = routine(x, y){ return x + y } 5 | res = add( 123, 456 ) 6 | @[test(code_01)] 7 | @[test(code_01)] 8 | 579 9 | @[test(code_01)] 10 | 11 | 12 | 13 | 14 | @[test(code_01)] 15 | a = "ABC"; 16 | rout = routine( x, y : string, z = a+a, s = 123 ){ 17 | a += "_abc"; 18 | io.writeln( "lambda ", a ) 19 | io.writeln( "lambda ", y ) 20 | io.writeln( "lambda ", z ) 21 | io.writeln( "lambda ", s ) 22 | } 23 | rout( 1, "XXX" ); 24 | @[test(code_01)] 25 | @[test(code_01)] 26 | {{At line}} .* {{Default parameter is not constant}} 27 | @[test(code_01)] 28 | -------------------------------------------------------------------------------- /tests/test_arrays.dao: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | @[test(code_01)] 6 | vec = [1, 2, 3] 7 | io.writeln( vec ) 8 | @[test(code_01)] 9 | @[test(code_01)] 10 | [ 1, 2, 3 ] 11 | @[test(code_01)] 12 | 13 | 14 | 15 | 16 | @[test(code_01)] 17 | vec = [1.0; 2; 3] 18 | io.writeln( std.about(vec), vec ) 19 | @[test(code_01)] 20 | @[test(code_01)] 21 | {{array}} .* {{[ 1.000000; 2.000000; 3.000000 ]}} 22 | @[test(code_01)] 23 | 24 | 25 | 26 | 27 | 28 | @[test(code_01)] 29 | mat = [1.0, 2; 3, 4] 30 | io.writeln( std.about(mat) ) 31 | io.writeln( mat ) 32 | @[test(code_01)] 33 | @[test(code_01)] 34 | {{array}} .* 35 | {{row[0,:]: 1.000000 2.000000 36 | row[1,:]: 3.000000 4.000000}} 37 | @[test(code_01)] 38 | 39 | 40 | 41 | 42 | @[test(code_01)] 43 | mat = [ [1, 2], [3, 4] ] 44 | io.writeln( std.about(mat), mat.dims() ) 45 | io.writeln( mat ) 46 | @[test(code_01)] 47 | @[test(code_01)] 48 | {{array}} .* 49 | {{row[0,:]: 1 2 50 | row[1,:]: 3 4}} 51 | @[test(code_01)] 52 | 53 | 54 | 55 | 56 | @[test(code_01)] 57 | mat = array{ 1, 2; 3, 4 } 58 | io.writeln( std.about(mat) ) 59 | io.writeln( mat ) 60 | @[test(code_01)] 61 | @[test(code_01)] 62 | {{array}} .* 63 | {{row[0,:]: 1 2 64 | row[1,:]: 3 4}} 65 | @[test(code_01)] 66 | 67 | 68 | 69 | 70 | @[test(code_01)] 71 | mat = array(2){ [1, 2, 3] } 72 | io.writeln( %mat, std.about(mat) ) 73 | io.writeln( mat ) 74 | @[test(code_01)] 75 | @[test(code_01)] 76 | {{6 array}} .* 77 | {{row[0,:]: 1 2 3 78 | row[1,:]: 1 2 3}} 79 | @[test(code_01)] 80 | 81 | 82 | 83 | 84 | @[test(code_01)] 85 | mat = array(2,2,3){ [I,J,K] [I,J,K] } 86 | io.writeln( mat ) 87 | @[test(code_01)] 88 | @[test(code_01)] 89 | {{row[0,0,0,:]: 0 0 0 90 | row[0,0,1,:]: 0 0 1 91 | row[0,0,2,:]: 0 0 2 92 | row[0,1,0,:]: 0 1 0 93 | row[0,1,1,:]: 0 1 1 94 | row[0,1,2,:]: 0 1 2 95 | row[1,0,0,:]: 1 0 0 96 | row[1,0,1,:]: 1 0 1 97 | row[1,0,2,:]: 1 0 2 98 | row[1,1,0,:]: 1 1 0 99 | row[1,1,1,:]: 1 1 1 100 | row[1,1,2,:]: 1 1 2}} 101 | @[test(code_01)] 102 | 103 | 104 | 105 | 106 | @[test(code_01)] 107 | mat = array(2,3,4){ [I,J,K] [I+1, J+2, K+3] } 108 | mat.iterate{ [X,I,J,K] 109 | if( (I+J+K) % 5 == 0 ) io.writeln( X, I, J, K ) 110 | } 111 | @[test(code_01)] 112 | @[test(code_01)] 113 | {{1 0 0 0 114 | 2 0 0 0 115 | 3 0 0 0 116 | 1 0 2 3 117 | 4 0 2 3 118 | 6 0 2 3 119 | 2 1 1 3 120 | 3 1 1 3 121 | 6 1 1 3 122 | 2 1 2 2 123 | 4 1 2 2 124 | 5 1 2 2}} 125 | @[test(code_01)] 126 | 127 | 128 | 129 | 130 | @[test(code_01)] 131 | [1] / 0 132 | @[test(code_01)] 133 | @[test(code_01)] 134 | {{Error::Float::DivByZero}} 135 | @[test(code_01)] 136 | 137 | 138 | 139 | 140 | @[test(code_01)] 141 | [1] / 0.0 142 | @[test(code_01)] 143 | @[test(code_01)] 144 | {{Error::Float::DivByZero}} 145 | @[test(code_01)] 146 | 147 | 148 | 149 | 150 | @[test(code_01)] 151 | [1] / 0.0C 152 | @[test(code_01)] 153 | @[test(code_01)] 154 | {{Error::Float::DivByZero}} 155 | @[test(code_01)] 156 | 157 | 158 | 159 | 160 | @[test(code_01)] 161 | [1] / [0] 162 | @[test(code_01)] 163 | @[test(code_01)] 164 | {{Error::Float::DivByZero}} 165 | @[test(code_01)] 166 | 167 | 168 | 169 | 170 | @[test(code_01)] 171 | [1] / [0.0] 172 | @[test(code_01)] 173 | @[test(code_01)] 174 | {{Error::Float::DivByZero}} 175 | @[test(code_01)] 176 | 177 | 178 | 179 | 180 | @[test(code_01)] 181 | [1] / [0.0C] 182 | @[test(code_01)] 183 | @[test(code_01)] 184 | {{Error::Float::DivByZero}} 185 | @[test(code_01)] 186 | 187 | 188 | 189 | 190 | @[test(code_01)] 191 | [1.0] / 0 192 | @[test(code_01)] 193 | @[test(code_01)] 194 | {{Error::Float::DivByZero}} 195 | @[test(code_01)] 196 | 197 | 198 | 199 | 200 | @[test(code_01)] 201 | [1.0] / 0.0 202 | @[test(code_01)] 203 | @[test(code_01)] 204 | {{Error::Float::DivByZero}} 205 | @[test(code_01)] 206 | 207 | 208 | 209 | 210 | @[test(code_01)] 211 | [1.0] / 0.0C 212 | @[test(code_01)] 213 | @[test(code_01)] 214 | {{Error::Float::DivByZero}} 215 | @[test(code_01)] 216 | 217 | 218 | 219 | 220 | @[test(code_01)] 221 | a = [] 222 | b = a[] 223 | @[test(code_01)] 224 | @[test(code_01)] 225 | [ ] 226 | @[test(code_01)] 227 | 228 | 229 | 230 | 231 | @[test(code_01)] 232 | a = [1] 233 | b = a[:] 234 | @[test(code_01)] 235 | @[test(code_01)] 236 | [ 1 ] 237 | @[test(code_01)] 238 | 239 | 240 | 241 | 242 | @[test(code_01)] 243 | a = [1] 244 | b = [a] 245 | @[test(code_01)] 246 | @[test(code_01)] 247 | [ 1 ] 248 | @[test(code_01)] 249 | 250 | 251 | 252 | 253 | @[test(code_01)] 254 | a = [1] 255 | b = [a,a] 256 | @[test(code_01)] 257 | @[test(code_01)] 258 | [ 1, 1 ] 259 | @[test(code_01)] 260 | -------------------------------------------------------------------------------- /tests/test_class_mixin.dao: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Base 4 | { 5 | var value = 456 6 | routine Meth2(){ io.writeln( "Base::Meth2():", value ) } 7 | } 8 | 9 | # 10 | # Classes to be used as mixin bases can be specified in a pair of brackets 11 | # following the class name. Only classes without parent classes can 12 | # be used as mixins. 13 | # 14 | class Mixin ( Base ) 15 | { 16 | var index = 123 17 | 18 | routine Meth(){ io.writeln( "Mixin::Meth():", index, value ) } 19 | routine Meth2( a : string ){ io.writeln( "Mixin::Meth2():", index, value, a ) } 20 | } 21 | 22 | # 23 | # The "Base" class will be presented only once in "Klass": 24 | # 25 | class Klass ( Base, Mixin ) 26 | { 27 | var index = 123456 28 | routine Meth2( a : int ){ io.writeln( "Klass::Meth():", index, value, a ) } 29 | } 30 | 31 | 32 | 33 | @[test(code_01)] 34 | k = Klass() 35 | 36 | io.writeln( k.index ) 37 | 38 | k.Meth() 39 | k.Meth2() 40 | k.Meth2( "abc" ) 41 | k.Meth2( 789 ) 42 | @[test(code_01)] 43 | @[test(code_01)] 44 | 123456 45 | Mixin::Meth(): 123 456 46 | Base::Meth2(): 456 47 | Mixin::Meth2(): 123 456 abc 48 | Klass::Meth(): 123456 456 789 49 | @[test(code_01)] 50 | -------------------------------------------------------------------------------- /tests/test_class_operator.dao: -------------------------------------------------------------------------------- 1 | 2 | @[test(code_01)] 3 | class Integer 4 | { 5 | var value = 0 6 | 7 | routine Integer( val = 0 ){ value = val } 8 | 9 | static routine +( A : Integer, B : Integer ){ 10 | io.writeln( "Integer + Integer" ); 11 | return Integer( A.value + B.value ); 12 | } 13 | } 14 | I1 = Integer( 123 ) 15 | I2 = Integer( 456 ) 16 | I3 = I1 + I2 17 | @[test(code_01)] 18 | @[test(code_01)] 19 | Integer + Integer 20 | @[test(code_01)] 21 | 22 | 23 | 24 | 25 | 26 | #{ Optimization not working: 27 | @[test(code_01)] 28 | class Integer 29 | { 30 | var value = 0 31 | 32 | routine Integer( val = 0 ){ value = val } 33 | 34 | static routine +( A : Integer, B : Integer ){ 35 | io.writeln( "Integer + Integer" ); 36 | return Integer( A.value + B.value ); 37 | } 38 | static routine +( C : Integer, A : Integer, B : Integer ){ 39 | io.writeln( "Integer = Integer + Integer" ); 40 | C.value = A.value + B.value; 41 | return C; 42 | } 43 | } 44 | I1 = Integer( 123 ) 45 | I2 = Integer( 456 ) 46 | for( i = 1 : 3 ) I3 = I1 + I2 47 | @[test(code_01)] 48 | @[test(code_01)] 49 | @[test(code_01)] 50 | #} 51 | 52 | 53 | 54 | 55 | 56 | @[test(code_01)] 57 | class Integer 58 | { 59 | var value = 0 60 | 61 | routine Integer( val = 0 ){ value = val } 62 | 63 | routine .val(){ io.writeln( "get value" ) } 64 | routine .val=( v : int ){ value = v; io.writeln( "set value", 456 ) } 65 | } 66 | I = Integer( 123 ) 67 | v = I.val 68 | I.val = 456 69 | @[test(code_01)] 70 | @[test(code_01)] 71 | get value 72 | set value 456 73 | @[test(code_01)] 74 | 75 | 76 | 77 | 78 | 79 | @[test(code_01)] 80 | class Integer 81 | { 82 | private 83 | var value = 0 84 | 85 | public 86 | routine Integer( val = 0 ){ value = val } 87 | 88 | routine .value(){ io.writeln( "get value" ) } 89 | routine .value=( v : int ){ value = v; io.writeln( "set value", 456 ) } 90 | } 91 | I = Integer( 123 ) 92 | v = I.value 93 | I.value = 456 94 | @[test(code_01)] 95 | @[test(code_01)] 96 | get value 97 | set value 456 98 | @[test(code_01)] 99 | 100 | 101 | 102 | 103 | 104 | @[test(code_01)] 105 | class Integer 106 | { 107 | var value = 0 108 | 109 | routine Integer( val = 0 ){ value = val } 110 | 111 | routine .value(){ io.writeln( "get value" ) } 112 | routine .value=( v : int ){ value = v; io.writeln( "set value" ) } 113 | } 114 | I = Integer( 123 ) 115 | v = I.value 116 | I.value = 456 117 | @[test(code_01)] 118 | @[test(code_01)] 119 | {{At line}} .* {{Getter/setter may not be used for}} 120 | @[test(code_01)] 121 | 122 | 123 | 124 | 125 | 126 | @[test(code_01)] 127 | class IntList 128 | { 129 | var ints = {} 130 | 131 | routine Append( value : int ){ ints.append( value ) } 132 | routine []( index : int ){ return ints[index] } 133 | routine []=( value :int, index : int ){ 134 | ints[index] = value 135 | io.writeln( "set item" ) 136 | } 137 | } 138 | ilist = IntList() 139 | ilist.Append( 123 ) 140 | ilist.Append( 456 ) 141 | ilist[0] = 789 142 | io.writeln( ilist[0] ) 143 | @[test(code_01)] 144 | @[test(code_01)] 145 | set item 146 | 789 147 | @[test(code_01)] 148 | 149 | 150 | 151 | 152 | 153 | @[test(code_01)] 154 | class Record 155 | { 156 | var name = ""; 157 | 158 | routine .Name() { 159 | io.writeln( "Get name:", name ) 160 | return name 161 | } 162 | routine .Name=( value : string ) { 163 | io.writeln( "Set name:", value ) 164 | name = value 165 | } 166 | 167 | routine .( name : string ) { 168 | io.writeln( "Get undefined field:", name ) 169 | return 123 170 | } 171 | routine .=( name : string, value : any ) { 172 | io.writeln( "Set undefined field:", name, "with value:", value ) 173 | } 174 | } 175 | record = Record() 176 | record.Name = "abc" 177 | name = record.Name 178 | 179 | record.index = 123 180 | index = record.index 181 | @[test(code_01)] 182 | @[test(code_01)] 183 | Set name: abc 184 | Get name: abc 185 | Set undefined field: index with value: 123 186 | Get undefined field: index 187 | @[test(code_01)] 188 | -------------------------------------------------------------------------------- /tests/test_class_static_fields.dao: -------------------------------------------------------------------------------- 1 | 2 | 3 | @[test(code_01)] 4 | class Klass 5 | { 6 | var id = 123 7 | static info = "Klass" 8 | static routine StaticMethod(){ io.writeln( info ) } 9 | } 10 | obj = Klass::StaticMethod() 11 | @[test(code_01)] 12 | @[test(code_01)] 13 | Klass 14 | @[test(code_01)] 15 | 16 | 17 | 18 | 19 | 20 | @[test(code_01)] 21 | class Klass 22 | { 23 | var id = 123 24 | static routine Klass(){ id += 1 } 25 | } 26 | obj = Klass() 27 | @[test(code_01)] 28 | @[test(code_01)] 29 | {{At line}} .* {{Variable declared out of context}} 30 | @[test(code_01)] 31 | 32 | 33 | 34 | 35 | @[test(code_01)] 36 | class Klass 37 | { 38 | var id = 123 39 | static routine StaticMethod(){ id += 1 } 40 | } 41 | obj = Klass::StaticMethod() 42 | @[test(code_01)] 43 | @[test(code_01)] 44 | {{At line}} .* {{Variable declared out of context}} 45 | @[test(code_01)] 46 | 47 | 48 | 49 | 50 | @[test(code_01)] 51 | class Klass 52 | { 53 | var id = 123 54 | routine NonStaticMeth(){ id = 3 } 55 | static routine StaticMethod(){ NonStaticMeth() } 56 | } 57 | obj = Klass::StaticMethod() 58 | @[test(code_01)] 59 | @[test(code_01)] 60 | {{At line}} .* {{Calling non-static method without instance}} 61 | @[test(code_01)] 62 | 63 | 64 | 65 | 66 | 67 | ############################################################ 68 | # Test overloading between static and non-static methods: 69 | ############################################################ 70 | @[test(code_01)] 71 | class Klass 72 | { 73 | var id = 123 74 | routine MaybeStaticMeth(){ id = 3 } 75 | static routine MaybeStaticMeth( a ){} 76 | static routine StaticMethod(){ MaybeStaticMeth() } 77 | } 78 | obj = Klass::StaticMethod() 79 | @[test(code_01)] 80 | @[test(code_01)] 81 | {{At line}} .* {{Calling non-static method without instance}} 82 | @[test(code_01)] 83 | 84 | 85 | 86 | 87 | @[test(code_01)] 88 | class Klass 89 | { 90 | var id = 123 91 | routine MaybeStaticMeth(){ id = 3 } 92 | static routine MaybeStaticMeth( a ){ io.writeln( a ) } 93 | static routine StaticMethod2(){ MaybeStaticMeth( "OK" ) } 94 | } 95 | obj = Klass::StaticMethod2() 96 | @[test(code_01)] 97 | @[test(code_01)] 98 | OK 99 | @[test(code_01)] 100 | -------------------------------------------------------------------------------- /tests/test_closure.dao: -------------------------------------------------------------------------------- 1 | 2 | @[test] 3 | closures = {}; 4 | 5 | for( i = 1 : 6 ){ 6 | ls = { i }; 7 | closure = routine(){ 8 | io.writeln( ls, i ) 9 | } 10 | closures.append( closure ) 11 | } 12 | 13 | for( closure in closures ) closure() 14 | @[test] 15 | @[test] 16 | { 1 } 1 17 | { 2 } 2 18 | { 3 } 3 19 | { 4 } 4 20 | { 5 } 5 21 | @[test] 22 | 23 | 24 | 25 | 26 | @[test] 27 | routine Test() 28 | { 29 | abc = "abc" 30 | rout = routine(){ 31 | io.writeln( "outer closure", abc ) 32 | rout = routine(){ 33 | io.writeln( "inner closure", abc ) 34 | } 35 | return rout; 36 | } 37 | return rout() 38 | } 39 | 40 | rout = Test() 41 | rout() 42 | @[test] 43 | @[test] 44 | outer closure abc 45 | inner closure abc 46 | @[test] 47 | 48 | 49 | 50 | 51 | @[test] 52 | class Klass 53 | { 54 | var value = 123; 55 | routine Meth(){ 56 | value = 456; 57 | return routine{ 58 | io.writeln( value ) # Accessing class member is OK; 59 | } 60 | } 61 | } 62 | k = Klass(); 63 | m = k.Meth() 64 | m() 65 | @[test] 66 | @[test] 67 | 456 68 | @[test] 69 | 70 | 71 | 72 | 73 | @[test] 74 | class Klass 75 | { 76 | var value = 123; 77 | routine Func( param: string ){ 78 | io.writeln( param, value ) 79 | } 80 | routine Meth(){ 81 | value = 456; 82 | return routine{ 83 | Func( "hello" ); # Calling instance method is not OK; 84 | } 85 | } 86 | } 87 | k = Klass(); 88 | m = k.Meth() 89 | m() 90 | @[test] 91 | @[test] 92 | {{At line}} .* {{Invalid parameter type}} 93 | @[test] 94 | 95 | 96 | 97 | 98 | @[test] 99 | class K { 100 | routine F( a ){} 101 | routine M(){ 102 | defer { 103 | self.F(1) 104 | } 105 | } 106 | } 107 | k=K() 108 | k.M() 109 | @[test] 110 | @[test] 111 | @[test] 112 | 113 | 114 | 115 | 116 | @[test] 117 | class K { 118 | routine F( a ){} 119 | routine M(){ 120 | defer { 121 | F(1) 122 | } 123 | } 124 | } 125 | k=K() 126 | k.M() 127 | @[test] 128 | @[test] 129 | {{At line}} .* {{Invalid parameter type}} 130 | @[test] 131 | -------------------------------------------------------------------------------- /tests/test_concrete_interface.dao: -------------------------------------------------------------------------------- 1 | 2 | # Abstract interface: 3 | interface InterA 4 | { 5 | routine size()=>int 6 | routine serialize()=>string 7 | } 8 | 9 | # Concrete interface for int: 10 | interface InterA for int 11 | { 12 | routine size(){ 13 | io.writeln( "InterA::size()", std.about(self) ) 14 | io.writeln( "InterA::size()", self.serialize() ); 15 | return (int)self + 1; 16 | } 17 | routine serialize() => string { return "abc" + (string) self; } 18 | } 19 | 20 | @[test()] 21 | var a: InterA = 123 # a: value type InterA; variable type InterA; 22 | io.writeln( std.about(a) ) 23 | 24 | class K 25 | { 26 | routine size(){ return 1 } 27 | routine serialize() => string { return "abc"; } 28 | } 29 | 30 | a = K() 31 | @[test()] 32 | @[test()] 33 | {{InterA}} 34 | @[test()] 35 | 36 | 37 | 38 | @[test()] 39 | var b = (InterA) 123; 40 | io.writeln( std.about(b) ) 41 | @[test()] 42 | @[test()] 43 | {{InterA}} 44 | @[test()] 45 | 46 | 47 | 48 | 49 | @[test()] 50 | var c: InterA = 123 51 | io.writeln( std.about(c) ) 52 | @[test()] 53 | @[test()] 54 | {{InterA}} 55 | @[test()] 56 | 57 | 58 | 59 | 60 | @[test()] 61 | var c: InterA = 123 62 | var d: int = c 63 | @[test()] 64 | @[test()] 65 | @[test()] 66 | 67 | 68 | 69 | @[test()] 70 | var e: list> = { 123 } 71 | e.append(456) 72 | io.writeln( e ) 73 | @[test()] 74 | @[test()] 75 | {{abc123, abc456}} 76 | @[test()] 77 | 78 | 79 | 80 | 81 | @[test()] 82 | var f: list = { 678 } 83 | f.append(456) 84 | io.writeln( f ); 85 | @[test()] 86 | @[test()] 87 | {{abc678, abc456}} 88 | @[test()] 89 | 90 | 91 | 92 | 93 | 94 | interface InterB : InterA 95 | { 96 | routine []( index: int ) => int 97 | } 98 | interface InterB for int : InterA 99 | { 100 | routine []( index: int ) => int { 101 | return ((int)self & (1<> index; 102 | } 103 | } 104 | 105 | 106 | @[test()] 107 | var k = (InterB) 0x7ffeff; 108 | var f: list = { 678 } 109 | f.append( k ) 110 | 111 | io.writeln( f, k[1] ) 112 | @[test()] 113 | @[test()] 114 | { abc678, abc8388351 } 1 115 | @[test()] 116 | 117 | 118 | 119 | 120 | @[test()] 121 | var k = (InterB) 0x7ffeff; 122 | var h = (InterA) k; 123 | io.writeln( std.about(h) ) 124 | @[test()] 125 | @[test()] 126 | {{InterB}} 127 | @[test()] 128 | 129 | 130 | 131 | 132 | @[test()] 133 | var k = (InterB) 0x7ffeff; 134 | var m: InterA = k; 135 | io.writeln( std.about(m) ) 136 | @[test()] 137 | @[test()] 138 | {{InterB}} 139 | @[test()] 140 | 141 | 142 | 143 | 144 | @[test()] 145 | var k = (InterB) 0x7ffeff; 146 | var s = (InterA) k; 147 | io.writeln( std.about(s) ) 148 | @[test()] 149 | @[test()] 150 | {{InterB}} 151 | @[test()] 152 | 153 | 154 | 155 | 156 | 157 | @[test()] 158 | interface InterC : InterB 159 | { 160 | } 161 | @[test()] 162 | @[test()] 163 | {{Invalid parent interface}} 164 | @[test()] 165 | 166 | 167 | 168 | 169 | 170 | @[test()] 171 | interface InterC for int : InterB 172 | { 173 | } 174 | @[test()] 175 | @[test()] 176 | {{Need symbol of interface}} 177 | @[test()] 178 | 179 | 180 | 181 | 182 | 183 | @[test()] 184 | interface InterC {} 185 | interface InterC for int : InterB 186 | { 187 | } 188 | @[test()] 189 | @[test()] 190 | {{Invalid parent interface}} 191 | @[test()] 192 | 193 | 194 | 195 | 196 | 197 | @[test()] 198 | interface InterC : InterA 199 | { 200 | } 201 | interface InterC for int : InterB 202 | { 203 | } 204 | @[test()] 205 | @[test()] 206 | {{Invalid parent interface}} 207 | @[test()] 208 | 209 | 210 | 211 | 212 | 213 | @[test()] 214 | interface InterC : InterA 215 | { 216 | routine method(); 217 | } 218 | interface InterC for int : InterA 219 | { 220 | } 221 | @[test()] 222 | @[test()] 223 | {{Incomplete concrete interface implementation}} 224 | @[test()] 225 | -------------------------------------------------------------------------------- /tests/test_coroutine.dao: -------------------------------------------------------------------------------- 1 | 2 | routine Foo( a = 0, b = "" )=>[?] 3 | { 4 | io.writeln( "Foo():", a ); 5 | return yield( 2 * a, "by Foo()" ); 6 | } 7 | 8 | routine Bar( a = 0, b = "" )=>[?] 9 | { 10 | io.writeln( "Bar():", a, b ); 11 | ( r, s ) = Foo( a + 1, b ); 12 | io.writeln( "Bar():", r, s ); 13 | ( r, s ) = yield( a + 100, b ); 14 | io.writeln( "Bar():", r, s ); 15 | return a, "ended"; 16 | } 17 | 18 | global co = Bar::( 100, "AA" ); 19 | 20 | 21 | 22 | @[test(code_01)] 23 | 24 | io.writeln( "Main: ", co() ); 25 | 26 | @[test(code_01)] 27 | @[test(code_01)] 28 | Bar(): 100 AA 29 | Foo(): 101 30 | Main: ( 202, "by Foo()" ) 31 | @[test(code_01)] 32 | 33 | 34 | 35 | @[test(code_01)] 36 | 37 | io.writeln( "Main: ", co( 200, "XX" ) ); 38 | 39 | @[test(code_01)] 40 | @[test(code_01)] 41 | Bar(): 200 XX 42 | Main: ( 200, "AA" ) 43 | @[test(code_01)] 44 | 45 | 46 | 47 | @[test(code_01)] 48 | 49 | io.writeln( "Main: ", co( 300, "YY" ) ); 50 | 51 | @[test(code_01)] 52 | @[test(code_01)] 53 | Bar(): 300 YY 54 | Main: ( 100, "ended" ) 55 | @[test(code_01)] 56 | 57 | 58 | 59 | @[test(code_01)] 60 | 61 | # coroutine has been finished, the following will rise an exception. 62 | io.writeln( "Main: ", co( 400, "ZZ" ) ); 63 | 64 | @[test(code_01)] 65 | @[test(code_01)] 66 | {{Exception.Warning}} .* {{coroutine execution is finished}} 67 | @[test(code_01)] 68 | 69 | 70 | 71 | @[test(code_01)] 72 | routine Test() 73 | { 74 | yield( 1 ) # Error: cannot yield; 75 | } 76 | @[test(code_01)] 77 | @[test(code_01)] 78 | {{Cannot yield from normal function}} .* {{ERROR}} .* {{At line}} 79 | @[test(code_01)] 80 | 81 | 82 | 83 | @[test(code_01)] 84 | routine Test() 85 | { 86 | return 1 87 | } 88 | co2 = Test::() # Error??? 89 | @[test(code_01)] 90 | @[test(code_01)] 91 | @[test(code_01)] 92 | -------------------------------------------------------------------------------- /tests/test_enum_symbol_def.dao: -------------------------------------------------------------------------------- 1 | 2 | #{ 3 | EnumEntry ::= Identifier [ = ConstExpr ] 4 | 5 | Enum1 ::= 'enum' Identifier '{' EnumEntry { ',' EnumEntry } '}' 6 | Enum2 ::= 'enum' Identifier '{' EnumEntry { ';' EnumEntry } '}' 7 | 8 | Enum ::= Enum1 | Enum2 9 | 10 | EnumType1 ::= 'enum' '<' EnumEntry { ',' EnumEntry } '>' 11 | EnumType2 ::= 'enum' '<' EnumEntry { ';' EnumEntry } '>' 12 | 13 | EnumType ::= EnumType1 | EnumType2 14 | #} 15 | 16 | 17 | 18 | 19 | @[test()] 20 | enum 21 | { 22 | } 23 | @[test()] 24 | @[test()] 25 | {{ERROR}} .* {{At line}} .* {{Invalid enum definition}} 26 | @[test()] 27 | 28 | 29 | 30 | enum Bool 31 | { 32 | False, 33 | True 34 | } 35 | 36 | 37 | @[test()] 38 | io.writeln( Bool::False ) 39 | io.writeln( Bool.True ) 40 | @[test()] 41 | @[test()] 42 | $False(0) 43 | $True(1) 44 | @[test()] 45 | 46 | 47 | @[test()] 48 | switch( Bool.False ){ 49 | case Bool::False : io.writeln( "Bool::False" ) 50 | case Bool::True : io.writeln( "Bool::True" ) 51 | } 52 | @[test()] 53 | @[test()] 54 | Bool::False 55 | @[test()] 56 | 57 | 58 | 59 | @[test()] 60 | switch( (Bool) $True ){ 61 | case Bool::False : io.writeln( "Bool::False" ) 62 | case Bool::True : io.writeln( "Bool::True" ) 63 | } 64 | @[test()] 65 | @[test()] 66 | Bool::True 67 | @[test()] 68 | 69 | 70 | 71 | @[test()] 72 | bl : Bool = $True 73 | io.writeln( bl ) 74 | @[test()] 75 | @[test()] 76 | $True(1) 77 | @[test()] 78 | 79 | 80 | 81 | @[test()] 82 | a = True; 83 | @[test()] 84 | @[test()] 85 | {{ERROR}} .* {{At line}} .* {{Symbol not defined}} 86 | @[test()] 87 | 88 | 89 | 90 | @[test()] 91 | flag = Bool.False + Bool.True 92 | @[test()] 93 | @[test()] 94 | {{not combinable enum}} 95 | @[test()] 96 | 97 | 98 | 99 | 100 | @[test()] 101 | const False : int = Bool::False 102 | const True : int = Bool::True 103 | io.writeln( False, True ) 104 | @[test()] 105 | @[test()] 106 | 0 1 107 | @[test()] 108 | 109 | 110 | 111 | @[test()] 112 | enum EC 113 | { 114 | AA; 115 | BB = 3; 116 | CC 117 | } 118 | io.writeln( EC::AA ) 119 | io.writeln( EC::BB ) 120 | io.writeln( EC::CC ) 121 | @[test()] 122 | @[test()] 123 | $AA(1) 124 | $AA$BB(3) 125 | $CC(6) 126 | @[test()] 127 | 128 | 129 | 130 | @[test()] 131 | enum Test 132 | { 133 | ABC = 'abc' 134 | } 135 | @[test()] 136 | @[test()] 137 | {{ERROR}} .* {{At line}} .* {{Invalid enum definition}} 138 | @[test()] 139 | 140 | 141 | 142 | @[test()] 143 | enum Test 144 | { 145 | A = 1 146 | B = 1 147 | } 148 | @[test()] 149 | @[test()] 150 | {{ERROR}} .* {{At line}} .* {{Invalid enum definition}} 151 | @[test()] 152 | 153 | 154 | 155 | @[test()] 156 | enum Test 157 | { 158 | A = 1, 159 | A = 1 160 | } 161 | @[test()] 162 | @[test()] 163 | {{ERROR}} .* {{At line}} .* {{Symbol was defined}} 164 | @[test()] 165 | 166 | 167 | 168 | @[test()] 169 | enum Test 170 | { 171 | A = 1, 172 | B = 2 - 1 173 | } 174 | @[test()] 175 | @[test()] 176 | {{ERROR}} .* {{At line}} .* {{Value was used}} 177 | @[test()] 178 | -------------------------------------------------------------------------------- /tests/test_enum_symbol_type.dao: -------------------------------------------------------------------------------- 1 | 2 | #{ 3 | EnumEntry ::= Identifier [ = ConstExpr ] 4 | 5 | Enum1 ::= 'enum' Identifier '{' EnumEntry { ',' EnumEntry } '}' 6 | Enum2 ::= 'enum' Identifier '{' EnumEntry { ';' EnumEntry } '}' 7 | 8 | Enum ::= Enum1 | Enum2 9 | 10 | EnumType1 ::= 'enum' '<' EnumEntry { ',' EnumEntry } '>' 11 | EnumType2 ::= 'enum' '<' EnumEntry { ';' EnumEntry } '>' 12 | 13 | EnumType ::= EnumType1 | EnumType2 14 | #} 15 | 16 | 17 | 18 | type Bool = enum 19 | 20 | 21 | @[test()] 22 | io.writeln( Bool::False ) 23 | io.writeln( Bool.True ) 24 | @[test()] 25 | @[test()] 26 | $False(0) 27 | $True(1) 28 | @[test()] 29 | 30 | 31 | @[test()] 32 | switch( Bool.False ){ 33 | case Bool::False : io.writeln( "Bool::False" ) 34 | case Bool::True : io.writeln( "Bool::True" ) 35 | } 36 | @[test()] 37 | @[test()] 38 | Bool::False 39 | @[test()] 40 | 41 | 42 | 43 | @[test()] 44 | switch( (Bool) $True ){ 45 | case Bool::False : io.writeln( "Bool::False" ) 46 | case Bool::True : io.writeln( "Bool::True" ) 47 | } 48 | @[test()] 49 | @[test()] 50 | Bool::True 51 | @[test()] 52 | 53 | 54 | 55 | @[test()] 56 | bl : Bool = $True 57 | io.writeln( bl ) 58 | @[test()] 59 | @[test()] 60 | $True(1) 61 | @[test()] 62 | 63 | 64 | 65 | @[test()] 66 | a = True; 67 | @[test()] 68 | @[test()] 69 | {{ERROR}} .* {{At line}} .* {{Symbol not defined}} 70 | @[test()] 71 | 72 | 73 | 74 | @[test()] 75 | flag = Bool.False + Bool.True 76 | @[test()] 77 | @[test()] 78 | {{not combinable enum}} 79 | @[test()] 80 | 81 | 82 | 83 | 84 | @[test()] 85 | type E = enum 86 | @[test()] 87 | @[test()] 88 | {{ERROR}} .* {{At line}} .* {{Invalid type form}} 89 | @[test()] 90 | 91 | 92 | 93 | @[test()] 94 | type E = enum 95 | @[test()] 96 | @[test()] 97 | {{ERROR}} .* {{At line}} .* {{Invalid type form}} 98 | @[test()] 99 | 100 | 101 | 102 | @[test()] 103 | type E = enum 104 | @[test()] 105 | @[test()] 106 | {{ERROR}} .* {{At line}} .* {{Invalid type form}} 107 | @[test()] 108 | 109 | 110 | 111 | @[test()] 112 | type E = enum 113 | @[test()] 114 | @[test()] 115 | {{ERROR}} .* {{At line}} .* {{Value was used}} 116 | @[test()] 117 | 118 | 119 | 120 | 121 | @[test()] 122 | type E = enum; 123 | var m: map = {->}; 124 | m[$x] = true; 125 | io.writeln( m[$x] ) 126 | @[test()] 127 | @[test()] 128 | true 129 | @[test()] 130 | -------------------------------------------------------------------------------- /tests/test_error_handling.dao: -------------------------------------------------------------------------------- 1 | 2 | @[test(code_01)] 3 | routine Test() 4 | { 5 | defer { 6 | io.writeln( "always executed" ) 7 | } 8 | defer( none ){ 9 | io.writeln( "defer( none )" ) 10 | } 11 | defer( Error as error ){ 12 | io.writeln( "defer( Exception::Error as error )" ) 13 | return 999 14 | } 15 | 16 | for( i = 2 : 6 ) defer { io.writeln( "deferred", i ) } 17 | 18 | std.error( Error( "something" ) ) 19 | io.writeln( "returning" ); 20 | return 123 21 | } 22 | 23 | io.writeln( Test() ) 24 | @[test(code_01)] 25 | @[test(code_01)] 26 | deferred 5 27 | deferred 4 28 | deferred 3 29 | deferred 2 30 | defer( Exception::Error as error ) 31 | always executed 32 | 999 33 | @[test(code_01)] 34 | 35 | 36 | 37 | 38 | @[test(code_01)] 39 | routine Test() 40 | { 41 | defer ( Error ){ 42 | io.writeln( "Error is handled! And a new value is returned!" ) 43 | return 456 44 | } 45 | io.writeln( "Test(): before error;" ) 46 | std.error( "some error" ) 47 | io.writeln( "Test(): after error;" ) 48 | return 123 49 | } 50 | 51 | io.writeln( Test() ) 52 | @[test(code_01)] 53 | @[test(code_01)] 54 | Test(): before error; 55 | Error is handled! And a new value is returned! 56 | 456 57 | @[test(code_01)] 58 | 59 | 60 | 61 | 62 | @[test(code_01)] 63 | class MyError : Error 64 | { 65 | routine (string)(){ return "MyError.{" + self.summary + "}" } 66 | } 67 | 68 | routine Test2() 69 | { 70 | defer ( MyError as error ) { 71 | io.writeln( "recovering from", error ) 72 | return none 73 | } 74 | 75 | io.writeln( "Test2(): before error;" ) 76 | std.error( MyError() ); 77 | io.writeln( "Test2(): after error;" ) 78 | } 79 | 80 | Test2() 81 | @[test(code_01)] 82 | @[test(code_01)] 83 | {{Test2(): before error;}} .* 84 | {{recovering from MyError}} 85 | @[test(code_01)] 86 | 87 | 88 | 89 | 90 | @[test(code_01)] 91 | fout = io::stdio 92 | 93 | std.exec { 94 | defer ( any ) { return none } 95 | #fout = io.open( "NonExistentFile.txt", "r+" ) 96 | std.error( "error" ); 97 | } 98 | 99 | #if( fout != io::stdio ) defer{ fout.close() } 100 | 101 | fout.writeln( "hello" ) 102 | @[test(code_01)] 103 | @[test(code_01)] 104 | hello 105 | @[test(code_01)] 106 | 107 | 108 | 109 | 110 | @[test(code_01)] 111 | s = { io::stdio, io::stderr } 112 | fout = std.exec( io::stdio ){ s[3] } 113 | #if( fout != io::stdio ) defer{ fout.close() } 114 | fout.writeln( "hello" ) 115 | @[test(code_01)] 116 | @[test(code_01)] 117 | hello 118 | @[test(code_01)] 119 | 120 | 121 | 122 | 123 | 124 | @[test(code_01)] 125 | const UserError = Error::define( "Error::User" ) 126 | @[test(code_01)] 127 | @[test(code_01)] 128 | @[test(code_01)] 129 | 130 | 131 | 132 | 133 | 134 | @[test(code_01)] 135 | const UserError = Error::define( "Error::User" ) 136 | std.error( UserError, "Test" ) 137 | @[test(code_01)] 138 | @[test(code_01)] 139 | {{[[Error::User]]}} .* {{Test}} 140 | @[test(code_01)] 141 | 142 | 143 | 144 | 145 | 146 | @[test(code_01)] 147 | const UserError = Error::define( "User" ) 148 | std.error( UserError, "Test" ) 149 | @[test(code_01)] 150 | @[test(code_01)] 151 | {{[[Error::User]]}} .* {{Test}} 152 | @[test(code_01)] 153 | 154 | 155 | 156 | 157 | @[test(code_01)] 158 | var abc = 123 159 | std.assert( abc == 0, "Test" ) 160 | @[test(code_01)] 161 | @[test(code_01)] 162 | {{[[Error::Assertion]]}} .* {{Assertion failed at line 3 in file}} 163 | @[test(code_01)] 164 | 165 | 166 | 167 | 168 | @[test(code_01)] 169 | const err = Error::define('Error::SomeError') 170 | e = std.try { std.error(err, 'test') } 171 | switch (e) type { case err: std.error(e) } 172 | @[test(code_01)] 173 | @[test(code_01)] 174 | {{[[Error::SomeError]]}} 175 | @[test(code_01)] 176 | 177 | 178 | 179 | 180 | @[test(code_01)] 181 | const E = Error::define('Error::SomeError2'); 182 | e = E('xyz'); 183 | std.error(e) 184 | @[test(code_01)] 185 | @[test(code_01)] 186 | {{[[Error::SomeError2]]}} 187 | @[test(code_01)] 188 | -------------------------------------------------------------------------------- /tests/test_for.dao: -------------------------------------------------------------------------------- 1 | 2 | 3 | @[test(code_01)] 4 | i = 0 5 | for( i = 1 : 4 ) io.writeln( i ) 6 | io.writeln( i ) 7 | @[test(code_01)] 8 | @[test(code_01)] 9 | 1 10 | 2 11 | 3 12 | 4 13 | @[test(code_01)] 14 | 15 | 16 | 17 | @[test(code_01)] 18 | i = 0 19 | for(var i = 1 : 4 ) io.writeln( i ) 20 | io.writeln( i ) 21 | @[test(code_01)] 22 | @[test(code_01)] 23 | 1 24 | 2 25 | 3 26 | 0 27 | @[test(code_01)] 28 | 29 | 30 | 31 | @[test(code_01)] 32 | i = 0 33 | for(i=1; i<=3; ++i) io.writeln( i ) 34 | io.writeln( i ) 35 | @[test(code_01)] 36 | @[test(code_01)] 37 | 1 38 | 2 39 | 3 40 | 4 41 | @[test(code_01)] 42 | 43 | 44 | 45 | @[test(code_01)] 46 | i = 0 47 | for(var i=1; i<=3; ++i) io.writeln( i ) 48 | io.writeln( i ) 49 | @[test(code_01)] 50 | @[test(code_01)] 51 | 1 52 | 2 53 | 3 54 | 0 55 | @[test(code_01)] 56 | 57 | 58 | 59 | @[test(code_01)] 60 | i = 0 61 | for(; i<=3; ++i) io.writeln( i ) 62 | io.writeln( i ) 63 | @[test(code_01)] 64 | @[test(code_01)] 65 | 0 66 | 1 67 | 2 68 | 3 69 | 4 70 | @[test(code_01)] 71 | 72 | 73 | 74 | @[test(code_01)] 75 | i = 0 76 | for( i in {1, 2, 3} ) io.writeln( i ) 77 | io.writeln( i ) 78 | @[test(code_01)] 79 | @[test(code_01)] 80 | 1 81 | 2 82 | 3 83 | 3 84 | @[test(code_01)] 85 | 86 | 87 | 88 | @[test(code_01)] 89 | i = 0 90 | for(var i in {1, 2, 3} ) io.writeln( i ) 91 | io.writeln( i ) 92 | @[test(code_01)] 93 | @[test(code_01)] 94 | 1 95 | 2 96 | 3 97 | 0 98 | @[test(code_01)] 99 | 100 | 101 | 102 | 103 | @[test(code_01)] 104 | invar ls = {(1,1), (2,2), (3,3)}; 105 | for( invar x in ls ){ 106 | io.writeln(x) 107 | } 108 | @[test(code_01)] 109 | @[test(code_01)] 110 | ( 1, 1 ) 111 | ( 2, 2 ) 112 | ( 3, 3 ) 113 | @[test(code_01)] 114 | 115 | 116 | 117 | 118 | @[test(code_01)] 119 | for( i = 1 : 4 ) io.writeln( i ) 120 | io.writeln( i ) 121 | @[test(code_01)] 122 | @[test(code_01)] 123 | {{At line}} .* {{Symbol not defined}} 124 | @[test(code_01)] 125 | 126 | 127 | 128 | @[test(code_01)] 129 | for( i=1; i<=3; ++i ) io.writeln( i ) 130 | io.writeln( i ) 131 | @[test(code_01)] 132 | @[test(code_01)] 133 | {{At line}} .* {{Symbol not defined}} 134 | @[test(code_01)] 135 | 136 | 137 | 138 | @[test(code_01)] 139 | for( i in {1, 2, 3} ) io.writeln( i ) 140 | io.writeln( i ) 141 | @[test(code_01)] 142 | @[test(code_01)] 143 | {{At line}} .* {{Symbol not defined}} 144 | @[test(code_01)] 145 | 146 | 147 | 148 | 149 | @[test(code_01)] 150 | m = 151 | { 152 | "AA" => 12, 153 | "BB" => 34 154 | } 155 | for( x in m ){ 156 | for( y in m ){ # Must never mess with the outer loop; 157 | io.writeln( x, y ) 158 | } 159 | } 160 | @[test(code_01)] 161 | @[test(code_01)] 162 | ( "AA", 12 ) ( "AA", 12 ) 163 | ( "AA", 12 ) ( "BB", 34 ) 164 | ( "BB", 34 ) ( "AA", 12 ) 165 | ( "BB", 34 ) ( "BB", 34 ) 166 | @[test(code_01)] 167 | -------------------------------------------------------------------------------- /tests/test_if_else.dao: -------------------------------------------------------------------------------- 1 | 2 | @[test(code_01)] 3 | if( 1 ) io.writeln( 123 ) 4 | @[test(code_01)] 5 | @[test(code_01)] 6 | 123 7 | @[test(code_01)] 8 | 9 | 10 | 11 | @[test(code_01)] 12 | if( 0 ) 13 | a = 1 14 | else 15 | io.writeln( 123 ) 16 | @[test(code_01)] 17 | @[test(code_01)] 18 | 123 19 | @[test(code_01)] 20 | 21 | 22 | 23 | @[test(code_01)] 24 | a = 1 25 | if( 0 ) 26 | a == 1 27 | else 28 | io.writeln( 123 ) 29 | @[test(code_01)] 30 | @[test(code_01)] 31 | 123 32 | @[test(code_01)] 33 | 34 | 35 | 36 | @[test(code_01)] 37 | if( 0 ) 38 | a = 1 39 | else if( 0 ) 40 | a = 2 41 | else 42 | io.writeln( 123 ) 43 | @[test(code_01)] 44 | @[test(code_01)] 45 | 123 46 | @[test(code_01)] 47 | 48 | 49 | 50 | @[test(code_01)] 51 | a = 123 52 | if( 1 ) 53 | a = 456 54 | 55 | io.writeln( a ) 56 | @[test(code_01)] 57 | @[test(code_01)] 58 | 456 59 | @[test(code_01)] 60 | 61 | 62 | 63 | @[test(code_01)] 64 | a = 123 65 | if( 1 ) 66 | var a = 456 67 | 68 | io.writeln( a ) 69 | @[test(code_01)] 70 | @[test(code_01)] 71 | 123 72 | @[test(code_01)] 73 | 74 | 75 | 76 | @[test(code_01)] 77 | if( 1 ) 78 | if( 1 ) 79 | io.writeln( 123 ) 80 | @[test(code_01)] 81 | @[test(code_01)] 82 | 123 83 | @[test(code_01)] 84 | 85 | 86 | 87 | @[test(code_01)] 88 | if( 1 ) 89 | if( 0 ) 90 | io.writeln( 123 ) 91 | else 92 | io.writeln( 456 ) 93 | @[test(code_01)] 94 | @[test(code_01)] 95 | 456 96 | @[test(code_01)] 97 | 98 | 99 | 100 | @[test(code_01)] 101 | if( 1 ) 102 | if( 0 ) 103 | io.writeln( 123 ) 104 | else 105 | io.writeln( 456 ) 106 | else 107 | io.writeln( 789 ) 108 | @[test(code_01)] 109 | @[test(code_01)] 110 | 456 111 | @[test(code_01)] 112 | 113 | 114 | 115 | @[test(code_01)] 116 | if( var a = 1; a > 0 ) 117 | io.writeln( 123 ) 118 | @[test(code_01)] 119 | @[test(code_01)] 120 | 123 121 | @[test(code_01)] 122 | 123 | 124 | -------------------------------------------------------------------------------- /tests/test_interface.dao: -------------------------------------------------------------------------------- 1 | 2 | interface MethodInterface 3 | { 4 | routine Method( a = 0 ); 5 | } 6 | 7 | routine TestMethodInterface( inter : MethodInterface ) 8 | { 9 | inter.Method( 123 ) 10 | } 11 | 12 | class MethodClass 13 | { 14 | routine Method( a = 0 ){ io.writeln( a ) } 15 | } 16 | 17 | 18 | @[test()] 19 | TestMethodInterface( MethodClass() ) 20 | @[test()] 21 | @[test()] 22 | 123 23 | @[test()] 24 | 25 | 26 | 27 | interface OperatorInterface 28 | { 29 | routine []( index : int ) => int; 30 | routine .name() => string; 31 | } 32 | 33 | routine TestOperatorInterface( inter : OperatorInterface ) 34 | { 35 | io.writeln( inter[123] ); 36 | io.writeln( inter.name ); 37 | } 38 | 39 | class OperatorClass 40 | { 41 | routine []( index : int ){ return index } 42 | routine .name(){ return "name" } 43 | } 44 | 45 | 46 | @[test()] 47 | TestOperatorInterface( OperatorClass() ) 48 | @[test()] 49 | @[test()] 50 | 123 51 | name 52 | @[test()] 53 | 54 | 55 | 56 | 57 | 58 | interface IteratorInterface 59 | { 60 | routine for( iter: tuple ); 61 | routine []( iter: tuple )=>int; 62 | } 63 | 64 | routine TestIteratorInterface( inter : IteratorInterface ) 65 | { 66 | for( i in inter ) io.writeln( i ) 67 | } 68 | 69 | class IteratorClass 70 | { 71 | routine for( iter: tuple ){ 72 | iter[0] = true; 73 | iter[1] = 0; 74 | } 75 | routine []( iter: tuple ){ 76 | id = iter[1]; 77 | iter[0] = id + 1 < 5; 78 | iter[1] = id + 1; 79 | return id; 80 | } 81 | } 82 | 83 | 84 | @[test()] 85 | TestIteratorInterface( IteratorClass() ) 86 | @[test()] 87 | @[test()] 88 | 0 89 | 1 90 | 2 91 | 3 92 | 4 93 | @[test()] 94 | 95 | 96 | 97 | 98 | 99 | interface JointInterface : MethodInterface, OperatorInterface, IteratorInterface 100 | { 101 | } 102 | 103 | routine TestJointInterface( inter : JointInterface ) 104 | { 105 | TestMethodInterface( inter ) 106 | TestOperatorInterface( inter ) 107 | TestIteratorInterface( inter ) 108 | } 109 | 110 | class JointClass ( MethodClass, OperatorClass, IteratorClass ) 111 | { 112 | } 113 | 114 | 115 | @[test()] 116 | TestJointInterface( JointClass() ) 117 | @[test()] 118 | @[test()] 119 | 123 120 | 123 121 | name 122 | 0 123 | 1 124 | 2 125 | 3 126 | 4 127 | @[test()] 128 | -------------------------------------------------------------------------------- /tests/test_maps.dao: -------------------------------------------------------------------------------- 1 | 2 | #@[test(code_01)] 3 | #@[test(code_01)] 4 | #@[test(code_01)] 5 | #@[test(code_01)] 6 | 7 | 8 | 9 | 10 | #@[test(code_01)] 11 | #@[test(code_01)] 12 | #@[test(code_01)] 13 | #@[test(code_01)] 14 | 15 | 16 | 17 | 18 | #@[test(code_01)] 19 | #@[test(code_01)] 20 | #@[test(code_01)] 21 | #@[test(code_01)] 22 | 23 | 24 | 25 | 26 | #@[test(code_01)] 27 | #@[test(code_01)] 28 | #@[test(code_01)] 29 | #@[test(code_01)] 30 | 31 | 32 | 33 | 34 | #@[test(code_01)] 35 | #@[test(code_01)] 36 | #@[test(code_01)] 37 | #@[test(code_01)] 38 | 39 | 40 | 41 | 42 | #@[test(code_01)] 43 | #@[test(code_01)] 44 | #@[test(code_01)] 45 | #@[test(code_01)] 46 | 47 | 48 | 49 | 50 | #{ 51 | @[test(code_01)] 52 | class MyKey 53 | { 54 | var value = 123 55 | 56 | routine ==( other: MyKey ){ 57 | return value == other.value; 58 | } 59 | routine <( other: MyKey ){ 60 | return value < other.value; 61 | } 62 | routine (int)( hashing = false ){ 63 | return value 64 | } 65 | routine (string)(){ 66 | return "MyKey.{" + (string) value + "}" 67 | } 68 | } 69 | 70 | var m1 = { MyKey.{5} => 5, MyKey.{2} => 2, MyKey.{3} => 3, MyKey.{4} => 4 } 71 | var m2 = { MyKey.{5} -> 5, MyKey.{2} -> 2, MyKey.{3} -> 3, MyKey.{4} -> 4 } 72 | io.writeln( m1 ) 73 | io.writeln( m2.find( MyKey.{0} ) ) 74 | io.writeln( m2.find( MyKey.{2} ) ) 75 | @[test(code_01)] 76 | @[test(code_01)] 77 | { MyKey.{2} => 2, MyKey.{3} => 3, MyKey.{4} => 4, MyKey.{5} => 5 } 78 | none 79 | ( MyKey.{2}, 2 ) 80 | @[test(code_01)] 81 | #} 82 | 83 | 84 | 85 | 86 | @[test(code_01)] 87 | load UserType 88 | var m1 = { UserType(3) => 3, UserType(1) => 1, UserType(4) => 4, UserType(2) => 2 } 89 | var m2 = { UserType(3) -> 3, UserType(1) -> 1, UserType(4) -> 4, UserType(2) -> 2 } 90 | io.writeln( m1 ) 91 | io.writeln( m2.find( UserType(0) ) ) 92 | io.writeln( m2.find( UserType(2) ) ) 93 | @[test(code_01)] 94 | @[test(code_01)] 95 | { UserType.{1} => 1, UserType.{2} => 2, UserType.{3} => 3, UserType.{4} => 4 } 96 | none 97 | ( UserType.{2}, 2 ) 98 | @[test(code_01)] 99 | 100 | 101 | 102 | 103 | @[test(code_01)] 104 | load UserPodType 105 | var m1 = { UserPodType(3) => 3, UserPodType(1) => 1, UserPodType(4) => 4, UserPodType(2) => 2 } 106 | var m2 = { UserPodType(3) -> 3, UserPodType(1) -> 1, UserPodType(4) -> 4, UserPodType(2) -> 2 } 107 | io.writeln( m1 ) 108 | io.writeln( m2.find( UserPodType(0) ) ) 109 | io.writeln( m2.find( UserPodType(2) ) ) 110 | @[test(code_01)] 111 | @[test(code_01)] 112 | { UserPodType.{1} => 1, UserPodType.{2} => 2, UserPodType.{3} => 3, UserPodType.{4} => 4 } 113 | none 114 | ( UserPodType.{2}, 2 ) 115 | @[test(code_01)] 116 | -------------------------------------------------------------------------------- /tests/test_misc.dao: -------------------------------------------------------------------------------- 1 | 2 | @[test(code_01)] 3 | a : array 4 | @[test(code_01)] 5 | 6 | @[test(output_01)] 7 | Invalid %s type %s form 8 | @[test(output_01)] 9 | 10 | @[test(code_02)] 11 | a : array 12 | @[test(code_02)] 13 | 14 | @[test(output_02)] 15 | Invalid %s type %s form 16 | @[test(output_02)] 17 | 18 | #{ 19 | DecDigit ::= '0' ... '9' 20 | HexDigit ::= DecDigit | 'a' ... 'f' | 'A' ... 'F' 21 | 22 | DecInteger ::= DecDigit + 23 | HexInteger ::= ('0x' | '0X') DecDigit + 24 | Integer ::= DecInteger | HexInteger 25 | #} 26 | 27 | @[test(code_03)] 28 | io.writef( "%g", .5 ) 29 | @[test(code_03)] 30 | @[test(code_03)] 31 | 0.5 32 | @[test(code_03)] 33 | 34 | 35 | @[test(code_03)] 36 | io.writef( "%g", 123. ) 37 | @[test(code_03)] 38 | @[test(code_03)] 39 | 123 40 | @[test(code_03)] 41 | 42 | 43 | @[test(code_03)] 44 | 12a 45 | @[test(code_03)] 46 | @[test(code_03)] 47 | Invalid %s token 48 | @[test(code_03)] 49 | 50 | 51 | @[test(code_03)] 52 | 0x 53 | @[test(code_03)] 54 | @[test(code_03)] 55 | Invalid %s token 56 | @[test(code_03)] 57 | 58 | 59 | @[test(code_03)] 60 | 0xh 61 | @[test(code_03)] 62 | @[test(code_03)] 63 | Invalid %s token 64 | @[test(code_03)] 65 | 66 | 67 | 68 | # Incomplete string: 69 | @[test(code_03)] 70 | "incomplete string 71 | @[test(code_03)] 72 | @[test(code_03)] 73 | Invalid %s token 74 | @[test(code_03)] 75 | 76 | # Incomplete string: 77 | @[test(code_03)] 78 | "incomplete string 79 | @[test(code_03)] 80 | @[test(code_03)] 81 | Invalid %s token 82 | @[test(code_03)] 83 | 84 | 85 | 86 | 87 | # Test tail call optimization: 88 | @[test(code_03)] 89 | routine TestTailCall( n = 0 ) 90 | { 91 | if( n == 0 ) std.error( "test" ) 92 | TestTailCall( n - 1 ) 93 | } 94 | TestTailCall( 5 ) 95 | @[test(code_03)] 96 | # If broken, it will print multiple "Called by: TestTailCall()" 97 | @[test(code_03)] 98 | {{Exception}} [^%n]* %n 99 | [^%n]* %n 100 | {{Raised by:}} [^%n]* %n 101 | {{In code snippet:}} [^%n]* %n 102 | [^%n]* {{GETCL}} [^%n]* %n 103 | [^%n]* {{MCALL}} [^%n]* %n 104 | [^%n]* {{GETCG}} [^%n]* %n 105 | {{Called by: TestTailCall()}} [^%n]* %s* 106 | {{Called by: __main__()}} [^%n]* %s* 107 | @[test(code_03)] 108 | 109 | 110 | 111 | 112 | 113 | @[test(code_01)] 114 | std.try{ std.load( "WrongModule" ) } 115 | std.load( "WrongModule" ) 116 | @[test(code_01)] 117 | @[test(code_01)] 118 | {{ERROR}} .* 119 | {{Invalid number of parameter}} .* 120 | {{ERROR}} .* 121 | {{Invalid number of parameter}} .* 122 | @[test(code_01)] 123 | -------------------------------------------------------------------------------- /tests/test_multi_threading.dao: -------------------------------------------------------------------------------- 1 | 2 | 3 | @[test(code_00)] 4 | routine Test()[ int ] 5 | { 6 | a = { 123 } # One item so that the result will be deterministic; 7 | mt.iterate(a) { [X] io.writeln(X) } 8 | } 9 | Test { [X] io.writeln( X ) } 10 | @[test(code_00)] 11 | @[test(code_00)] 12 | 123 13 | @[test(code_00)] 14 | 15 | 16 | 17 | 18 | 19 | @[test(code_00)] 20 | routine Test()[ int ] 21 | { 22 | a = {1, 2, 3} 23 | mt.iterate(a) { [X] yield(X) } 24 | } 25 | Test { [X] io.writeln( X ) } 26 | @[test(code_00)] 27 | @[test(code_00)] 28 | {{Error}} .* {{Invalid code section from different process}} 29 | @[test(code_00)] 30 | 31 | 32 | 33 | 34 | 35 | @[test(code_00)] 36 | routine Test()[ int ] 37 | { 38 | a = {1, 2, 3} 39 | mt.iterate(a) { ... } 40 | } 41 | Test { [X] io.writeln( X ) } 42 | @[test(code_00)] 43 | @[test(code_00)] 44 | {{Error}} .* {{Invalid code section from non-immediate caller}} 45 | @[test(code_00)] 46 | -------------------------------------------------------------------------------- /tests/test_numbers.dao: -------------------------------------------------------------------------------- 1 | 2 | @[test(code_01)] 3 | io.writeln( 0xff ) 4 | @[test(code_01)] 5 | 6 | @[test(output_01)] 7 | 255 8 | @[test(output_01)] 9 | 10 | 11 | 12 | 13 | @[test(code_01)] 14 | io.writeln( std.about(1.0) ) 15 | @[test(code_01)] 16 | @[test(code_01)] 17 | {{float}} 18 | @[test(code_01)] 19 | 20 | 21 | 22 | 23 | @[test(code_01)] 24 | io.writeln( std.about(1F) ) 25 | @[test(code_01)] 26 | @[test(code_01)] 27 | Invalid %s token 28 | @[test(code_01)] 29 | 30 | 31 | 32 | 33 | @[test(code_01)] 34 | io.writeln( std.about(1D) ) 35 | @[test(code_01)] 36 | @[test(code_01)] 37 | Invalid %s token 38 | @[test(code_01)] 39 | 40 | 41 | 42 | 43 | @[test(code_01)] 44 | io.writeln( std.about(1C) ) 45 | @[test(code_01)] 46 | @[test(code_01)] 47 | {{complex}} 48 | @[test(code_01)] 49 | 50 | 51 | 52 | 53 | @[test(code_01)] 54 | io.writeln( std.about(1.2C) ) 55 | @[test(code_01)] 56 | @[test(code_01)] 57 | {{complex}} 58 | @[test(code_01)] 59 | 60 | 61 | 62 | 63 | @[test(code_01)] 64 | io.writeln( std.about(1.) ) 65 | @[test(code_01)] 66 | @[test(code_01)] 67 | {{float}} 68 | @[test(code_01)] 69 | 70 | 71 | 72 | 73 | @[test(code_01)] 74 | io.writeln( std.about(.5) ) 75 | @[test(code_01)] 76 | @[test(code_01)] 77 | {{float}} 78 | @[test(code_01)] 79 | 80 | 81 | 82 | 83 | @[test(code_01)] 84 | io.writeln( std.about(1.D) ) 85 | @[test(code_01)] 86 | @[test(code_01)] 87 | Invalid %s token 88 | @[test(code_01)] 89 | 90 | 91 | 92 | 93 | @[test(code_01)] 94 | io.writeln( std.about(.1D) ) 95 | @[test(code_01)] 96 | @[test(code_01)] 97 | Invalid %s token 98 | @[test(code_01)] 99 | 100 | 101 | 102 | @[test(output_01)] 103 | 123/0 104 | @[test(output_01)] 105 | @[test(output_01)] 106 | {{At line}} .* {{Constant evaluation aborted with exception(s)}} .* 107 | {{Error::Float::DivByZero}} 108 | @[test(output_01)] 109 | 110 | 111 | 112 | @[test(output_01)] 113 | a = 123; 114 | b = a/0 115 | @[test(output_01)] 116 | @[test(output_01)] 117 | {{[[Error::Float::DivByZero]]}} 118 | @[test(output_01)] 119 | 120 | 121 | 122 | 123 | @[test(output_01)] 124 | 123 / (any) 0 125 | @[test(output_01)] 126 | @[test(output_01)] 127 | {{[[Error::Float::DivByZero]]}} 128 | @[test(output_01)] 129 | 130 | 131 | 132 | @[test(output_01)] 133 | io.writeln( 123 / 0.0 ) 134 | @[test(output_01)] 135 | @[test(output_01)] 136 | {{[[Error::Float::DivByZero]]}} 137 | @[test(output_01)] 138 | -------------------------------------------------------------------------------- /tests/test_operators.dao: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @[test(code_01)] 5 | a = 1; 6 | b = (a<<1) + (a<<2) 7 | io.writeln(a, b) 8 | @[test(code_01)] 9 | @[test(code_01)] 10 | 1 6 11 | @[test(code_01)] 12 | 13 | 14 | 15 | 16 | @[test(code_01)] 17 | io.writeln( (int) true, (int) false ) 18 | @[test(code_01)] 19 | @[test(code_01)] 20 | 1 0 21 | @[test(code_01)] 22 | 23 | 24 | 25 | 26 | @[test(code_01)] 27 | io.writeln( (string) true, (string) false ) 28 | @[test(code_01)] 29 | @[test(code_01)] 30 | true false 31 | @[test(code_01)] 32 | 33 | 34 | 35 | 36 | @[test(code_01)] 37 | io.writeln( (bool) 1, (bool) 0 ) 38 | @[test(code_01)] 39 | @[test(code_01)] 40 | true false 41 | @[test(code_01)] 42 | 43 | 44 | 45 | 46 | @[test(code_01)] 47 | io.writeln( (bool) "true", (bool) "false" ) 48 | @[test(code_01)] 49 | @[test(code_01)] 50 | true false 51 | @[test(code_01)] 52 | 53 | 54 | 55 | @[test(code_01)] 56 | io.writeln( (float) true, (float) false ) 57 | @[test(code_01)] 58 | @[test(code_01)] 59 | 1.000000 0.000000 60 | @[test(code_01)] 61 | 62 | 63 | 64 | @[test(code_01)] 65 | io.writeln( (float) 123 ) 66 | @[test(code_01)] 67 | @[test(code_01)] 68 | 123.000000 69 | @[test(code_01)] 70 | 71 | 72 | 73 | @[test(code_01)] 74 | io.writeln( (string) 123 ) 75 | @[test(code_01)] 76 | @[test(code_01)] 77 | 123 78 | @[test(code_01)] 79 | 80 | 81 | 82 | 83 | @[test(code_01)] 84 | io.writeln( (string) 123.45 ) 85 | @[test(code_01)] 86 | @[test(code_01)] 87 | 123.45 88 | @[test(code_01)] 89 | 90 | 91 | 92 | 93 | @[test(code_01)] 94 | io.writeln( (list) (123.45, 'abc') ) 95 | @[test(code_01)] 96 | @[test(code_01)] 97 | { 123.450000, "abc" } 98 | @[test(code_01)] 99 | 100 | 101 | 102 | 103 | @[test(code_01)] 104 | io.writeln( (tuple) {123.45, 'abc'} ) 105 | @[test(code_01)] 106 | @[test(code_01)] 107 | ( 123.450000, "abc" ) 108 | @[test(code_01)] 109 | 110 | 111 | 112 | 113 | @[test(code_01)] 114 | invar ls = { 1, 2, 3 } 115 | ls2 = (any) ls 116 | io.writeln( std.about(ls) != std.about(ls2) ) 117 | @[test(code_01)] 118 | @[test(code_01)] 119 | true 120 | @[test(code_01)] 121 | 122 | 123 | 124 | @[test(code_01)] 125 | class K 126 | { 127 | } 128 | invar k = K() 129 | o = (any) k 130 | @[test(code_01)] 131 | @[test(code_01)] 132 | {{[[Error::Type]]}} .* {{casting}} 133 | @[test(code_01)] 134 | 135 | 136 | 137 | 138 | @[test(code_01)] 139 | class K 140 | { 141 | routine M(){} 142 | } 143 | invar k = { K() } 144 | o = (any) k 145 | o[0].M() 146 | @[test(code_01)] 147 | @[test(code_01)] 148 | @[test(code_01)] 149 | 150 | 151 | 152 | 153 | @[test(code_01)] 154 | invar class K 155 | { 156 | routine M(){} 157 | } 158 | invar k = { K() } 159 | o = (any) k # Allowed, K instance is invariable anyway; 160 | o[0].M() 161 | @[test(code_01)] 162 | @[test(code_01)] 163 | @[test(code_01)] 164 | 165 | 166 | 167 | 168 | @[test(code_01)] 169 | routine Func( a: int ){} 170 | 171 | var a = (any) (123, Func) 172 | @[test(code_01)] 173 | @[test(code_01)] 174 | @[test(code_01)] 175 | 176 | 177 | 178 | @[test(code_01)] 179 | a = 1 180 | b = (string) ++i 181 | @[test(code_01)] 182 | @[test(code_01)] 183 | {{At line 3 : Invalid expression}} 184 | @[test(code_01)] 185 | 186 | 187 | 188 | 189 | @[test(code_01)] 190 | var a: tuple = (123, none) 191 | var b: tuple = (123, none) 192 | io.writeln( a == b ) 193 | @[test(code_01)] 194 | @[test(code_01)] 195 | true 196 | @[test(code_01)] 197 | 198 | 199 | 200 | 201 | @[test(code_01)] 202 | var a: tuple = (123, none) 203 | var b: tuple = (123, none) 204 | a[1] = a 205 | b[1] = b 206 | io.writeln( a == b ) 207 | @[test(code_01)] 208 | @[test(code_01)] 209 | false 210 | @[test(code_01)] 211 | 212 | 213 | 214 | 215 | @[test(code_01)] 216 | class K 217 | { 218 | routine ==( other: K ){ 219 | return (self,none) == (other,none) 220 | } 221 | } 222 | k1 = K() 223 | k2 = K() 224 | io.writeln( k1 == k2 ) 225 | @[test(code_01)] 226 | @[test(code_01)] 227 | false 228 | @[test(code_01)] 229 | -------------------------------------------------------------------------------- /tests/test_parser.dao: -------------------------------------------------------------------------------- 1 | 2 | @[test(code_01)] 3 | io.writeln( std.about( (123.45) ) ) 4 | @[test(code_01)] 5 | @[test(code_01)] 6 | {{float}} 7 | @[test(code_01)] 8 | 9 | 10 | 11 | 12 | @[test(code_01)] 13 | io.writeln( std.about( (123.45,) ) ) 14 | @[test(code_01)] 15 | @[test(code_01)] 16 | {{tuple}} 17 | @[test(code_01)] 18 | 19 | 20 | 21 | 22 | @[test(code_01)] 23 | routine Test() { 123.45 } 24 | io.writeln( std.about( Test ) ) 25 | @[test(code_01)] 26 | @[test(code_01)] 27 | Test%{routine%<=%>float%>%} 28 | @[test(code_01)] 29 | 30 | 31 | 32 | 33 | @[test(code_01)] 34 | routine Test() { if( 1 ) 123.45 } 35 | io.writeln( std.about( Test ) ) 36 | @[test(code_01)] 37 | @[test(code_01)] 38 | Test%{routine%<=%>none%>%} 39 | @[test(code_01)] 40 | 41 | 42 | 43 | 44 | @[test(code_01)] 45 | var a 46 | @[test(code_01)] 47 | @[test(code_01)] 48 | {{At line}} .* {{Variable declared without initialization}} 49 | @[test(code_01)] 50 | 51 | 52 | 53 | 54 | @[test(code_01)] 55 | invar a 56 | @[test(code_01)] 57 | @[test(code_01)] 58 | {{At line}} .* {{Variable declared without initialization}} 59 | @[test(code_01)] 60 | -------------------------------------------------------------------------------- /tests/test_strings.dao: -------------------------------------------------------------------------------- 1 | 2 | @[test(code)] 3 | io.writeln( "hello world" ) 4 | @[test(code)] 5 | @[test(output)] 6 | {{hello world}} 7 | @[test(output)] 8 | 9 | 10 | 11 | 12 | @[test(code)] 13 | io.writeln( 'hello world' ) 14 | @[test(code)] 15 | @[test(output)] 16 | {{hello world}} 17 | @[test(output)] 18 | 19 | 20 | 21 | 22 | @[test(code)] 23 | io.writeln( @[]verbatim@[] ) 24 | @[test(code)] 25 | @[test(code)] 26 | verbatim 27 | @[test(code)] 28 | 29 | 30 | 31 | 32 | @[test(code)] 33 | io.writeln( @[abc]verbatim@[abc] ) 34 | @[test(code)] 35 | @[test(code)] 36 | verbatim 37 | @[test(code)] 38 | -------------------------------------------------------------------------------- /tests/test_switch.dao: -------------------------------------------------------------------------------- 1 | 2 | @[test(code_01)] 3 | switch(2){ 4 | case 1 : io.writeln( "case 1" ) 5 | case 2 : io.writeln( "case 2" ) 6 | case 3 : io.writeln( "case 3" ) 7 | } 8 | @[test(code_01)] 9 | @[test(code_01)] 10 | case 2 11 | @[test(code_01)] 12 | 13 | 14 | 15 | @[test(code_01)] 16 | switch(22){ 17 | case 1 : io.writeln( "case 1" ) 18 | case 2 : io.writeln( "case 2" ) 19 | default : io.writeln( "default" ) 20 | } 21 | @[test(code_01)] 22 | @[test(code_01)] 23 | default 24 | @[test(code_01)] 25 | 26 | 27 | 28 | @[test(code_01)] 29 | switch(2){ 30 | case 1, 2 : io.writeln( "case 1,2" ) 31 | case 3 : io.writeln( "case 3" ) 32 | } 33 | @[test(code_01)] 34 | @[test(code_01)] 35 | case 1,2 36 | @[test(code_01)] 37 | 38 | 39 | 40 | @[test(code_01)] 41 | switch(2){ 42 | case 1, 2 : io.writeln( "case 1,2" ) 43 | case 2 : io.writeln( "case 2" ) 44 | case 3 : io.writeln( "case 3" ) 45 | } 46 | @[test(code_01)] 47 | @[test(code_01)] 48 | {{At line}} .* {{Case values not distinctive}} 49 | @[test(code_01)] 50 | 51 | 52 | 53 | 54 | @[test(code_01)] 55 | lst = { 123, 'abc', [1,2,3] } 56 | for( item in lst ){ 57 | switch( item ) type { 58 | case int: io.writeln( 'int' ) 59 | case string: io.writeln( 'string' ) 60 | case array: io.writeln( 'arrry' ) 61 | } 62 | } 63 | @[test(code_01)] 64 | @[test(code_01)] 65 | int 66 | string 67 | arrry 68 | @[test(code_01)] 69 | 70 | 71 | 72 | 73 | @[test(code_01)] 74 | a: any = 123 75 | switch( a ) type { 76 | case int: a += 456 77 | case string: a += 'abc' 78 | } 79 | @[test(code_01)] 80 | @[test(code_01)] 81 | @[test(code_01)] 82 | 83 | 84 | 85 | 86 | @[test(code_01)] 87 | a: any = 123 88 | switch( a ) type { 89 | case int: a += 'abc' 90 | case string: a += 123 91 | } 92 | @[test(code_01)] 93 | @[test(code_01)] 94 | {{At line}} .* {{Invalid virtual machine instruction}} .* 95 | {{At line}} .* {{Invalid operation on the type}} 96 | @[test(code_01)] 97 | -------------------------------------------------------------------------------- /tests/test_tasklet.dao: -------------------------------------------------------------------------------- 1 | 2 | @[test(code_00)] 3 | a = {1,2,3} 4 | b = a.max()!! 5 | c=b.value() 6 | io.writeln( b, c ) 7 | @[test(code_00)] 8 | @[test(code_00)] 9 | {{Future = ( 1, 2, 3 ) 4 | io.writeln( tup ) 5 | io.writeln( std.about(tup) ) 6 | @[test(code)] 7 | @[test(code)] 8 | {{( 1, 2, 3 ) 9 | tuple}} 10 | @[test(code)] 11 | 12 | 13 | 14 | 15 | @[test(code)] 16 | tup : tuple = ( 1, 2, 3 ) 17 | io.writeln( tup[1:] ) 18 | io.writeln( std.about(tup[1:]) ) 19 | @[test(code)] 20 | @[test(code)] 21 | {{( 2, 3 ) 22 | tuple}} 23 | @[test(code)] 24 | 25 | 26 | 27 | 28 | @[test(code)] 29 | tup = ( "abc", 1, 2, 3 ) 30 | idx = 2 31 | tup[idx] += 10 32 | @[test(code)] 33 | @[test(code)] 34 | @[test(code)] 35 | 36 | 37 | 38 | 39 | @[test(code)] 40 | tup = ( 1.5, 1, 2, 3 ) 41 | idx = 2 42 | tup[idx] += 10 43 | @[test(code)] 44 | @[test(code)] 45 | @[test(code)] 46 | -------------------------------------------------------------------------------- /tests/test_type.dao: -------------------------------------------------------------------------------- 1 | 2 | 3 | @[test(code_01)] 4 | var a: dao::int = 1 5 | var b: dao::string = "x" 6 | var c: dao::list = {} 7 | var d: dao::tuple = (1,"a") 8 | @[test(code_01)] 9 | @[test(code_01)] 10 | @[test(code_01)] 11 | 12 | 13 | 14 | # Test auto-type casting: 15 | @[test(code_01)] 16 | var a : none|int = 123 17 | var b = a + 100 18 | @[test(code_01)] 19 | # no error, no output 20 | @[test(code_01)] 21 | @[test(code_01)] 22 | 23 | @[test(code_01)] 24 | var a : none|@T = 123 25 | var b = a + 100 26 | @[test(code_01)] 27 | # no error, no output 28 | @[test(code_01)] 29 | @[test(code_01)] 30 | 31 | @[test(code_01)] 32 | x = (none|@V)99 33 | y = x + x 34 | @[test(code_01)] 35 | @[test(code_01)] 36 | @[test(code_01)] 37 | 38 | # Test recursive types: 39 | @[test(code_01)] 40 | type Node = tuple 41 | var node : Node = ( 123, none ) 42 | node.next = node 43 | io.writeln( node ) 44 | @[test(code_01)] 45 | @[test(code_01)] 46 | {{( 123, (...) )}} 47 | @[test(code_01)] 48 | 49 | 50 | 51 | @[test(code_01)] 52 | type Node = tuple 53 | var node : Node = ( 123, (Node)( 456, none ) ) 54 | node.next.next = node 55 | io.writeln( node ) 56 | @[test(code_01)] 57 | @[test(code_01)] 58 | {{( 123, ( 456, (...) ) )}} 59 | @[test(code_01)] 60 | 61 | 62 | 63 | @[test(code_01)] 64 | type Test1 = none | tuple 65 | type Test2 = none | tuple 66 | type Test3 = none | tuple 67 | type Test4 = none | tuple 68 | 69 | type Test5 = none | tuple 70 | type Test6 = none | tuple 71 | 72 | io.writeln( Test1 ?= Test2, Test1 ?= Test3, Test3 ?= Test4, Test5 ?= Test6 ) 73 | @[test(code_01)] 74 | @[test(code_01)] 75 | ^ {{false false true true}} $ 76 | @[test(code_01)] 77 | -------------------------------------------------------------------------------- /tests/test_while.dao: -------------------------------------------------------------------------------- 1 | 2 | @[test(code_01)] 3 | i = 0 4 | while( i < 3 ) io.writeln( ++i ) 5 | io.writeln( i ) 6 | @[test(code_01)] 7 | @[test(code_01)] 8 | 1 9 | 2 10 | 3 11 | 3 12 | @[test(code_01)] 13 | 14 | 15 | 16 | @[test(code_01)] 17 | i = 0 18 | while( i += 1; i < 3 ) io.writeln( i ) 19 | io.writeln( i ) 20 | @[test(code_01)] 21 | @[test(code_01)] 22 | 1 23 | 2 24 | 3 25 | @[test(code_01)] 26 | 27 | 28 | 29 | @[test(code_01)] 30 | i = 0 31 | do io.writeln(++i) while( i < 3 ) 32 | io.writeln( i ) 33 | @[test(code_01)] 34 | @[test(code_01)] 35 | 1 36 | 2 37 | 3 38 | 3 39 | @[test(code_01)] 40 | 41 | -------------------------------------------------------------------------------- /tools/daomake/makefile.dao: -------------------------------------------------------------------------------- 1 | 2 | project = DaoMake::Project( "DaoMake" ) 3 | 4 | daovm = DaoMake::FindPackage( "Dao", $REQUIRED ) 5 | 6 | if( daovm == none ) return 7 | 8 | project_objs = project.AddObjects( { "source/daoMake.c" } ) 9 | project_exe = project.AddExecutable( "daomake", project_objs ) 10 | 11 | project.UseSharedLibrary( daovm ) 12 | project_exe.SetTargetPath( "../../bin" ) 13 | 14 | libpath = "../../lib/daomake/" 15 | 16 | copy = project.AddCommand( "configs", "$(DAOMAKE) mkdir2 " + libpath ) 17 | copy.AddCommand( "$(DAOMAKE) copy " + project.MakeSourcePath( "platforms" ) + " " + libpath ) 18 | copy.AddCommand( "$(DAOMAKE) copy " + project.MakeSourcePath( "packages" ) + " " + libpath ) 19 | 20 | libpath = DaoMake::MakePath( DaoMake::Variables[ "INSTALL_LIB" ], "daomake/" ); 21 | 22 | project.Install( DaoMake::Variables[ "INSTALL_BIN" ], project_exe ); 23 | project.Install( libpath, "platforms" ); 24 | project.Install( libpath, "packages" ); 25 | 26 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindFFI.dao: -------------------------------------------------------------------------------- 1 | 2 | header_hints = ".;" 3 | if( DaoMake::IsPlatform( "MACOSX" ) ){ 4 | header_hints += "/usr/local/Cellar/libffi/include;" 5 | } 6 | header_path = DaoMake::FindFile( "ffi.h", header_hints ) 7 | 8 | if( header_path == "" ) return; 9 | 10 | sqlite = DaoMake::Project( "FFI" ) 11 | sqlite.AddIncludePath( header_path ) 12 | sqlite.AddLinkingFlag( "-lffi" ) 13 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindFLTK.dao: -------------------------------------------------------------------------------- 1 | 2 | if( DaoMake::IsPlatform( "UNIX" ) ){ 3 | cflags = DaoMake::Shell( "fltk-config --cflags" ) 4 | lflags = DaoMake::Shell( "fltk-config --use-gl --use-images --use-forms --ldflags" ) 5 | libs = DaoMake::Shell( "fltk-config --libs" ) 6 | stlibs = DaoMake::Shell( "fltk-config --ldstaticflags" ) 7 | if( stlibs == "" ) return; 8 | 9 | fltk = DaoMake::Project( "FLTK" ) 10 | fltk.AddSharedLibrary( "fltk" ) 11 | fltk.AddCompilingFlag( cflags.chop() ) 12 | fltk.AddLinkingFlag( "-L/usr/local/lib " + lflags.chop() + " " + libs.chop() ) 13 | } 14 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindGIR.dao: -------------------------------------------------------------------------------- 1 | 2 | header_hints = ".;" 3 | if( DaoMake::IsPlatform( "MACOSX" ) ){ 4 | header_hints += "/usr/local/Cellar/gobject-introspection/include;" 5 | } 6 | header_path = DaoMake::FindFile( "girepository.h", header_hints ) 7 | 8 | if( header_path == "" ) return; 9 | 10 | gir = DaoMake::Project( "GIR" ) 11 | gir.AddSharedLibrary( "gir" ) 12 | gir.AddIncludePath( header_path ) 13 | gir.AddLinkingFlag( "-lgirepository-1.0" ) 14 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindGLUT.dao: -------------------------------------------------------------------------------- 1 | 2 | 3 | if( DaoMake::IsPlatform( "IOS" ) ) return 4 | 5 | 6 | header_hints = ".;" 7 | 8 | 9 | if( DaoMake::IsPlatform( "MACOSX" ) ){ 10 | sdk_path = DaoMake::Variables[ "MACOSX_SDK_PATH" ] 11 | header_hints += sdk_path /"System/Library/Frameworks/GLUT.framework/Headers;" 12 | header_path = DaoMake::FindFile( "glut.h", header_hints ) 13 | if( header_path != "" ){ 14 | opengl = DaoMake::Project( "GLUT" ) 15 | shlibs = "-framework GLUT" 16 | opengl.AddSharedLibrary( "" ) 17 | opengl.AddIncludePath( header_path ) 18 | opengl.AddLinkingFlag( shlibs ) 19 | return; 20 | } 21 | } 22 | 23 | if( DaoMake::IsPlatform( "UNIX" ) ){ 24 | header_path = DaoMake::FindFile( "GLUT/glut.h", header_hints ) 25 | if( % header_path ) header_path = header_path/"GLUT" 26 | if( header_path == "" ) return; 27 | 28 | opengl = DaoMake::Project( "GLUT" ) 29 | shlibs = "-lGL -lGLUT" 30 | opengl.AddSharedLibrary( "" ) 31 | opengl.AddIncludePath( header_path ) 32 | opengl.AddLinkingFlag( shlibs ) 33 | } 34 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindGLib.dao: -------------------------------------------------------------------------------- 1 | 2 | header_hints = ".;" 3 | if( DaoMake::IsPlatform( "MACOSX" ) ){ 4 | header_hints += "/usr/local/Cellar/glib/include;" 5 | } 6 | header_path = DaoMake::FindFile( "glib.h", header_hints ) 7 | 8 | if( header_path == "" ) return; 9 | 10 | glib = DaoMake::Project( "GLib" ) 11 | glib.AddSharedLibrary( "glib" ) 12 | glib.AddIncludePath( header_path ) 13 | glib.AddLinkingFlag( "-lglib-2.0 -lgobject-2.0" ) 14 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindGSL.dao: -------------------------------------------------------------------------------- 1 | 2 | if( DaoMake::IsPlatform( "UNIX" ) ){ 3 | cflags = DaoMake::Shell( "gsl-config --cflags" ) 4 | lflags = DaoMake::Shell( "gsl-config --libs" ) 5 | if( lflags == "" ) return; 6 | 7 | gsl = DaoMake::Project( "GSL" ) 8 | gsl.AddSharedLibrary( "gsl" ) 9 | gsl.AddCompilingFlag( cflags.chop() ) 10 | gsl.AddLinkingFlag( lflags.chop() ) 11 | } 12 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindGraphicsMagick.dao: -------------------------------------------------------------------------------- 1 | 2 | if( DaoMake::IsPlatform( "UNIX" ) ){ 3 | prefix = DaoMake::Shell( "GraphicsMagick-config --prefix" ) 4 | cflags = DaoMake::Shell( "GraphicsMagick-config --cflags" ) 5 | lflags = DaoMake::Shell( "GraphicsMagick-config --ldflags" ) 6 | libs = DaoMake::Shell( "GraphicsMagick-config --libs" ) 7 | stlibs = "" 8 | if( libs == "" ) return; 9 | 10 | magick = DaoMake::Project( "GraphicsMagick" ) 11 | magick.AddSharedLibrary( "Magick" ) 12 | magick.AddIncludePath( prefix.chop() ) 13 | magick.AddCompilingFlag( cflags.chop() ) 14 | magick.AddLinkingFlag( lflags.chop() + " " + libs.chop() ) 15 | } 16 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindGraphicsMagickWand.dao: -------------------------------------------------------------------------------- 1 | 2 | if( DaoMake::IsPlatform( "UNIX" ) ){ 3 | cflags = DaoMake::Shell( "GraphicsMagickWand-config --cflags" ) 4 | lflags = DaoMake::Shell( "GraphicsMagickWand-config --ldflags" ) 5 | libs = DaoMake::Shell( "GraphicsMagickWand-config --libs" ) 6 | stlibs = "" 7 | if( libs == "" ) return; 8 | 9 | wand = DaoMake::Project( "GraphicsMagickWand" ) 10 | wand.AddSharedLibrary( "Wand" ) 11 | wand.AddCompilingFlag( cflags.chop() ) 12 | wand.AddLinkingFlag( lflags.chop() + " " + libs.chop() ) 13 | } 14 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindIconv.dao: -------------------------------------------------------------------------------- 1 | 2 | code = 3 | @[cxx] 4 | #include 5 | #include 6 | int main(void){ 7 | iconv_t state = iconv_open( "", "UTF-8" ); 8 | return 0; 9 | } 10 | @[cxx] 11 | 12 | if( DaoMake::IsPlatform( "UNIX" ) ){ 13 | header_path = DaoMake::FindFile( "iconv.h" ) 14 | if( header_path == "" ) return; 15 | 16 | lflags = ""; 17 | if( DaoMake::TestCompile( code ) == 0 ){ 18 | if( DaoMake::TestCompile( code, "-liconv" ) == 0 ) return; 19 | lflags = "-liconv" 20 | } 21 | 22 | iconv = DaoMake::Project( "Iconv" ) 23 | iconv.AddSharedLibrary( "" ) 24 | iconv.AddIncludePath( header_path ) 25 | } 26 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindLLVM.dao: -------------------------------------------------------------------------------- 1 | 2 | if( DaoMake::IsPlatform( "UNIX" ) ){ 3 | cflags = DaoMake::Shell( "llvm-config --cppflags" ) 4 | lflags = DaoMake::Shell( "llvm-config --ldflags" ) 5 | libs = DaoMake::Shell( "llvm-config --libs" ) 6 | syslibs = DaoMake::Shell( "llvm-config --system-libs" ).chop() 7 | if( libs == "" ) return; 8 | 9 | llvm = DaoMake::Project( "LLVM" ) 10 | llvm.AddSharedLibrary( "" ); 11 | llvm.AddCompilingFlag( cflags.chop() + " -std=c++11" ) 12 | llvm.AddLinkingFlag( libs.chop() + " " + lflags.chop() + " " + syslibs ) 13 | } 14 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindMySQL.dao: -------------------------------------------------------------------------------- 1 | 2 | header_path = DaoMake::FindFile( "mysql/mysql.h" ) 3 | 4 | if( header_path == "" ) return; 5 | 6 | code = 7 | @[cxx] 8 | #include 9 | #include 10 | int main(void){ 11 | mysql_get_client_version(); 12 | return 0; 13 | } 14 | @[cxx] 15 | 16 | cflags = "-I" + header_path 17 | lflags = "-L" + header_path.change( "include $", "lib" ) 18 | 19 | ismysql = DaoMake::TestCompile( code, lflags + " -lmysqlclient", cflags ) 20 | ismaria = DaoMake::TestCompile( code, lflags + " -lmariadbclient -lssl -lz", cflags ) 21 | 22 | if( ismysql == 0 and ismaria == 0 ) return 23 | 24 | mysql = DaoMake::Project( "MySQL" ) 25 | mysql.AddSharedLibrary( "" ) 26 | mysql.AddIncludePath( header_path + "/mysql" ) 27 | if( ismysql ){ 28 | mysql.AddLinkingFlag( lflags + " -lmysqlclient" ) 29 | }else{ 30 | mysql.AddLinkingFlag( lflags + " -lmariadbclient -lssl -lz" ) 31 | } 32 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindOpenGL.dao: -------------------------------------------------------------------------------- 1 | 2 | if( DaoMake::IsPlatform( "IOS" ) ) return 3 | 4 | header_hints = ".;" 5 | 6 | if( DaoMake::IsPlatform( "MACOSX" ) ){ 7 | sdk_path = DaoMake::Variables[ "MACOSX_SDK_PATH" ] 8 | header_hints += sdk_path /"System/Library/Frameworks/OpenGL.framework/Headers;" 9 | header_path = DaoMake::FindFile( "gl.h", header_hints ) 10 | if( header_path != "" ){ 11 | opengl = DaoMake::Project( "OpenGL" ) 12 | shlibs = "-framework OpenGL" 13 | opengl.AddSharedLibrary( "" ) 14 | opengl.AddIncludePath( header_path ) 15 | opengl.AddLinkingFlag( shlibs ) 16 | return; 17 | } 18 | } 19 | 20 | if( DaoMake::IsPlatform( "UNIX" ) ){ 21 | header_path = DaoMake::FindFile( "GL/gl.h", header_hints ) 22 | if( % header_path ) header_path = header_path/"GL" 23 | if( header_path == "" ) return; 24 | 25 | opengl = DaoMake::Project( "OpenGL" ) 26 | shlibs = "-lGL -lGLU" 27 | opengl.AddSharedLibrary( "" ) 28 | opengl.AddIncludePath( header_path ) 29 | opengl.AddLinkingFlag( shlibs ) 30 | } 31 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindOpenGL3.dao: -------------------------------------------------------------------------------- 1 | 2 | if( DaoMake::IsPlatform( "IOS" ) ) return 3 | 4 | header_hints = ".;" 5 | 6 | if( DaoMake::IsPlatform( "MACOSX" ) ){ 7 | sdk_path = DaoMake::Variables[ "MACOSX_SDK_PATH" ] 8 | header_hints += sdk_path /"System/Library/Frameworks/OpenGL.framework/Headers;" 9 | header_path = DaoMake::FindFile( "gl3.h", header_hints ) 10 | if( header_path != "" ){ 11 | opengl = DaoMake::Project( "OpenGL3" ) 12 | shlibs = "-framework OpenGL" 13 | opengl.AddSharedLibrary( "" ) 14 | opengl.AddIncludePath( header_path ) 15 | opengl.AddLinkingFlag( shlibs ) 16 | return; 17 | } 18 | } 19 | 20 | if( DaoMake::IsPlatform( "UNIX" ) ){ 21 | header_path = DaoMake::FindFile( "GL/gl3.h", header_hints ) 22 | if( % header_path ) header_path = header_path /"GL" 23 | if( header_path == "" ) return; 24 | 25 | opengl = DaoMake::Project( "OpenGL3" ) 26 | shlibs = "-lGL -lGLU" 27 | opengl.AddSharedLibrary( "" ) 28 | opengl.AddIncludePath( header_path ) 29 | opengl.AddLinkingFlag( shlibs ) 30 | } 31 | 32 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindOpenGLES.dao: -------------------------------------------------------------------------------- 1 | 2 | 3 | header_hints = ".;" 4 | 5 | 6 | if( DaoMake::IsPlatform( "IOS" ) ){ 7 | sdk_path = DaoMake::Variables[ "IOS_SDK_PATH" ] 8 | header_path = ""; 9 | header_hints += sdk_path /"System/Library/Frameworks/OpenGLES.framework/Headers/ES3;" 10 | header_path = DaoMake::FindFile( "gl.h", header_hints ) 11 | if( header_path == "" ) return; 12 | 13 | opengl = DaoMake::Project( "OpenGLES" ) 14 | shlibs = "-framework OpenGLES" 15 | opengl.AddSharedLibrary( "" ) 16 | opengl.AddIncludePath( header_path ) 17 | opengl.AddLinkingFlag( shlibs ) 18 | } 19 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindPostgreSQL.dao: -------------------------------------------------------------------------------- 1 | 2 | header_path = DaoMake::FindFile( "libpq-fe.h" ) 3 | 4 | inc = "" 5 | lib = "" 6 | 7 | if( header_path == "" ){ 8 | if( DaoMake::IsPlatform( "MACOSX" ) ){ 9 | header_path = DaoMake::FindFile( "libpq-fe.h", "/usr/local/pgsql/include" ) 10 | inc = "/usr/local/pgsql/include" 11 | lib = "/usr/local/pgsql/lib" 12 | }else if( DaoMake::IsPlatform( "UNIX" ) ){ 13 | header_path = DaoMake::FindFile( "libpq-fe.h", "/usr/include/postgresql" ) 14 | inc = "/usr/include/postgresql" 15 | lib = "/usr/lib" 16 | } 17 | } 18 | 19 | if( header_path == "" ) return; 20 | 21 | mysql = DaoMake::Project( "PostgreSQL" ) 22 | mysql.AddSharedLibrary( "pq" ) 23 | mysql.AddIncludePath( header_path ) 24 | 25 | if( inc != "" ) mysql.AddIncludePath( inc ) 26 | if( lib != "" ) mysql.AddLinkingPath( lib ) 27 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindReadLine.dao: -------------------------------------------------------------------------------- 1 | 2 | code = 3 | @[cxx] 4 | #include 5 | #include 6 | int main(void){ 7 | char *chs = readline( "test" ); 8 | return chs != NULL; 9 | } 10 | @[cxx] 11 | 12 | if( DaoMake::IsPlatform( "UNIX" ) ){ 13 | header_path = DaoMake::FindFile( "readline/readline.h" ) 14 | header_path2 = DaoMake::FindFile( "readline/history.h" ) 15 | if( header_path == "" or header_path2 == "" ) return; 16 | 17 | lflags = "-lreadline"; 18 | if( DaoMake::TestCompile( code, "-lreadline", "-I." ) == 0 ){ 19 | if( DaoMake::TestCompile( code, "-lreadline -lncurses", "-I." ) == 0 ) return; 20 | lflags = "-lreadline -lncurses"; 21 | } 22 | 23 | readline = DaoMake::Project( "ReadLine" ) 24 | readline.AddSharedLibrary( "readline" ) 25 | readline.AddIncludePath( header_path ) 26 | readline.AddLinkingFlag( lflags ) 27 | } 28 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindSDL.dao: -------------------------------------------------------------------------------- 1 | 2 | if( DaoMake::IsPlatform( "UNIX" ) ){ 3 | cflags = DaoMake::Shell( "sdl2-config --cflags" ) 4 | lflags = DaoMake::Shell( "sdl2-config --ldflags" ) 5 | libs = DaoMake::Shell( "sdl2-config --libs" ) 6 | stlibs = DaoMake::Shell( "sdl2-config --static-libs" ) 7 | if( stlibs == "" ) return; 8 | 9 | archive = " /usr/local/lib/libSDL2.a " 10 | if( DaoMake::IsPlatform( "IOS" ) ) archive = " /Users/min/Projects/dao/modules/DaoSDL/libSDL2-Simulator.a " 11 | 12 | sdl = DaoMake::Project( "SDL" ) 13 | sdl_dll = sdl.AddSharedLibrary( "" ) 14 | sdl_lib = sdl.AddStaticLibrary( "" ) 15 | sdl.AddCompilingFlag( cflags.chop() ) 16 | sdl_dll.AddLinkingFlag( stlibs.chop() + " " + libs.chop() ) 17 | if( DaoMake::IsPlatform( "IOS" ) ){ 18 | sdl_lib.AddLinkingFlag( archive ) 19 | }else{ 20 | sdl_lib.AddLinkingFlag( archive ) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tools/daomake/packages/FindSQLite.dao: -------------------------------------------------------------------------------- 1 | 2 | header_path = DaoMake::FindFile( "sqlite3.h" ) 3 | if( header_path == "" ) return; 4 | 5 | sqlite = DaoMake::Project( "SQLite" ) 6 | sqlite.AddSharedLibrary( "sqlite3" ) 7 | sqlite.AddIncludePath( header_path ) 8 | sqlite.AddLinkingFlag( "-lsqlite3" ) 9 | -------------------------------------------------------------------------------- /tools/daomake/platforms/beos.dao: -------------------------------------------------------------------------------- 1 | 2 | io.writeln( "DaoMake: using BeOS settings!" ) 3 | 4 | DaoMake::Platforms["BEOS"] = 1 5 | 6 | DaoMake::Settings["AR"] = "ar rcs" 7 | 8 | DaoMake::Settings["EXE-SUFFIX"] = "" 9 | DaoMake::Settings["DLL-SUFFIX"] = ".so" 10 | DaoMake::Settings["LIB-SUFFIX"] = ".a" 11 | DaoMake::Settings["DLL-PREFIX"] = "lib" 12 | DaoMake::Settings["LIB-PREFIX"] = "lib" 13 | DaoMake::Settings["EXE-FLAG"] = "" 14 | DaoMake::Settings["DLL-FLAG"] = "-shared" 15 | DaoMake::Settings["DLL-NAME"] = "-Wl,-soname," 16 | DaoMake::Settings["DYNAMIC-EXPORT"] = "-Wl,-export-dynamic" 17 | DaoMake::Settings["DYNAMIC-IMPORT"] = "" 18 | DaoMake::Settings["DLL-RPATH"] = "-Wl,-rpath=" 19 | DaoMake::Settings["DLL-RPATH-REL"] = "-Wl,-rpath=" 20 | 21 | DaoMake::Settings["RELEASE-CFLAG"] = "-O2" 22 | DaoMake::Settings["RELEASE-LFLAG"] = "" 23 | DaoMake::Settings["DEBUG-CFLAG"] = "-ggdb -O0 -DDEBUG" 24 | DaoMake::Settings["DEBUG-LFLAG"] = "-ggdb" 25 | DaoMake::Settings["PROFILE-CFLAG"] = "-pg" 26 | DaoMake::Settings["PROFILE-LFLAG"] = "-pg" 27 | 28 | -------------------------------------------------------------------------------- /tools/daomake/platforms/bsd.dao: -------------------------------------------------------------------------------- 1 | load unix; 2 | 3 | io.writeln( "DaoMake: using BSD settings!" ) 4 | 5 | DaoMake::Platforms["BSD"] = DaoMake::Platforms["UNIX"] + 1 6 | 7 | DaoMake::Settings["AR"] = "ar -rcs" 8 | -------------------------------------------------------------------------------- /tools/daomake/platforms/freebsd.dao: -------------------------------------------------------------------------------- 1 | load bsd; 2 | 3 | io.writeln( "DaoMake: using FreeBSD settings!" ) 4 | 5 | DaoMake::Platforms["FREEBSD"] = DaoMake::Platforms["BSD"] + 1 6 | -------------------------------------------------------------------------------- /tools/daomake/platforms/haiku.dao: -------------------------------------------------------------------------------- 1 | load beos 2 | 3 | io.writeln( "DaoMake: using Haiku settings!" ) 4 | 5 | DaoMake::Platforms["HAIKU"] = DaoMake::Platforms["BEOS"] + 1 6 | -------------------------------------------------------------------------------- /tools/daomake/platforms/ios.dao: -------------------------------------------------------------------------------- 1 | load macosx 2 | 3 | io.writeln( "DaoMake: using IOS settings!" ) 4 | 5 | xcode_path = DaoMake::Shell( "xcode-select --print-path" ).trim() 6 | if( xcode_path == "" ){ 7 | std.error( "Cannot find XCode location (try xcode-select -switch to set the correct path)" ) 8 | } 9 | 10 | sdks = DaoMake::Shell( "xcodebuild -showsdks" ) 11 | parts = sdks.capture( "iphoneos (%S+)" ) 12 | if( %parts == 0 ) std.error( "Cannot find a valid iOS SDK" ) 13 | 14 | sdk_version = parts[1]; 15 | 16 | dev_path = xcode_path/"Platforms/iPhoneSimulator.platform/Developer" 17 | dev_path2 = xcode_path/"Platforms/iPhoneOS.platform/Developer" 18 | sdk_path = ""; 19 | 20 | arch = DaoMake::Architecture() 21 | 22 | if( arch == "i386" or arch == "x86_64" ){ 23 | sdk_path = dev_path/"SDKs/iPhoneSimulator" + sdk_version + ".sdk" 24 | }else if( arch == "armv6" or arch == "armv7" ){ 25 | sdk_path = dev_path2/"SDKs/iPhoneOS" + sdk_version + ".sdk" 26 | }else{ 27 | std.error( "Invalid architecture" ) 28 | } 29 | 30 | ios_version_min = DaoMake::GetEnv( "IOS_VERSION_MIN" ) 31 | if( ios_version_min == "" ) ios_version_min = sdk_version.change( "%. %d+", ".0" ) 32 | 33 | 34 | DaoMake::Platforms["IOS"] = DaoMake::Platforms["MACOSX"] + 1 35 | 36 | DaoMake::Variables["IOS_DEV_PATH", "="] = dev_path 37 | DaoMake::Variables["IOS_DEV_PATH2", "="] = dev_path2 38 | DaoMake::Variables["IOS_SDK_PATH", "="] = sdk_path 39 | DaoMake::Variables["IOS_VERSION_MIN", "="] = ios_version_min 40 | 41 | DaoMake::Variables["CC", "="] = "$(IOS_DEV_PATH)/usr/bin/gcc" 42 | DaoMake::Variables["CXX", "="] = "$(IOS_DEV_PATH)/usr/bin/g++" 43 | DaoMake::Variables["LD", "="] = "$(IOS_DEV_PATH)/usr/bin/ld" 44 | 45 | DaoMake::Settings["AR"] = "$(IOS_DEV_PATH2)/usr/bin/ar rcs" 46 | 47 | 48 | cflags = " -pipe -no-cpp-precomp -isysroot$(IOS_SDK_PATH)" 49 | cflags += " -miphoneos-version-min=$(IOS_VERSION_MIN)" 50 | cflags += " -I$(IOS_SDK_PATH)/usr/include/" 51 | 52 | ldflags = " -L$(IOS_SDK_PATH)/usr/lib/ -isysroot$(IOS_SDK_PATH)" 53 | ldflags += " -miphoneos-version-min=$(IOS_VERSION_MIN)" 54 | 55 | cflags += " -arch " + arch 56 | ldflags += " -arch " + arch 57 | 58 | ldflags += " -lobjc -framework Foundation -framework CoreGraphics" 59 | ldflags += " -framework UIKit -framework GLKit -framework OpenGLES" 60 | 61 | #DaoMake::Settings["EXE-FLAG"] = "-static-libgcc" 62 | DaoMake::Settings["RELEASE-CFLAG"] = "-O2" + cflags 63 | DaoMake::Settings["RELEASE-LFLAG"] = ldflags 64 | DaoMake::Settings["DEBUG-CFLAG"] = "-O0" + cflags 65 | DaoMake::Settings["DEBUG-LFLAG"] = ldflags 66 | DaoMake::Settings["PROFILE-CFLAG"] = cflags 67 | DaoMake::Settings["PROFILE-LFLAG"] = ldflags 68 | 69 | DaoMake::Settings["DLL-NAME"] = "-install_name " 70 | DaoMake::Settings["DYNAMIC-EXPORT"] = "" 71 | DaoMake::Settings["DYNAMIC-IMPORT"] = "-undefined dynamic_lookup" 72 | DaoMake::Settings["DLL-RPATH"] = "" 73 | DaoMake::Settings["DLL-RPATH-REL"] = "" 74 | 75 | name = "OpenGLES" 76 | path = sdk_path /"System/Library/Frameworks/" + name + ".framework/Headers/ES3" 77 | DaoMake::Packages[ name ] = ( path, header, "", "-framework " + name ) 78 | 79 | system_packages = 80 | { 81 | "Cocoa" => "Cocoa.h", 82 | "CoreFoundation" => "CoreFoundation.h", 83 | "CoreVideo" => "CoreVideo.h", 84 | "GLUT" => "glut.h", 85 | "IOKit" => "IOKitLib.h", 86 | "OpenGL" => "gl.h", 87 | } 88 | 89 | # DaoMake::Packages is for system packages that have standard header files 90 | # and header locations, and can be used with standard compiling and linking flags. 91 | # Packages intended for static linking (not the case for most system packages) 92 | # should not be included here. 93 | 94 | system_packages.iterate { [name, header] 95 | path = sdk_path /"System/Library/Frameworks/" + name + ".framework/Headers" 96 | DaoMake::Packages[ name ] = ( path, header, "", "-framework " + name ) 97 | } 98 | -------------------------------------------------------------------------------- /tools/daomake/platforms/linux.dao: -------------------------------------------------------------------------------- 1 | load unix; 2 | 3 | io.writeln( "DaoMake: using Linux settings!" ) 4 | 5 | DaoMake::Platforms["LINUX"] = DaoMake::Platforms["UNIX"] + 1 6 | -------------------------------------------------------------------------------- /tools/daomake/platforms/macosx.dao: -------------------------------------------------------------------------------- 1 | load bsd; 2 | 3 | io.writeln( "DaoMake: using MacOSX settings!" ) 4 | 5 | xcode_path = DaoMake::Shell( "xcode-select --print-path" ).trim() 6 | if( xcode_path == "" ){ 7 | std.error( "Cannot find XCode location (try xcode-select -switch to set the correct path)" ) 8 | } 9 | 10 | sdks = DaoMake::Shell( "xcodebuild -showsdks" ) 11 | parts = sdks.capture( "macosx (%S+)" ) 12 | if( %parts == 0 ) std.error( "Cannot find a valid MacOSX SDK" ) 13 | 14 | sdk_version = parts[1]; 15 | 16 | io.writeln( "DaoMake: using MacOSX SDK" + sdk_version + "!" ) 17 | 18 | dev_path = xcode_path/"Platforms/MacOSX.platform/Developer" 19 | sdk_path = dev_path/"SDKs/MacOSX" + sdk_version + ".sdk" 20 | 21 | DaoMake::Platforms["MACOSX"] = DaoMake::Platforms["BSD"] + 1 22 | 23 | DaoMake::Variables["MACOSX_DEV_PATH", "="] = dev_path 24 | DaoMake::Variables["MACOSX_SDK_PATH", "="] = sdk_path 25 | 26 | DaoMake::Settings["DLL-SUFFIX"] = ".dylib" 27 | DaoMake::Settings["DLL-FLAG"] = "-dynamiclib" 28 | DaoMake::Settings["DLL-NAME"] = "-install_name @rpath/" 29 | DaoMake::Settings["DYNAMIC-EXPORT"] = "" 30 | DaoMake::Settings["DYNAMIC-IMPORT"] = "-undefined dynamic_lookup" 31 | DaoMake::Settings["DLL-RPATH"] = "-Wl,-rpath," 32 | DaoMake::Settings["DLL-RPATH-REL"] = "-Wl,-rpath,@loader_path/" 33 | 34 | 35 | system_packages = 36 | { 37 | "Cocoa" => "Cocoa.h", 38 | "CoreFoundation" => "CoreFoundation.h", 39 | "CoreVideo" => "CoreVideo.h", 40 | "GLUT" => "glut.h", 41 | "IOKit" => "IOKitLib.h", 42 | "OpenGL" => "gl.h", 43 | } 44 | 45 | # DaoMake::Packages is for system packages that have standard header files 46 | # and header locations, and can be used with standard compiling and linking flags. 47 | # Packages intended for static linking (not the case for most system packages) 48 | # should not be included here. 49 | 50 | system_packages.iterate { [name, header] 51 | path = sdk_path /"System/Library/Frameworks/" + name + ".framework/Headers" 52 | DaoMake::Packages[ name ] = ( path, header, "", "-framework " + name ) 53 | } 54 | -------------------------------------------------------------------------------- /tools/daomake/platforms/mingw.dao: -------------------------------------------------------------------------------- 1 | 2 | load win32; 3 | 4 | io.writeln( "DaoMake: using MinGW settings!" ) 5 | 6 | DaoMake::Platforms["MINGW"] = DaoMake::Platforms["WIN32"] + 1 7 | 8 | # 9 | # 2013-07-24: -shared-libgcc 10 | # This flag is added as a workaround for a known bug in MinGW. 11 | # http://permalink.gmane.org/gmane.comp.lang.lua.luajit/2352 12 | # 13 | DaoMake::Settings["DLL-FLAG"] = "-shared -shared-libgcc" 14 | DaoMake::Settings["RELEASE-LFLAG"] = "-shared-libgcc" 15 | DaoMake::Settings["DEBUG-LFLAG"] = "-ggdb -shared-libgcc" 16 | DaoMake::Settings["PROFILE-LFLAG"] = "-pg -shared-libgcc" 17 | -------------------------------------------------------------------------------- /tools/daomake/platforms/minix.dao: -------------------------------------------------------------------------------- 1 | load unix; 2 | 3 | io.writeln( "DaoMake: using Minix settings!" ) 4 | 5 | DaoMake::Platforms["MINIX"] = DaoMake::Platforms["UNIX"] + 1 6 | -------------------------------------------------------------------------------- /tools/daomake/platforms/openbsd.dao: -------------------------------------------------------------------------------- 1 | load bsd; 2 | 3 | io.writeln( "DaoMake: using OpenBSD settings!" ) 4 | 5 | DaoMake::Platforms["OPENBSD"] = DaoMake::Platforms["BSD"] + 1 6 | -------------------------------------------------------------------------------- /tools/daomake/platforms/unix.dao: -------------------------------------------------------------------------------- 1 | 2 | io.writeln( "DaoMake: using Unix settings!" ) 3 | 4 | DaoMake::Platforms["UNIX"] = 1 5 | 6 | DaoMake::Settings["AR"] = "ar -rcsT" 7 | 8 | DaoMake::Settings["EXE-SUFFIX"] = "" 9 | DaoMake::Settings["DLL-SUFFIX"] = ".so" 10 | DaoMake::Settings["LIB-SUFFIX"] = ".a" 11 | DaoMake::Settings["DLL-PREFIX"] = "lib" 12 | DaoMake::Settings["LIB-PREFIX"] = "lib" 13 | DaoMake::Settings["EXE-FLAG"] = "" 14 | DaoMake::Settings["DLL-FLAG"] = "-shared" 15 | DaoMake::Settings["DLL-NAME"] = "-Wl,-soname," 16 | DaoMake::Settings["DYNAMIC-EXPORT"] = "-Wl,-export-dynamic" 17 | DaoMake::Settings["DYNAMIC-IMPORT"] = "-rdynamic" 18 | DaoMake::Settings["DLL-RPATH"] = "-Wl,-rpath=" 19 | DaoMake::Settings["DLL-RPATH-REL"] = "-Wl,-rpath=\\$$ORIGIN/" 20 | 21 | DaoMake::Settings["RELEASE-CFLAG"] = "-O2" 22 | DaoMake::Settings["RELEASE-LFLAG"] = "" 23 | DaoMake::Settings["DEBUG-CFLAG"] = "-ggdb -O0 -DDEBUG" 24 | DaoMake::Settings["DEBUG-LFLAG"] = "-ggdb" 25 | DaoMake::Settings["PROFILE-CFLAG"] = "-pg" 26 | DaoMake::Settings["PROFILE-LFLAG"] = "-pg" 27 | 28 | DaoMake::Includes.append( "/usr/local/include;/usr/include;" ) 29 | 30 | 31 | var x11_packages: list> = 32 | { 33 | ("X11" , "X.h", "-lX11" ), 34 | ("Xrandr" , "extensions/Xrandr.h", "-lXrandr" ), 35 | ("Xinerama" , "extensions/Xinerama.h", "-lXinerama"), 36 | ("XInput" , "extensions/XInput.h", "-lXi" ), 37 | ("Xf86VidMode", "extensions/xf86vm.h", "-lXxf86vm" ), 38 | ("XKB" , "extensions/XKB.h", "" ), 39 | ("Xcursor" , "Xcursor/Xcursor.h", "-lXcursor" ), 40 | } 41 | 42 | # DaoMake::Packages is for system packages that have standard header files 43 | # and header locations, and can be used with standard compiling and linking flags. 44 | # Packages intended for static linking (not the case for most system packages) 45 | # should not be included here. 46 | 47 | x11_packages.iterate { [tup] 48 | path = "/usr/include/X11" 49 | DaoMake::Packages[ tup.name ] = ( path, tup.header, "", tup.lib ) 50 | } 51 | -------------------------------------------------------------------------------- /tools/daomake/platforms/win32.dao: -------------------------------------------------------------------------------- 1 | 2 | io.writeln( "DaoMake: using Win32 settings!" ) 3 | 4 | DaoMake::Platforms["WIN32"] = 1 5 | 6 | DaoMake::Settings["AR"] = "ar rcs" 7 | 8 | DaoMake::Settings["EXE-SUFFIX"] = ".exe" 9 | DaoMake::Settings["DLL-SUFFIX"] = ".dll" 10 | DaoMake::Settings["LIB-SUFFIX"] = ".a" 11 | DaoMake::Settings["DLL-PREFIX"] = "" 12 | DaoMake::Settings["LIB-PREFIX"] = "" 13 | DaoMake::Settings["EXE-FLAG"] = "" 14 | DaoMake::Settings["DLL-FLAG"] = "-shared" 15 | DaoMake::Settings["DLL-NAME"] = "-Wl,--out-implib,lib" 16 | DaoMake::Settings["DYNAMIC-EXPORT"] = "" 17 | DaoMake::Settings["DYNAMIC-IMPORT"] = "" 18 | DaoMake::Settings["DLL-RPATH"] = "-Wl,-rpath=" 19 | DaoMake::Settings["DLL-RPATH-REL"] = "-Wl,-rpath=" 20 | 21 | DaoMake::Settings["RELEASE-CFLAG"] = "-O2" 22 | DaoMake::Settings["RELEASE-LFLAG"] = "" 23 | DaoMake::Settings["DEBUG-CFLAG"] = "-ggdb -O0 -DDEBUG" 24 | DaoMake::Settings["DEBUG-LFLAG"] = "-ggdb" 25 | DaoMake::Settings["PROFILE-CFLAG"] = "-pg" 26 | DaoMake::Settings["PROFILE-LFLAG"] = "-pg" 27 | -------------------------------------------------------------------------------- /tools/daotest/makefile.dao: -------------------------------------------------------------------------------- 1 | 2 | project = DaoMake::Project( "DaoTest" ) 3 | 4 | daovm = DaoMake::FindPackage( "Dao", $REQUIRED ) 5 | 6 | if( daovm == none ) return 7 | 8 | libdao_dll = daovm.FindTarget( "dao", $shared ); 9 | 10 | project_objs = project.AddObjects( { "source/daoTest.c" } ) 11 | project_exe = project.AddExecutable( "daotest", project_objs ) 12 | project_exe.AddDependency( libdao_dll ) 13 | 14 | project.UseSharedLibrary( daovm ) 15 | project_exe.SetTargetPath( "../../bin" ) 16 | 17 | project.Install( DaoMake::Variables[ "INSTALL_BIN" ], project_exe ); 18 | 19 | -------------------------------------------------------------------------------- /tools/doctools/sdml.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | padding: 0; 3 | max-width: 900px; 4 | height: 100%; 5 | border: none; 6 | background-color: #F4F8FD; 7 | font-family:Verdana, Arial, Helvetica, sans-serif; 8 | } 9 | div.body{ 10 | border: 1px solid #E0E4EC; 11 | background-color: #F4F8FD; 12 | } 13 | h1{ 14 | text-align: center; 15 | } 16 | h3{ 17 | text-align: left; 18 | } 19 | div.leftcolum { 20 | float: left; 21 | } 22 | div.rightcolum { 23 | float: right; 24 | } 25 | span.vline { 26 | border-left: thin solid #CDBFDC; 27 | border-right: thin solid #CDBFDC; 28 | } 29 | span.hlred { 30 | font-weight : bold; 31 | color : #FF0000; 32 | } 33 | table { 34 | width: 100%; 35 | } 36 | table.textwrap { 37 | width: 1px; 38 | margin: 5px; 39 | } 40 | table.topsection{ 41 | border: 1px solid #CDB; 42 | background-color: #DEC; 43 | } 44 | td.textleft { text-align: left; } 45 | td.textright { text-align: right; } 46 | 47 | SPAN.PermiPrefix { color: #008080 } 48 | SPAN.DataPrefix { color: #22EEAA } 49 | SPAN.CodeStruct { color: #CC00FF; font-weight: bold; } 50 | SPAN.DataType { color: #10CC20 } 51 | SPAN.StmtKey { color: #FF9900; font-weight: bold; } 52 | SPAN.Comment { color: #0066FF; font-style: italic; } 53 | SPAN.String { color: #FF0066 } 54 | SPAN.Number { color: #FF0044 } 55 | SPAN.Method { color: #448800 } 56 | SPAN.SpecSymbol { color: #999900 } 57 | .text_italic { font-style: italic; } 58 | .text_bold { font-weight: bold; } 59 | .text_delete { text-decoration: centerline; } 60 | .text_underline { text-decoration: underline; } 61 | .flushright{ text-align: right; } 62 | .bold{ font-weight: bold; } 63 | .vspace{ padding: 0.3em 0.3em; } 64 | span.codeback{ 65 | background-color: #cda; 66 | } 67 | 68 | TABLE.boardHeader { 69 | padding: 8px 2px; 70 | background-color: #D5EFDC; 71 | width: 100%; 72 | } 73 | 74 | div.hlcode { 75 | background-color: #E8F8F8; 76 | margin: 5px; 77 | padding : 5px; 78 | width: 90%; 79 | margin-left : 5%; 80 | margin-right : 5%; 81 | border: 2px dashed #bdc; 82 | } 83 | TABLE.outputTable { 84 | background-color: #D8FEFE; 85 | width: 90%; 86 | margin-left : 5%; 87 | margin-right : 5%; 88 | } 89 | .sdmltable { 90 | background-color: #F8E8FB; 91 | width: 90%; 92 | margin-left : 5%; 93 | margin-right : 5%; 94 | border: 1px solid #CCCCCC; 95 | } 96 | .docTableRow { 97 | padding: 10px 10px; 98 | background-color: #F4EEFB; 99 | } 100 | .docTableCell { 101 | background-color: #F8EEFB; 102 | padding-right : 10px; 103 | padding-top : 2px; 104 | padding-left : 10px; 105 | padding-bottom : 2px; 106 | border: 1px solid #CCCCCC; 107 | } 108 | -------------------------------------------------------------------------------- /tools/doctools/sdml2pdf.dao: -------------------------------------------------------------------------------- 1 | load os 2 | 3 | routine main( input : string, cjk='' ) 4 | { 5 | output = input; 6 | if( output.find( "_utf8" ) >=0 ){ 7 | output.replace( "_utf8", "" ); 8 | io.writeln( output ); 9 | os.run( "iconv -f utf8 -t gb2312 -o " + output + " " + input ); 10 | } 11 | std.load( "sdml2tex.dao " + output + " " + cjk ); 12 | output.replace( ".sdml", ".tex" ); 13 | os.run( "pdflatex " + output ); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /tools/filetools/archive.dao: -------------------------------------------------------------------------------- 1 | load stream 2 | 3 | routine DaoDecodeUInt16( data : string, i = 0 ) 4 | { 5 | return (data[i]<<8) + data[i+1]; 6 | } 7 | routine DaoDecodeUInt32( data : string, i = 0 ) 8 | { 9 | return (data[i]<<24) + (data[i+1]<<16) + (data[i+2]<<8) + data[i+3]; 10 | } 11 | routine CharToNumber( source : string ) 12 | { 13 | var numbers = "\t"; 14 | var count = 0; 15 | for(var char in source ){ 16 | if( %numbers - count > 58 ){ 17 | numbers += "\n\t"; 18 | count = %numbers; 19 | } 20 | numbers += (string)char + ","; 21 | if( %numbers - count > 60 ){ 22 | numbers += "\n\t"; 23 | count = %numbers; 24 | } 25 | } 26 | numbers += "0"; 27 | return numbers; 28 | } 29 | 30 | routine ArchiveToCSource( archive : string ) 31 | { 32 | var onloads = ''; 33 | var sources = ''; 34 | var modules = ''; 35 | var finders = ''; 36 | 37 | var size = archive.size(); 38 | if( size < 8 ) return '', ''; 39 | 40 | var pos = 4 41 | var files = DaoDecodeUInt32( archive, pos ); 42 | pos += 4; 43 | 44 | for(var i=0; i= size ) break; 46 | var m = DaoDecodeUInt16( archive, pos ); 47 | if( (pos + 2 + m + 4) >= size ) break; 48 | var n = DaoDecodeUInt32( archive, pos + 2 + m ); 49 | 50 | var name = archive[pos+2 : pos+2+m]; 51 | var source = archive[pos+2+m+4 : pos+2+m+4+n]; 52 | if( name.match( '%.(dll|so|dylib)$' ) != none ){ 53 | onloads += 'extern int ' + source + '( DaoVmSpace *vms, DaoNamespace *ns );\n'; 54 | modules += ' { "' + name + '", 0, NULL, ' + source + ' },\n'; 55 | 56 | var stlib = name.change( '%.(dll|so|dylib)$', '.a' ) 57 | var name = name.change( 'lib [^/\\]* %.(dll|so|dylib)$', '' ) 58 | var source = source.change( '_OnLoad$', '' ); 59 | finders += source + '\t' + name + 'Find' + source + '.dao\t' + stlib + '\n'; 60 | }else{ 61 | var variable = 'source' + (string)i; 62 | sources += 'unsigned char ' + variable + '[] =\n{\n'; 63 | sources += CharToNumber( source ) + '\n};\n'; 64 | modules += ' { "' + name + '", '; 65 | modules += (string)source.size() + ', ' + variable + ', NULL },\n'; 66 | } 67 | pos += 2 + m + 4 + n; 68 | } 69 | modules = 'DaoVirtualModule dao_virtual_modules[] =\n{\n' + modules; 70 | modules += ' { NULL, 0, NULL, NULL }\n};\n'; 71 | return onloads + sources + modules, finders; 72 | } 73 | 74 | routine main( file : string ) 75 | { 76 | var archive = io.read( file ) 77 | if( archive[0:2] != '\33\33' ){ 78 | io.writeln( 'ERROR: input is not a Dao archive file!' ); 79 | return 1; 80 | } 81 | #archive = archive.collect{ (X+256)%256 } 82 | var (source, finders) = ArchiveToCSource( archive ) 83 | var fout = io.open( file + '.c', 'w+' ); 84 | var fout2 = io.open( file + '.finders', 'w+' ); 85 | fout.writeln( '#include "dao.h"' ) 86 | fout.writeln( source ) 87 | fout2.writeln( finders ) 88 | fout.close() 89 | fout2.close() 90 | return 0; 91 | } 92 | --------------------------------------------------------------------------------