int validatorSentence(char *sentence){ char a; int i = 0; int openBrackets = 0; int closedBrackets = 0; int operator = 0; a = sentence[i++]; while(a != '\0'){ if(!isNumber(a) && !isOperator(a) && !isBracket(a)){ printf("invalid chars\n"); return 0; }else if(isOperator(a)){ if(operator){ printf("invalid input operators %c\n", a); return 0; } operator++; } else if(isNumber(a)){ operator = 0; }else if(isBracket(a)){ operator = 0; if(a == ASC_OPEN_BRACKET){ openBrackets++; }else{ closedBrackets++; } if(closedBrackets > openBrackets){ printf("invalid Brackets\n"); return 0; } } a = sentence[i++]; } if(openBrackets != closedBrackets){ printf("invalid Bracket without match\n"); return 0; }else if(operator){ printf("invalid input operator end of input\n"); return 0; } return 1; }
DMJSON * Parser::parseCode(char* code_char_string, int string_length) { indicator_stack_top = 0; CodeIndicator * indicator = indicator_stack + indicator_stack_top; //current indicator DMJSON * root = this->json_pool->getDMJSON(); root->type = 34; indicator->code = root; indicator->parse_status = 14; DMString * code_string = newDMString(string_length); code_string->copy(code_char_string, string_length); char* char_string = code_string->char_string; char preChar; char localChar = 0; char nextChar; int last_index = 0; int i = -1; int line_number = 0; while (true) { if (i >= string_length) { break; } else { i++; } if (last_index > i) { continue; } preChar = localChar; localChar = char_string[i]; nextChar = char_string[i + 1]; if (localChar == '\n') { line_number++; } if (indicator->parse_status == 51) { //@operator@ if (isOperator(localChar)) { continue; } indicator->end = i; DMString * dm_string = parseDMString(char_string, indicator); dm_string->type = TYPE_CODE_OPERATOR; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; pushMeta((MemorySpace *) dm_string, indicator); last_index = i; } if (indicator->parse_status == 41) { //"string" int string_state = checkString(preChar, localChar, nextChar); if (string_state == 0 || indicator->flag != string_state || indicator->start + 1 > i) { continue; } if (string_state % 10 == 1) { indicator->end = i; last_index = i + 1; } else if (string_state % 10 == 3) { indicator->end = i - 1; last_index = i + 2; } DMString * dm_string = parseDMString(char_string, indicator); clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; pushMeta((MemorySpace *) dm_string, indicator); continue; } if (indicator->parse_status == 61) { // //comments if (isLineEnd(localChar)) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 2; } else { continue; } } if (isLetter(localChar)) { if (indicator->isInLine == NOT_IN_LINE) { indicator->isInLine = IN_LINE; } if (indicator->isInWord == NOT_IN_WORD) { indicator->isInWord = IN_WORD; } continue; } else { if (indicator->isInWord == IN_WORD && indicator->isInLine == IN_LINE) { if (last_index < i) { MemorySpace * element = parseElement(char_string, last_index, i); pushMeta(element, indicator); } last_index = i + 1; indicator->isInWord = NOT_IN_WORD; } } if (indicator->parse_status != 74) { if (indicator->includer == NULL) { } else if (indicator->includer->type == 80) { DMJSON * last_includer = indicator->includer; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->parse_status = 74; indicator->includer = last_includer; indicator->isInLine = IN_LINE; } else if (indicator->includer->type == 33) { DMJSON * last_includer = indicator->includer; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->parse_status = 33; indicator->code = last_includer; indicator->isInLine = IN_LINE; } else { } } if (isLineEnd(localChar)) { if (indicator->isInLine == NOT_IN_LINE) { last_index = i + 1; continue; } else { indicator->isInLine = NOT_IN_LINE; } if (indicator->parse_status == 74) { DMJSON * last_expression = indicator->includer; MemorySpace * last_meta = last_expression->get(-1, NOT_DEL); if (last_meta == NULL) { } else if (last_meta->type == TYPE_CODE_OPERATOR) { continue; } clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; MemorySpace * element = resolveExpression(last_expression); pushElement(element, indicator); indicator->includer = NULL; } if (indicator->parse_status == 33) { DMJSON* functionReturn = indicator->code; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; pushElement(functionReturn->self, indicator); indicator->includer = NULL; } if (indicator->parse_status == 81) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; } last_index = i + 1; continue; } if (isBlank(localChar)) { if (indicator->isInWord == NOT_IN_WORD) { last_index = i + 1; continue; } if (indicator->parse_status == 31) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 1; continue; } if (indicator->parse_status == 32) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 1; continue; } if (indicator->parse_status == 33) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 1; continue; } if (indicator->parse_status == 22) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 1; continue; } last_index = i + 1; continue; } if (isSeparator(localChar)) { if (indicator->parse_status == 74) { DMJSON * last_expression = indicator->includer; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; MemorySpace * element = resolveExpression(last_expression); pushElement(element, indicator); indicator->includer = NULL; } if (indicator->parse_status == 81) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; } if (indicator->parse_status == 12) { DMJSON * last_function_definition = indicator->includer; if (last_function_definition == NULL) { } else if (last_function_definition->type == 30) { pushElement(last_function_definition->self, indicator); indicator->includer = NULL; } else { //syntax error } } last_index = i + 1; continue; } if (localChar == ':') { MemorySpace * key = NULL; if (indicator->parse_status == 74) { DMJSON * last_expression = indicator->includer; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; MemorySpace * element = resolveExpression(last_expression); if (element->type == TYPE_CODE_NAME) { key = element; CodeName * key_name = (CodeName *) key; key_name->nameType = 0x99; } else if (element->type == TYPE_STRING) { key = element; key->type = TYPE_CODE_NAME; CodeName * key_name = (CodeName *) key; key_name->nameType = 0x99; } else { //syntax error } indicator->includer = NULL; last_index = i + 1; } if (key != NULL && (indicator->parse_status == 11 || indicator->parse_status == 21)) { DMKeyValue * key_value = newDMKeyValue(); key_value->key = key; DMJSON * parent = indicator->code; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->key_value = key_value; indicator->parse_status = 81; parent->set(-1, key_value->self, NOT_REPLACE); } last_index = i + 1; continue; } int string_state = checkString(preChar, localChar, nextChar); if (0 != string_state) { if (indicator->parse_status != 41) { if (string_state == 12 || string_state == 22) { DMString * dm_string = newDMString(0); pushMeta((MemorySpace *) dm_string, indicator); last_index = i + 1; continue; } indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->parse_status = 41; indicator->flag = string_state; if (string_state % 10 == 1) { indicator->start = i + 1; } else if (string_state % 10 == 3) { indicator->start = i + 2; } continue; } else { //logic error } } if (localChar == '/' && nextChar == '/') { indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->parse_status = 61; last_index = i + 1; continue; } if (isBracket(localChar)) { if (localChar == '{') { if (indicator->includer == NULL) { DMJSON* includer = this->json_pool->getDMJSON(); includer->type = 80; indicator->includer = includer; } DMJSON * last_includer = indicator->includer; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->start = i; if (last_includer != NULL && last_includer->type == 20) { indicator->parse_status = 12; indicator->code = last_includer; } else if (last_includer != NULL && last_includer->type == 30) { indicator->parse_status = 13; indicator->code = last_includer; } else if (last_includer != NULL && last_includer->type / 10 == 4) { indicator->parse_status = 14; indicator->code = last_includer; } else { indicator->parse_status = 11; DMJSON* json = this->json_pool->getDMJSON(); json->type = 0; indicator->code = json; last_includer->set(-1, json->self, NOT_REPLACE); } last_index = i + 1; continue; } if (localChar == '}') { if (indicator->parse_status == 74) { DMJSON * last_expression = indicator->includer; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; MemorySpace * element = resolveExpression(last_expression); pushElement(element, indicator); indicator->includer = NULL; } if (indicator->parse_status == 81) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 1; } if (indicator->parse_status / 10 != 1) { //syntax error break; } DMJSON * code = indicator->code; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; if (indicator->parse_status == 11 && code->type == 0) { } else if (indicator->parse_status == 12 || indicator->parse_status == 13 || indicator->parse_status == 14) { pushElement(code->self, indicator); indicator->includer = NULL; } else if (indicator->parse_status == 74) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; } last_index = i + 1; continue; } if (localChar == '[') { if (indicator->includer == NULL) { DMJSON* includer = this->json_pool->getDMJSON(); includer->type = 80; indicator->includer = includer; } CodeIndicator * last_indicator = indicator; DMJSON * last_includer = indicator->includer; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->start = i; MemorySpace * last_meta = last_indicator->last_meta; if (last_meta == NULL) { if (last_includer != NULL) { last_meta = last_includer->get(-1, NOT_DEL); } } if (last_meta == NULL) { //21:[json] indicator->parse_status = 21; DMJSON* json = this->json_pool->getDMJSON(); json->type = 0; indicator->code = json; last_includer->set(-1, json->self, NOT_REPLACE); } else if (last_meta->type == TYPE_CODE_KEYWORD) { //has with 22:[enum] in: 21:[json] DMString *last_keyword = (DMString *) last_meta; if (*last_keyword == "with" || *last_keyword == "has") { indicator->parse_status = 22; DMJSON* enumDefinition = this->json_pool->getDMJSON(); enumDefinition->type = 61; indicator->code = enumDefinition; last_includer->set(-1, enumDefinition->self, NOT_REPLACE); } else if (*last_keyword == "in" || *last_keyword == "import") { indicator->parse_status = 21; DMJSON* json = this->json_pool->getDMJSON(); json->type = 0; indicator->code = json; last_includer->set(-1, json->self, NOT_REPLACE); } else { //syntax error break; } } else if (last_meta->type == TYPE_CODE_NAME) { //23:[key|index|selector], indicator->parse_status = 23; DMJSON* selector = this->json_pool->getDMJSON(); selector->type = 71; indicator->code = selector; last_includer->set(-1, selector->self, NOT_REPLACE); } else { //21:[json] indicator->parse_status = 21; DMJSON* json = this->json_pool->getDMJSON(); json->type = 0; indicator->code = json; last_includer->set(-1, json->self, NOT_REPLACE); } last_index = i + 1; continue; } if (localChar == ']') { if (indicator->parse_status == 74) { DMJSON * last_expression = indicator->includer; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; MemorySpace * element = resolveExpression(last_expression); pushElement(element, indicator); indicator->includer = NULL; } if (indicator->parse_status == 81) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; last_index = i + 1; } if (indicator->parse_status / 10 != 2) { //syntax error break; } DMJSON * code = indicator->code; CodeIndicator * last_indicator = indicator; indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; clearCodeIndicator(last_indicator); if (indicator->parse_status == 21 && code->type == 0) { } else if (indicator->parse_status == 12 || indicator->parse_status == 13 || indicator->parse_status == 14) { pushElement(code->self, indicator); indicator->includer = NULL; } else if (indicator->parse_status == 74) { clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; } last_index = i + 1; continue; } if (localChar == '(') { if (indicator->includer == NULL) { DMJSON* includer = this->json_pool->getDMJSON(); includer->type = 80; indicator->includer = includer; } CodeIndicator * last_indicator = indicator; if (last_indicator->parse_status == 33) { last_index = i + 1; continue; } DMJSON * last_includer = indicator->includer; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->start = i; if (last_includer != NULL && last_includer->type == 30) { indicator->parse_status = 31; indicator->code = last_includer; } else if (last_includer != NULL && last_includer->type / 10 == 4) { indicator->parse_status = 35; indicator->code = last_includer; // last_includer->set(-1, last_includer->self, NOT_REPLACE); } else if (last_includer != NULL && last_includer->type == 33) { indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; if (indicator->parse_status != 33) { //syntax error break; } } else { MemorySpace * last_meta = last_includer->get(-1, NOT_DEL); if (last_meta != NULL && last_meta->type == TYPE_CODE_NAME) { //function call () if (last_includer->dm_list->length > 0) { CodeName * function_name = (CodeName *) last_includer->get(-1, DEL); if (function_name->nameType != 0x82 || function_name->nameType != 0x83) { function_name->nameType = 0x81; } DMJSON * functionCall = this->json_pool->getDMJSON(); functionCall->type = 32; functionCall->name = (DMString *) function_name; indicator->parse_status = 32; indicator->code = functionCall; last_includer->set(-1, functionCall->self, NOT_REPLACE); } else { //syntax error break; } } else if (last_meta != NULL && last_meta->type == TYPE_JSON) { //Anonymous function definition if (last_includer->dm_list->length > 0) { MemorySpace * function_definition_space = last_includer->get(-1, NOT_DEL); DMJSON * functionDefinition = (DMJSON *) function_definition_space->pointer; if (functionDefinition->type != 30) { //syntax error break; } MemorySpace * name = last_includer->get(-3, NOT_DEL); if (name == NULL && indicator_stack_top >= 2) { CodeIndicator * last_last_indicator = indicator_stack + indicator_stack_top - 2; if (last_last_indicator->parse_status == 81 && last_last_indicator->key_value != NULL) { name = last_last_indicator->key_value->key; } } if (name == NULL) { functionDefinition->name = this->helper->no_name; } else if (name->type == TYPE_JSON) { DMJSON * selector = (DMJSON *) name->pointer; if (selector->type != 71) { //syntax error } DMString * function_name = (DMString *) selector->get(-1, NOT_DEL); if (function_name == NULL) { functionDefinition->name = this->helper->no_name; } else if (function_name->type == TYPE_CODE_NAME || function_name->type == TYPE_STRING) { functionDefinition->name = function_name; } else { functionDefinition->name = this->helper->no_name; } } else if (name->type == TYPE_CODE_NAME) { DMString * function_name = spliteFunctionName((DMString *) name); functionDefinition->name = function_name; } else { //syntax error break; } indicator->parse_status = 74; indicator->includer = functionDefinition; indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->parse_status = 31; indicator->code = functionDefinition; } else { //syntax error break; } } else { //expression () DMJSON * expression = this->json_pool->getDMJSON(); expression->type = 10; indicator->parse_status = 34; indicator->includer = expression; last_includer->set(-1, expression->self, NOT_REPLACE); } } last_index = i + 1; continue; } if (localChar == ')') { if (indicator->parse_status == 74) { DMJSON * last_expression = indicator->includer; clearCodeIndicator(indicator); indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; MemorySpace * element = resolveExpression(last_expression); pushElement(element, indicator); indicator->includer = NULL; } CodeIndicator * last_indicator = indicator; indicator_stack_top--; indicator = indicator_stack + indicator_stack_top; if (last_indicator->parse_status == 31) { last_indicator->code->block_start = last_indicator->code->dm_list->length; } else if (last_indicator->parse_status == 32) { } else if (last_indicator->parse_status == 33) { DMJSON* functionReturn = last_indicator->code; pushElement(functionReturn->self, indicator); indicator->includer = NULL; } else if (last_indicator->parse_status == 34) { } else if (last_indicator->parse_status == 35) { last_indicator->code->block_start = last_indicator->code->dm_list->length; } else { //syntax error break; } clearCodeIndicator(last_indicator); last_index = i + 1; continue; } } if (isOperator(localChar)) { if (indicator->parse_status != 51) { indicator_stack_top++; indicator = indicator_stack + indicator_stack_top; indicator->parse_status = 51; indicator->start = i; last_index = i; continue; } } } return root; }
void Tokenizer::shift() { mpCurrent.reset(); if (mBlockComment) { skipEOL(); } else { skipWhiteSpaces(); if (mpInput->eof()) return; } mpCurrent.reset(new Token); mpCurrent->setLine(line()); mpCurrent->setBeginColumn(column()); if (mBlockComment) { consumeCStyleBlockComment(); return; } auto ch = mpInput->get(); if (isLetter(ch) || isUnderscore(ch)) { consumeIdentifier(ch); } else if (isBiwiseOperatorSymbol(ch)) { mpCurrent->setType(Token::TYPE_BITWISE_OPERATOR); absorbed(ch); mpCurrent->addChar(ch); mpCurrent->setEndColumn(column()); } else if (isDot(ch) && consumeDot(ch)) { // nothing } else if ((isDecimalDigit(ch) || isDot(ch) || isSign(ch)) && consumeNumber(ch)) { // nothing } else if (isQuotationMark(ch)) { if (!consumeString(ch)) shift(); } else if (isCStyleInitialCommentChar(ch)) { consumeComment(ch); } else if (isArrowSymbol(ch) && consumeArrow(ch)) { // nothing } else if (isBracket(ch)) { mpCurrent->setType(Token::TYPE_BRACKET); absorbed(ch); mpCurrent->addChar(ch); mpCurrent->setEndColumn(column()); } else if (isAngleBracket(ch)) { mpCurrent->setType(Token::TYPE_ANGLE_BRACKET); absorbed(ch); mpCurrent->addChar(ch); mpCurrent->setEndColumn(column()); } else if (isDelimiter(ch)) { mpCurrent->setType(Token::TYPE_DELIMITER); absorbed(ch); mpCurrent->addChar(ch); mpCurrent->setEndColumn(column()); } else if (isOperator(ch) && consumeEqualOperator(ch)) { // nothing } else if (isOperator(ch)) { mpCurrent->setType(Token::TYPE_OPERATOR); absorbed(ch); mpCurrent->addChar(ch); mpCurrent->setEndColumn(column()); } else if (isAsterisk(ch)) { mpCurrent->setType(Token::TYPE_ASTERISK); absorbed(ch); mpCurrent->addChar(ch); mpCurrent->setEndColumn(column()); } else { mpCurrent.reset(); } }
void Editor::updateFocus() { focus.clear(); //if (caret != selStart) // return; POINT pt = toPoint(caret); int ctx = lines[pt.y].ctx; int ctxType = lines[pt.y].ctxType; wchar_t const* text = lines[pt.y].text.c_str(); int pos = 0; while (pos < pt.x && text[pos]) { if (ctx) { if (text[pos] == ']') { pos++; int count = 0; while (text[pos] == '=' && count < ctxType) pos++, count++; if (text[pos] == ']' && count == ctxType) { pos++; ctx = 0; ctxType = 0; } } else pos++; } else { if (text[pos] == '[') { pos++; while (text[pos] == '=') pos++, ctxType++; if (text[pos] == '[') { pos++; ctx = ctxString; } else ctxType = 0; } else if (text[pos] == '-' && text[pos + 1] == '-') { pos += 2; if (text[pos] == '[') { pos++; while (text[pos] == '=') pos++, ctxType++; if (text[pos] == '[') { pos++; ctx = ctxComment; } else return; } else return; } else if (text[pos] == '"' || text[pos] == '\'') { wchar_t end = text[pos++]; while (text[pos] && text[pos] != end) { if (text[pos] == '\\') pos++; if (text[pos]) pos++; } if (text[pos]) pos++; } else pos++; } } if (pos > pt.x || ctx) return; if (text[pt.x] == '[') { int pos = pt.x + 1; while (text[pos] == '=') pos++; if (text[pos] == '[') return; } int start = pt.x; int type = 0; WideString kw; if (isBracket(lines[pt.y].text[pt.x])) type = 1; else { int end = start; while (start > 0 && iswalpha(lines[pt.y].text[start - 1])) start--; while (iswalpha(lines[pt.y].text[end])) end++; kw = lines[pt.y].text.substring(start, end); if (keywords.has(kw)) type = -1; } if (type == 0 && pt.x > 0 && isBracket(lines[pt.y].text[pt.x - 1])) { start = pt.x - 1; type = 1; } pt.x = start; if (type == 1) { int stack = 1; wchar_t fwd = lines[pt.y].text[start]; wchar_t rev = isBracket(fwd); bool forward = (fwd == '(' || fwd == '[' || fwd == '{'); while (stack > 0) { WideString brk = (forward ? nextKey(pt, true) : prevKey(pt, true)); if (brk.length() == 0 || pt.y < 0 || pt.y >= lines.length()) break; if (brk[0] == fwd) stack++; else if (brk[0] == rev) stack--; } if (stack == 0) { focus.push(FocusWord(fromPoint(pt), 1)); pt = toPoint(caret); pt.x = start; focus.push(FocusWord(fromPoint(pt), 1)); } } else if (type == -1 && kwInGraph.has(kw)) { Array<WideString> stk; stk.push(kw); POINT save = pt; while (stk.length() && pt.y < lines.length()) { WideString next = nextKey(pt, false); if (next.length() == 0) break; if (inKwGraph(stk.top(), next)) { if (stk.length() == 1) focus.push(FocusWord(fromPoint(pt), next.length())); stk.top() = next; } else if (kwBegin.has(next)) stk.push(next); if (kwEnd.has(stk.top())) stk.pop(); } pt = save; stk.clear(); stk.push(kw); while (stk.length() && pt.y >= 0) { WideString prev = prevKey(pt, false); if (prev.length() == 0) break; if (inKwGraph(prev, stk.top())) { if (stk.length() == 1) focus.push(FocusWord(fromPoint(pt), prev.length())); stk.top() = prev; } else if (kwEnd.has(prev)) stk.push(prev); if (kwBegin.has(stk.top()) && (stk.top() != L"do" || stk.length() > 1)) stk.pop(); } if (focus.length()) { pt = toPoint(caret); pt.x = start; focus.push(FocusWord(fromPoint(pt), kw.length())); } } focus.sort(); }
WideString Editor::nextKey(POINT& pt, bool bracket) { pt.x++; int ctx = 0; int ctxType = 0; while (pt.y < lines.length()) { if (pt.x >= lines[pt.y].text.length()) { pt.x = 0; pt.y++; } else { wchar_t const* text = lines[pt.y].text.c_str(); if (ctx) { if (text[pt.x] == ']') { pt.x++; int count = 0; while (text[pt.x] == '=' && count < ctxType) pt.x++, count++; if (text[pt.x] == ']' && count == ctxType) { pt.x++; ctx = 0; ctxType = 0; } } else pt.x++; } else { if (text[pt.x] == '[') { int start = pt.x; pt.x++; while (text[pt.x] == '=') pt.x++, ctxType++; if (text[pt.x] == '[') { pt.x++; ctx = ctxString; } else { if (bracket) { pt.x = start; return L"["; } ctxType = 0; } } else if (text[pt.x] == '-' && text[pt.x + 1] == '-') { pt.x += 2; if (text[pt.x] == '[') { pt.x++; while (text[pt.x] == '=') pt.x++, ctxType++; if (text[pt.x] == '[') { pt.x++; ctx = ctxComment; } else { ctxType = 0; pt.x = lines[pt.y].text.length(); } } else { ctxType = 0; pt.x = lines[pt.y].text.length(); } } else if (text[pt.x] == '"' || text[pt.x] == '\'') { wchar_t end = text[pt.x++]; while (text[pt.x] && text[pt.x] != end) { if (text[pt.x] == '\\') pt.x++; pt.x++; } if (text[pt.x]) pt.x++; } else if (bracket && isBracket(text[pt.x])) return WideString(text[pt.x]); else if (!bracket && iswalpha(text[pt.x]) && (pt.x == 0 || !iswalpha(text[pt.x - 1]))) { int end = pt.x + 1; while (iswalpha(text[end])) end++; WideString kw = lines[pt.y].text.substring(pt.x, end); if (keywords.has(kw)) return kw; pt.x = end; } else pt.x++; } } } return L""; }
WideString Editor::prevKey(POINT& pt, bool bracket) { pt.x--; int ctx = 0; int ctxType = 0; while (pt.y >= 0) { if (pt.x < 0) { pt.y--; if (pt.y < 0) break; pt.x = lines[pt.y].text.length() - 1; if (lines[pt.y].endComment >= 0) pt.x = lines[pt.y].endComment; } else { wchar_t const* text = lines[pt.y].text.c_str(); if (ctx) { if (text[pt.x] == '[') { pt.x--; int count = 0; while (pt.x >= 0 && text[pt.x] == '=' && count < ctxType) pt.x--, count++; if (pt.x >= 0 && text[pt.x] == '[' && count == ctxType) { pt.x--; if (pt.x >= 1 && text[pt.x] == '-' && text[pt.x - 1] == '-') pt.x -= 2; ctx = 0; ctxType = 0; } } else pt.x--; } else { if (text[pt.x] == ']') { int start = pt.x; pt.x--; while (pt.x >= 0 && text[pt.x] == '=') pt.x--, ctxType++; if (pt.x >= 0 && text[pt.x] == ']') { pt.x--; ctx = ctxString; } else { if (bracket) { pt.x = start; return L"]"; } ctxType = 0; } } else if (text[pt.x] == '"' || text[pt.x] == '\'') { wchar_t end = text[pt.x--]; while (pt.x >= 0) { if (text[pt.x] == end) { int cur = pt.x; while (cur > 0 && text[cur - 1] == '\\') cur--; if (((pt.x - cur) & 1) == 0) break; } pt.x--; } pt.x--; } else if (bracket && isBracket(text[pt.x])) return WideString(text[pt.x]); else if (!bracket && iswalpha(text[pt.x])) { int end = pt.x + 1; while (pt.x > 0 && iswalpha(text[pt.x - 1])) pt.x--; while (iswalpha(text[end])) end++; WideString kw = lines[pt.y].text.substring(pt.x, end); if (keywords.has(kw)) return kw; pt.x--; } else pt.x--; } } } return L""; }