예제 #1
0
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);
} // }}}
예제 #2
0
	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();
	}