1 /* "CodeWorker": a scripting language for parsing and generating text. 2 3 Copyright (C) 1996-1997, 1999-2002 C�dric Lemaire 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 To contact the author: codeworker@free.fr 20 */ 21 22 #ifdef WIN32 23 #pragma warning (disable : 4786) 24 #endif 25 26 #include "ScpStream.h" 27 #include "CppCompilerEnvironment.h" 28 #include "CGRuntime.h" 29 30 #include "DtaScriptVariable.h" 31 #include "ExprScriptVariable.h" 32 #include "DtaBNFScript.h" 33 #include "DtaVisitor.h" 34 #include "BNFPushItem.h" 35 36 namespace CodeWorker { 37 BNFPushItem(DtaBNFScript * pBNFScript,GrfBlock * pParent)38 BNFPushItem::BNFPushItem(DtaBNFScript* pBNFScript, GrfBlock* pParent) : _pBNFScript(pBNFScript), GrfBlock(pParent), _pVariable(NULL) {} 39 ~BNFPushItem()40 BNFPushItem::~BNFPushItem() { 41 } 42 accept(DtaVisitor & visitor,DtaVisitorEnvironment & env)43 void BNFPushItem::accept(DtaVisitor& visitor, DtaVisitorEnvironment& env) { 44 visitor.visitBNFPushItem(*this, env); 45 } 46 isABNFCommand() const47 bool BNFPushItem::isABNFCommand() const { return true; } 48 execute(DtaScriptVariable & visibility)49 SEQUENCE_INTERRUPTION_LIST BNFPushItem::execute(DtaScriptVariable& visibility) { 50 SEQUENCE_INTERRUPTION_LIST result; 51 DtaScriptVariable* pVariable = visibility.getExistingVariable(*_pVariable); 52 bool bCreation = (pVariable == NULL); 53 if (bCreation) { 54 pVariable = visibility.getVariable(*_pVariable); 55 if (pVariable->isLocal()) CGRuntime::throwBNFExecutionError("declare the local variable '" + _pVariable->toString() + "' before calling '#pushItem'"); 56 } 57 pVariable->pushItem(""); 58 int iCursor = CGRuntime::getInputLocation(); 59 int iImplicitCopyPosition = ((_pBNFScript->implicitCopy()) ? CGRuntime::getOutputLocation() : -1); 60 result = GrfBlock::executeInternal(visibility); 61 if (result != NO_INTERRUPTION) { 62 if (bCreation && !pVariable->isLocal()) CGRuntime::removeVariable(pVariable); 63 else CGRuntime::removeLastElement(pVariable); 64 CGRuntime::setInputLocation(iCursor); 65 if (iImplicitCopyPosition >= 0) CGRuntime::resizeOutputStream(iImplicitCopyPosition); 66 } 67 return result; 68 } 69 compileCpp(CppCompilerEnvironment & theCompilerEnvironment) const70 void BNFPushItem::compileCpp(CppCompilerEnvironment& theCompilerEnvironment) const { 71 std::vector<GrfCommand*>::const_iterator i = getCommands().begin(); 72 if (i != getCommands().end()) { 73 CW_BODY_INDENT << "// " << toString(); 74 CW_BODY_ENDL; 75 int iCursor = theCompilerEnvironment.newCursor(); 76 CW_BODY_INDENT << "int _compilerClauseCursor_" << iCursor << " = CGRuntime::getInputLocation();"; 77 CW_BODY_ENDL; 78 CW_BODY_INDENT << "bool _compilerClauseCreation_" << iCursor << " = CGRuntime::existVariable("; 79 _pVariable->compileCpp(theCompilerEnvironment); 80 CW_BODY_STREAM << ");"; 81 CW_BODY_ENDL; 82 CW_BODY_INDENT; 83 _pVariable->compileCppForSet(theCompilerEnvironment); 84 CW_BODY_STREAM << ".pushItem(\"\");";CW_BODY_ENDL; 85 CW_BODY_INDENT << "if (_compilerClauseCreation_" << iCursor << " && "; 86 _pVariable->compileCpp(theCompilerEnvironment); 87 CW_BODY_STREAM << ".isLocal()) CGRuntime::throwBNFExecutionError(\"declare the local variable '" << _pVariable->toString() << "' before calling '#pushItem'\");";CW_BODY_ENDL; 88 GrfBlock::compileCppBNFSequence(theCompilerEnvironment); 89 CW_BODY_INDENT << "if (!_compilerClauseSuccess) {";CW_BODY_ENDL; 90 CW_BODY_INDENT << "\tif (!_compilerClauseCreation_" << iCursor << ") CGRuntime::removeVariable("; 91 _pVariable->compileCpp(theCompilerEnvironment); 92 CW_BODY_STREAM << ");";CW_BODY_ENDL; 93 CW_BODY_INDENT << "\telse CGRuntime::removeLastElement("; 94 _pVariable->compileCpp(theCompilerEnvironment); 95 CW_BODY_STREAM << ");";CW_BODY_ENDL; 96 CW_BODY_INDENT << "\tCGRuntime::setInputLocation(_compilerClauseCursor_" << iCursor << ");";CW_BODY_ENDL; 97 CW_BODY_INDENT << "}";CW_BODY_ENDL; 98 } 99 } 100 toString() const101 std::string BNFPushItem::toString() const { 102 std::string sText = "#pushItem(" + _pVariable->toString() + ")"; 103 for (std::vector<GrfCommand*>::const_iterator i = getCommands().begin(); i != getCommands().end(); i++) { 104 if ((*i)->isABNFCommand()) { 105 if (i != getCommands().begin()) sText += " "; 106 sText += (*i)->toString(); 107 } 108 } 109 return sText; 110 } 111 112 } 113