/*----------------------------------------------------------------------------- * * ID: c_if 08.02.07 0.0.A. * * Summary: The if-elif-else processing * -----------------------------------------------------------------------------*/ plexem STDCALL c_if( plexem curlex ) { uint jmpnext; //Смещение в стэке меток - переход к следующему elif, else uint jmpend; //Смещение в стэке меток - переход к концу uint labend; //Смещение в стэке меток - метка конца D( "If start" ); jmpend = -1; while ( 1 ) { //Обработка логического выражения curlex = f_expr( curlex, EXPR_BOOL, 0, 0 ); //Добавляем переход на следующий jmpnext = j_jump( CIfze, LABT_GTVIRT, -1 ); //Обработка тела curlex = f_body( curlex ); curlex = lexem_next( curlex, LEXNEXT_IGNLINE ); if ( curlex->type == LEXEM_KEYWORD && ( curlex->key == KEY_ELIF || curlex->key == KEY_ELSE )) { //Добавляем переход на конец jmpend = j_jump( CGoto, LABT_GTVIRT, jmpend ); //Добавляем метку на следующий, устанавливаем связь с последним переходом ((pflabel)( fd.blabels.data + jmpnext ))->link = j_label( LABT_LABELVIRT, -1); jmpnext = -1; if ( curlex->key == KEY_ELIF ) { D( "Elif start\n" ); curlex = lexem_next( curlex, 0 ); continue; } D( "Else start\n" ); curlex = f_body( lexem_next( curlex, LEXNEXT_IGNLINE ) ); curlex = lexem_next( curlex, LEXNEXT_IGNLINE ); break; } break; } //Добавляем метку на последний labend = j_label( LABT_LABELVIRT, -1 ); //Корректируем все переходы на конец j_correct( jmpend, labend ); //Корректировка, если нет else if ( jmpnext != -1 ) ((pflabel)( fd.blabels.data + jmpnext ))->link = labend; D( "If stop\n" ); return curlex; }
/*----------------------------------------------------------------------------- * * ID: c_dowhile 09.02.07 0.0.A. * * Summary: <do_while> processing * -----------------------------------------------------------------------------*/ plexem STDCALL c_dowhile( plexem curlex ) { uint labbeg; //Метка начало uint labend; //Метка конец uint labcont; //Метка продолжить uint fd_offlcbreak; //Смещение в таблице меток uint fd_offlccontinue; //Смещение в таблице меток D( "DoWhile start\n" ); fd.blcycle++; //Добавляем метку на начало labbeg = j_label( LABT_LABELVIRT, -1 ); //Сохраняем последние метки цикла fd_offlcbreak = fd.offlcbreak; fd_offlccontinue = fd.offlccontinue; //Добавляем переход на конец fd.offlcbreak = -1; fd.offlccontinue = -1; //Обработка тела curlex = f_body( curlex ); //Проверка ключевого слова while curlex = lexem_next( curlex, LEXNEXT_IGNLINE ); if ( curlex->type != LEXEM_KEYWORD || curlex->key != KEY_WHILE ) msg( MExpwhile | MSG_LEXERR, curlex ); curlex = lexem_next( curlex, 0 ); //Добавляем метку на продолжить labcont = j_label( LABT_LABELVIRT, -1 ); //Обработка логического выражения curlex = f_expr( curlex, EXPR_BOOL, 0, 0); //Добавляем переход на начало j_jump( CIfnze, LABT_GTVIRT, labbeg ); //Добавляем метку на конец labend = j_label( LABT_LABELVIRT, -1 ); //Цикл установки переходов на конец j_correct( fd.offlcbreak, labend ); //Цикл установки переходов на продолжить j_correct( fd.offlccontinue, labcont ); //Восстановление меток цикла fd.offlcbreak = fd_offlcbreak; fd.offlccontinue = fd_offlccontinue; fd.blcycle--; D( "DoWhile stop\n" ); return curlex; }
void SMSMessageBuilder::initialize() { QString location = QString(""); QString source = QString(""); location += (config->getPropertyValue("SMS", "TemplateLocation")).toString(); source += location; source += QString("/"); source += (config->getPropertyValue("SMS", "TemplateDescription")).toString(); // Opens a file and sets a document content QFile f_document(source); QDomDocument d_document; QString errorMessage; int errorLine; int errorColumn; d_document.setContent(&f_document, &errorMessage, &errorLine, &errorColumn); // Gets the root node QDomElement d_description = d_document.namedItem("Description").toElement(); // Gets a file which contains a message body QDomElement d_body = d_description.firstChildElement("body"); // Reads the message body QFile f_body(location + QString("/") + d_body.text().trimmed()); if (f_body.open(QIODevice::ReadOnly)) { QTextStream stream(&f_body); stream.setCodec("UTF-8"); body = new QString(stream.readAll()); } // Reads tags QHash<QString, QString> tags; QDomElement d_tags = d_description.firstChildElement("tags"); QDomNode d_tag = d_tags.firstChild(); for ( ; !d_tag.isNull(); d_tag = d_tag.nextSibling()) { QDomElement tmp = d_tag.toElement(); tags[tmp.attribute("key")] = tmp.attribute("value"); } // Replaces tags within the message body QList<QString> keys = tags.keys(); QList<QString>::iterator i; for (i = keys.begin(); i != keys.end(); ++i) { body->replace(QRegExp(*i), tags[*i]); } }
/*----------------------------------------------------------------------------- * * ID: c_while 09.02.07 0.0.A. * * Summary: The while processing * -----------------------------------------------------------------------------*/ plexem STDCALL c_while( plexem curlex ) { uint labbeg; //Метка начало uint labend; //Метка конец uint offlcbreak; //Смещение в таблице меток uint offlccontinue; //Смещение в таблице меток fd.blcycle++; D( "While start\n" ); //Добавляем метку на начало labbeg = j_label( LABT_LABELVIRT, -1 ); //Обработка логического выражения curlex = f_expr( curlex, EXPR_BOOL, 0, 0 ); //Сохраняем последние метки цикла offlcbreak = fd.offlcbreak; offlccontinue = fd.offlccontinue; //Добавляем переход на конец fd.offlcbreak = j_jump( CIfze, LABT_GTVIRT, -1); fd.offlccontinue = -1; //Обработка тела curlex = f_body( curlex ); //Добавляем переход на начало j_jump( CGoto, LABT_GTVIRT, labbeg ); //Добавляем метку на конец labend = j_label( LABT_LABELVIRT, -1 ); //Цикл установки переходов на конец j_correct( fd.offlcbreak, labend ); //Цикл установки переходов на начало j_correct( fd.offlccontinue, labbeg ); //Восстановление меток цикла fd.offlcbreak = offlcbreak; fd.offlccontinue = offlccontinue; fd.blcycle--; D( "While stop\n" ); return curlex; }
/*----------------------------------------------------------------------------- * * ID: m_func 02.11.06 0.0.A. * * Summary: The func, method, operator, property, text processing * -----------------------------------------------------------------------------*/ plexem STDCALL m_func( plexem curlex, uint flgextern ) { #ifdef DOUT uint i; #endif uint funckey; //Вид функции uint flgfunc; //Флаги функции pflabel curlabel; // Текущий элемент в таблице меток pflabel endlabel; // Конец таблицы меток uint isreturn; //Есть return uint thistype; //Тип переменной this для методов+ pubyte name; //Имя функции plexem lexname; //Лексема с именем функции plexem lexprev; s_desctype desctype;//Описание типа s_descid descvar; //Описание переменной uint off_parcount; //Смещение в заголовке функции на кол. параметров uint off_blccount; //Смещение в заголовке функции на кол. блоков bcflag bcf; //Переменная для получение флагов функции pbuf b; pfwith pwith; pvmobj funcobj; uint thisid; //Номер переменной для this в текст функции D( "Func start\n" ); // Инициализация desctype.idtype = 0; descvar.idtype = 0; descvar.flgdesc = 0; mem_zero( &fd, sizeof( fd ) ); thistype = 0; funckey = curlex->key; hash_init( &fd.nvars, sizeof( uint ) ); hash_init( &fd.nlabels, sizeof( uint ) ); for ( b = &fd.bhead; b <= &fd.bvarsas; b++ ) { buf_init( b ); buf_reserve( b, 0x200 ); b->step = 0x200; } fd.bvars.use = sizeof( fvar ); fd.blabels.use = sizeof( flabel ); // _compile->pout = &fd.bhead; // fd.blcount = 0; // fd.varcount = 0; // fd.curcount = 0; // fd.lastcurcount = 0; // fd.bllevel = 0; // fd.blcycle = 0; fd.offlcbreak = -1; fd.offlccontinue = -1; // fd.functype = 0; switch ( funckey ) { case KEY_METHOD: flgfunc = GHBC_METHOD; break; case KEY_OPERATOR: flgfunc = GHBC_OPERATOR; break; case KEY_PROPERTY: flgfunc = GHBC_PROPERTY; break; case KEY_TEXT: flgfunc = GHBC_TEXT; break; default: flgfunc = 0; } curlex = lexem_next( curlex, LEXNEXT_IGNLINE ); // Получаем тип возвращаемого значения функции/метода если он есть if ( curlex->type == LEXEM_NAME ) curlex = desc_idtype( curlex, &desctype ); if ( desctype.idtype ) { if ( ( funckey == KEY_METHOD || funckey == KEY_PROPERTY ) && curlex->type == LEXEM_OPER && curlex->oper.operid == OpWith ) { //Возврат на лексему влево текущая лексема тип объекта desctype.idtype = 0; curlex--; } else { fd.functype = desctype.idtype; fd.funcoftype = desctype.oftype; } } lexprev = curlex; curlex = lexem_next( curlex, LEXNEXT_SKIPLINE ); // Получаем тип объекта для метода if ( funckey == KEY_METHOD || funckey == KEY_PROPERTY ) { //Получаем тип объекта if ( curlex->type > 32 ) msg( MExptype | MSG_LEXERR, lexprev ); if ( thistype = bc_type( curlex ) ) { curlex = lexem_next( curlex, 0 ); if ( curlex->type == LEXEM_OPER && curlex->oper.operid == OpWith ) { curlex = lexem_next( curlex, 0 ); } else msg( MExppoint | MSG_LEXERR, curlex ); } else msg( MExptype | MSG_LEXERR, curlex ); } // Получение имени функции, метода ... if ( funckey == KEY_OPERATOR ) { if ( curlex->type != LEXEM_OPER ) msg( MExpoper | MSG_LEXERR, curlex ); name = ( pubyte )&curlex->oper.name; } else { if ( curlex->type != LEXEM_NAME ) msg( MExpname | MSG_LEXERR, curlex ); name = lexem_getname( curlex ); } lexname = curlex; _vm.pos = curlex->pos; // Получение списка директив curlex = lexem_next( curlex, flgextern ? 0 : LEXNEXT_IGNLINE ); curlex = bc_flag( curlex, BFLAG_FUNC, &bcf ); flgfunc |= GHCOM_NAME | bcf.value; _compile->pout = &fd.bhead; out_head( OVM_BYTECODE, flgfunc, name ); create_varmode( &fd.bhead, &desctype, 0 );//Возвращаемое значение off_parcount = fd.bhead.use; out_adduint( 0 );//Количество параметров if ( funckey == KEY_METHOD || funckey == KEY_PROPERTY ) { //Создание параметра this mem_zero( &descvar, sizeof( descvar )); descvar.idtype = thistype; descvar.name = "this"; descvar.lex = curlex; descvar.flgdesc = DESCID_PARFUNC; pwith = ( pfwith )buf_appendtype( &fd.bwith, sizeof( fwith )) ; pwith->num = var_checkadd( &descvar ); pwith->oftype = 0; pwith->type = thistype; } //Получение списка параметров if ( curlex->type == LEXEM_OPER && curlex->oper.operid == OpLbrack )//Открывающая скобка { curlex = lexem_next( curlex, LEXNEXT_IGNLINE ); curlex = var_def( curlex, DESCID_PARFUNC ); if ( curlex->type != LEXEM_OPER ||//Системная лексема curlex->oper.operid != OpRbrack )//Закрывающая скобка msg( MExpclosebr | MSG_LEXERR, curlex ); curlex = lexem_next( curlex, flgextern ? 0 : LEXNEXT_IGNLINE ); } else { if ( funckey == KEY_OPERATOR ) msg( MExpopenbr | MSG_LEXERR, curlex ); } fd.flgfunc = flgfunc; if ( flgfunc & GHBC_RESULT ) { //Создание параметра result if ( !fd.functype || fd.functype <= TUlong ) msg( MResulttype | MSG_LEXERR, curlex ); mem_zero( &descvar, sizeof( descvar )); descvar.idtype = desctype.idtype; descvar.oftype = desctype.oftype; descvar.flgdesc = DESCID_PARFUNC; descvar.name = "result"; descvar.lex = curlex; fd.idresult = var_checkadd( &descvar ); fd.functype = 0; } if ( fd.varcount ) { *( puint )( fd.bhead.data + off_parcount ) = fd.varcount;//Кол-во параметров if ( flgfunc & ( GHBC_ENTRY | GHBC_MAIN ) ) msg( MMainpar | MSG_LEXERR, curlex ); fd.curcount = 0; } off_blccount = fd.bhead.use; out_adduint( 0 );//Количество блоков if ( funckey == KEY_PROPERTY ) { if ( ( fd.functype && fd.varcount > 1 ) || (!fd.functype && fd.varcount != 2 )) { msg( MProppar | MSG_LEXERR, curlex );//Неверное количество параметров в описании свойства } if ( type_fieldname( thistype, name ) ) { msg( MPropfield | MSG_LEXERR, curlex );//Свойство совпадает с именем поля } } funcobj = load_bytecode( &fd.bhead.data, flgextern ? VMLOAD_EXTERN : VMLOAD_FIRST ); if ( bcf.value & GHRT_ALIAS ) { alias_setid( bcf.alias, funcobj->id ); } if ( !( flgextern ) ) { if ( _compile->flag & CMPL_DEBUG ) { _compile->pout = fd.bout = &fd.bsubout; out_adduints( 3, CDatasize, str_len( _compile->cur->filename ) + 5, str_pos2line( _compile->cur->src, lexname->pos, 0 ) + 1 ); out_addptr( str_ptr( _compile->cur->filename ), str_len( _compile->cur->filename ) + 1 ); out_adduint( CDbgFunc ); _compile->pout = fd.bout = &fd.bfuncout; } _compile->pout = fd.bout = &fd.bfuncout; if ( funckey == KEY_TEXT ) { //Создание параметра this для Text функции mem_zero( &descvar, sizeof( descvar )); descvar.idtype = TUint; descvar.name = "this"; descvar.lex = curlex; descvar.flgdesc = DESCID_VAR;///DESCID_PARFUNC; thisid = var_checkadd( &descvar ); /*pwith = ( pfwith )buf_appendtype( &fd.bwith, sizeof( fwith )) ; pwith->num = var_checkadd( &descvar ); //print( "ssssssssss %x %x %x %x", fd.bvars.data, fd.bvars.use, pwith->num, sizeof( fvar ) ); pwith->oftype = 0; pwith->type = TStr;*/ ((pfvar)(fd.bvars.data + fd.bvars.use - sizeof( fvar )))->type = TStr; out_adduints( 4, CVarptrload, thisid, CGetText, CSetI ); /*buf_appenduint( &fd.bblinit, CVarptrload ); buf_appenduint( &fd.bblinit, thisid ); buf_appenduint( &fd.bblinit, CGetText ); buf_appenduint( &fd.bblinit, CSetI );*/ } curlex = f_body( curlex ); *((puint)(fd.bhead.data+off_blccount)) = fd.blcount; curlabel = ( pflabel )( fd.blabels.data ) + 1; endlabel = ( pflabel )( fd.blabels.data + fd.blabels.use ); //Контроль неразрешённых меток и проверка выходов из функции isreturn = 0; while( curlabel < endlabel ) { if ( curlabel->type & LABT_GT ) { if ( ( curlabel->type & LABT_GTUNDEF ) == LABT_GTUNDEF ) msg( MUnklabel | MSG_LEXNAMEERR, curlabel->lex ); *( puint )(fd.bfuncout.data + curlabel->offbout ) = ((( pflabel )(fd.blabels.data + curlabel->link ))->offbout + fd.bsubout.use )/sizeof(uint); if ( !isreturn )//Помечаем метку как отработавшую (на неё был переход) (( pflabel )(fd.blabels.data + curlabel->link ))->type |= LABT_LABELWORK; } else if ( curlabel->type & LABT_RETURN ) { isreturn = 1;//Устанавливаем флаг } else if ( curlabel->type & LABT_LABELWORK ) isreturn = 0;//Если была отработавшая метка, то сбрасываем флаг curlabel++; } if ( fd.functype ) { if ( !isreturn ) msg( MMustret | MSG_LEXNAMEERR, lexname ); } else if ( !isreturn ) { if ( fd.flgfunc & GHBC_RESULT ) { out_add2uint( CVarload, fd.idresult ); } out_adduint( CReturn ); } buf_add( &fd.bhead, &fd.bvardef ); if ( fd.bsubout.use ) { if ( fd.offsubgoto ) { //*((( puint)fd.bsubout.data ) + 1) = fd.bsubout.use/sizeof( uint ); *( puint )( fd.bsubout.data + fd.offsubgoto ) = fd.bsubout.use / sizeof( uint ); } buf_add( &fd.bhead, &fd.bsubout ); } buf_add( &fd.bhead, &fd.bfuncout ); _compile->pout = &fd.bhead; out_finish(); #ifdef DOUT //Тестируемый вывод //if ( name[0] == 'c' && name[1] == 'r' ) getch(); print( "FUNC OUT %x %s:\n", funcobj->id, name ); for (i = 0; i < fd.bhead.use ; i++ ) { print( " %x", fd.bhead.data[i] ); } print( "\n" ); #endif load_bytecode( &fd.bhead.data, VMLOAD_OK ); // print( "funcobjid2 =%x\n", funcobj->id ); } //Очистка памяти for ( b = &fd.bhead;/*&fd.bblinit;*/ b <= &fd.bvarsas; b++ ) { buf_delete( b ); } hash_delete( &fd.nvars ); hash_delete( &fd.nlabels ); D( "Func Stop\n" ); return curlex; }
/*----------------------------------------------------------------------------- * * ID: f_subfunc 02.02.06 0.0.A. * * Summary: The subfunc processing * -----------------------------------------------------------------------------*/ plexem STDCALL f_subfunc( plexem curlex ) { uint fd_lastcurcount;//Предыдущее значение кол. переменных в верхнем блоке uint fd_functype; //Текущий тип функции uint fd_funcoftype; //Текущий подтип функции uint fd_oldoffbvar;//Текущее смещение в стэке локальных переменных uint offbvars; //Смещение в стэке локальных переменных для подфункции pflabel curlabel; //Текущий элемент в таблице меток pflabel endlabel; //Конец таблицы меток uint offblabels; //Начало подфункции в стэке меток uint addr; //Адрес подфункции в байткоде uint pars; //Количество параметров у подфункции uint offbvardef; //Смещение в буфере описание переменных s_desctype desctype; //Структура для получения типа подфункции s_descid descvar; //Структура для описания подфункции как локальной переменной pfvar var; //Указатель на локальную переменную-подфункцию uint isreturn; //Флаг выхода из функции plexem lexname; //Лексема с именем функции uint off; //Временная переменная для смещений if ( fd.bllevel > 1 ) msg( MSublevel | MSG_LEXERR, curlex ); //Инициализация desctype.idtype = 0; descvar.idtype = 0; _compile->pout = fd.bout = &fd.bsubout; offblabels = fd.blabels.use; fd_functype = fd.functype; fd_funcoftype = fd.funcoftype; //if ( !fd.bsubout.use ) if ( !fd.offsubgoto ) { out_add2uint( CGoto, 0 ); fd.offsubgoto = fd.bsubout.use - 4; } addr = fd.bsubout.use/sizeof( uint ); //Тип возвращаемого значения если указан if ( curlex->type == LEXEM_NAME ) curlex = desc_idtype( curlex, &desctype ); if ( desctype.idtype ) { fd.functype = desctype.idtype; fd.funcoftype = desctype.oftype; //Инициализация возврата out_add2uint( CSubret, (( povmtype)PCMD( fd.functype ))->stsize ); } else { fd.functype = 0; fd.funcoftype = 0; } //Имя функции curlex = lexem_next( curlex, LEXNEXT_SKIPLINE ); if ( curlex->type != LEXEM_NAME ) msg( MExpname | MSG_LEXERR, curlex );//Ошибка Должен быть идентификатор lexname = curlex; offbvars = fd.bvars.use; descvar.idtype = fd.functype; descvar.oftype = fd.funcoftype; descvar.name = lexem_getname( lexname ); descvar.lex = lexname; descvar.flgdesc = DESCID_SUBFUNC; var_checkadd( &descvar ); //Список параметров curlex = lexem_next( curlex, LEXNEXT_IGNLINE ); fd_oldoffbvar = fd.oldoffbvar; fd.oldoffbvar = fd.bvars.use; pars = 0; if ( curlex->type == LEXEM_OPER && curlex->oper.operid == OpLbrack )//Открывающая скобка { curlex = lexem_next( curlex, LEXNEXT_IGNLINE ); fd_lastcurcount = fd.lastcurcount; fd.lastcurcount = fd.curcount; fd.curcount = 0; offbvardef = fd.bvardef.use; curlex = var_def( curlex, DESCID_PARSUBFUNC ); pars = fd.curcount; if ( fd.curcount ) { out_add2uint( CSubpar, fd.blcount - 1 );//Загрузка параметров buf_appenduint( &fd.bhead, fd.curcount ); fd.curcount = 0; } else { fd.curcount = fd.lastcurcount; fd.lastcurcount = fd_lastcurcount; } if ( curlex->type != LEXEM_OPER || curlex->oper.operid != OpRbrack )//Закрывающая скобка msg( MExpclosebr | MSG_LEXERR, curlex );// Ошибка Ожадается закрывающая скобка curlex = lexem_next( curlex, LEXNEXT_IGNLINE ); } //Запись подфункции как локальной переменной var = (pfvar)( fd.bvars.data + offbvars ); var->flg = FVAR_SUBFUNC; var->addr = addr; var->pars = pars; var->offbvardef = offbvardef; //Обработка тела функции curlex = f_body( curlex ); //Очистка параметров из стэка локальных переменных off = (uint)fd.bvars.data + fd.oldoffbvar; for ( (uint)var = (uint)fd.bvars.data + fd.bvars.use - sizeof( fvar ); (uint)var >= off; var-- ) { if ( var->hidn ) var->hidn->val = var->oldoffbvar; } fd.bvars.use = fd.oldoffbvar; fd.oldoffbvar = fd_oldoffbvar; //Установка переходов, корректировка меток isreturn = 0; curlabel = ( pflabel )( fd.blabels.data + offblabels ); endlabel = ( pflabel )( fd.blabels.data + fd.blabels.use ); while( curlabel < endlabel ) { if ( curlabel->type & LABT_GT ) { if ( ( curlabel->type & LABT_GTUNDEF ) == LABT_GTUNDEF ) msg( MUnklabel | MSG_LEXNAMEERR, curlabel->lex ); *( puint )(fd.bsubout.data + curlabel->offbout ) = ((( pflabel )(fd.blabels.data + curlabel->link ))->offbout)/sizeof(uint); if ( !isreturn ) { //Помечаем метку как отработавшую (на неё был переход) (( pflabel )(fd.blabels.data + curlabel->link ))->type |= LABT_LABELWORK; } } else if ( curlabel->type & LABT_RETURN ) isreturn = 1;//Устанавливаем флаг else if ( curlabel->type & LABT_LABELWORK ) isreturn = 0;//Если была отработавшая метка, то сбрасываем флаг curlabel++; } fd.blabels.use = offblabels; //Проверка выходов из функции if ( fd.functype ) { if ( !isreturn ) msg( MMustret | MSG_LEXNAMEERR, lexname ); } else if ( !isreturn ) out_adduint( CSubreturn ); //Восстановление данных _compile->pout = fd.bout = &fd.bfuncout; fd.functype = fd_functype; fd.funcoftype = fd_funcoftype; return curlex; }