/* // Special relative paths: // 1. ::path, path relative to the current source code file; // 2. :path, path relative to the current working directory; */ static void DaoIO_MakePath( DaoProcess *proc, DString *path ) { if( path->size ==0 ) return; if( path->chars[0] != ':' ) return; if( path->chars[1] == ':' ){ DString_Erase( path, 0, 2 ); DString_MakePath( proc->activeNamespace->path, path ); return; } DString_Erase( path, 0, 1 ); DString_MakePath( proc->vmSpace->pathWorking, path ); }
int DaoStream_ReadLine( DaoStream *self, DString *line ) { int ch, delim = '\n'; char buf[IO_BUF_SIZE]; char *start = buf, *end = buf + IO_BUF_SIZE; DString_Clear( line ); DString_ToMBS( line ); if( self->redirect && self->redirect->StdioRead ){ self->redirect->StdioRead( self->redirect, line, 0 ); return line->size >0; }else if( self->file ){ return DaoFile_ReadLine( self->file, line ); }else if( self->attribs & DAO_IO_STRING ){ daoint pos = DString_FindWChar( self->streamString, delim, 0 ); if( pos == MAXSIZE ){ DString_Assign( line, self->streamString ); DString_Clear( self->streamString ); }else{ DString_SubString( self->streamString, line, 0, pos+1 ); DString_Erase( self->streamString, 0, pos+1 ); } return self->streamString->size >0; }else{ *start = ch = getchar(); start += 1; while( ch != delim && ch != EOF ){ *start = ch = getchar(); start += 1; if( start == end ){ if( ch == EOF ) start -= 1; DString_AppendDataMBS( line, buf, start-buf ); start = buf; } } if( ch == EOF && start != buf ) start -= 1; DString_AppendDataMBS( line, buf, start-buf ); clearerr( stdin ); return ch != EOF; } return 0; }
DaoClass* DaoClass_Instantiate( DaoClass *self, DArray *types ) { DaoClass *klass = NULL; DaoType *type; DString *name; DNode *node; DMap *deftypes; daoint lt = DString_FindChar( self->className, '<', 0 ); daoint i, holders = 0; if( self->typeHolders == NULL || self->typeHolders->size ==0 ) return self; while( types->size < self->typeHolders->size ){ type = self->typeDefaults->items.pType[ types->size ]; if( type == NULL ) type = self->typeHolders->items.pType[ types->size ]; DArray_Append( types, type ); } name = DString_New(1); DString_Append( name, self->className ); if( lt != MAXSIZE ) DString_Erase( name, lt, MAXSIZE ); DString_AppendChar( name, '<' ); for(i=0; i<types->size; i++){ type = types->items.pType[i]; holders += type->tid == DAO_THT; if( i ) DString_AppendChar( name, ',' ); DString_Append( name, type->name ); } DString_AppendChar( name, '>' ); while( self->templateClass ) self = self->templateClass; node = DMap_Find( self->instanceClasses, name ); if( node ){ klass = node->value.pClass; }else{ deftypes = DMap_New(0,0); klass = DaoClass_New(); if( holders ) klass->templateClass = self; DMap_Insert( self->instanceClasses, name, klass ); DaoClass_AddReference( self, klass ); /* No need for cleanup of klass; */ DaoClass_SetName( klass, name, self->classRoutine->nameSpace ); for(i=0; i<types->size; i++){ type = types->items.pType[i]; if( DaoType_MatchTo( type, self->typeHolders->items.pType[i], deftypes ) ==0 ){ DString_Delete( name ); return NULL; } MAP_Insert( deftypes, self->typeHolders->items.pVoid[i], type ); } klass->objType->nested = DArray_New(D_VALUE); DArray_Assign( klass->objType->nested, types ); if( DaoClass_CopyField( klass, self, deftypes ) == 0 ){ DString_Delete( name ); return NULL; } DaoClass_DeriveClassData( klass ); DaoClass_DeriveObjectData( klass ); DaoClass_ResetAttributes( klass ); DMap_Delete( deftypes ); if( holders ){ klass->typeHolders = DArray_New(0); klass->typeDefaults = DArray_New(0); klass->instanceClasses = DMap_New(D_STRING,0); DMap_Insert( klass->instanceClasses, klass->className, klass ); for(i=0; i<types->size; i++){ DArray_Append( klass->typeHolders, types->items.pType[i] ); DArray_Append( klass->typeDefaults, NULL ); } for(i=0; i<klass->typeHolders->size; i++){ DaoClass_AddReference( klass, klass->typeHolders->items.pType[i] ); DaoClass_AddReference( klass, klass->typeDefaults->items.pType[i] ); } } } DString_Delete( name ); return klass; }
static int DaoParser_MakeMacroGroup( DaoParser *self, DMacroGroup *group, DMacroGroup *parent, int from, int to ) { DaoToken **toks = self->tokens->items.pToken; unsigned char tk; int i, sep, rb, prev; DMacroUnit *unit; DMacroGroup *grp, *group2; /* mingw don't like grp2 ?! */ /* for( i=from; i<to; i++ ) printf( "%s ", toks[i]->mbs ); printf("\n"); */ i = from; while( i < to ){ char *chs = toks[i]->string.mbs; self->curLine = toks[i]->line; tk = toks[i]->name; #if 0 //printf( "%i %s\n", i, chs ); #endif if( tk == DTOK_ESC_LB || tk == DTOK_ESC_LSB || tk == DTOK_ESC_LCB ){ grp = DMacroGroup_New(); grp->cpos = toks[i]->cpos; grp->parent = parent; DArray_Append( group->units, (void*)grp ); switch( tk ){ case DTOK_ESC_LB : rb = DaoParser_FindPairToken( self, DTOK_ESC_LB, DTOK_ESC_RB, i, to ); break; case DTOK_ESC_LSB : rb = DaoParser_FindPairToken( self, DTOK_ESC_LSB, DTOK_ESC_RSB, i, to ); grp->repeat = DMACRO_ZERO_OR_ONE; break; case DTOK_ESC_LCB : rb = DaoParser_FindPairToken( self, DTOK_ESC_LCB, DTOK_ESC_RCB, i, to ); grp->repeat = DMACRO_ZERO_OR_MORE; break; default : { rb = -1; DaoParser_Error( self, DAO_CTW_INV_MAC_OPEN, & toks[i]->string ); break; } } if( rb <0 ) return 0; prev = i+1; sep = DaoParser_FindOpenToken( self, DTOK_ESC_PIPE, i+1, rb, 0 ); if( sep >=0 ){ while( sep >=0 ){ group2 = DMacroGroup_New(); group2->parent = grp; if( DaoParser_MakeMacroGroup( self, group2, group2, prev, sep ) == 0 ) return 0; DArray_Append( grp->units, (void*)group2 ); prev = sep +1; sep = DaoParser_FindOpenToken( self, DTOK_ESC_PIPE, prev, rb, 0 ); if( prev < rb && sep <0 ) sep = rb; } grp->type = DMACRO_ALT; }else if( DaoParser_MakeMacroGroup( self, grp, grp, i+1, rb ) == 0 ){ return 0; } i = rb +1; self->curLine = toks[i]->line; if( toks[i]->string.mbs[0] == '\\' ){ switch( toks[i]->name ){ case DTOK_ESC_EXCLA : grp->repeat = DMACRO_ZERO; i++; break; case DTOK_ESC_QUES : grp->repeat = DMACRO_ZERO_OR_ONE; i++; break; case DTOK_ESC_STAR : grp->repeat = DMACRO_ZERO_OR_MORE; i++; break; case DTOK_ESC_PLUS : grp->repeat = DMACRO_ONE_OR_MORE; i++; break; case DTOK_ESC_SQUO : case DTOK_ESC_DQUO : case DTOK_ESC_LB : case DTOK_ESC_RB : case DTOK_ESC_LCB : case DTOK_ESC_RCB : case DTOK_ESC_LSB : case DTOK_ESC_RSB : break; default : DaoParser_Error( self, DAO_CTW_INV_MAC_REPEAT, & toks[i]->string ); return 0; } } continue; } self->curLine = toks[i]->line; unit = DMacroUnit_New(); DaoToken_Assign( unit->marker, toks[i] ); DArray_Append( group->units, (void*)unit ); switch( chs[0] ){ case '$' : if( DString_FindMBS( & toks[i]->string, "EXP", 0 ) == 1 ){ unit->type = DMACRO_EXP; }else if( DString_FindMBS( & toks[i]->string, "VAR", 0 ) == 1 ){ unit->type = DMACRO_VAR; }else if( DString_FindMBS( & toks[i]->string, "ID", 0 ) == 1 ){ unit->type = DMACRO_ID; }else if( DString_FindMBS( & toks[i]->string, "OP", 0 ) == 1 ){ unit->type = DMACRO_OP; }else if( DString_FindMBS( & toks[i]->string, "BL", 0 ) == 1 ){ unit->type = DMACRO_BL; }else if( DString_FindMBS( & toks[i]->string, "IBL", 0 ) == 1 ){ unit->type = DMACRO_IBL; } break; case '(' : case '[' : case '{' : switch( chs[0] ){ case '(' : rb = DaoParser_FindPairToken( self, DTOK_LB, DTOK_RB, i, to ); break; case '[' : rb = DaoParser_FindPairToken( self, DTOK_LSB, DTOK_RSB, i, to ); break; case '{' : rb = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, i, to ); break; default : rb = -1; } if( rb <0 ) return 0; grp = DMacroGroup_New(); grp->parent = group; grp->repeat = DMACRO_AUTO; DArray_Append( group->units, (void*)grp ); if( DaoParser_MakeMacroGroup( self, grp, parent, i+1, rb ) == 0 ) return 0; i = rb; continue; case '\'' : if( chs[2] == '\'' ){ unit->marker->type = 0; switch( chs[1] ){ case '(' : unit->marker->type = unit->marker->name = DTOK_LB; break; case ')' : unit->marker->type = unit->marker->name = DTOK_RB; break; case '[' : unit->marker->type = unit->marker->name = DTOK_LSB; break; case ']' : unit->marker->type = unit->marker->name = DTOK_RSB; break; case '{' : unit->marker->type = unit->marker->name = DTOK_LCB; break; case '}' : unit->marker->type = unit->marker->name = DTOK_RCB; break; case '\'' : unit->marker->type= unit->marker->name = DTOK_ESC_SQUO;break; case '\"' : unit->marker->type= unit->marker->name = DTOK_ESC_DQUO;break; default : break; } if( unit->marker->type == 0 ){ DaoParser_Error( self, DAO_CTW_INV_MAC_SPECTOK, & toks[i]->string ); return 0; } unit->type = DMACRO_BR; DString_SetMBS( & unit->marker->string, chs+1 ); DString_Erase( & unit->marker->string, unit->marker->string.size-1, 1 ); } default : break; } if( i+1 < to && toks[i+1]->string.mbs[0] == '@' ){ char ch = toks[i+1]->string.mbs[1]; if( ch != '@' ){ if( toks[i+1]->string.size != 2 || ch < '1' || ch >'9' ){ DaoParser_Error( self, DAO_CTW_INV_MAC_INDENT, & toks[i+1]->string ); return 0; } unit->indent = ch - '0'; i ++; } } i ++; } return 1; }
int main( int argc, char **argv ) { int restart = 0; int i, k, idsrc, vmods = 0; DString *opts = NULL, *args = NULL; /*mtrace(); */ for(i=1; i<argc; i++){ if( strcmp( argv[i], "-r" ) ==0 || strcmp( argv[i], "--restart" ) ==0 ){ restart = i; break; } } if( restart ) DaoRestartRun( argv, argc, restart ); vmSpace = DaoInit( argv[0] ); idsrc = -1; for(i=1; i<argc; i++){ if( strcmp( argv[i], "-e" ) ==0 || strcmp( argv[i], "--eval" ) ==0 ) break; /* also allows execution of script files without suffix .dao */ if( argv[i][0] != '-' ){ idsrc = i; break; } } #ifdef DAO_WITH_STATIC_MODULES /* // For single file deployment. // Identify the script argument, such that the arguments before the script // can be passed in as virtual machine arguments. // Example: ./script --restart script.dao ... */ args = DString_Copy( vmSpace->daoBinFile ); DString_Erase( args, 0, vmSpace->daoBinPath->size ); DString_AppendChars( args, ".dao" ); idsrc = 1; for(i=1; i<argc; i++){ if( strcmp( argv[i], args->chars ) == 0 ){ idsrc = i; break; } } vmods = DaoVmSpace_AddVirtualModules( vmSpace, dao_virtual_modules ); DString_Reset( args, 0 ); #endif k = idsrc; if( k < 0 ) k = argc; if( opts == NULL ) opts = DString_New(); if( args == NULL ) args = DString_New(); for(i=1; i<k; i++ ){ DString_AppendChars( opts, argv[i] ); DString_AppendChar( opts, '\1' ); } if( idsrc >= 0 ){ #ifdef DAO_WITH_STATIC_MODULES idsrc += 1; #endif for(i=idsrc; i<argc; i++ ){ DString_AppendChars( args, argv[i] ); DString_AppendChar( args, '\1' ); } } DaoVmSpace_ParseOptions( vmSpace, DString_GetData( opts ) ); #ifdef DAO_WITH_STATIC_MODULES if( vmods ){ DString_InsertChars( args, "/@/\1", 0, 0, 0 ); DString_InsertChars( args, dao_virtual_modules[0].name, 3, 0, 0 ); /* set the path for the virtual files: */ DaoVmSpace_SetPath( vmSpace, "/@/" ); }else #endif if( idsrc < 0 && argc == 1 ){ DString_AppendChar( opts, '\1' ); DString_AppendChars( opts, "-vi" ); DaoVmSpace_ParseOptions( vmSpace, DString_GetData( opts ) ); } #ifdef DAO_USE_READLINE DaoVmSpace_ReadLine( vmSpace, DaoReadLine ); DaoVmSpace_AddHistory( vmSpace, (AddHistory) add_history ); read_history( NULL ); #endif signal( SIGINT, DaoSignalHandler ); signal( SIGSEGV, DaoStackTrace ); /* Start execution. */ k = DaoVmSpace_RunMain( vmSpace, DString_GetData( args ) ); #ifdef DAO_USE_READLINE write_history( NULL ); #endif DString_Delete( args ); DString_Delete( opts ); DaoQuit(); return k; }