Exemplo n.º 1
0
static bool change_frame(struct luadebug_debugger *session, const char *option)
{
	const int index = option ? atoi(option) : session->frame_index;

	if (!lua_getstack(session->L, index, &session->frame)) {
		session->user->print(session->user, RED "invalid frame index '%d'\n" CLEAR, index);
	}
	else {
		UNUSED int env_index;

		session->user->print(session->user, "  #%d\t" CYAN, index);
		dump_frame(session->L, &session->frame, session->user);

		session->frame_index = index;

		env_index = capture_env(session->L, index);
		assert(env_index != -1);

		lua_replace(session->L, session->env_index);

		session->list_line = session->frame.currentline - LIST_DEFAULT_LINE/2;
	}

	return false;
}
Exemplo n.º 2
0
//------------------------------------------------------------------------------
static void apply_env(const env_block_t* block)
{
    env_block_t to_clear;

    capture_env(&to_clear);
    apply_env_impl(&to_clear, 1);
    free_env(&to_clear);

    apply_env_impl(block, 0);
}
Exemplo n.º 3
0
//------------------------------------------------------------------------------
void prepare_env_for_inputrc()
{
    // Give readline a chance to find the inputrc by modifying the
    // environment slightly.

    char buffer[1024];
    void* env_handle;
    env_block_t env_block;

    capture_env(&env_block);

    // HOME is where Readline will expand ~ to.
    {
        static const char home_eq[] = "HOME=";
        int size = sizeof_array(home_eq);

        strcpy(buffer, home_eq);
        get_config_dir(buffer + size - 1, sizeof_array(buffer) - size);

        putenv(buffer);
    }

    // INPUTRC is the path where looks for it's configuration file.
    {
        static const char inputrc_eq[] = "INPUTRC=";
        int size = sizeof_array(inputrc_eq);

        strcpy(buffer, inputrc_eq);
        get_dll_dir(buffer + size - 1, sizeof_array(buffer) - size);
        str_cat(buffer, "/clink_inputrc_base", sizeof_array(buffer));

        putenv(buffer);
    }

    apply_env(&env_block);
    free_env(&env_block);
}
Exemplo n.º 4
0
static SCM
memoize (SCM exp, SCM env)
{
  if (!SCM_EXPANDED_P (exp))
    abort ();

  switch (SCM_EXPANDED_TYPE (exp))
    {
    case SCM_EXPANDED_VOID:
      return MAKMEMO_QUOTE (SCM_UNSPECIFIED);
      
    case SCM_EXPANDED_CONST:
      return MAKMEMO_QUOTE (REF (exp, CONST, EXP));

    case SCM_EXPANDED_PRIMITIVE_REF:
      if (scm_is_eq (scm_current_module (), scm_the_root_module ()))
        return maybe_makmemo_capture_module
          (MAKMEMO_BOX_REF (MAKMEMO_TOP_BOX (SCM_EXPANDED_TOPLEVEL_REF,
                                             REF (exp, PRIMITIVE_REF, NAME))),
           env);
      else
        return MAKMEMO_BOX_REF (MAKMEMO_MOD_BOX (SCM_EXPANDED_MODULE_REF,
                                                 list_of_guile,
                                                 REF (exp, PRIMITIVE_REF, NAME),
                                                 SCM_BOOL_F));
                                
    case SCM_EXPANDED_LEXICAL_REF:
      return MAKMEMO_LEX_REF (lookup (REF (exp, LEXICAL_REF, GENSYM), env));

    case SCM_EXPANDED_LEXICAL_SET:
      return MAKMEMO_LEX_SET (lookup (REF (exp, LEXICAL_SET, GENSYM), env),
                              memoize (REF (exp, LEXICAL_SET, EXP), env));

    case SCM_EXPANDED_MODULE_REF:
      return MAKMEMO_BOX_REF (MAKMEMO_MOD_BOX
                              (SCM_EXPANDED_MODULE_REF,
                               REF (exp, MODULE_REF, MOD),
                               REF (exp, MODULE_REF, NAME),
                               REF (exp, MODULE_REF, PUBLIC)));

    case SCM_EXPANDED_MODULE_SET:
      return MAKMEMO_BOX_SET (MAKMEMO_MOD_BOX
                              (SCM_EXPANDED_MODULE_SET,
                               REF (exp, MODULE_SET, MOD),
                               REF (exp, MODULE_SET, NAME),
                               REF (exp, MODULE_SET, PUBLIC)),
                              memoize (REF (exp, MODULE_SET, EXP), env));

    case SCM_EXPANDED_TOPLEVEL_REF:
      return maybe_makmemo_capture_module
        (MAKMEMO_BOX_REF (MAKMEMO_TOP_BOX (SCM_EXPANDED_TOPLEVEL_REF,
                                           REF (exp, TOPLEVEL_REF, NAME))),
         env);

    case SCM_EXPANDED_TOPLEVEL_SET:
      return maybe_makmemo_capture_module
        (MAKMEMO_BOX_SET (MAKMEMO_TOP_BOX (SCM_EXPANDED_TOPLEVEL_SET,
                                           REF (exp, TOPLEVEL_SET, NAME)),
                          memoize (REF (exp, TOPLEVEL_SET, EXP),
                                   capture_env (env))),
         env);

    case SCM_EXPANDED_TOPLEVEL_DEFINE:
      return maybe_makmemo_capture_module
        (MAKMEMO_BOX_SET (MAKMEMO_TOP_BOX (SCM_EXPANDED_TOPLEVEL_DEFINE,
                                           REF (exp, TOPLEVEL_DEFINE, NAME)),
                          memoize (REF (exp, TOPLEVEL_DEFINE, EXP),
                                   capture_env (env))),
         env);

    case SCM_EXPANDED_CONDITIONAL:
      return MAKMEMO_IF (memoize (REF (exp, CONDITIONAL, TEST), env),
                         memoize (REF (exp, CONDITIONAL, CONSEQUENT), env),
                         memoize (REF (exp, CONDITIONAL, ALTERNATE), env));

    case SCM_EXPANDED_CALL:
      {
        SCM proc, args;

        proc = REF (exp, CALL, PROC);
        args = memoize_exps (REF (exp, CALL, ARGS), env);

        return MAKMEMO_CALL (memoize (proc, env), args);
      }

    case SCM_EXPANDED_PRIMCALL:
      {
        SCM name, args;
        int nargs;

        name = REF (exp, PRIMCALL, NAME);
        args = memoize_exps (REF (exp, PRIMCALL, ARGS), env);
        nargs = scm_ilength (args);

        if (nargs == 3
            && scm_is_eq (name, scm_from_latin1_symbol ("call-with-prompt")))
          return MAKMEMO_CALL_WITH_PROMPT (CAR (args),
                                           CADR (args),
                                           CADDR (args));
        else if (nargs == 2
                 && scm_is_eq (name, scm_from_latin1_symbol ("apply")))
          return MAKMEMO_APPLY (CAR (args), CADR (args));
        else if (nargs == 1
                 && scm_is_eq (name,
                               scm_from_latin1_symbol
                               ("call-with-current-continuation")))
          return MAKMEMO_CONT (CAR (args));
        else if (nargs == 2
                 && scm_is_eq (name,
                               scm_from_latin1_symbol ("call-with-values")))
          return MAKMEMO_CALL_WITH_VALUES (CAR (args), CADR (args));
        else if (nargs == 1
                 && scm_is_eq (name,
                               scm_from_latin1_symbol ("variable-ref")))
          return MAKMEMO_BOX_REF (CAR (args));
        else if (nargs == 2
                 && scm_is_eq (name,
                               scm_from_latin1_symbol ("variable-set!")))
          return MAKMEMO_BOX_SET (CAR (args), CADR (args));
        else if (nargs == 2
                 && scm_is_eq (name, scm_from_latin1_symbol ("wind")))
          return MAKMEMO_CALL (MAKMEMO_QUOTE (wind), args);
        else if (nargs == 0
                 && scm_is_eq (name, scm_from_latin1_symbol ("unwind")))
          return MAKMEMO_CALL (MAKMEMO_QUOTE (unwind), SCM_EOL);
        else if (nargs == 2
                 && scm_is_eq (name, scm_from_latin1_symbol ("push-fluid")))
          return MAKMEMO_CALL (MAKMEMO_QUOTE (push_fluid), args);
        else if (nargs == 0
                 && scm_is_eq (name, scm_from_latin1_symbol ("pop-fluid")))
          return MAKMEMO_CALL (MAKMEMO_QUOTE (pop_fluid), SCM_EOL);
        else if (nargs == 1
                 && scm_is_eq (name,
                               scm_from_latin1_symbol ("push-dynamic-state")))
          return MAKMEMO_CALL (MAKMEMO_QUOTE (push_dynamic_state), args);
        else if (nargs == 0
                 && scm_is_eq (name,
                               scm_from_latin1_symbol ("pop-dynamic-state")))
          return MAKMEMO_CALL (MAKMEMO_QUOTE (pop_dynamic_state), SCM_EOL);
        else if (scm_is_eq (scm_current_module (), scm_the_root_module ()))
          return MAKMEMO_CALL (maybe_makmemo_capture_module
                               (MAKMEMO_BOX_REF
                                (MAKMEMO_TOP_BOX (SCM_EXPANDED_TOPLEVEL_REF,
                                                  name)),
                                env),
                               args);
        else
          return MAKMEMO_CALL (MAKMEMO_BOX_REF
                               (MAKMEMO_MOD_BOX (SCM_EXPANDED_MODULE_REF,
                                                 list_of_guile,
                                                 name,
                                                 SCM_BOOL_F)),
                               args);
      }

    case SCM_EXPANDED_SEQ:
      return MAKMEMO_SEQ (memoize (REF (exp, SEQ, HEAD), env),
                          memoize (REF (exp, SEQ, TAIL), env));

    case SCM_EXPANDED_LAMBDA:
      /* The body will be a lambda-case. */
      {
	SCM meta, body, proc, new_env;

	meta = REF (exp, LAMBDA, META);
        body = REF (exp, LAMBDA, BODY);
        new_env = push_flat_link (capture_env (env));
        proc = memoize (body, new_env);
        SCM_SETCAR (SCM_CDR (SCM_MEMOIZED_ARGS (proc)), meta);

	return maybe_makmemo_capture_module (capture_flat_env (proc, new_env),
                                             env);
      }

    case SCM_EXPANDED_LAMBDA_CASE:
      {
        SCM req, rest, opt, kw, inits, vars, body, alt;
        SCM unbound, arity, rib, new_env;
        int nreq, nopt, ninits;

        req = REF (exp, LAMBDA_CASE, REQ);
        rest = scm_not (scm_not (REF (exp, LAMBDA_CASE, REST)));
        opt = REF (exp, LAMBDA_CASE, OPT);
        kw = REF (exp, LAMBDA_CASE, KW);
        inits = REF (exp, LAMBDA_CASE, INITS);
        vars = REF (exp, LAMBDA_CASE, GENSYMS);
        body = REF (exp, LAMBDA_CASE, BODY);
        alt = REF (exp, LAMBDA_CASE, ALTERNATE);

        nreq = scm_ilength (req);
        nopt = scm_is_pair (opt) ? scm_ilength (opt) : 0;
        ninits = scm_ilength (inits);
        /* This relies on assignment conversion turning inits into a
           sequence of CONST expressions whose values are a unique
           "unbound" token.  */
        unbound = ninits ? REF (CAR (inits), CONST, EXP) : SCM_BOOL_F;
        rib = scm_vector (vars);
        new_env = push_nested_link (rib, env);

        if (scm_is_true (kw))
          {
            /* (aok? (kw name sym) ...) -> (aok? (kw . index) ...) */
            SCM aok = CAR (kw), indices = SCM_EOL;
            for (kw = CDR (kw); scm_is_pair (kw); kw = CDR (kw))
              {
                SCM k;
                int idx;

                k = CAR (CAR (kw));
                idx = lookup_rib (CADDR (CAR (kw)), rib);
                indices = scm_acons (k, SCM_I_MAKINUM (idx), indices);
              }
            kw = scm_cons (aok, scm_reverse_x (indices, SCM_UNDEFINED));
          }

        if (scm_is_false (alt) && scm_is_false (kw) && scm_is_false (opt))
          {
            if (scm_is_false (rest))
              arity = FIXED_ARITY (nreq);
            else
              arity = REST_ARITY (nreq, SCM_BOOL_T);
          }
        else if (scm_is_true (alt))
          arity = FULL_ARITY (nreq, rest, nopt, kw, ninits, unbound,
                              SCM_MEMOIZED_ARGS (memoize (alt, env)));
        else
          arity = FULL_ARITY (nreq, rest, nopt, kw, ninits, unbound,
                              SCM_BOOL_F);

        return MAKMEMO_LAMBDA (memoize (body, new_env), arity,
                               SCM_EOL /* meta, filled in later */);
      }

    case SCM_EXPANDED_LET:
      {
        SCM vars, exps, body, varsv, inits, new_env;
        int i;
        
        vars = REF (exp, LET, GENSYMS);
        exps = REF (exp, LET, VALS);
        body = REF (exp, LET, BODY);
        
        varsv = scm_vector (vars);
        inits = scm_c_make_vector (VECTOR_LENGTH (varsv),
                                   SCM_BOOL_F);
        new_env = push_nested_link (varsv, capture_env (env));
        for (i = 0; scm_is_pair (exps); exps = CDR (exps), i++)
          VECTOR_SET (inits, i, memoize (CAR (exps), env));

        return maybe_makmemo_capture_module
          (MAKMEMO_LET (inits, memoize (body, new_env)), env);
      }

    default:
      abort ();
    }
}
Exemplo n.º 5
0
void luadebug_interactive_enter(struct lua_State *L, const char *single, const char *multi,
		const char *msg)
{
	char *line, *full_line = NULL;
	bool multiline = false;
	bool stop = false;
	struct luadebug_interactive session;

	{
		mutex_lock(&current_user_mutex);
		session.user = current_user;

		if (!session.user) {
			message(HAKA_LOG_ERROR, L"interactive", L"no input/output handler");
			mutex_unlock(&current_user_mutex);
			return;
		}

		luadebug_user_addref(session.user);
		mutex_unlock(&current_user_mutex);
	}

	mutex_lock(&active_session_mutex);

	if (!single) single = ">  ";
	if (!multi) multi = ">> ";

	session.user->completion = completion;

	if (!session.user->start(session.user, "haka")) {
		on_user_error();
		luadebug_user_release(&session.user);
		mutex_unlock(&active_session_mutex);
		return;
	}

	current_session = &session;
	LUA_STACK_MARK(L);

	session.user->print(session.user, GREEN "entering interactive session" CLEAR ": %s\n", msg);

	session.L = L;
	session.env_index = capture_env(L, 1);
	assert(session.env_index != -1);

	session.complete.stack_env = session.env_index;

	while (!stop && (line = session.user->readline(session.user, multiline ? multi : single))) {
		int status = -1;
		bool is_return = false;
		char *current_line;

		if (multiline) {
			const size_t full_line_size = strlen(full_line);

			assert(full_line);

			full_line = realloc(full_line, full_line_size + 1 + strlen(line) + 1);
			full_line[full_line_size] = ' ';
			strcpy(full_line + full_line_size + 1, line);

			current_line = full_line;
		}
		else {
			session.user->addhistory(session.user, line);
			current_line = line;
		}

		while (*current_line == ' ' || *current_line == '\t') {
			++current_line;
		}

		is_return = (strncmp(current_line, "return ", 7) == 0) ||
				(strcmp(current_line, "return") == 0);

		if (!multiline && !is_return) {
			char *return_line = malloc(7 + strlen(current_line) + 1);
			strcpy(return_line, "return ");
			strcpy(return_line+7, current_line);

			status = luaL_loadbuffer(L, return_line, strlen(return_line), "stdin");
			if (status) {
				lua_pop(L, 1);
				status = -1;
			}

			free(return_line);
		}

		if (status == -1) {
			status = luaL_loadbuffer(L, current_line, strlen(current_line), "stdin");
		}

		multiline = false;

		/* Change the chunk environment */
		lua_pushvalue(L, session.env_index);
		lua_setfenv(L, -2);

		if (status == LUA_ERRSYNTAX) {
			const char *message;
			const int k = sizeof(EOF_MARKER) / sizeof(char) - 1;
			size_t n;

			message = lua_tolstring(L, -1, &n);

			if (n > k &&
				!strncmp(message + n - k, EOF_MARKER, k) &&
				strlen(line) > 0) {
				multiline = true;
			} else {
				session.user->print(session.user, RED "%s" CLEAR "\n", lua_tostring(L, -1));
			}

			lua_pop(L, 1);
		}
		else if (status == LUA_ERRMEM) {
			session.user->print(session.user, RED "%s" CLEAR "\n", lua_tostring(L, -1));

			lua_pop(L, 1);
		}
		else {
			execute_print(L, session.user);
			lua_pop(L, 1);

			if (is_return) {
				stop = true;
			}
		}

		if (!multiline) {
			free(full_line);
			full_line = NULL;
		}
		else if (!full_line) {
			full_line = strdup(line);
		}

		free(line);
	}

	free(full_line);

	session.user->print(session.user, "\n");
	session.user->print(session.user, GREEN "continue" CLEAR "\n");

	lua_pop(L, 1);
	LUA_STACK_CHECK(L, 0);

	if (!session.user->stop(session.user)) {
		on_user_error();
	}

	luadebug_user_release(&session.user);
	current_session = NULL;

	mutex_unlock(&active_session_mutex);
}