void ib::Completer::completeOption(std::vector<ib::CompletionValue*> &candidates, const std::string &command) { // {{{ if(!hasCompletionFunc(command)) return; auto maininput = ib::Singleton<ib::MainWindow>::getInstance()->getInput(); const auto &input = maininput->getCursorValue(); const auto &tokens = maininput->getTokens(); const auto token = maininput->getCursorToken(); const unsigned int position = maininput->position(); method_option_->beforeMatch(candidates, input); const auto start = lua_gettop(IB_LUA); lua_getglobal(IB_LUA, "system"); lua_getfield(IB_LUA, -1, "completer"); lua_getfield(IB_LUA, -1, "option_func"); lua_getfield(IB_LUA, -1, command.c_str()); lua_newtable(IB_LUA); const auto top = lua_gettop(IB_LUA); int i = 1; int current_index = 1; unsigned int token_index = 1; // 0 is command name for(; token_index < tokens.size(); token_index++){ const auto token = tokens.at(token_index); const auto is_current = token->getStartPos() < position && token->getEndPos() >= position; const auto is_last = (tokens.size() - 1 == token_index); if(token->isValueToken()) { lua_pushinteger(IB_LUA, i); lua_pushstring(IB_LUA, token->getValue().c_str()); lua_settable(IB_LUA, top); if(is_current) current_index = i; i++; } else if(is_current){ current_index = i; if(is_last){ lua_pushinteger(IB_LUA, i); lua_pushstring(IB_LUA, ""); lua_settable(IB_LUA, top); i++; } } } lua_pushinteger(IB_LUA, current_index); if(lua_pcall(IB_LUA, 2, 1, 0) != 0){ ib::utils::message_box("%s", lua_tostring(IB_LUA, lua_gettop(IB_LUA))); return; } if(!lua_istable(IB_LUA, -1)) { ib::utils::message_box("Completion function must return a table, but got a(n) %s", lua_typename(IB_LUA, lua_type(IB_LUA, -1))); return; } for(i = 1;;i++){ lua_pushinteger(IB_LUA, i); lua_gettable(IB_LUA, -2); if(lua_isnil(IB_LUA, -1)){ lua_pop(IB_LUA, 1); break; } switch(lua_type(IB_LUA, -1)) { case LUA_TSTRING: { const auto value = luaL_checkstring(IB_LUA, -1); if(!token->isValueToken() || method_option_->match(value, input) > -1){ candidates.push_back(new ib::CompletionString(value)); } } break; case LUA_TTABLE: { lua_getfield(IB_LUA, -1, "value"); const auto value = luaL_checkstring(IB_LUA, -1); lua_pop(IB_LUA, 1); lua_getfield(IB_LUA, -1, "always_match"); const auto is_always_match = lua_toboolean(IB_LUA, -1); lua_pop(IB_LUA, 1); if(is_always_match || !token->isValueToken() || method_option_->match(value, input) > -1){ ib::CompletionString *compstr = new ib::CompletionString(value); lua_getfield(IB_LUA, -1, "description"); if(!lua_isnil(IB_LUA, -1)){ compstr->setDescription(luaL_checkstring(IB_LUA, -1)); } lua_pop(IB_LUA, 1); lua_getfield(IB_LUA, -1, "icon"); if(!lua_isnil(IB_LUA, -1)){ compstr->setIconFile(luaL_checkstring(IB_LUA, -1)); } lua_pop(IB_LUA, 1); if(is_always_match) { if(token->isValueToken()) { compstr->setCompvalue(input.c_str()); }else { compstr->setCompvalue(value); } } candidates.push_back(compstr); } } break; default: ; } lua_pop(IB_LUA, 1); } lua_pop(IB_LUA, lua_gettop(IB_LUA) - start); method_option_->afterMatch(candidates, input); } // }}}
Compiler::llvmObject Compiler::compile(parsing::AST ast) { TRACE_INDATA(ast.display()); for (unsigned int i = 0; i < ast.size(); i++) { if (ast[i].size() == 0 && symbols.find(ast[i].getContent().get()) != symbols.end()) { TRACE_COUT("found symbol - " << ast[i].getContent().get() << "\n"); if (ast[i+1].size() == 0 && ast[i+1].getContent().get().compare("(") == 0) { TRACE_COUT(" with arguments...\n"); vector<parsing::AST> args = tokenizeAST(ast[i+2], ","); for (vector<parsing::AST>::iterator j = args.begin(); j != args.end(); j++) { if (j->size() == 0) { errors.push_back(parsing::ASTError(ast[i+1].getContent(), "empty argument")); return llvmObjectNull(); } else { llvmObject tmp = compile(*j); } } if (ast[i+3].size() != 0 || ast[i+3].getContent().get().compare(")") != 0) { errors.push_back(parsing::ASTError(ast[i+3].getContent(), "expected a right parenthesis")); } if (ast[i+4].size() != 0 || ast[i+4].getContent().get().compare(";") != 0) { errors.push_back(parsing::ASTError(ast[i+4].getContent(), "expected a semicolon")); } } else if (ast[i+1].size() == 0 && ast[i+1].getContent().get().compare(";") == 0) { TRACE_COUT(" line ends...\n"); } else if (ast[i+1].size() == 0 && ast[i+1].getContent().get().compare("=") == 0) { TRACE_COUT("found assignment of expression - " << ast[i+1].getContent().get() << "\n"); } else { errors.push_back(parsing::ASTError(ast[i+1].getContent(), "unexpected token")); return llvmObjectNull(); } } else if (ast[i].size() == 0 && types.find(ast[i].getContent().get()) != types.end()) { TRACE_COUT("found type - " << ast[i].getContent().get() << "\n"); for (i++; i < ast.size(); i++) { if (ast[i].size() == 0 && types.find(ast[i].getContent().get()) != types.end()) { TRACE_COUT("found type - " << ast[i].getContent().get() << "\n"); } else if (ast[i].size() == 0 && ast[i].getContent().get().compare("(") == 0) { if (ast[i+1].size() == 0) { errors.push_back(parsing::ASTError(ast[i].getContent(), "expected scope, but got a leaf")); return llvmObjectNull(); } else { llvmObject tmp = compile(ast[i+1]); } if (ast[i+2].size() != 0 || ast[i+2].getContent().get().compare(")") != 0) { errors.push_back(parsing::ASTError(ast[i+2].getContent(), "expected a left parenthesis")); return llvmObjectNull(); } } else if (ast[i].size() == 0 && isSymbolToken(ast[i].getContent())) { TRACE_COUT("found symbol after types - " << ast[i].getContent().get() << "\n"); addSymbol(ast[i].getContent().get()); break; } else { errors.push_back(parsing::ASTError(ast[i].getContent(), "expected either type, type expression, or an expression symbol")); return llvmObjectNull(); } } } else if (ast[i].size() == 0 && isValueToken(ast[i].getContent())) { TRACE_COUT("found value - " << ast[i].getContent().get() << "\n"); } else if (ast[i].size() == 0 && isOperatorToken(ast[i].getContent())) { TRACE_COUT("found operator - " << ast[i].getContent().get() << "\n"); if (ast[i].getContent().get().compare("!") == 0 || ast[i].getContent().get().compare("~") == 0) { TRACE_COUT(" unary right operation\n"); } else if (ast[i].getContent().get().compare("++") == 0 || ast[i].getContent().get().compare("--") == 0) { TRACE_COUT(" unary left operation\n"); } else { TRACE_COUT(" binary operation\n"); } } } return llvmObjectNull(); }