void AppFalcon::applyConstants ( Compiler &compiler ) { ListElement *dliter = m_options.defines.begin(); while ( dliter != 0 ) { String &directive = * ( ( String * ) dliter->data() ); // find "=" uint32 pos = directive.find ( "=" ); if ( pos == String::npos ) { throw String( "constant not in <directive>=<value> syntax: \"" + directive + "\"" ); } //split the directive String dirname ( directive, 0, pos ); String dirvalue ( directive, pos + 1 ); dirname.trim(); dirvalue.trim(); // is the value a number? int64 number; if ( dirvalue.parseInt ( number ) ) compiler.addIntConstant( dirname, number ); else { compiler.addStringConstant( dirname, dirvalue ); } dliter = dliter->next(); } }
void List::clear() { ListElement *elem = m_head; if( m_deletor != 0 ) { while( elem != 0 ) { ListElement *toBeDeleted = elem; elem = elem->next(); m_deletor( (void *) toBeDeleted->data() ); memFree( toBeDeleted ); } } else { while( elem != 0 ) { ListElement *toBeDeleted = elem; elem = elem->next(); memFree( toBeDeleted ); } } m_head = m_tail = 0; m_size = 0; }
void AppFalcon::applyDirectives ( Compiler &compiler ) { ListElement *dliter = m_options.directives.begin(); while ( dliter != 0 ) { String &directive = * ( ( String * ) dliter->data() ); // find "=" uint32 pos = directive.find ( "=" ); if ( pos == String::npos ) { throw String( "directive not in <directive>=<value> syntax: \"" + directive + "\"" ); } //split the directive String dirname ( directive, 0, pos ); String dirvalue ( directive, pos + 1 ); dirname.trim(); dirvalue.trim(); // is the value a number? int64 number; bool result; if ( dirvalue.parseInt ( number ) ) result = compiler.setDirective ( dirname, number ); else result = compiler.setDirective ( dirname, dirvalue ); if ( ! result ) { throw String( "invalid directive or value: \"" + directive + "\"" ); } dliter = dliter->next(); } }
void GenTree::gen_array( const ArrayDecl *ad ) { ListElement *iter = ad->begin(); while( iter != 0 ) { const Value *val = (const Value *) iter->data(); gen_value( val ); iter = iter->next(); if( iter != 0 ) m_out->writeString( ", " ); } }
void VMSemaphore::unsubscribe( VMContext *ctx ) { ListElement *elem = m_waiting.begin(); while( elem != 0 ) { VMContext *cty = (VMContext *) elem->data(); if ( ctx == cty ) { m_waiting.erase( elem ); return; } elem = elem->next(); } }
// // Create a PasswordAclSubject // PasswordAclSubject *PasswordAclSubject::Maker::make(const TypedList &list) const { Allocator &alloc = Allocator::standard(Allocator::sensitive); switch (list.length()) { case 1: return new PasswordAclSubject(alloc, true); case 2: { ListElement *password; crack(list, 1, &password, CSSM_LIST_ELEMENT_DATUM); return new PasswordAclSubject(alloc, password->data()); } default: CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE); } }
void List::insertBefore( ListElement *position, const void *data ) { ListElement *element = (ListElement *) memAlloc( sizeof( ListElement ) ); element->data( data ); element->next( position ); element->prev( position->prev() ); if( position->prev() != 0 ) { position->prev()->next( element ); } position->prev( element ); m_size++; if ( position == m_head ) m_head = element; }
void List::pushBack( const void *data ) { ListElement *element = (ListElement *) memAlloc( sizeof( ListElement ) ); element->data( data ); if ( m_head == 0 ) { m_head = m_tail = element; element->prev(0); } else { element->prev( m_tail ); m_tail->next( element ); m_tail = element; } m_size++; element->next( 0 ); }
void List::popBack() { if ( m_tail == 0 ) return; ListElement *element = m_tail; m_tail = m_tail->prev(); if( m_tail == 0 ) m_head = 0; else m_tail->next(0); if( m_deletor != 0 ) { m_deletor( (void *) element->data() ); } m_size--; memFree( element ); }
void List::popFront() { if ( m_head == 0 ) return; ListElement *element = m_head; m_head = m_head->next(); if( m_head != 0 ) m_head->prev( 0 ); else m_tail = 0; if( m_deletor != 0 ) { m_deletor( (void *) element->data() ); } m_size--; memFree( element ); }
void GenTree::gen_dict( const DictDecl *ad ) { if( ad->empty() ) { m_out->writeString( " =>" ); return; } ListElement *iter = ad->begin(); while( iter != 0 ) { DictDecl::pair *pair = (DictDecl::pair *) iter->data(); const Value *key = pair->first; const Value *value = pair->second; gen_value( key ); m_out->writeString( "=>" ); gen_value( value ); iter = iter->next(); if( iter != 0 ) m_out->writeString( ", " ); } }
void AppFalcon::runModule() { ModuleLoader ml; prepareLoader( ml ); // Create the runtime using the given module loader. Runtime runtime( &ml ); // now that we have the main module, inject other requested modules ListElement *pliter = m_options.preloaded.begin(); while ( pliter != 0 ) { Module *module = ml.loadName ( * ( ( String * ) pliter->data() ) ); runtime.addModule( module ); // abandon our reference to the injected module module->decref(); pliter = pliter->next(); } // then add the main module Module* mainMod = loadInput(ml); runtime.addModule( mainMod ); // abandon our reference to the main module mainMod->decref(); //=========================================== // Prepare the virtual machine // VMachineWrapper vmachine; //redirect the VM streams to ours. // The machine takes ownership of the streams, so they won't be useable anymore // after the machine destruction. readyStreams(); vmachine->stdIn( m_stdIn ); vmachine->stdOut( m_stdOut ); vmachine->stdErr( m_stdErr ); // I have given real process streams to the vm vmachine->hasProcessStreams( true ); // push the core module // we know we're not launching the core module. vmachine->launchAtLink( false ); Module* core = core_module_init(); #ifdef NDEBUG vmachine->link ( core ); #else LiveModule *res = vmachine->link ( core ); fassert ( res != 0 ); // should not fail #endif core->decref(); // prepare environment Item *item_args = vmachine->findGlobalItem ( "args" ); fassert ( item_args != 0 ); CoreArray *args = new CoreArray ( m_argc - m_script_pos ); String ioEncoding = getIoEncoding(); for ( int ap = m_script_pos; ap < m_argc; ap ++ ) { CoreString *cs = new CoreString; if ( ! TranscodeFromString ( m_argv[ap], ioEncoding, *cs ) ) { cs->bufferize ( m_argv[ap] ); } args->append ( cs ); } item_args->setArray ( args ); Item *script_name = vmachine->findGlobalItem ( "scriptName" ); fassert ( script_name != 0 ); *script_name = new CoreString ( mainMod->name() ); Item *script_path = vmachine->findGlobalItem ( "scriptPath" ); fassert ( script_path != 0 ); *script_path = new CoreString ( mainMod->path() ); // Link the runtime in the VM. // We'll be running the modules as we link them in. vmachine->launchAtLink( true ); if ( vmachine->link( &runtime ) ) { vmachine->launch(); if ( vmachine->regA().isInteger() ) exitval( ( int32 ) vmachine->regA().asInteger() ); } }
int main( int argc, char *argv[] ) { // Install a void ctrl-c handler (let ctrl-c to kill this app) Sys::_dummy_ctrl_c_handler(); Falcon::Engine::AutoInit autoInit; int script_pos = argc; char *input_file = 0; FileStream *bincode_stream; stdOut = stdOutputStream(); stdErr = stdErrorStream(); stdIn = stdInputStream(); // option decoding for ( int i = 1; i < argc; i++ ) { char *op = argv[i]; if (op[0] == '-' ) { switch ( op[1] ) { case 'e': if ( op[2] == 0 && i < argc + 1) { io_encoding = argv[++i]; } else { io_encoding = op + 2; } break; case 'h': usage(); return 0; case 'L': if ( op[2] == 0 && i < argc + 1) load_path = argv[++i]; else load_path = op + 2; break; break; case 'P': ignore_defpath = true; break; case 'l': if ( op[2] == 0 && i + 1 < argc ) module_language = argv[++i]; else module_language = op + 2; break; case 'p': if ( op[2] == 0 && i < argc + 1) preloaded.pushBack( argv[++i] ); else preloaded.pushBack( op + 2 ); break; case 'v': version(); return 0; default: stdOut->writeString( "falrun: unrecognized option '" ); stdOut->writeString( op ); stdOut->writeString( "'.\n\n" ); usage(); return 1; } } else { input_file = op; script_pos = i+1; break; } } // eventually change the encodings. io_encoding = get_io_encoding(); if ( io_encoding != "" ) { Transcoder *trans = TranscoderFactory( io_encoding, 0, true ); if ( trans == 0 ) { stdOut->writeString( "Fatal: unrecognized encoding '" + io_encoding + "'.\n\n" ); return 1; } delete stdIn ; delete stdOut; delete stdErr; trans->setUnderlying( new StdInStream ); stdIn = AddSystemEOL( trans, true ); stdOut = AddSystemEOL( TranscoderFactory( io_encoding, new StdOutStream, true ), true ); stdErr = AddSystemEOL( TranscoderFactory( io_encoding, new StdErrStream, true ), true ); } if ( input_file == 0 ) { stdOut->writeString( "falrun: missing script name.\n" ); usage(); return 1; } bincode_stream = new FileStream; bincode_stream->open( input_file ); if ( ! bincode_stream->good() ) { stdOut->writeString( "falrun: Can't open file " ); stdOut->writeString( input_file ); stdOut->writeString( "\n" ); stdOut->flush(); return 1; } String module_name; String source_path; findModuleName( input_file, module_name ); findModulepath( input_file, source_path ); //----------------------------------------- // execute the script. // if ( source_path != "" ) source_path += ";"; try { ModuleLoader *modloader = new ModuleLoader( source_path + get_load_path() ); Engine::setSearchPath( modloader->getSearchPath() ); // set the module preferred language; ok also if default ("") is used modloader->setLanguage( module_language ); Module *core = core_module_init(); Module *main_mod = modloader->loadModule( bincode_stream ); VMachine *vmachine = new VMachine(false); // change default machine streams. vmachine->stdIn( stdIn ); vmachine->stdOut( stdOut ); vmachine->stdErr( stdErr ); vmachine->init(); vmachine->link( core ); core->decref(); Runtime *runtime = new Runtime( modloader ); // preload required modules ListElement *pliter = preloaded.begin(); while( pliter != 0 ) { Module *module = modloader->loadName( * ((String *) pliter->data()) ); runtime->addModule( module ); pliter = pliter->next(); } Item *item_args = vmachine->findGlobalItem( "args" ); fassert( item_args != 0 ); CoreArray *args = new CoreArray( argc - script_pos ); for ( int ap = script_pos; ap < argc; ap ++ ) { args->append( new CoreString( argv[ap] ) ); } item_args->setArray( args ); Item *script_name = vmachine->findGlobalItem( "scriptName" ); fassert( script_name != 0 ); script_name->setString( new CoreString( module_name ) ); // the runtime will try to load the references. runtime->addModule( main_mod ); if( vmachine->link( runtime ) ) { vmachine->launch(); if ( vmachine->regA().type() == FLC_ITEM_INT ) return (int32) vmachine->regA().asInteger(); return 0; } vmachine->finalize(); } catch ( Error *err ) { String temp; err->toString( temp ); stdErr->writeString( "falcon: FATAL - Program terminated with error.\n" ); stdErr->writeString( temp + "\n" ); err->decref(); return 1; } return 255; }
void GenTree::generate( const Statement *cmp, const char *specifier, bool sameline, int depth ) { if ( ! sameline ) { String line; line.writeNumber( (int64) cmp->line() ); int pos = 0; while (pos + line.length() < 5 ) { pos ++; m_out->writeString( " " ); } m_out->writeString( line + " : " ); for (int i = 0; i < depth; i++ ) m_out->writeString( " " ); } if ( specifier != 0 ) { m_out->writeString( specifier ); m_out->writeString( " " ); } switch( cmp->type() ) { case Statement::t_none: m_out->writeString( "(placeholder none statement)\n" ); break; case Statement::t_break: m_out->writeString( "BREAK\n" ); break; case Statement::t_continue: m_out->writeString( "CONTINUE" ); if( static_cast< const StmtContinue *>( cmp )->dropping() ) m_out->writeString( " DROPPING" ); m_out->writeString( "\n" ); break; case Statement::t_launch: m_out->writeString( "LAUNCH " ); gen_value( static_cast< const StmtExpression *>( cmp )->value() ); m_out->writeString( "\n" ); break; case Statement::t_autoexp: m_out->writeString( "AUTOEXPR " ); gen_value( static_cast< const StmtExpression *>( cmp )->value() ); m_out->writeString( "\n" ); break; case Statement::t_return: m_out->writeString( "RETURN " ); gen_value( static_cast< const StmtExpression *>( cmp )->value() ); m_out->writeString( "\n" ); break; case Statement::t_fordot: m_out->writeString( "FORDOT " ); gen_value( static_cast< const StmtExpression *>( cmp )->value() ); m_out->writeString( "\n" ); break; case Statement::t_raise: m_out->writeString( "RAISE " ); gen_value( static_cast< const StmtExpression *>( cmp )->value() ); m_out->writeString( "\n" ); break; case Statement::t_give: { const StmtGive *give = static_cast< const StmtGive *>( cmp ); m_out->writeString( "GIVE " ); gen_array( give->attributes() ); m_out->writeString( " to " ); gen_array( give->objects() ); m_out->writeString( "\n" ); } break; case Statement::t_self_print: { const StmtSelfPrint *sp = static_cast< const StmtSelfPrint *>( cmp ); m_out->writeString( "FAST PRINT " ); gen_array( sp->toPrint() ); m_out->writeString( "\n" ); } break; case Statement::t_if: { m_out->writeString( "IF " ); const StmtIf *sif = static_cast< const StmtIf *>( cmp ); gen_value( sif->condition() ); m_out->writeString( "\n" ); gen_block( sif->children(), depth ); const Statement *stmt = sif->elifChildren().front(); while( stmt != 0 ) { generate( stmt, 0, false, depth + 1 ); stmt = static_cast<const Statement *>(stmt->next()); } gen_block( sif->elseChildren(), depth, "ELSE" ); } break; case Statement::t_select: case Statement::t_switch: { if ( cmp->type() == Statement::t_switch ) m_out->writeString( "SWITCH " ); else m_out->writeString( "SELECT " ); const StmtSwitch *sw = static_cast< const StmtSwitch *>( cmp ); gen_value( sw->switchItem() ); m_out->writeString( "\n" ); // generates the switch lists MapIterator iter; // generatest the switch integer list if ( !sw->intCases().empty() ) { m_out->writeString( "INT cases " ); iter = sw->intCases().begin(); while( iter.hasCurrent() ) { Value *first = *(Value **) iter.currentKey(); uint32 second = *(uint32 *) iter.currentValue(); String temp; temp.writeNumber( (int64) second ); gen_value( first ); m_out->writeString( "->" + temp + "; " ); iter.next(); } m_out->writeString( "\n" ); } if ( !sw->rngCases().empty() ) { m_out->writeString( "RANGE cases " ); iter = sw->rngCases().begin(); while( iter.hasCurrent() ) { Value *first = *(Value **) iter.currentKey(); uint32 second = *(uint32 *) iter.currentValue(); String temp; temp.writeNumber( (int64) second ); gen_value( first ); m_out->writeString( "->" + temp + "; " ); iter.next(); } m_out->writeString( "\n" ); } if ( !sw->strCases().empty() ) { m_out->writeString( "STRING cases " ); iter = sw->strCases().begin(); while( iter.hasCurrent() ) { Value *first = *(Value **) iter.currentKey(); uint32 second = *(uint32 *) iter.currentValue(); String temp; temp.writeNumber( (int64) second ); gen_value( first ); m_out->writeString( "->" + temp + "; " ); iter.next(); } m_out->writeString( "\n" ); } if ( !sw->objCases().empty() ) { m_out->writeString( "Symbol cases " ); iter = sw->objCases().begin(); while( iter.hasCurrent() ) { Value *first = *(Value **) iter.currentKey(); uint32 second = *(uint32 *) iter.currentValue(); String temp; temp.writeNumber( (int64) second ); gen_value( first ); m_out->writeString( "->" + temp + "; " ); iter.next(); } m_out->writeString( "\n" ); } // generates the blocks int blockId = 0; const Statement *stmt = sw->blocks().front(); while( stmt != 0 ) { String blockStr; blockStr.writeNumber( (int64) blockId ); if( blockId == sw->nilBlock() ) m_out->writeString( "CASE BLOCK (NIL)" + blockStr + "\n" ); else m_out->writeString( "CASE BLOCK " + blockStr + "\n" ); generate( stmt, 0, false, depth + 1 ); stmt = static_cast<const Statement *>(stmt->next()); blockId ++ ; } if ( ! sw->defaultBlock().empty() ) { m_out->writeString( "DEFAULT BLOCK\n" ); gen_block( sw->defaultBlock(), depth + 1 ); } } break; case Statement::t_case: { //m_out->writeString( "CASE \n" ); const StmtCaseBlock *scase = static_cast< const StmtCaseBlock *>( cmp ); gen_block( scase->children(), depth ); } break; case Statement::t_catch: { //m_out->writeString( "CASE \n" ); const StmtCatchBlock *scase = static_cast< const StmtCatchBlock *>( cmp ); if ( scase->intoValue() != 0 ) { m_out->writeString( "CATCH into " ); gen_value( scase->intoValue() ); m_out->writeString( "\n" ); } else m_out->writeString( "CATCH witout into\n" ); gen_block( scase->children(), depth ); } break; case Statement::t_elif: { m_out->writeString( "ELIF " ); const StmtElif *selif = static_cast< const StmtElif *>( cmp ); gen_value( selif->condition() ); m_out->writeString( "\n" ); gen_block( selif->children(), depth ); } break; case Statement::t_while: { const StmtWhile *wh = static_cast< const StmtWhile *>( cmp ); m_out->writeString( "WHILE " ); gen_value( wh->condition() ); m_out->writeString( "\n" ); gen_block( wh->children(), depth ); } break; case Statement::t_loop: { const StmtLoop *wh = static_cast< const StmtLoop *>( cmp ); m_out->writeString( "LOOP " ); m_out->writeString( "\n" ); gen_block( wh->children(), depth ); if( wh->condition() != 0 ) { m_out->writeString( "END LOOP WHEN " ); gen_value( wh->condition() ); m_out->writeString( "\n" ); } else m_out->writeString( "END\n" ); } break; case Statement::t_global: { m_out->writeString( "GLOBAL " ); const StmtGlobal *sglobal = static_cast< const StmtGlobal *>( cmp ); ListElement *iter = sglobal->getSymbols().begin(); while ( iter != 0 ) { Symbol *sym = (Symbol *) iter->data(); m_out->writeString( sym->name() + ", " ); iter = iter->next(); } m_out->writeString( "\n" ); } break; case Statement::t_forin: { m_out->writeString( "FOR-IN " ); const StmtForin *sfor = static_cast< const StmtForin *>( cmp ); gen_array( sfor->dest() ); m_out->writeString( " IN " ); gen_value( sfor->source() ); m_out->writeString( "\n" ); gen_block( sfor->children(), depth ); gen_block( sfor->firstBlock(), depth, "FORFIRST" ); gen_block( sfor->middleBlock(), depth, "FORMIDDLE" ); gen_block( sfor->lastBlock(), depth, "FORLAST" ); } break; case Statement::t_try: { m_out->writeString( "TRY\n" ); const StmtTry *stry = static_cast< const StmtTry *>( cmp ); gen_block( stry->children(), depth ); // generatest the switch integer list if ( ! stry->intCases().empty() ) { m_out->writeString( "TYPE ID CATCHES " ); MapIterator iter = stry->intCases().begin(); while( iter.hasCurrent() ) { Value *first = *(Value **) iter.currentKey(); uint32 second = *(uint32 *) iter.currentValue(); String temp; temp.writeNumber( (int64) second ); gen_value( first ); m_out->writeString( "->" + temp + "; " ); iter.next(); } m_out->writeString( "\n" ); } // Generates the switch symbol list if ( ! stry->objCases().empty() ) { m_out->writeString( "SYMBOL CATCHES " ); MapIterator iter = stry->objCases().begin(); while( iter.hasCurrent() ) { Value *first = *(Value **) iter.currentKey(); uint32 second = *(uint32 *) iter.currentValue(); String temp; temp.writeNumber( (int64) second ); gen_value( first ); m_out->writeString( "->" + temp + "; " ); iter.next(); } m_out->writeString( "\n" ); } // generates the blocks int blockId = 0; const Statement *stmt = stry->handlers().front(); while( stmt != 0 ) { String blockStr; blockStr.writeNumber( (int64) blockId ); m_out->writeString( "HANDLER BLOCK " + blockStr + "\n" ); generate( stmt, 0, false, depth + 1 ); stmt = static_cast<const Statement *>( stmt->next() ); blockId ++ ; } if ( stry->defaultHandler() != 0 ) { m_out->writeString( "DEFAULT HANDLER" ); if ( stry->defaultHandler()->intoValue() != 0 ) { m_out->writeString( " into " ); gen_value( stry->defaultHandler()->intoValue() ); } m_out->writeString( "\n" ); gen_block( stry->defaultHandler()->children(), depth + 1 ); } } break; case Statement::t_propdef: { m_out->writeString( "PROPDEF " ); const StmtVarDef *spd = static_cast< const StmtVarDef *>( cmp ); m_out->writeString( *spd->name() ); m_out->writeString( "=" ); gen_value( spd->value() ); m_out->writeString( "\n" ); } break; default: m_out->writeString( "????\n" ); } }