mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:07:34 +00:00
Shell: Place all variables in the closest nonlocal frame in POSIX mode
This commit is contained in:
parent
0d8b90aec6
commit
1403e56535
2 changed files with 23 additions and 8 deletions
|
@ -407,7 +407,16 @@ void Shell::set_local_variable(DeprecatedString const& name, RefPtr<AST::Value>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_local_frames.last()->local_variables.set(name, move(value));
|
LocalFrame* selected_frame = nullptr;
|
||||||
|
if (m_in_posix_mode) {
|
||||||
|
// POSIX mode: Drop everything in the closest function frame (or the global frame if there is no function frame).
|
||||||
|
auto& closest_function_frame = m_local_frames.last_matching([](auto& frame) { return frame->is_function_frame; }).value();
|
||||||
|
selected_frame = closest_function_frame.ptr();
|
||||||
|
} else {
|
||||||
|
selected_frame = m_local_frames.last().ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
selected_frame->local_variables.set(name, move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shell::unset_local_variable(StringView name, bool only_in_current_frame)
|
void Shell::unset_local_variable(StringView name, bool only_in_current_frame)
|
||||||
|
@ -458,7 +467,7 @@ bool Shell::invoke_function(const AST::Command& command, int& retval)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto frame = push_frame(DeprecatedString::formatted("function {}", function.name));
|
auto frame = push_frame(DeprecatedString::formatted("function {}", function.name), LocalFrameKind::FunctionOrGlobal);
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
for (auto& arg : function.arguments) {
|
for (auto& arg : function.arguments) {
|
||||||
++index;
|
++index;
|
||||||
|
@ -487,9 +496,9 @@ DeprecatedString Shell::format(StringView source, ssize_t& cursor) const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shell::Frame Shell::push_frame(DeprecatedString name)
|
Shell::Frame Shell::push_frame(DeprecatedString name, Shell::LocalFrameKind kind)
|
||||||
{
|
{
|
||||||
m_local_frames.append(make<LocalFrame>(name, decltype(LocalFrame::local_variables) {}));
|
m_local_frames.append(make<LocalFrame>(name, decltype(LocalFrame::local_variables) {}, kind));
|
||||||
dbgln_if(SH_DEBUG, "New frame '{}' at {:p}", name, &m_local_frames.last());
|
dbgln_if(SH_DEBUG, "New frame '{}' at {:p}", name, &m_local_frames.last());
|
||||||
return { m_local_frames, *m_local_frames.last() };
|
return { m_local_frames, *m_local_frames.last() };
|
||||||
}
|
}
|
||||||
|
@ -2179,7 +2188,7 @@ void Shell::notify_child_event()
|
||||||
Shell::Shell()
|
Shell::Shell()
|
||||||
: m_default_constructed(true)
|
: m_default_constructed(true)
|
||||||
{
|
{
|
||||||
push_frame("main").leak_frame();
|
push_frame("main", LocalFrameKind::FunctionOrGlobal).leak_frame();
|
||||||
|
|
||||||
int rc = gethostname(hostname, Shell::HostNameSize);
|
int rc = gethostname(hostname, Shell::HostNameSize);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
|
@ -2223,7 +2232,7 @@ Shell::Shell(Line::Editor& editor, bool attempt_interactive, bool posix_mode)
|
||||||
tcsetpgrp(0, getpgrp());
|
tcsetpgrp(0, getpgrp());
|
||||||
m_pid = getpid();
|
m_pid = getpid();
|
||||||
|
|
||||||
push_frame("main").leak_frame();
|
push_frame("main", LocalFrameKind::FunctionOrGlobal).leak_frame();
|
||||||
|
|
||||||
int rc = gethostname(hostname, Shell::HostNameSize);
|
int rc = gethostname(hostname, Shell::HostNameSize);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
|
|
|
@ -191,15 +191,21 @@ public:
|
||||||
|
|
||||||
RefPtr<Line::Editor> editor() const { return m_editor; }
|
RefPtr<Line::Editor> editor() const { return m_editor; }
|
||||||
|
|
||||||
|
enum class LocalFrameKind {
|
||||||
|
FunctionOrGlobal,
|
||||||
|
Block,
|
||||||
|
};
|
||||||
struct LocalFrame {
|
struct LocalFrame {
|
||||||
LocalFrame(DeprecatedString name, HashMap<DeprecatedString, RefPtr<AST::Value>> variables)
|
LocalFrame(DeprecatedString name, HashMap<DeprecatedString, RefPtr<AST::Value>> variables, LocalFrameKind kind = LocalFrameKind::Block)
|
||||||
: name(move(name))
|
: name(move(name))
|
||||||
, local_variables(move(variables))
|
, local_variables(move(variables))
|
||||||
|
, is_function_frame(kind == LocalFrameKind::FunctionOrGlobal)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DeprecatedString name;
|
DeprecatedString name;
|
||||||
HashMap<DeprecatedString, RefPtr<AST::Value>> local_variables;
|
HashMap<DeprecatedString, RefPtr<AST::Value>> local_variables;
|
||||||
|
bool is_function_frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Frame {
|
struct Frame {
|
||||||
|
@ -218,7 +224,7 @@ public:
|
||||||
bool should_destroy_frame { true };
|
bool should_destroy_frame { true };
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] Frame push_frame(DeprecatedString name);
|
[[nodiscard]] Frame push_frame(DeprecatedString name, LocalFrameKind = LocalFrameKind::Block);
|
||||||
void pop_frame();
|
void pop_frame();
|
||||||
|
|
||||||
struct Promise {
|
struct Promise {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue