int CInterpreter::GetLoop( void ) { CBlock block; block.Create( ID_LOOP ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); if ( LookAhead( TK_CLOSED_PARENTHESIS ) ) { //-1 denotes an infinite loop block.Write( TK_FLOAT, (float) -1); } else { if ( GetInteger( &block ) == false ) return false; } if (!Match( TK_CLOSED_PARENTHESIS )) return Error("GetLoop : too many parameters"); m_blockStream->WriteBlock( &block ); return true; }
int CInterpreter::GetElse( void ) { CBlock block; block.Create( ID_ELSE ); /* if ( Match( TK_OPEN_PARENTHESIS ) == false ) return Error("syntax error : '(' not found"); */ /* if ( GetAny( &block ) == false ) return false; if ( GetEvaluator( &block ) == false ) return false; if ( GetAny( &block ) == false ) return false; */ /* if ( Match( TK_CLOSED_PARENTHESIS ) == false ) return Error("sound : too many parameters"); */ m_blockStream->WriteBlock( &block ); return true; }
int CInterpreter::GetWait( void ) { CBlock block; block.Create( ID_WAIT ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); if ( LookAhead( TK_STRING ) ) { if ( GetString( &block ) == false ) return false; } else { if ( GetFloat( &block ) == false ) return false; } if (!Match( TK_CLOSED_PARENTHESIS )) return Error("wait : too many parameters"); m_blockStream->WriteBlock( &block ); return true; }
int CInterpreter::GetMove( void ) { CBlock block; block.Create( ID_MOVE ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); if ( GetVector( &block ) == false ) return false; //Angles are optional if ( LookAhead( TK_VECTOR_START ) || LookAhead( TK_IDENTIFIER ) ) { if ( GetVector( &block ) == false ) return false; } if ( GetFloat( &block ) == false ) return false; if (!Match( TK_CLOSED_PARENTHESIS )) return Error("move : too many parameters"); m_blockStream->WriteBlock( &block ); return true; }
int CInterpreter::GetVariable( int type ) { const char *varName; variable_t *var; CToken *token; //Get the variable's name token = m_tokenizer->GetToken( 0, 0 ); varName = token->GetStringValue(); //See if we already have a variable by this name var = FindVar( varName ); //Variable names must be unique on creation if ( var ) return Error( "\"%s\" : already exists\n", varName ); //Add the variable AddVar( varName, type ); //Insert the variable into the stream CBlock block; block.Create( TYPE_VARIABLE ); block.Write( TK_FLOAT, (float) type ); block.Write( TK_STRING, varName ); m_blockStream->WriteBlock( &block ); token->Delete(); return true; }
int CInterpreter::GetDoWait( void ) { CBlock block; //Write out the "do" portion block.Create( ID_DO ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); if ( GetString( &block ) == false ) return false; if (!Match( TK_CLOSED_PARENTHESIS )) return Error("do : too many parameters"); //Write out the accompanying "wait" char *str = (char *) block.GetMemberData( 0 ); CBlock block2; block2.Create( ID_WAIT ); block2.Write( TK_STRING, (char *) str ); m_blockStream->WriteBlock( &block ); m_blockStream->WriteBlock( &block2 ); return true; }
int CInterpreter::GetAffect( void ) { CBlock block; char typeName[MAX_STRING_SIZE]; int type; block.Create( ID_AFFECT ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); if ( GetString( &block ) == false ) return false; if (!LookAhead( TK_IDENTIFIER )) return Error("syntax error : identifier not found"); if ( MatchGet() ) return Error("syntax error : illegal use of \"get\""); if ( GetType( (char *) typeName ) == false ) return false; type = FindSymbol( typeName, m_typeKeywords); switch ( type ) { case TYPE_INSERT: case TYPE_FLUSH: block.Write( TK_FLOAT, (float) type ); break; default: return Error("'%s': unknown affect type", typeName ); break; } if (!Match( TK_CLOSED_PARENTHESIS )) return Error("affect : too many parameters"); if (!LookAhead( TK_BLOCK_START )) return Error("syntax error : '{' not found"); m_blockStream->WriteBlock( &block ); return true; }
int CInterpreter::GetFlush( void ) { CBlock block; block.Create( ID_FLUSH ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); if (!Match( TK_CLOSED_PARENTHESIS )) return Error("flush : too many parameters"); m_blockStream->WriteBlock( &block ); return true; }
int CInterpreter::GetRemove( void ) { CBlock block; block.Create( ID_REMOVE ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); if ( GetString( &block ) == false ) return false; if (!Match( TK_CLOSED_PARENTHESIS )) return Error("remove : too many parameters"); m_blockStream->WriteBlock( &block ); return true; }
int CInterpreter::GetWaitSignal( void ) { CBlock block; block.Create( ID_WAITSIGNAL ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); if ( GetString( &block ) == false ) return false; if (!Match( TK_CLOSED_PARENTHESIS )) return Error("waitsignal : too many parameters"); m_blockStream->WriteBlock( &block ); return true; }
CBlock *CBlock::Duplicate( void ) { blockMember_v::iterator mi; CBlock *newblock; newblock = new CBlock; if ( newblock == NULL ) return NULL; newblock->Create( m_id ); //Duplicate entire block and return the cc for ( mi = m_members.begin(); mi != m_members.end(); mi++ ) { newblock->AddMember( (*mi)->Duplicate() ); } return newblock; }
// this is just so people can put comments in scripts in BehavEd and not have them lost as normal comments would be. // int CInterpreter::GetRem( void ) { CBlock block; block.Create( ID_REM ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); // optional string? if (Match( TK_CLOSED_PARENTHESIS )) return true; GetString( &block ); if (!Match( TK_CLOSED_PARENTHESIS )) return Error("rem : function only takes 1 optional parameter"); return true; }
int CInterpreter::GetDeclare( void ) { CBlock block; char typeName[MAX_STRING_LENGTH]; int type; block.Create( ID_DECLARE ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); if ( GetType( (char *) typeName ) == false ) return false; type = FindSymbol( typeName, m_typeKeywords); switch ( type ) { case TK_FLOAT: case TK_VECTOR: case TK_STRING: block.Write( TK_FLOAT, (float) type ); break; default: return Error("unknown identifier %s", typeName ); break; } if ( GetString( &block ) == false ) return false; if (!Match( TK_CLOSED_PARENTHESIS )) return Error("declare : too many parameters"); m_blockStream->WriteBlock( &block ); return true; }
int CInterpreter::GetSound( void ) { CBlock block; block.Create( ID_SOUND ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); if ( GetIdentifier( &block ) == false ) return false; if ( GetString( &block ) == false ) return false; if (!Match( TK_CLOSED_PARENTHESIS )) return Error("sound : too many parameters"); m_blockStream->WriteBlock( &block ); return true; }
// note new return type, this now returns the bad block number, else 0 for success. // // I also return -ve block numbers for errors between blocks. Eg if you read 3 good blocks, then find an unexpected // float in the script between blocks 3 & 4 then I return -3 to indicate the error is after that, but not block 4 // int CInterpreter::Interpret( CTokenizer *Tokenizer, CBlockStream *BlockStream, char *filename ) { CBlock block; CToken *token; int type, blockLevel = 0, parenthesisLevel = 0; m_sCurrentFile = filename; // used during error reporting because you can't ask tokenizer for pushed streams m_tokenizer = Tokenizer; m_blockStream = BlockStream; m_iCurrentLine = m_tokenizer->GetCurLine(); token = m_tokenizer->GetToEndOfLine(TK_STRING); m_sCurrentLine = token->GetStringValue(); m_tokenizer->PutBackToken(token, false, NULL, true); m_iBadCBlockNumber = 0; while (m_tokenizer->GetRemainingSize() > 0) { token = m_tokenizer->GetToken( TKF_USES_EOL, 0 ); type = token->GetType(); switch ( type ) { case TK_UNDEFINED: token->Delete(); m_iBadCBlockNumber = -m_iBadCBlockNumber; Error("%d : undefined token", type); return m_iBadCBlockNumber; break; case TK_EOF: break; case TK_EOL: // read the next line, then put it back token->Delete(); m_iCurrentLine = m_tokenizer->GetCurLine(); token = m_tokenizer->GetToEndOfLine(TK_STRING); m_sCurrentLine = token->GetStringValue(); m_tokenizer->PutBackToken(token, false, NULL, true); break; case TK_CHAR: case TK_STRING: token->Delete(); m_iBadCBlockNumber = -m_iBadCBlockNumber; Error("syntax error : unexpected string"); return m_iBadCBlockNumber; break; case TK_INT: token->Delete(); m_iBadCBlockNumber = -m_iBadCBlockNumber; Error("syntax error : unexpected integer"); return m_iBadCBlockNumber; break; case TK_FLOAT: token->Delete(); m_iBadCBlockNumber = -m_iBadCBlockNumber; Error("syntax error : unexpected float"); return m_iBadCBlockNumber; break; case TK_IDENTIFIER: m_iBadCBlockNumber++; if (!GetID( (char *) token->GetStringValue() )) { token->Delete(); return m_iBadCBlockNumber; } token->Delete(); break; case TK_BLOCK_START: token->Delete(); if (parenthesisLevel) { m_iBadCBlockNumber = -m_iBadCBlockNumber; Error("syntax error : brace inside parenthesis"); return m_iBadCBlockNumber; } blockLevel++; break; case TK_BLOCK_END: token->Delete(); if (parenthesisLevel) { m_iBadCBlockNumber = -m_iBadCBlockNumber; Error("syntax error : brace inside parenthesis"); return m_iBadCBlockNumber; } block.Create( ID_BLOCK_END ); m_blockStream->WriteBlock( &block ); block.Free(); blockLevel--; break; case TK_OPEN_PARENTHESIS: token->Delete(); blockLevel++; parenthesisLevel++; break; case TK_CLOSED_PARENTHESIS: token->Delete(); blockLevel--; parenthesisLevel--; if (parenthesisLevel<0) { m_iBadCBlockNumber = -m_iBadCBlockNumber; Error("syntax error : closed parenthesis with no opening match"); return m_iBadCBlockNumber; } break; case TK_VECTOR_START: token->Delete(); m_iBadCBlockNumber = -m_iBadCBlockNumber; Error("syntax error : unexpected vector"); return m_iBadCBlockNumber; break; case TK_VECTOR_END: token->Delete(); m_iBadCBlockNumber = -m_iBadCBlockNumber; Error("syntax error : unexpected vector"); return m_iBadCBlockNumber; break; } } if ( blockLevel ) { m_iBadCBlockNumber = -m_iBadCBlockNumber; Error("error : open brace was not closed"); return m_iBadCBlockNumber; } if ( parenthesisLevel ) { m_iBadCBlockNumber = -m_iBadCBlockNumber; Error("error: open parenthesis"); return m_iBadCBlockNumber; } //Release all the variable information, because it's already been written out FreeVars(); m_iBadCBlockNumber = 0; return m_iBadCBlockNumber; //true; }
int CInterpreter::GetSet( void ) { CBlock block; block.Create( ID_SET ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); if ( GetString( &block ) == false ) return false; //Check for get placement if ( MatchGet() ) { if ( GetGet( &block ) == false ) return false; } else { switch( GetNextType() ) { case TK_INT: if ( GetInteger( &block ) == false ) return false; break; case TK_FLOAT: if ( GetFloat( &block ) == false ) return false; break; case TK_STRING: if ( GetString( &block ) == false ) return false; break; case TK_VECTOR_START: if ( GetVector( &block ) == false ) return false; break; default: if ( MatchTag() ) { GetTag( &block ); break; } if ( MatchRandom() ) { GetRandom( &block ); break; } return Error("unknown parameter type"); break; } } if (!Match( TK_CLOSED_PARENTHESIS )) return Error("set : too many parameters"); m_blockStream->WriteBlock( &block ); return true; }
int CInterpreter::GetCamera( void ) { CBlock block; char typeName[MAX_STRING_SIZE]; int type; block.Create( ID_CAMERA ); if (!Match( TK_OPEN_PARENTHESIS )) return Error("syntax error : '(' not found"); if ( GetType( (char *) typeName ) == false ) return false; type = FindSymbol( typeName, m_typeKeywords); switch ( type ) { case TYPE_PAN: //PAN ( ANGLES, DURATION ) block.Write( TK_FLOAT, (float) type ); if ( GetVector( &block ) == false ) return false; if ( GetVector( &block ) == false ) return false; if ( GetFloat( &block ) == false ) return false; break; case TYPE_ZOOM: //ZOOM ( FOV, DURATION ) block.Write( TK_FLOAT, (float) type ); if ( GetFloat( &block ) == false ) return false; if ( GetFloat( &block ) == false ) return false; break; case TYPE_MOVE: //MOVE ( ORIGIN, DURATION ) block.Write( TK_FLOAT, (float) type ); if ( GetVector( &block ) == false ) return false; if ( GetFloat( &block ) == false ) return false; break; case TYPE_FADE: //FADE ( SOURCE(R,G,B,A), DEST(R,G,B,A), DURATION ) block.Write( TK_FLOAT, (float) type ); //Source color if ( GetVector( &block ) == false ) return false; if ( GetFloat( &block ) == false ) return false; //Dest color if ( GetVector( &block ) == false ) return false; if ( GetFloat( &block ) == false ) return false; //Duration if ( GetFloat( &block ) == false ) return false; break; case TYPE_PATH: //PATH ( FILENAME ) block.Write( TK_FLOAT, (float) type ); //Filename if ( GetString( &block ) == false ) return false; break; case TYPE_ENABLE: case TYPE_DISABLE: block.Write( TK_FLOAT, (float) type ); break; case TYPE_SHAKE: //SHAKE ( INTENSITY, DURATION ) block.Write( TK_FLOAT, (float) type ); //Intensity if ( GetFloat( &block ) == false ) return false; //Duration if ( GetFloat( &block ) == false ) return false; break; case TYPE_ROLL: //ROLL ( ANGLE, TIME ) block.Write( TK_FLOAT, (float) type ); //Angle if ( GetFloat( &block ) == false ) return false; //Time if ( GetFloat( &block ) == false ) return false; break; case TYPE_TRACK: //TRACK ( TARGETNAME, SPEED, INITLERP ) block.Write( TK_FLOAT, (float) type ); //Target name if ( GetString( &block ) == false ) return false; //Speed if ( GetFloat( &block ) == false ) return false; //Init lerp if ( GetFloat( &block ) == false ) return false; break; case TYPE_FOLLOW: //FOLLOW ( CAMERAGROUP, SPEED, INITLERP ) block.Write( TK_FLOAT, (float) type ); //Camera group if ( GetString( &block ) == false ) return false; //Speed if ( GetFloat( &block ) == false ) return false; //Init lerp if ( GetFloat( &block ) == false ) return false; break; case TYPE_DISTANCE: //DISTANCE ( DISTANCE, INITLERP ) block.Write( TK_FLOAT, (float) type ); //Distance if ( GetFloat( &block ) == false ) return false; //Init lerp if ( GetFloat( &block ) == false ) return false; break; } if (!Match( TK_CLOSED_PARENTHESIS )) return Error("camera : too many parameters"); m_blockStream->WriteBlock( &block ); return true; }