// 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; }