mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-20 17:58:18 +03:00
Shell: Use NonnullRefPtr to store non-null subnodes
Also replaces null-is-invalid nodes with syntax error nodes.
This commit is contained in:
parent
2d7aaab897
commit
51e598cf0b
Notes:
sideshowbarker
2024-07-19 02:12:18 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/51e598cf0b8 Pull-request: https://github.com/SerenityOS/serenity/pull/3505 Reviewed-by: https://github.com/awesomekling Reviewed-by: https://github.com/devsh0
@ -83,7 +83,7 @@ static inline Vector<Command> join_commands(Vector<Command> left, Vector<Command
|
|||||||
return commands;
|
return commands;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(RefPtr<Value>)> callback)
|
void Node::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(NonnullRefPtr<Value>)> callback)
|
||||||
{
|
{
|
||||||
auto value = run(shell)->resolve_without_cast(shell);
|
auto value = run(shell)->resolve_without_cast(shell);
|
||||||
if (value->is_job()) {
|
if (value->is_job()) {
|
||||||
@ -219,13 +219,14 @@ HitTestResult And::hit_test_position(size_t offset)
|
|||||||
result.closest_command_node = m_right;
|
result.closest_command_node = m_right;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = m_right->hit_test_position(offset);
|
result = m_right->hit_test_position(offset);
|
||||||
if (!result.closest_command_node)
|
if (!result.closest_command_node)
|
||||||
result.closest_command_node = m_right;
|
result.closest_command_node = m_right;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
And::And(Position position, RefPtr<Node> left, RefPtr<Node> right)
|
And::And(Position position, NonnullRefPtr<Node> left, NonnullRefPtr<Node> right)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_left(move(left))
|
, m_left(move(left))
|
||||||
, m_right(move(right))
|
, m_right(move(right))
|
||||||
@ -324,7 +325,7 @@ RefPtr<Node> ListConcatenate::leftmost_trivial_literal() const
|
|||||||
return m_list.first()->leftmost_trivial_literal();
|
return m_list.first()->leftmost_trivial_literal();
|
||||||
}
|
}
|
||||||
|
|
||||||
ListConcatenate::ListConcatenate(Position position, Vector<RefPtr<Node>> list)
|
ListConcatenate::ListConcatenate(Position position, Vector<NonnullRefPtr<Node>> list)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_list(move(list))
|
, m_list(move(list))
|
||||||
{
|
{
|
||||||
@ -368,7 +369,7 @@ HitTestResult Background::hit_test_position(size_t offset)
|
|||||||
return m_command->hit_test_position(offset);
|
return m_command->hit_test_position(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Background::Background(Position position, RefPtr<Node> command)
|
Background::Background(Position position, NonnullRefPtr<Node> command)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_command(move(command))
|
, m_command(move(command))
|
||||||
{
|
{
|
||||||
@ -491,7 +492,7 @@ RefPtr<Node> CastToCommand::leftmost_trivial_literal() const
|
|||||||
return m_inner->leftmost_trivial_literal();
|
return m_inner->leftmost_trivial_literal();
|
||||||
}
|
}
|
||||||
|
|
||||||
CastToCommand::CastToCommand(Position position, RefPtr<Node> inner)
|
CastToCommand::CastToCommand(Position position, NonnullRefPtr<Node> inner)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_inner(move(inner))
|
, m_inner(move(inner))
|
||||||
{
|
{
|
||||||
@ -723,7 +724,7 @@ HitTestResult DynamicEvaluate::hit_test_position(size_t offset)
|
|||||||
return m_inner->hit_test_position(offset);
|
return m_inner->hit_test_position(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicEvaluate::DynamicEvaluate(Position position, RefPtr<Node> inner)
|
DynamicEvaluate::DynamicEvaluate(Position position, NonnullRefPtr<Node> inner)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_inner(move(inner))
|
, m_inner(move(inner))
|
||||||
{
|
{
|
||||||
@ -807,6 +808,9 @@ HitTestResult FunctionDeclaration::hit_test_position(size_t offset)
|
|||||||
if (!position().contains(offset))
|
if (!position().contains(offset))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
if (!m_block)
|
||||||
|
return {};
|
||||||
|
|
||||||
auto result = m_block->hit_test_position(offset);
|
auto result = m_block->hit_test_position(offset);
|
||||||
if (result.matching_node && result.matching_node->is_simple_variable())
|
if (result.matching_node && result.matching_node->is_simple_variable())
|
||||||
result.closest_node_with_semantic_meaning = this;
|
result.closest_node_with_semantic_meaning = this;
|
||||||
@ -927,10 +931,13 @@ HitTestResult ForLoop::hit_test_position(size_t offset)
|
|||||||
if (auto result = m_iterated_expression->hit_test_position(offset); result.matching_node)
|
if (auto result = m_iterated_expression->hit_test_position(offset); result.matching_node)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
if (!m_block)
|
||||||
|
return {};
|
||||||
|
|
||||||
return m_block->hit_test_position(offset);
|
return m_block->hit_test_position(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
ForLoop::ForLoop(Position position, String variable_name, RefPtr<AST::Node> iterated_expr, RefPtr<AST::Node> block, Optional<size_t> in_kw_position)
|
ForLoop::ForLoop(Position position, String variable_name, NonnullRefPtr<AST::Node> iterated_expr, RefPtr<AST::Node> block, Optional<size_t> in_kw_position)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_variable_name(move(variable_name))
|
, m_variable_name(move(variable_name))
|
||||||
, m_iterated_expression(move(iterated_expr))
|
, m_iterated_expression(move(iterated_expr))
|
||||||
@ -984,7 +991,7 @@ void Execute::dump(int level) const
|
|||||||
m_command->dump(level + 1);
|
m_command->dump(level + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Execute::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(RefPtr<Value>)> callback)
|
void Execute::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(NonnullRefPtr<Value>)> callback)
|
||||||
{
|
{
|
||||||
if (m_command->would_execute())
|
if (m_command->would_execute())
|
||||||
return m_command->for_each_entry(shell, move(callback));
|
return m_command->for_each_entry(shell, move(callback));
|
||||||
@ -1176,7 +1183,7 @@ Vector<Line::CompletionSuggestion> Execute::complete_for_editor(Shell& shell, si
|
|||||||
return shell.complete_program_name(node->text(), corrected_offset);
|
return shell.complete_program_name(node->text(), corrected_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Execute::Execute(Position position, RefPtr<Node> command, bool capture_stdout)
|
Execute::Execute(Position position, NonnullRefPtr<Node> command, bool capture_stdout)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_command(move(command))
|
, m_command(move(command))
|
||||||
, m_capture_stdout(capture_stdout)
|
, m_capture_stdout(capture_stdout)
|
||||||
@ -1266,7 +1273,7 @@ HitTestResult IfCond::hit_test_position(size_t offset)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
IfCond::IfCond(Position position, Optional<Position> else_position, RefPtr<Node> condition, RefPtr<Node> true_branch, RefPtr<Node> false_branch)
|
IfCond::IfCond(Position position, Optional<Position> else_position, NonnullRefPtr<Node> condition, RefPtr<Node> true_branch, RefPtr<Node> false_branch)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_condition(move(condition))
|
, m_condition(move(condition))
|
||||||
, m_true_branch(move(true_branch))
|
, m_true_branch(move(true_branch))
|
||||||
@ -1281,10 +1288,16 @@ IfCond::IfCond(Position position, Optional<Position> else_position, RefPtr<Node>
|
|||||||
set_is_syntax_error(m_false_branch->syntax_error_node());
|
set_is_syntax_error(m_false_branch->syntax_error_node());
|
||||||
|
|
||||||
m_condition = create<AST::Execute>(m_condition->position(), m_condition);
|
m_condition = create<AST::Execute>(m_condition->position(), m_condition);
|
||||||
if (m_true_branch)
|
|
||||||
m_true_branch = create<AST::Execute>(m_true_branch->position(), m_true_branch);
|
if (m_true_branch) {
|
||||||
if (m_false_branch)
|
auto true_branch = m_true_branch.release_nonnull();
|
||||||
m_false_branch = create<AST::Execute>(m_false_branch->position(), m_false_branch);
|
m_true_branch = create<AST::Execute>(true_branch->position(), true_branch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_false_branch) {
|
||||||
|
auto false_branch = m_false_branch.release_nonnull();
|
||||||
|
m_false_branch = create<AST::Execute>(false_branch->position(), false_branch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IfCond::~IfCond()
|
IfCond::~IfCond()
|
||||||
@ -1322,6 +1335,7 @@ HitTestResult Join::hit_test_position(size_t offset)
|
|||||||
auto result = m_left->hit_test_position(offset);
|
auto result = m_left->hit_test_position(offset);
|
||||||
if (result.matching_node)
|
if (result.matching_node)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
return m_right->hit_test_position(offset);
|
return m_right->hit_test_position(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1332,7 +1346,7 @@ RefPtr<Node> Join::leftmost_trivial_literal() const
|
|||||||
return m_right->leftmost_trivial_literal();
|
return m_right->leftmost_trivial_literal();
|
||||||
}
|
}
|
||||||
|
|
||||||
Join::Join(Position position, RefPtr<Node> left, RefPtr<Node> right)
|
Join::Join(Position position, NonnullRefPtr<Node> left, NonnullRefPtr<Node> right)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_left(move(left))
|
, m_left(move(left))
|
||||||
, m_right(move(right))
|
, m_right(move(right))
|
||||||
@ -1428,8 +1442,7 @@ void MatchExpr::highlight_in_editor(Line::Editor& editor, Shell& shell, Highligh
|
|||||||
editor.stylize({ m_as_position.value().start_offset, m_as_position.value().end_offset }, { Line::Style::Foreground(Line::Style::XtermColor::Yellow) });
|
editor.stylize({ m_as_position.value().start_offset, m_as_position.value().end_offset }, { Line::Style::Foreground(Line::Style::XtermColor::Yellow) });
|
||||||
|
|
||||||
metadata.is_first_in_list = false;
|
metadata.is_first_in_list = false;
|
||||||
if (m_matched_expr)
|
m_matched_expr->highlight_in_editor(editor, shell, metadata);
|
||||||
m_matched_expr->highlight_in_editor(editor, shell, metadata);
|
|
||||||
|
|
||||||
for (auto& entry : m_entries) {
|
for (auto& entry : m_entries) {
|
||||||
metadata.is_first_in_list = false;
|
metadata.is_first_in_list = false;
|
||||||
@ -1465,14 +1478,14 @@ HitTestResult MatchExpr::hit_test_position(size_t offset)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchExpr::MatchExpr(Position position, RefPtr<Node> expr, String name, Optional<Position> as_position, Vector<MatchEntry> entries)
|
MatchExpr::MatchExpr(Position position, NonnullRefPtr<Node> expr, String name, Optional<Position> as_position, Vector<MatchEntry> entries)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_matched_expr(move(expr))
|
, m_matched_expr(move(expr))
|
||||||
, m_expr_name(move(name))
|
, m_expr_name(move(name))
|
||||||
, m_as_position(move(as_position))
|
, m_as_position(move(as_position))
|
||||||
, m_entries(move(entries))
|
, m_entries(move(entries))
|
||||||
{
|
{
|
||||||
if (m_matched_expr && m_matched_expr->is_syntax_error()) {
|
if (m_matched_expr->is_syntax_error()) {
|
||||||
set_is_syntax_error(m_matched_expr->syntax_error_node());
|
set_is_syntax_error(m_matched_expr->syntax_error_node());
|
||||||
} else {
|
} else {
|
||||||
for (auto& entry : m_entries) {
|
for (auto& entry : m_entries) {
|
||||||
@ -1521,13 +1534,14 @@ HitTestResult Or::hit_test_position(size_t offset)
|
|||||||
result.closest_command_node = m_right;
|
result.closest_command_node = m_right;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = m_right->hit_test_position(offset);
|
result = m_right->hit_test_position(offset);
|
||||||
if (!result.closest_command_node)
|
if (!result.closest_command_node)
|
||||||
result.closest_command_node = m_right;
|
result.closest_command_node = m_right;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Or::Or(Position position, RefPtr<Node> left, RefPtr<Node> right)
|
Or::Or(Position position, NonnullRefPtr<Node> left, NonnullRefPtr<Node> right)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_left(move(left))
|
, m_left(move(left))
|
||||||
, m_right(move(right))
|
, m_right(move(right))
|
||||||
@ -1595,10 +1609,11 @@ HitTestResult Pipe::hit_test_position(size_t offset)
|
|||||||
auto result = m_left->hit_test_position(offset);
|
auto result = m_left->hit_test_position(offset);
|
||||||
if (result.matching_node)
|
if (result.matching_node)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
return m_right->hit_test_position(offset);
|
return m_right->hit_test_position(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pipe::Pipe(Position position, RefPtr<Node> left, RefPtr<Node> right)
|
Pipe::Pipe(Position position, NonnullRefPtr<Node> left, NonnullRefPtr<Node> right)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_left(move(left))
|
, m_left(move(left))
|
||||||
, m_right(move(right))
|
, m_right(move(right))
|
||||||
@ -1613,7 +1628,7 @@ Pipe::~Pipe()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PathRedirectionNode::PathRedirectionNode(Position position, int fd, RefPtr<Node> path)
|
PathRedirectionNode::PathRedirectionNode(Position position, int fd, NonnullRefPtr<Node> path)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_fd(fd)
|
, m_fd(fd)
|
||||||
, m_path(move(path))
|
, m_path(move(path))
|
||||||
@ -1687,7 +1702,7 @@ RefPtr<Value> ReadRedirection::run(RefPtr<Shell> shell)
|
|||||||
return create<CommandValue>(move(command));
|
return create<CommandValue>(move(command));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadRedirection::ReadRedirection(Position position, int fd, RefPtr<Node> path)
|
ReadRedirection::ReadRedirection(Position position, int fd, NonnullRefPtr<Node> path)
|
||||||
: PathRedirectionNode(move(position), fd, move(path))
|
: PathRedirectionNode(move(position), fd, move(path))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -1714,7 +1729,7 @@ RefPtr<Value> ReadWriteRedirection::run(RefPtr<Shell> shell)
|
|||||||
return create<CommandValue>(move(command));
|
return create<CommandValue>(move(command));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadWriteRedirection::ReadWriteRedirection(Position position, int fd, RefPtr<Node> path)
|
ReadWriteRedirection::ReadWriteRedirection(Position position, int fd, NonnullRefPtr<Node> path)
|
||||||
: PathRedirectionNode(move(position), fd, move(path))
|
: PathRedirectionNode(move(position), fd, move(path))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -1781,7 +1796,7 @@ HitTestResult Sequence::hit_test_position(size_t offset)
|
|||||||
return m_right->hit_test_position(offset);
|
return m_right->hit_test_position(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sequence::Sequence(Position position, RefPtr<Node> left, RefPtr<Node> right)
|
Sequence::Sequence(Position position, NonnullRefPtr<Node> left, NonnullRefPtr<Node> right)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_left(move(left))
|
, m_left(move(left))
|
||||||
, m_right(move(right))
|
, m_right(move(right))
|
||||||
@ -2049,7 +2064,7 @@ HitTestResult Juxtaposition::hit_test_position(size_t offset)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Juxtaposition::Juxtaposition(Position position, RefPtr<Node> left, RefPtr<Node> right)
|
Juxtaposition::Juxtaposition(Position position, NonnullRefPtr<Node> left, NonnullRefPtr<Node> right)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_left(move(left))
|
, m_left(move(left))
|
||||||
, m_right(move(right))
|
, m_right(move(right))
|
||||||
@ -2129,7 +2144,7 @@ HitTestResult StringPartCompose::hit_test_position(size_t offset)
|
|||||||
return m_right->hit_test_position(offset);
|
return m_right->hit_test_position(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringPartCompose::StringPartCompose(Position position, RefPtr<Node> left, RefPtr<Node> right)
|
StringPartCompose::StringPartCompose(Position position, NonnullRefPtr<Node> left, NonnullRefPtr<Node> right)
|
||||||
: Node(move(position))
|
: Node(move(position))
|
||||||
, m_left(move(left))
|
, m_left(move(left))
|
||||||
, m_right(move(right))
|
, m_right(move(right))
|
||||||
@ -2252,7 +2267,7 @@ RefPtr<Value> WriteAppendRedirection::run(RefPtr<Shell> shell)
|
|||||||
return create<CommandValue>(move(command));
|
return create<CommandValue>(move(command));
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteAppendRedirection::WriteAppendRedirection(Position position, int fd, RefPtr<Node> path)
|
WriteAppendRedirection::WriteAppendRedirection(Position position, int fd, NonnullRefPtr<Node> path)
|
||||||
: PathRedirectionNode(move(position), fd, move(path))
|
: PathRedirectionNode(move(position), fd, move(path))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -2279,7 +2294,7 @@ RefPtr<Value> WriteRedirection::run(RefPtr<Shell> shell)
|
|||||||
return create<CommandValue>(move(command));
|
return create<CommandValue>(move(command));
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteRedirection::WriteRedirection(Position position, int fd, RefPtr<Node> path)
|
WriteRedirection::WriteRedirection(Position position, int fd, NonnullRefPtr<Node> path)
|
||||||
: PathRedirectionNode(move(position), fd, move(path))
|
: PathRedirectionNode(move(position), fd, move(path))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
92
Shell/AST.h
92
Shell/AST.h
@ -371,7 +371,7 @@ private:
|
|||||||
class Node : public RefCounted<Node> {
|
class Node : public RefCounted<Node> {
|
||||||
public:
|
public:
|
||||||
virtual void dump(int level) const = 0;
|
virtual void dump(int level) const = 0;
|
||||||
virtual void for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(RefPtr<Value>)> callback);
|
virtual void for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(NonnullRefPtr<Value>)> callback);
|
||||||
virtual RefPtr<Value> run(RefPtr<Shell>) = 0;
|
virtual RefPtr<Value> run(RefPtr<Shell>) = 0;
|
||||||
virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) = 0;
|
virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) = 0;
|
||||||
virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&);
|
virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&);
|
||||||
@ -422,7 +422,7 @@ protected:
|
|||||||
|
|
||||||
class PathRedirectionNode : public Node {
|
class PathRedirectionNode : public Node {
|
||||||
public:
|
public:
|
||||||
PathRedirectionNode(Position, int, RefPtr<Node>);
|
PathRedirectionNode(Position, int, NonnullRefPtr<Node>);
|
||||||
virtual ~PathRedirectionNode();
|
virtual ~PathRedirectionNode();
|
||||||
virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
|
virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
|
||||||
virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
|
virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
|
||||||
@ -432,12 +432,12 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_fd { -1 };
|
int m_fd { -1 };
|
||||||
RefPtr<Node> m_path;
|
NonnullRefPtr<Node> m_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
class And final : public Node {
|
class And final : public Node {
|
||||||
public:
|
public:
|
||||||
And(Position, RefPtr<Node>, RefPtr<Node>);
|
And(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>);
|
||||||
virtual ~And();
|
virtual ~And();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -447,13 +447,13 @@ private:
|
|||||||
virtual HitTestResult hit_test_position(size_t) override;
|
virtual HitTestResult hit_test_position(size_t) override;
|
||||||
virtual String class_name() const override { return "And"; }
|
virtual String class_name() const override { return "And"; }
|
||||||
|
|
||||||
RefPtr<Node> m_left;
|
NonnullRefPtr<Node> m_left;
|
||||||
RefPtr<Node> m_right;
|
NonnullRefPtr<Node> m_right;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ListConcatenate final : public Node {
|
class ListConcatenate final : public Node {
|
||||||
public:
|
public:
|
||||||
ListConcatenate(Position, Vector<RefPtr<Node>>);
|
ListConcatenate(Position, Vector<NonnullRefPtr<Node>>);
|
||||||
virtual ~ListConcatenate();
|
virtual ~ListConcatenate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -465,12 +465,12 @@ private:
|
|||||||
virtual bool is_list() const override { return true; }
|
virtual bool is_list() const override { return true; }
|
||||||
virtual RefPtr<Node> leftmost_trivial_literal() const override;
|
virtual RefPtr<Node> leftmost_trivial_literal() const override;
|
||||||
|
|
||||||
Vector<RefPtr<Node>> m_list;
|
Vector<NonnullRefPtr<Node>> m_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Background final : public Node {
|
class Background final : public Node {
|
||||||
public:
|
public:
|
||||||
Background(Position, RefPtr<Node>);
|
Background(Position, NonnullRefPtr<Node>);
|
||||||
virtual ~Background();
|
virtual ~Background();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -480,7 +480,7 @@ private:
|
|||||||
virtual HitTestResult hit_test_position(size_t) override;
|
virtual HitTestResult hit_test_position(size_t) override;
|
||||||
virtual String class_name() const override { return "Background"; }
|
virtual String class_name() const override { return "Background"; }
|
||||||
|
|
||||||
RefPtr<Node> m_command;
|
NonnullRefPtr<Node> m_command;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BarewordLiteral final : public Node {
|
class BarewordLiteral final : public Node {
|
||||||
@ -502,7 +502,7 @@ private:
|
|||||||
|
|
||||||
class CastToCommand final : public Node {
|
class CastToCommand final : public Node {
|
||||||
public:
|
public:
|
||||||
CastToCommand(Position, RefPtr<Node>);
|
CastToCommand(Position, NonnullRefPtr<Node>);
|
||||||
virtual ~CastToCommand();
|
virtual ~CastToCommand();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -516,7 +516,7 @@ private:
|
|||||||
virtual bool is_list() const override { return true; }
|
virtual bool is_list() const override { return true; }
|
||||||
virtual RefPtr<Node> leftmost_trivial_literal() const override;
|
virtual RefPtr<Node> leftmost_trivial_literal() const override;
|
||||||
|
|
||||||
RefPtr<Node> m_inner;
|
NonnullRefPtr<Node> m_inner;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastToList final : public Node {
|
class CastToList final : public Node {
|
||||||
@ -584,7 +584,7 @@ private:
|
|||||||
|
|
||||||
class DynamicEvaluate final : public Node {
|
class DynamicEvaluate final : public Node {
|
||||||
public:
|
public:
|
||||||
DynamicEvaluate(Position, RefPtr<Node>);
|
DynamicEvaluate(Position, NonnullRefPtr<Node>);
|
||||||
virtual ~DynamicEvaluate();
|
virtual ~DynamicEvaluate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -603,7 +603,7 @@ private:
|
|||||||
return m_inner->is_list() || m_inner->is_command() || m_inner->is_glob(); // Anything that generates a list.
|
return m_inner->is_list() || m_inner->is_command() || m_inner->is_glob(); // Anything that generates a list.
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Node> m_inner;
|
NonnullRefPtr<Node> m_inner;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DoubleQuotedString final : public Node {
|
class DoubleQuotedString final : public Node {
|
||||||
@ -662,7 +662,7 @@ private:
|
|||||||
|
|
||||||
class ForLoop final : public Node {
|
class ForLoop final : public Node {
|
||||||
public:
|
public:
|
||||||
ForLoop(Position, String variable_name, RefPtr<AST::Node> iterated_expr, RefPtr<AST::Node> block, Optional<size_t> in_kw_position = {});
|
ForLoop(Position, String variable_name, NonnullRefPtr<AST::Node> iterated_expr, RefPtr<AST::Node> block, Optional<size_t> in_kw_position = {});
|
||||||
virtual ~ForLoop();
|
virtual ~ForLoop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -674,7 +674,7 @@ private:
|
|||||||
virtual bool would_execute() const override { return true; }
|
virtual bool would_execute() const override { return true; }
|
||||||
|
|
||||||
String m_variable_name;
|
String m_variable_name;
|
||||||
RefPtr<AST::Node> m_iterated_expression;
|
NonnullRefPtr<AST::Node> m_iterated_expression;
|
||||||
RefPtr<AST::Node> m_block;
|
RefPtr<AST::Node> m_block;
|
||||||
Optional<size_t> m_in_kw_position;
|
Optional<size_t> m_in_kw_position;
|
||||||
};
|
};
|
||||||
@ -698,11 +698,11 @@ private:
|
|||||||
|
|
||||||
class Execute final : public Node {
|
class Execute final : public Node {
|
||||||
public:
|
public:
|
||||||
Execute(Position, RefPtr<Node>, bool capture_stdout = false);
|
Execute(Position, NonnullRefPtr<Node>, bool capture_stdout = false);
|
||||||
virtual ~Execute();
|
virtual ~Execute();
|
||||||
void capture_stdout() { m_capture_stdout = true; }
|
void capture_stdout() { m_capture_stdout = true; }
|
||||||
RefPtr<Node> command() { return m_command; }
|
NonnullRefPtr<Node> command() { return m_command; }
|
||||||
virtual void for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(RefPtr<Value>)> callback) override;
|
virtual void for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(NonnullRefPtr<Value>)> callback) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void dump(int level) const override;
|
virtual void dump(int level) const override;
|
||||||
@ -714,13 +714,13 @@ private:
|
|||||||
virtual bool is_execute() const override { return true; }
|
virtual bool is_execute() const override { return true; }
|
||||||
virtual bool would_execute() const override { return true; }
|
virtual bool would_execute() const override { return true; }
|
||||||
|
|
||||||
RefPtr<Node> m_command;
|
NonnullRefPtr<Node> m_command;
|
||||||
bool m_capture_stdout { false };
|
bool m_capture_stdout { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
class IfCond final : public Node {
|
class IfCond final : public Node {
|
||||||
public:
|
public:
|
||||||
IfCond(Position, Optional<Position> else_position, RefPtr<AST::Node> cond_expr, RefPtr<AST::Node> true_branch, RefPtr<AST::Node> false_branch);
|
IfCond(Position, Optional<Position> else_position, NonnullRefPtr<AST::Node> cond_expr, RefPtr<AST::Node> true_branch, RefPtr<AST::Node> false_branch);
|
||||||
virtual ~IfCond();
|
virtual ~IfCond();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -731,7 +731,7 @@ private:
|
|||||||
virtual String class_name() const override { return "IfCond"; }
|
virtual String class_name() const override { return "IfCond"; }
|
||||||
virtual bool would_execute() const override { return true; }
|
virtual bool would_execute() const override { return true; }
|
||||||
|
|
||||||
RefPtr<AST::Node> m_condition;
|
NonnullRefPtr<AST::Node> m_condition;
|
||||||
RefPtr<AST::Node> m_true_branch;
|
RefPtr<AST::Node> m_true_branch;
|
||||||
RefPtr<AST::Node> m_false_branch;
|
RefPtr<AST::Node> m_false_branch;
|
||||||
|
|
||||||
@ -740,7 +740,7 @@ private:
|
|||||||
|
|
||||||
class Join final : public Node {
|
class Join final : public Node {
|
||||||
public:
|
public:
|
||||||
Join(Position, RefPtr<Node>, RefPtr<Node>);
|
Join(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>);
|
||||||
virtual ~Join();
|
virtual ~Join();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -753,8 +753,8 @@ private:
|
|||||||
virtual bool is_list() const override { return true; }
|
virtual bool is_list() const override { return true; }
|
||||||
virtual RefPtr<Node> leftmost_trivial_literal() const override;
|
virtual RefPtr<Node> leftmost_trivial_literal() const override;
|
||||||
|
|
||||||
RefPtr<Node> m_left;
|
NonnullRefPtr<Node> m_left;
|
||||||
RefPtr<Node> m_right;
|
NonnullRefPtr<Node> m_right;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MatchEntry {
|
struct MatchEntry {
|
||||||
@ -765,7 +765,7 @@ struct MatchEntry {
|
|||||||
|
|
||||||
class MatchExpr final : public Node {
|
class MatchExpr final : public Node {
|
||||||
public:
|
public:
|
||||||
MatchExpr(Position, RefPtr<Node> expr, String name, Optional<Position> as_position, Vector<MatchEntry> entries);
|
MatchExpr(Position, NonnullRefPtr<Node> expr, String name, Optional<Position> as_position, Vector<MatchEntry> entries);
|
||||||
virtual ~MatchExpr();
|
virtual ~MatchExpr();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -776,7 +776,7 @@ private:
|
|||||||
virtual String class_name() const override { return "MatchExpr"; }
|
virtual String class_name() const override { return "MatchExpr"; }
|
||||||
virtual bool would_execute() const override { return true; }
|
virtual bool would_execute() const override { return true; }
|
||||||
|
|
||||||
RefPtr<Node> m_matched_expr;
|
NonnullRefPtr<Node> m_matched_expr;
|
||||||
String m_expr_name;
|
String m_expr_name;
|
||||||
Optional<Position> m_as_position;
|
Optional<Position> m_as_position;
|
||||||
Vector<MatchEntry> m_entries;
|
Vector<MatchEntry> m_entries;
|
||||||
@ -784,7 +784,7 @@ private:
|
|||||||
|
|
||||||
class Or final : public Node {
|
class Or final : public Node {
|
||||||
public:
|
public:
|
||||||
Or(Position, RefPtr<Node>, RefPtr<Node>);
|
Or(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>);
|
||||||
virtual ~Or();
|
virtual ~Or();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -794,13 +794,13 @@ private:
|
|||||||
virtual HitTestResult hit_test_position(size_t) override;
|
virtual HitTestResult hit_test_position(size_t) override;
|
||||||
virtual String class_name() const override { return "Or"; }
|
virtual String class_name() const override { return "Or"; }
|
||||||
|
|
||||||
RefPtr<Node> m_left;
|
NonnullRefPtr<Node> m_left;
|
||||||
RefPtr<Node> m_right;
|
NonnullRefPtr<Node> m_right;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Pipe final : public Node {
|
class Pipe final : public Node {
|
||||||
public:
|
public:
|
||||||
Pipe(Position, RefPtr<Node>, RefPtr<Node>);
|
Pipe(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>);
|
||||||
virtual ~Pipe();
|
virtual ~Pipe();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -811,13 +811,13 @@ private:
|
|||||||
virtual String class_name() const override { return "Pipe"; }
|
virtual String class_name() const override { return "Pipe"; }
|
||||||
virtual bool is_list() const override { return true; }
|
virtual bool is_list() const override { return true; }
|
||||||
|
|
||||||
RefPtr<Node> m_left;
|
NonnullRefPtr<Node> m_left;
|
||||||
RefPtr<Node> m_right;
|
NonnullRefPtr<Node> m_right;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ReadRedirection final : public PathRedirectionNode {
|
class ReadRedirection final : public PathRedirectionNode {
|
||||||
public:
|
public:
|
||||||
ReadRedirection(Position, int, RefPtr<Node>);
|
ReadRedirection(Position, int, NonnullRefPtr<Node>);
|
||||||
virtual ~ReadRedirection();
|
virtual ~ReadRedirection();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -828,7 +828,7 @@ private:
|
|||||||
|
|
||||||
class ReadWriteRedirection final : public PathRedirectionNode {
|
class ReadWriteRedirection final : public PathRedirectionNode {
|
||||||
public:
|
public:
|
||||||
ReadWriteRedirection(Position, int, RefPtr<Node>);
|
ReadWriteRedirection(Position, int, NonnullRefPtr<Node>);
|
||||||
virtual ~ReadWriteRedirection();
|
virtual ~ReadWriteRedirection();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -839,7 +839,7 @@ private:
|
|||||||
|
|
||||||
class Sequence final : public Node {
|
class Sequence final : public Node {
|
||||||
public:
|
public:
|
||||||
Sequence(Position, RefPtr<Node>, RefPtr<Node>);
|
Sequence(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>);
|
||||||
virtual ~Sequence();
|
virtual ~Sequence();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -851,8 +851,8 @@ private:
|
|||||||
virtual bool is_list() const override { return true; }
|
virtual bool is_list() const override { return true; }
|
||||||
virtual bool would_execute() const override { return m_left->would_execute() || m_right->would_execute(); }
|
virtual bool would_execute() const override { return m_left->would_execute() || m_right->would_execute(); }
|
||||||
|
|
||||||
RefPtr<Node> m_left;
|
NonnullRefPtr<Node> m_left;
|
||||||
RefPtr<Node> m_right;
|
NonnullRefPtr<Node> m_right;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Subshell final : public Node {
|
class Subshell final : public Node {
|
||||||
@ -908,7 +908,7 @@ private:
|
|||||||
|
|
||||||
class Juxtaposition final : public Node {
|
class Juxtaposition final : public Node {
|
||||||
public:
|
public:
|
||||||
Juxtaposition(Position, RefPtr<Node>, RefPtr<Node>);
|
Juxtaposition(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>);
|
||||||
virtual ~Juxtaposition();
|
virtual ~Juxtaposition();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -919,8 +919,8 @@ private:
|
|||||||
virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
|
virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
|
||||||
virtual String class_name() const override { return "Juxtaposition"; }
|
virtual String class_name() const override { return "Juxtaposition"; }
|
||||||
|
|
||||||
RefPtr<Node> m_left;
|
NonnullRefPtr<Node> m_left;
|
||||||
RefPtr<Node> m_right;
|
NonnullRefPtr<Node> m_right;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StringLiteral final : public Node {
|
class StringLiteral final : public Node {
|
||||||
@ -941,7 +941,7 @@ private:
|
|||||||
|
|
||||||
class StringPartCompose final : public Node {
|
class StringPartCompose final : public Node {
|
||||||
public:
|
public:
|
||||||
StringPartCompose(Position, RefPtr<Node>, RefPtr<Node>);
|
StringPartCompose(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>);
|
||||||
virtual ~StringPartCompose();
|
virtual ~StringPartCompose();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -951,8 +951,8 @@ private:
|
|||||||
virtual HitTestResult hit_test_position(size_t) override;
|
virtual HitTestResult hit_test_position(size_t) override;
|
||||||
virtual String class_name() const override { return "StringPartCompose"; }
|
virtual String class_name() const override { return "StringPartCompose"; }
|
||||||
|
|
||||||
RefPtr<Node> m_left;
|
NonnullRefPtr<Node> m_left;
|
||||||
RefPtr<Node> m_right;
|
NonnullRefPtr<Node> m_right;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SyntaxError final : public Node {
|
class SyntaxError final : public Node {
|
||||||
@ -1016,7 +1016,7 @@ private:
|
|||||||
|
|
||||||
class WriteAppendRedirection final : public PathRedirectionNode {
|
class WriteAppendRedirection final : public PathRedirectionNode {
|
||||||
public:
|
public:
|
||||||
WriteAppendRedirection(Position, int, RefPtr<Node>);
|
WriteAppendRedirection(Position, int, NonnullRefPtr<Node>);
|
||||||
virtual ~WriteAppendRedirection();
|
virtual ~WriteAppendRedirection();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -1027,7 +1027,7 @@ private:
|
|||||||
|
|
||||||
class WriteRedirection final : public PathRedirectionNode {
|
class WriteRedirection final : public PathRedirectionNode {
|
||||||
public:
|
public:
|
||||||
WriteRedirection(Position, int, RefPtr<Node>);
|
WriteRedirection(Position, int, NonnullRefPtr<Node>);
|
||||||
virtual ~WriteRedirection();
|
virtual ~WriteRedirection();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
137
Shell/Parser.cpp
137
Shell/Parser.cpp
@ -128,9 +128,10 @@ RefPtr<AST::Node> Parser::parse()
|
|||||||
auto error_start = push_start();
|
auto error_start = push_start();
|
||||||
m_offset = m_input.length();
|
m_offset = m_input.length();
|
||||||
auto syntax_error_node = create<AST::SyntaxError>("Unexpected tokens past the end");
|
auto syntax_error_node = create<AST::SyntaxError>("Unexpected tokens past the end");
|
||||||
if (toplevel)
|
if (!toplevel)
|
||||||
return create<AST::Join>(move(toplevel), move(syntax_error_node));
|
toplevel = move(syntax_error_node);
|
||||||
return syntax_error_node;
|
else
|
||||||
|
toplevel->set_is_syntax_error(*syntax_error_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return toplevel;
|
return toplevel;
|
||||||
@ -141,7 +142,7 @@ RefPtr<AST::Node> Parser::parse_toplevel()
|
|||||||
auto rule_start = push_start();
|
auto rule_start = push_start();
|
||||||
|
|
||||||
if (auto sequence = parse_sequence())
|
if (auto sequence = parse_sequence())
|
||||||
return create<AST::Execute>(sequence);
|
return create<AST::Execute>(sequence.release_nonnull());
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -164,7 +165,7 @@ RefPtr<AST::Node> Parser::parse_sequence()
|
|||||||
consume_while(is_any_of("\n;"));
|
consume_while(is_any_of("\n;"));
|
||||||
auto rest = parse_sequence();
|
auto rest = parse_sequence();
|
||||||
if (rest)
|
if (rest)
|
||||||
return create<AST::Sequence>(move(var_decls), move(rest));
|
return create<AST::Sequence>(var_decls.release_nonnull(), rest.release_nonnull());
|
||||||
return var_decls;
|
return var_decls;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -180,7 +181,7 @@ RefPtr<AST::Node> Parser::parse_sequence()
|
|||||||
return var_decls;
|
return var_decls;
|
||||||
|
|
||||||
if (var_decls)
|
if (var_decls)
|
||||||
first = create<AST::Sequence>(move(var_decls), move(first));
|
first = create<AST::Sequence>(var_decls.release_nonnull(), first.release_nonnull());
|
||||||
|
|
||||||
consume_while(is_whitespace);
|
consume_while(is_whitespace);
|
||||||
|
|
||||||
@ -189,15 +190,15 @@ RefPtr<AST::Node> Parser::parse_sequence()
|
|||||||
case '\n':
|
case '\n':
|
||||||
consume_while(is_any_of("\n;"));
|
consume_while(is_any_of("\n;"));
|
||||||
if (auto expr = parse_sequence()) {
|
if (auto expr = parse_sequence()) {
|
||||||
return create<AST::Sequence>(move(first), move(expr)); // Sequence
|
return create<AST::Sequence>(first.release_nonnull(), expr.release_nonnull()); // Sequence
|
||||||
}
|
}
|
||||||
return first;
|
return first;
|
||||||
case '&': {
|
case '&': {
|
||||||
auto execute_pipe_seq = first->would_execute() ? first : static_cast<RefPtr<AST::Node>>(create<AST::Execute>(first));
|
auto execute_pipe_seq = first->would_execute() ? first.release_nonnull() : static_cast<NonnullRefPtr<AST::Node>>(create<AST::Execute>(first.release_nonnull()));
|
||||||
consume();
|
consume();
|
||||||
auto bg = create<AST::Background>(move(first)); // Execute Background
|
auto bg = create<AST::Background>(execute_pipe_seq); // Execute Background
|
||||||
if (auto rest = parse_sequence())
|
if (auto rest = parse_sequence())
|
||||||
return create<AST::Sequence>(move(bg), move(rest)); // Sequence Background Sequence
|
return create<AST::Sequence>(move(bg), rest.release_nonnull()); // Sequence Background Sequence
|
||||||
|
|
||||||
return bg;
|
return bg;
|
||||||
}
|
}
|
||||||
@ -369,7 +370,7 @@ RefPtr<AST::Node> Parser::parse_or_logical_sequence()
|
|||||||
if (!right_and_sequence)
|
if (!right_and_sequence)
|
||||||
right_and_sequence = create<AST::SyntaxError>("Expected an expression after '||'");
|
right_and_sequence = create<AST::SyntaxError>("Expected an expression after '||'");
|
||||||
|
|
||||||
return create<AST::Or>(move(and_sequence), move(right_and_sequence));
|
return create<AST::Or>(and_sequence.release_nonnull(), right_and_sequence.release_nonnull());
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Parser::parse_and_logical_sequence()
|
RefPtr<AST::Node> Parser::parse_and_logical_sequence()
|
||||||
@ -391,7 +392,7 @@ RefPtr<AST::Node> Parser::parse_and_logical_sequence()
|
|||||||
if (!right_and_sequence)
|
if (!right_and_sequence)
|
||||||
right_and_sequence = create<AST::SyntaxError>("Expected an expression after '&&'");
|
right_and_sequence = create<AST::SyntaxError>("Expected an expression after '&&'");
|
||||||
|
|
||||||
return create<AST::And>(move(pipe_sequence), move(right_and_sequence));
|
return create<AST::And>(pipe_sequence.release_nonnull(), right_and_sequence.release_nonnull());
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Parser::parse_pipe_sequence()
|
RefPtr<AST::Node> Parser::parse_pipe_sequence()
|
||||||
@ -413,7 +414,7 @@ RefPtr<AST::Node> Parser::parse_pipe_sequence()
|
|||||||
consume();
|
consume();
|
||||||
|
|
||||||
if (auto pipe_seq = parse_pipe_sequence()) {
|
if (auto pipe_seq = parse_pipe_sequence()) {
|
||||||
return create<AST::Pipe>(move(left), move(pipe_seq)); // Pipe
|
return create<AST::Pipe>(left.release_nonnull(), pipe_seq.release_nonnull()); // Pipe
|
||||||
}
|
}
|
||||||
|
|
||||||
putback();
|
putback();
|
||||||
@ -431,20 +432,20 @@ RefPtr<AST::Node> Parser::parse_command()
|
|||||||
if (!list_expr)
|
if (!list_expr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto cast = create<AST::CastToCommand>(move(list_expr)); // Cast List Command
|
auto cast = create<AST::CastToCommand>(list_expr.release_nonnull()); // Cast List Command
|
||||||
|
|
||||||
auto next_command = parse_command();
|
auto next_command = parse_command();
|
||||||
if (!next_command)
|
if (!next_command)
|
||||||
return cast;
|
return cast;
|
||||||
|
|
||||||
return create<AST::Join>(move(cast), move(next_command)); // Join List Command
|
return create<AST::Join>(move(cast), next_command.release_nonnull()); // Join List Command
|
||||||
}
|
}
|
||||||
|
|
||||||
auto command = parse_command();
|
auto command = parse_command();
|
||||||
if (!command)
|
if (!command)
|
||||||
return redir;
|
return redir;
|
||||||
|
|
||||||
return create<AST::Join>(move(redir), command); // Join Command Command
|
return create<AST::Join>(redir.release_nonnull(), command.release_nonnull()); // Join Command Command
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Parser::parse_control_structure()
|
RefPtr<AST::Node> Parser::parse_control_structure()
|
||||||
@ -509,7 +510,7 @@ RefPtr<AST::Node> Parser::parse_for_loop()
|
|||||||
auto obrace_error_start = push_start();
|
auto obrace_error_start = push_start();
|
||||||
if (!expect('{')) {
|
if (!expect('{')) {
|
||||||
auto syntax_error = create<AST::SyntaxError>("Expected an open brace '{' to start a 'for' loop body");
|
auto syntax_error = create<AST::SyntaxError>("Expected an open brace '{' to start a 'for' loop body");
|
||||||
return create<AST::ForLoop>(move(variable_name), move(iterated_expression), move(syntax_error), move(in_start_position)); // ForLoop Var Iterated Block
|
return create<AST::ForLoop>(move(variable_name), iterated_expression.release_nonnull(), move(syntax_error), move(in_start_position)); // ForLoop Var Iterated Block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,7 +520,7 @@ RefPtr<AST::Node> Parser::parse_for_loop()
|
|||||||
auto cbrace_error_start = push_start();
|
auto cbrace_error_start = push_start();
|
||||||
if (!expect('}')) {
|
if (!expect('}')) {
|
||||||
auto error_start = push_start();
|
auto error_start = push_start();
|
||||||
RefPtr<AST::SyntaxError> syntax_error = create<AST::SyntaxError>("Expected a close brace '}' to end a 'for' loop body");
|
auto syntax_error = create<AST::SyntaxError>("Expected a close brace '}' to end a 'for' loop body");
|
||||||
if (body)
|
if (body)
|
||||||
body->set_is_syntax_error(*syntax_error);
|
body->set_is_syntax_error(*syntax_error);
|
||||||
else
|
else
|
||||||
@ -527,7 +528,7 @@ RefPtr<AST::Node> Parser::parse_for_loop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return create<AST::ForLoop>(move(variable_name), move(iterated_expression), move(body), move(in_start_position)); // ForLoop Var Iterated Block
|
return create<AST::ForLoop>(move(variable_name), iterated_expression.release_nonnull(), move(body), move(in_start_position)); // ForLoop Var Iterated Block
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Parser::parse_if_expr()
|
RefPtr<AST::Node> Parser::parse_if_expr()
|
||||||
@ -547,22 +548,21 @@ RefPtr<AST::Node> Parser::parse_if_expr()
|
|||||||
{
|
{
|
||||||
auto cond_error_start = push_start();
|
auto cond_error_start = push_start();
|
||||||
condition = parse_or_logical_sequence();
|
condition = parse_or_logical_sequence();
|
||||||
if (!condition) {
|
if (!condition)
|
||||||
auto syntax_error = create<AST::SyntaxError>("Expected a logical sequence after 'if'");
|
condition = create<AST::SyntaxError>("Expected a logical sequence after 'if'");
|
||||||
return create<AST::IfCond>(Optional<AST::Position> {}, move(syntax_error), nullptr, nullptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parse_braced_toplevel = [&]() -> RefPtr<AST::Node> {
|
auto parse_braced_toplevel = [&]() -> RefPtr<AST::Node> {
|
||||||
|
RefPtr<AST::Node> body;
|
||||||
{
|
{
|
||||||
auto obrace_error_start = push_start();
|
auto obrace_error_start = push_start();
|
||||||
if (!expect('{')) {
|
if (!expect('{')) {
|
||||||
auto syntax_error = create<AST::SyntaxError>("Expected an open brace '{' to start an 'if' true branch");
|
body = create<AST::SyntaxError>("Expected an open brace '{' to start an 'if' true branch");
|
||||||
return syntax_error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto body = parse_toplevel();
|
if (!body)
|
||||||
|
body = parse_toplevel();
|
||||||
|
|
||||||
{
|
{
|
||||||
auto cbrace_error_start = push_start();
|
auto cbrace_error_start = push_start();
|
||||||
@ -582,9 +582,6 @@ RefPtr<AST::Node> Parser::parse_if_expr()
|
|||||||
consume_while(is_whitespace);
|
consume_while(is_whitespace);
|
||||||
auto true_branch = parse_braced_toplevel();
|
auto true_branch = parse_braced_toplevel();
|
||||||
|
|
||||||
if (true_branch && true_branch->is_syntax_error())
|
|
||||||
return create<AST::IfCond>(Optional<AST::Position> {}, move(condition), move(true_branch), nullptr); // If expr syntax_error
|
|
||||||
|
|
||||||
consume_while(is_whitespace);
|
consume_while(is_whitespace);
|
||||||
Optional<AST::Position> else_position;
|
Optional<AST::Position> else_position;
|
||||||
{
|
{
|
||||||
@ -597,14 +594,14 @@ RefPtr<AST::Node> Parser::parse_if_expr()
|
|||||||
consume_while(is_whitespace);
|
consume_while(is_whitespace);
|
||||||
if (peek() == '{') {
|
if (peek() == '{') {
|
||||||
auto false_branch = parse_braced_toplevel();
|
auto false_branch = parse_braced_toplevel();
|
||||||
return create<AST::IfCond>(else_position, move(condition), move(true_branch), move(false_branch)); // If expr true_branch Else false_branch
|
return create<AST::IfCond>(else_position, condition.release_nonnull(), move(true_branch), move(false_branch)); // If expr true_branch Else false_branch
|
||||||
}
|
}
|
||||||
|
|
||||||
auto else_if_branch = parse_if_expr();
|
auto else_if_branch = parse_if_expr();
|
||||||
return create<AST::IfCond>(else_position, move(condition), move(true_branch), move(else_if_branch)); // If expr true_branch Else If ...
|
return create<AST::IfCond>(else_position, condition.release_nonnull(), move(true_branch), move(else_if_branch)); // If expr true_branch Else If ...
|
||||||
}
|
}
|
||||||
|
|
||||||
return create<AST::IfCond>(else_position, move(condition), move(true_branch), nullptr); // If expr true_branch
|
return create<AST::IfCond>(else_position, condition.release_nonnull(), move(true_branch), nullptr); // If expr true_branch
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Parser::parse_subshell()
|
RefPtr<AST::Node> Parser::parse_subshell()
|
||||||
@ -658,7 +655,7 @@ RefPtr<AST::Node> Parser::parse_match_expr()
|
|||||||
|
|
||||||
if (consume_while(is_any_of(" \t\n")).is_empty()) {
|
if (consume_while(is_any_of(" \t\n")).is_empty()) {
|
||||||
auto node = create<AST::MatchExpr>(
|
auto node = create<AST::MatchExpr>(
|
||||||
move(match_expression),
|
match_expression.release_nonnull(),
|
||||||
String {}, move(as_position), Vector<AST::MatchEntry> {});
|
String {}, move(as_position), Vector<AST::MatchEntry> {});
|
||||||
node->set_is_syntax_error(create<AST::SyntaxError>("Expected whitespace after 'as' in 'match'"));
|
node->set_is_syntax_error(create<AST::SyntaxError>("Expected whitespace after 'as' in 'match'"));
|
||||||
return node;
|
return node;
|
||||||
@ -667,7 +664,7 @@ RefPtr<AST::Node> Parser::parse_match_expr()
|
|||||||
match_name = consume_while(is_word_character);
|
match_name = consume_while(is_word_character);
|
||||||
if (match_name.is_empty()) {
|
if (match_name.is_empty()) {
|
||||||
auto node = create<AST::MatchExpr>(
|
auto node = create<AST::MatchExpr>(
|
||||||
move(match_expression),
|
match_expression.release_nonnull(),
|
||||||
String {}, move(as_position), Vector<AST::MatchEntry> {});
|
String {}, move(as_position), Vector<AST::MatchEntry> {});
|
||||||
node->set_is_syntax_error(create<AST::SyntaxError>("Expected an identifier after 'as' in 'match'"));
|
node->set_is_syntax_error(create<AST::SyntaxError>("Expected an identifier after 'as' in 'match'"));
|
||||||
return node;
|
return node;
|
||||||
@ -678,7 +675,7 @@ RefPtr<AST::Node> Parser::parse_match_expr()
|
|||||||
|
|
||||||
if (!expect('{')) {
|
if (!expect('{')) {
|
||||||
auto node = create<AST::MatchExpr>(
|
auto node = create<AST::MatchExpr>(
|
||||||
move(match_expression),
|
match_expression.release_nonnull(),
|
||||||
move(match_name), move(as_position), Vector<AST::MatchEntry> {});
|
move(match_name), move(as_position), Vector<AST::MatchEntry> {});
|
||||||
node->set_is_syntax_error(create<AST::SyntaxError>("Expected an open brace '{' to start a 'match' entry list"));
|
node->set_is_syntax_error(create<AST::SyntaxError>("Expected an open brace '{' to start a 'match' entry list"));
|
||||||
return node;
|
return node;
|
||||||
@ -700,13 +697,13 @@ RefPtr<AST::Node> Parser::parse_match_expr()
|
|||||||
|
|
||||||
if (!expect('}')) {
|
if (!expect('}')) {
|
||||||
auto node = create<AST::MatchExpr>(
|
auto node = create<AST::MatchExpr>(
|
||||||
move(match_expression),
|
match_expression.release_nonnull(),
|
||||||
move(match_name), move(as_position), move(entries));
|
move(match_name), move(as_position), move(entries));
|
||||||
node->set_is_syntax_error(create<AST::SyntaxError>("Expected a close brace '}' to end a 'match' entry list"));
|
node->set_is_syntax_error(create<AST::SyntaxError>("Expected a close brace '}' to end a 'match' entry list"));
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
return create<AST::MatchExpr>(move(match_expression), move(match_name), move(as_position), move(entries));
|
return create<AST::MatchExpr>(match_expression.release_nonnull(), move(match_name), move(as_position), move(entries));
|
||||||
}
|
}
|
||||||
|
|
||||||
AST::MatchEntry Parser::parse_match_entry()
|
AST::MatchEntry Parser::parse_match_entry()
|
||||||
@ -792,9 +789,9 @@ RefPtr<AST::Node> Parser::parse_redirection()
|
|||||||
// Eat a character and hope the problem goes away
|
// Eat a character and hope the problem goes away
|
||||||
consume();
|
consume();
|
||||||
}
|
}
|
||||||
return create<AST::SyntaxError>("Expected a path");
|
path = create<AST::SyntaxError>("Expected a path after redirection");
|
||||||
}
|
}
|
||||||
return create<AST::WriteAppendRedirection>(pipe_fd, move(path)); // Redirection WriteAppend
|
return create<AST::WriteAppendRedirection>(pipe_fd, path.release_nonnull()); // Redirection WriteAppend
|
||||||
}
|
}
|
||||||
if (peek() == '&') {
|
if (peek() == '&') {
|
||||||
consume();
|
consume();
|
||||||
@ -827,9 +824,9 @@ RefPtr<AST::Node> Parser::parse_redirection()
|
|||||||
// Eat a character and hope the problem goes away
|
// Eat a character and hope the problem goes away
|
||||||
consume();
|
consume();
|
||||||
}
|
}
|
||||||
return create<AST::SyntaxError>("Expected a path");
|
path = create<AST::SyntaxError>("Expected a path after redirection");
|
||||||
}
|
}
|
||||||
return create<AST::WriteRedirection>(pipe_fd, move(path)); // Redirection Write
|
return create<AST::WriteRedirection>(pipe_fd, path.release_nonnull()); // Redirection Write
|
||||||
}
|
}
|
||||||
case '<': {
|
case '<': {
|
||||||
consume();
|
consume();
|
||||||
@ -851,12 +848,12 @@ RefPtr<AST::Node> Parser::parse_redirection()
|
|||||||
// Eat a character and hope the problem goes away
|
// Eat a character and hope the problem goes away
|
||||||
consume();
|
consume();
|
||||||
}
|
}
|
||||||
return create<AST::SyntaxError>("Expected a path");
|
path = create<AST::SyntaxError>("Expected a path after redirection");
|
||||||
}
|
}
|
||||||
if (mode == Read)
|
if (mode == Read)
|
||||||
return create<AST::ReadRedirection>(pipe_fd, move(path)); // Redirection Read
|
return create<AST::ReadRedirection>(pipe_fd, path.release_nonnull()); // Redirection Read
|
||||||
|
|
||||||
return create<AST::ReadWriteRedirection>(pipe_fd, move(path)); // Redirection ReadWrite
|
return create<AST::ReadWriteRedirection>(pipe_fd, path.release_nonnull()); // Redirection ReadWrite
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
m_offset = rule_start->offset;
|
m_offset = rule_start->offset;
|
||||||
@ -869,13 +866,13 @@ RefPtr<AST::Node> Parser::parse_list_expression()
|
|||||||
consume_while(is_whitespace);
|
consume_while(is_whitespace);
|
||||||
|
|
||||||
auto rule_start = push_start();
|
auto rule_start = push_start();
|
||||||
Vector<RefPtr<AST::Node>> nodes;
|
Vector<NonnullRefPtr<AST::Node>> nodes;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
auto expr = parse_expression();
|
auto expr = parse_expression();
|
||||||
if (!expr)
|
if (!expr)
|
||||||
break;
|
break;
|
||||||
nodes.append(move(expr));
|
nodes.append(expr.release_nonnull());
|
||||||
} while (!consume_while(is_whitespace).is_empty());
|
} while (!consume_while(is_whitespace).is_empty());
|
||||||
|
|
||||||
if (nodes.is_empty())
|
if (nodes.is_empty())
|
||||||
@ -889,14 +886,14 @@ RefPtr<AST::Node> Parser::parse_expression()
|
|||||||
auto rule_start = push_start();
|
auto rule_start = push_start();
|
||||||
auto starting_char = peek();
|
auto starting_char = peek();
|
||||||
|
|
||||||
auto read_concat = [&](auto expr) -> RefPtr<AST::Node> {
|
auto read_concat = [&](auto&& expr) -> NonnullRefPtr<AST::Node> {
|
||||||
if (is_whitespace(peek()))
|
if (is_whitespace(peek()))
|
||||||
return expr;
|
return move(expr);
|
||||||
|
|
||||||
if (auto next_expr = parse_expression())
|
if (auto next_expr = parse_expression())
|
||||||
return create<AST::Juxtaposition>(move(expr), move(next_expr));
|
return create<AST::Juxtaposition>(move(expr), next_expr.release_nonnull());
|
||||||
|
|
||||||
return expr;
|
return move(expr);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (strchr("&|){} ;<>\n", starting_char) != nullptr)
|
if (strchr("&|){} ;<>\n", starting_char) != nullptr)
|
||||||
@ -912,10 +909,10 @@ RefPtr<AST::Node> Parser::parse_expression()
|
|||||||
|
|
||||||
if (starting_char == '$') {
|
if (starting_char == '$') {
|
||||||
if (auto variable = parse_variable())
|
if (auto variable = parse_variable())
|
||||||
return read_concat(variable);
|
return read_concat(variable.release_nonnull());
|
||||||
|
|
||||||
if (auto inline_exec = parse_evaluate())
|
if (auto inline_exec = parse_evaluate())
|
||||||
return read_concat(inline_exec);
|
return read_concat(inline_exec.release_nonnull());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (starting_char == '#')
|
if (starting_char == '#')
|
||||||
@ -931,7 +928,10 @@ RefPtr<AST::Node> Parser::parse_expression()
|
|||||||
return read_concat(create<AST::CastToList>(move(list))); // Cast To List
|
return read_concat(create<AST::CastToList>(move(list))); // Cast To List
|
||||||
}
|
}
|
||||||
|
|
||||||
return read_concat(parse_string_composite());
|
if (auto composite = parse_string_composite())
|
||||||
|
return read_concat(composite.release_nonnull());
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Parser::parse_string_composite()
|
RefPtr<AST::Node> Parser::parse_string_composite()
|
||||||
@ -939,35 +939,35 @@ RefPtr<AST::Node> Parser::parse_string_composite()
|
|||||||
auto rule_start = push_start();
|
auto rule_start = push_start();
|
||||||
if (auto string = parse_string()) {
|
if (auto string = parse_string()) {
|
||||||
if (auto next_part = parse_string_composite())
|
if (auto next_part = parse_string_composite())
|
||||||
return create<AST::Juxtaposition>(move(string), move(next_part)); // Concatenate String StringComposite
|
return create<AST::Juxtaposition>(string.release_nonnull(), next_part.release_nonnull()); // Concatenate String StringComposite
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto variable = parse_variable()) {
|
if (auto variable = parse_variable()) {
|
||||||
if (auto next_part = parse_string_composite())
|
if (auto next_part = parse_string_composite())
|
||||||
return create<AST::Juxtaposition>(move(variable), move(next_part)); // Concatenate Variable StringComposite
|
return create<AST::Juxtaposition>(variable.release_nonnull(), next_part.release_nonnull()); // Concatenate Variable StringComposite
|
||||||
|
|
||||||
return variable;
|
return variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto glob = parse_glob()) {
|
if (auto glob = parse_glob()) {
|
||||||
if (auto next_part = parse_string_composite())
|
if (auto next_part = parse_string_composite())
|
||||||
return create<AST::Juxtaposition>(move(glob), move(next_part)); // Concatenate Glob StringComposite
|
return create<AST::Juxtaposition>(glob.release_nonnull(), next_part.release_nonnull()); // Concatenate Glob StringComposite
|
||||||
|
|
||||||
return glob;
|
return glob;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto bareword = parse_bareword()) {
|
if (auto bareword = parse_bareword()) {
|
||||||
if (auto next_part = parse_string_composite())
|
if (auto next_part = parse_string_composite())
|
||||||
return create<AST::Juxtaposition>(move(bareword), move(next_part)); // Concatenate Bareword StringComposite
|
return create<AST::Juxtaposition>(bareword.release_nonnull(), next_part.release_nonnull()); // Concatenate Bareword StringComposite
|
||||||
|
|
||||||
return bareword;
|
return bareword;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto inline_command = parse_evaluate()) {
|
if (auto inline_command = parse_evaluate()) {
|
||||||
if (auto next_part = parse_string_composite())
|
if (auto next_part = parse_string_composite())
|
||||||
return create<AST::Juxtaposition>(move(inline_command), move(next_part)); // Concatenate Execute StringComposite
|
return create<AST::Juxtaposition>(inline_command.release_nonnull(), next_part.release_nonnull()); // Concatenate Execute StringComposite
|
||||||
|
|
||||||
return inline_command;
|
return inline_command;
|
||||||
}
|
}
|
||||||
@ -1067,10 +1067,10 @@ RefPtr<AST::Node> Parser::parse_doublequoted_string_inner()
|
|||||||
if (auto variable = parse_variable()) {
|
if (auto variable = parse_variable()) {
|
||||||
auto inner = create<AST::StringPartCompose>(
|
auto inner = create<AST::StringPartCompose>(
|
||||||
move(string_literal),
|
move(string_literal),
|
||||||
move(variable)); // Compose String Variable
|
variable.release_nonnull()); // Compose String Variable
|
||||||
|
|
||||||
if (auto string = parse_doublequoted_string_inner()) {
|
if (auto string = parse_doublequoted_string_inner()) {
|
||||||
return create<AST::StringPartCompose>(move(inner), move(string)); // Compose Composition Composition
|
return create<AST::StringPartCompose>(move(inner), string.release_nonnull()); // Compose Composition Composition
|
||||||
}
|
}
|
||||||
|
|
||||||
return inner;
|
return inner;
|
||||||
@ -1079,10 +1079,10 @@ RefPtr<AST::Node> Parser::parse_doublequoted_string_inner()
|
|||||||
if (auto evaluate = parse_evaluate()) {
|
if (auto evaluate = parse_evaluate()) {
|
||||||
auto composition = create<AST::StringPartCompose>(
|
auto composition = create<AST::StringPartCompose>(
|
||||||
move(string_literal),
|
move(string_literal),
|
||||||
move(evaluate)); // Compose String Sequence
|
evaluate.release_nonnull()); // Compose String Sequence
|
||||||
|
|
||||||
if (auto string = parse_doublequoted_string_inner()) {
|
if (auto string = parse_doublequoted_string_inner()) {
|
||||||
return create<AST::StringPartCompose>(move(composition), move(string)); // Compose Composition Composition
|
return create<AST::StringPartCompose>(move(composition), string.release_nonnull()); // Compose Composition Composition
|
||||||
}
|
}
|
||||||
|
|
||||||
return composition;
|
return composition;
|
||||||
@ -1142,7 +1142,8 @@ RefPtr<AST::Node> Parser::parse_evaluate()
|
|||||||
inner = create<AST::SyntaxError>("Unexpected EOF in list");
|
inner = create<AST::SyntaxError>("Unexpected EOF in list");
|
||||||
if (!expect(')'))
|
if (!expect(')'))
|
||||||
inner->set_is_syntax_error(*create<AST::SyntaxError>("Expected a terminating close paren"));
|
inner->set_is_syntax_error(*create<AST::SyntaxError>("Expected a terminating close paren"));
|
||||||
return create<AST::Execute>(move(inner), true);
|
|
||||||
|
return create<AST::Execute>(inner.release_nonnull(), true);
|
||||||
}
|
}
|
||||||
auto inner = parse_expression();
|
auto inner = parse_expression();
|
||||||
|
|
||||||
@ -1150,11 +1151,11 @@ RefPtr<AST::Node> Parser::parse_evaluate()
|
|||||||
inner = create<AST::SyntaxError>("Expected a command");
|
inner = create<AST::SyntaxError>("Expected a command");
|
||||||
} else {
|
} else {
|
||||||
if (inner->is_list()) {
|
if (inner->is_list()) {
|
||||||
auto execute_inner = create<AST::Execute>(move(inner), true);
|
auto execute_inner = create<AST::Execute>(inner.release_nonnull(), true);
|
||||||
inner = execute_inner;
|
inner = move(execute_inner);
|
||||||
} else {
|
} else {
|
||||||
auto dyn_inner = create<AST::DynamicEvaluate>(move(inner));
|
auto dyn_inner = create<AST::DynamicEvaluate>(inner.release_nonnull());
|
||||||
inner = dyn_inner;
|
inner = move(dyn_inner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1237,7 +1238,7 @@ RefPtr<AST::Node> Parser::parse_bareword()
|
|||||||
text = create<AST::BarewordLiteral>(move(string));
|
text = create<AST::BarewordLiteral>(move(string));
|
||||||
}
|
}
|
||||||
|
|
||||||
return create<AST::Juxtaposition>(move(tilde), move(text)); // Juxtaposition Varible Bareword
|
return create<AST::Juxtaposition>(tilde.release_nonnull(), text.release_nonnull()); // Juxtaposition Varible Bareword
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.starts_with("\\~")) {
|
if (string.starts_with("\\~")) {
|
||||||
|
@ -292,7 +292,9 @@ Vector<AST::Command> Shell::expand_aliases(Vector<AST::Command> initial_commands
|
|||||||
auto* ast = static_cast<AST::Execute*>(subcommand_ast.ptr());
|
auto* ast = static_cast<AST::Execute*>(subcommand_ast.ptr());
|
||||||
subcommand_ast = ast->command();
|
subcommand_ast = ast->command();
|
||||||
}
|
}
|
||||||
RefPtr<AST::Node> substitute = adopt(*new AST::Join(subcommand_ast->position(), subcommand_ast, adopt(*new AST::CommandLiteral(subcommand_ast->position(), command))));
|
NonnullRefPtr<AST::Node> substitute = adopt(*new AST::Join(subcommand_ast->position(),
|
||||||
|
subcommand_ast.release_nonnull(),
|
||||||
|
adopt(*new AST::CommandLiteral(subcommand_ast->position(), command))));
|
||||||
for (auto& subst_command : substitute->run(*this)->resolve_as_commands(*this)) {
|
for (auto& subst_command : substitute->run(*this)->resolve_as_commands(*this)) {
|
||||||
if (!subst_command.argv.is_empty() && subst_command.argv.first() == argv0) // Disallow an alias resolving to itself.
|
if (!subst_command.argv.is_empty() && subst_command.argv.first() == argv0) // Disallow an alias resolving to itself.
|
||||||
commands.append(subst_command);
|
commands.append(subst_command);
|
||||||
|
Loading…
Reference in New Issue
Block a user