static ASTPtr parseSpecifiedLengthContent(const char** fptr, const char*** wordSourcesPtr, const LengthFunc** lengthFuncsPtr) { assert(**fptr == '\'' || std::isdigit(**fptr) || **fptr == '#'); ASTPtr slc; if (**fptr == '\'') { slc = parseStringLiteral(fptr); } else if (**fptr == '#') { slc = parseRepeatedCharFL(fptr, lengthFuncsPtr); } else { const char* f_at = *fptr; LiteralLength length = parseLiteralLength(fptr); if (**fptr == '\'') { slc.reset(new RepeatedCharLL(f_at, length, parseCharLiteral(fptr))); } else if (**fptr == '[') { Block* block = new Block(f_at, length); slc.reset(block); ++*fptr; parseWhitespaces(fptr); // [ is a token while (**fptr != ']') { if (**fptr == '\'' || std::isdigit(**fptr) || **fptr == '#') { block->addChild(parseSpecifiedLengthContent(fptr, wordSourcesPtr, lengthFuncsPtr)); } else if (**fptr == '{') { block->addWords(parseWords(fptr, wordSourcesPtr)); } else { throw DSLException(*fptr, "Expected ', digit, or # to begin specified-length content, " "or { to begin greedy-length content."); } } ++*fptr; parseWhitespaces(fptr); // ] is a token if (**fptr == '^') { parseTopOrBottomFiller(fptr, &block->topFillers, true); if (**fptr == 'v') { parseTopOrBottomFiller(fptr, &block->bottomFillers, false); } } else if (**fptr == 'v') { parseTopOrBottomFiller(fptr, &block->bottomFillers, false); if (**fptr == '^') { parseTopOrBottomFiller(fptr, &block->topFillers, true); } } } else { throw DSLException(*fptr, "Expected ' or [ after length specifier."); } } return slc; }
static ASTPtr parseFormat(const char** fptr, const char*** wordSourcesPtr, const LengthFunc** lengthFuncsPtr) { parseWhitespaces(fptr); // Will insert all root content as children into a super-root Block. Block* rootsParentBlock = new Block(*fptr, LiteralLength(0, false)); ASTPtr rootsParent(rootsParentBlock); while (**fptr != '\0') { if (**fptr == '\'' || std::isdigit(**fptr)) { ASTPtr root = parseSpecifiedLengthContent(fptr, wordSourcesPtr, lengthFuncsPtr); int rootLength = root->getFixedLength(); if (rootLength == UNKNOWN_COL) { throw DSLException(root->f_at, "Root content must be fixed-length."); } rootsParentBlock->addChild(std::move(root)); rootsParentBlock->length.value += rootLength; } else { throw DSLException(*fptr, "Expected ' or digit."); } } return rootsParent; }
std::string SceneModel::getStructureRepresentation( ScriptParser * parser, InSceneStructureWidget * structure, int index ) { //Write accessors to the scene variables std::string sceneVars = ""; for( unsigned int i = 1; i < variables.size(); i++ ) { sceneVars += "\r\tfrac " + variables[i].name + " = sceneVarData["+std::to_string(i)+"];"; } sceneVars += "\r\r"; //Parse the scripts that represent the outlets in relation to scene variables auto chil = structure->outletList->findChildren<QLineEdit*>(); std::string outletStatements = ""; for( int i = 0; i < chil.size(); i++ ) { std::string s = chil.at(i)->text().toStdString(); ScriptNode * node = parser->parseLine( s ); Block b; b.addChild( node ); for( unsigned int j = 1; j < variables.size(); j++ ) { b.variablesInScope[ variables[j].name ] = VariablePacket( Value() ); } outletStatements += "\r\tfrac " + structure->st.outletNames[ i ] + " = " + ScriptParser::textOf( node, 0, false ) + ";"; } outletStatements += "\r\r"; StructureObject structObject = StructureObject::load( structure->st.name ); Block * script = parser->parse( structObject.codeBlocks[ structure->currentType ] ); //Declare outlets for( int i = 0; i < structure->st.numOutlets; i++ ) { script->variablesInScope[ structure->st.outletNames[i] ] = VariablePacket( Value() ); } //Declare parameters script->variablesInScope[ "x" ] = VariablePacket( Value() ); script->variablesInScope[ "y" ] = VariablePacket( Value() ); script->variablesInScope[ "z" ] = VariablePacket( Value() ); script->variablesInScope[ "r" ] = VariablePacket( Value(), true ); script->variablesInScope[ "g" ] = VariablePacket( Value(), true ); script->variablesInScope[ "b" ] = VariablePacket( Value(), true ); //Pull ray cast functionality part std::string rayPart = ""; std::string scriptPart = ""; if( structure->currentType == 0 ) { std::ifstream t("Assets/clparts/clpartSUBSET.cl"); rayPart = std::string((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>()); t.close(); } else if( structure->currentType == 1 ) { std::ifstream t("Assets/clparts/clpartDISTANCE.cl"); rayPart = std::string((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>()); t.close(); } else if( structure->currentType == 2 ) { script->variablesInScope[ "dx" ] = VariablePacket( Value() ); script->variablesInScope[ "dy" ] = VariablePacket( Value() ); script->variablesInScope[ "dz" ] = VariablePacket( Value() ); script->variablesInScope[ "dist" ] = VariablePacket( Value(), true ); std::ifstream t("Assets/clparts/clpartTRACE.cl"); rayPart = std::string((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>()); t.close(); } //Seam everything together and replace hotlinks scriptPart = sceneVars + outletStatements + parser->textOf( script, 0, true ); stringReplaceAll( &rayPart, "$$FUNCTIONINJECTION$$", scriptPart ); stringReplaceAll( &rayPart, "$$NUM$$", std::to_string( index ) ); return rayPart + "\n\n"; }
Block * Interpreter::read(QString codeIn) { try { QString code; code = codeIn.replace(QRegExp("\\{[^}]*\\}"), " ").replace("["," [ ").replace("]"," ] ").toLower().simplified(); //qDebug() << code; QStringList tokens(code.split(" ", QString::SkipEmptyParts)); QStringListIterator it(tokens); /* hierarchia bloków: istnieje jeden blok główny (grandpa), do niego dołączane są w razie potrzeby (przy wystąpieniu [ ) kolejne, elementy dodawane są zawsze do najbardziej zewnętrznego bloku, czyli tego na początku tej listy: */ QList<Block*> blocksHier; blocksHier.prepend(&grandpa); while (it.hasNext()) { QString token = it.next(); //qDebug() << token; Eval * tmp = 0; if(tmp = getAction(token, it, blocksHier.first())); else if(tmp = getArithmetic(token, it, blocksHier.first())); // dodawanie bloku jako dziecka bloku aktualnego else if (token == "[") { Block * tmpblock = new Block(blocksHier.first()); blocksHier.first()->addChild(tmpblock); blocksHier.prepend(tmpblock); } /* elementy w następnym obrocie pętli będą dodawane już do 'wyższego bloku' w hierarchii */ else if (token == "]") { if (blocksHier.size() > 1) { blocksHier.removeFirst(); } } else if (token == "for") { if (! it.hasNext()) throw QString("For definition not ended"); For * tmpfor = new For(blocksHier.first(), it.next()); blocksHier.first()->addChild(tmpfor); // jeśli po forze otworzyliśmy blok if (it.hasNext() && (it.peekNext() == "[")) { Block * bl = new Block(tmpfor); tmpfor->setChild(bl); /* dzieki temu następne elementy będą wczytywane to nowego bloku aż do ] */ blocksHier.prepend(bl); it.next(); } else if (it.hasNext() && QRegExp("\\D*").exactMatch(it.peekNext())) { QString tok2 = it.next(); Eval * tmpaction; if(tmpaction = getAction(tok2, it, tmpfor)); else if(tmpaction = getArithmetic(tok2, it, tmpfor)); if (tmpaction) tmpfor->setChild(tmpaction); else if(procedures.contains(tok2)) { tmpfor->setChild(new Proc(tmpfor, &procedures, tok2)); } else throw QString("%1 - unknown operation/procedure").arg(tok2); } else if (it.hasNext() ) { throw QString("%1 - number cannot be action").arg(it.next()); } } else if (token == "block") { Block * tmpblock = new Block(&grandpa); if(it.hasNext() && it.peekNext() != "" && it.peekNext() != "[" ) { QString procName = it.peekNext(); if(procedures.contains(procName)) { delete procedures[procName]; procedures.remove(procName); } procedures.insert(procName, tmpblock); it.next(); } if(it.hasNext() && it.peekNext() == "[") { blocksHier.prepend(tmpblock); it.next(); } else if(it.hasNext()) { Action * tmpaction = getAction(it.next(), it, tmpblock); tmpblock->addChild(tmpaction); } } else if (procedures.contains(token)) { tmp = new Proc(blocksHier.first(), &procedures, token); //qDebug() << QString("Creatign Proc: %1, it's parent: %2").arg((int)tmp).arg((int)blocksHier.first()); } else { throw QString("%1 - don't understand").arg(token); } if (tmp) blocksHier.first()->addChild(tmp); } //qDebug() << "wyszedlem z interperetera"; } catch (QString err) { grandpa.clear(); throw err; } catch (...) { grandpa.clear(); throw 0; } return &grandpa; }