mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 18:07:35 +00:00
Shell: Make Immediate expression invocation fallible
This removes a whole bunch of FIXMEs in the immediate expr implementations as well :^)
This commit is contained in:
parent
007767fc14
commit
5f950df3d4
3 changed files with 79 additions and 79 deletions
|
@ -2048,7 +2048,7 @@ ErrorOr<void> ImmediateExpression::dump(int level) const
|
||||||
|
|
||||||
RefPtr<Value> ImmediateExpression::run(RefPtr<Shell> shell)
|
RefPtr<Value> ImmediateExpression::run(RefPtr<Shell> shell)
|
||||||
{
|
{
|
||||||
auto node = shell->run_immediate_function(m_function.name, *this, arguments());
|
auto node = shell->run_immediate_function(m_function.name, *this, arguments()).release_value_but_fixme_should_propagate_errors();
|
||||||
if (node)
|
if (node)
|
||||||
return node->run(shell);
|
return node->run(shell);
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
namespace Shell {
|
namespace Shell {
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments, bool across)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_length_impl(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments, bool across)
|
||||||
{
|
{
|
||||||
auto name = across ? "length_across" : "length";
|
auto name = across ? "length_across" : "length";
|
||||||
if (arguments.size() < 1 || arguments.size() > 2) {
|
if (arguments.size() < 1 || arguments.size() > 2) {
|
||||||
|
@ -59,18 +59,18 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
||||||
if (expr_node->is_list())
|
if (expr_node->is_list())
|
||||||
mode = List;
|
mode = List;
|
||||||
else if (expr_node->is_simple_variable()) // "Look inside" variables
|
else if (expr_node->is_simple_variable()) // "Look inside" variables
|
||||||
mode = const_cast<AST::Node*>(expr_node)->run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors()->is_list_without_resolution() ? List : String;
|
mode = TRY(const_cast<AST::Node*>(expr_node)->run(this)->resolve_without_cast(this))->is_list_without_resolution() ? List : String;
|
||||||
else if (is<AST::ImmediateExpression>(expr_node))
|
else if (is<AST::ImmediateExpression>(expr_node))
|
||||||
mode = List;
|
mode = List;
|
||||||
else
|
else
|
||||||
mode = String;
|
mode = String;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto value_with_number = [&](auto number) -> NonnullRefPtr<AST::Node> {
|
auto value_with_number = [&](auto number) -> ErrorOr<NonnullRefPtr<AST::Node>> {
|
||||||
return AST::make_ref_counted<AST::BarewordLiteral>(invoking_node.position(), String::number(number).release_value_but_fixme_should_propagate_errors());
|
return AST::make_ref_counted<AST::BarewordLiteral>(invoking_node.position(), TRY(String::number(number)));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto do_across = [&](StringView mode_name, auto& values) {
|
auto do_across = [&](StringView mode_name, auto& values) -> ErrorOr<RefPtr<AST::Node>> {
|
||||||
if (is_inferred)
|
if (is_inferred)
|
||||||
mode_name = "infer"sv;
|
mode_name = "infer"sv;
|
||||||
// Translate to a list of applications of `length <mode_name>`
|
// Translate to a list of applications of `length <mode_name>`
|
||||||
|
@ -80,9 +80,9 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
||||||
// ImmediateExpression(length <mode_name> <entry>)
|
// ImmediateExpression(length <mode_name> <entry>)
|
||||||
resulting_nodes.unchecked_append(AST::make_ref_counted<AST::ImmediateExpression>(
|
resulting_nodes.unchecked_append(AST::make_ref_counted<AST::ImmediateExpression>(
|
||||||
expr_node->position(),
|
expr_node->position(),
|
||||||
AST::NameWithPosition { String::from_utf8("length"sv).release_value_but_fixme_should_propagate_errors(), invoking_node.function_position() },
|
AST::NameWithPosition { TRY(String::from_utf8("length"sv)), invoking_node.function_position() },
|
||||||
NonnullRefPtrVector<AST::Node> { Vector<NonnullRefPtr<AST::Node>> {
|
NonnullRefPtrVector<AST::Node> { Vector<NonnullRefPtr<AST::Node>> {
|
||||||
static_cast<NonnullRefPtr<AST::Node>>(AST::make_ref_counted<AST::BarewordLiteral>(expr_node->position(), String::from_utf8(mode_name).release_value_but_fixme_should_propagate_errors())),
|
static_cast<NonnullRefPtr<AST::Node>>(AST::make_ref_counted<AST::BarewordLiteral>(expr_node->position(), TRY(String::from_utf8(mode_name)))),
|
||||||
AST::make_ref_counted<AST::SyntheticNode>(expr_node->position(), NonnullRefPtr<AST::Value>(entry)),
|
AST::make_ref_counted<AST::SyntheticNode>(expr_node->position(), NonnullRefPtr<AST::Value>(entry)),
|
||||||
} },
|
} },
|
||||||
expr_node->position()));
|
expr_node->position()));
|
||||||
|
@ -100,7 +100,7 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
||||||
if (!value)
|
if (!value)
|
||||||
return value_with_number(0);
|
return value_with_number(0);
|
||||||
|
|
||||||
value = value->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
value = TRY(value->resolve_without_cast(this));
|
||||||
|
|
||||||
if (auto list = dynamic_cast<AST::ListValue*>(value.ptr())) {
|
if (auto list = dynamic_cast<AST::ListValue*>(value.ptr())) {
|
||||||
if (across)
|
if (across)
|
||||||
|
@ -109,7 +109,7 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
||||||
return value_with_number(list->values().size());
|
return value_with_number(list->values().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto list = value->resolve_as_list(this).release_value_but_fixme_should_propagate_errors();
|
auto list = TRY(value->resolve_as_list(this));
|
||||||
if (!across)
|
if (!across)
|
||||||
return value_with_number(list.size());
|
return value_with_number(list.size());
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
||||||
if (!value)
|
if (!value)
|
||||||
return value_with_number(0);
|
return value_with_number(0);
|
||||||
|
|
||||||
value = value->resolve_without_cast(*this).release_value_but_fixme_should_propagate_errors();
|
value = TRY(value->resolve_without_cast(*this));
|
||||||
|
|
||||||
if (auto list = dynamic_cast<AST::ListValue*>(value.ptr())) {
|
if (auto list = dynamic_cast<AST::ListValue*>(value.ptr())) {
|
||||||
if (!across)
|
if (!across)
|
||||||
|
@ -165,7 +165,7 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the nodes and substitute with the lengths.
|
// Evaluate the nodes and substitute with the lengths.
|
||||||
auto list = value->resolve_as_list(this).release_value_but_fixme_should_propagate_errors();
|
auto list = TRY(value->resolve_as_list(this));
|
||||||
|
|
||||||
if (!expr_node->is_list()) {
|
if (!expr_node->is_list()) {
|
||||||
if (list.size() == 1) {
|
if (list.size() == 1) {
|
||||||
|
@ -189,17 +189,17 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_length(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_length(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
return immediate_length_impl(invoking_node, arguments, false);
|
return immediate_length_impl(invoking_node, arguments, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_length_across(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_length_across(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
return immediate_length_impl(invoking_node, arguments, true);
|
return immediate_length_impl(invoking_node, arguments, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_regex_replace(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_regex_replace(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 3) {
|
if (arguments.size() != 3) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 3 arguments to regex_replace", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 3 arguments to regex_replace", invoking_node.position());
|
||||||
|
@ -208,7 +208,7 @@ RefPtr<AST::Node> Shell::immediate_regex_replace(AST::ImmediateExpression& invok
|
||||||
|
|
||||||
auto pattern = const_cast<AST::Node&>(arguments[0]).run(this);
|
auto pattern = const_cast<AST::Node&>(arguments[0]).run(this);
|
||||||
auto replacement = const_cast<AST::Node&>(arguments[1]).run(this);
|
auto replacement = const_cast<AST::Node&>(arguments[1]).run(this);
|
||||||
auto value = const_cast<AST::Node&>(arguments[2]).run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
auto value = TRY(const_cast<AST::Node&>(arguments[2]).run(this)->resolve_without_cast(this));
|
||||||
|
|
||||||
if (!pattern->is_string()) {
|
if (!pattern->is_string()) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected the regex_replace pattern to be a string", arguments[0].position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected the regex_replace pattern to be a string", arguments[0].position());
|
||||||
|
@ -225,16 +225,16 @@ RefPtr<AST::Node> Shell::immediate_regex_replace(AST::ImmediateExpression& invok
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Regex<PosixExtendedParser> re { pattern->resolve_as_list(this).release_value_but_fixme_should_propagate_errors().first().to_deprecated_string() };
|
Regex<PosixExtendedParser> re { TRY(pattern->resolve_as_list(this)).first().to_deprecated_string() };
|
||||||
auto result = re.replace(
|
auto result = re.replace(
|
||||||
value->resolve_as_list(this).release_value_but_fixme_should_propagate_errors()[0],
|
TRY(value->resolve_as_list(this))[0],
|
||||||
replacement->resolve_as_list(this).release_value_but_fixme_should_propagate_errors()[0],
|
TRY(replacement->resolve_as_list(this))[0],
|
||||||
PosixFlags::Global | PosixFlags::Multiline | PosixFlags::Unicode);
|
PosixFlags::Global | PosixFlags::Multiline | PosixFlags::Unicode);
|
||||||
|
|
||||||
return AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), String::from_utf8(result).release_value_but_fixme_should_propagate_errors(), AST::StringLiteral::EnclosureType::None);
|
return AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), TRY(String::from_utf8(result)), AST::StringLiteral::EnclosureType::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_remove_suffix(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_remove_suffix(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to remove_suffix", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to remove_suffix", invoking_node.position());
|
||||||
|
@ -242,23 +242,23 @@ RefPtr<AST::Node> Shell::immediate_remove_suffix(AST::ImmediateExpression& invok
|
||||||
}
|
}
|
||||||
|
|
||||||
auto suffix = const_cast<AST::Node&>(arguments[0]).run(this);
|
auto suffix = const_cast<AST::Node&>(arguments[0]).run(this);
|
||||||
auto value = const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
auto value = TRY(const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this));
|
||||||
|
|
||||||
if (!suffix->is_string()) {
|
if (!suffix->is_string()) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected the remove_suffix suffix string to be a string", arguments[0].position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected the remove_suffix suffix string to be a string", arguments[0].position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto suffix_str = suffix->resolve_as_list(this).release_value_but_fixme_should_propagate_errors()[0];
|
auto suffix_str = TRY(suffix->resolve_as_list(this))[0];
|
||||||
auto values = value->resolve_as_list(this).release_value_but_fixme_should_propagate_errors();
|
auto values = TRY(value->resolve_as_list(this));
|
||||||
|
|
||||||
Vector<NonnullRefPtr<AST::Node>> nodes;
|
Vector<NonnullRefPtr<AST::Node>> nodes;
|
||||||
|
|
||||||
for (auto& value_str : values) {
|
for (auto& value_str : values) {
|
||||||
String removed = String::from_utf8(value_str).release_value_but_fixme_should_propagate_errors();
|
String removed = TRY(String::from_utf8(value_str));
|
||||||
|
|
||||||
if (value_str.bytes_as_string_view().ends_with(suffix_str))
|
if (value_str.bytes_as_string_view().ends_with(suffix_str))
|
||||||
removed = removed.substring_from_byte_offset(0, value_str.bytes_as_string_view().length() - suffix_str.bytes_as_string_view().length()).release_value_but_fixme_should_propagate_errors();
|
removed = TRY(removed.substring_from_byte_offset(0, value_str.bytes_as_string_view().length() - suffix_str.bytes_as_string_view().length()));
|
||||||
|
|
||||||
nodes.append(AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), move(removed), AST::StringLiteral::EnclosureType::None));
|
nodes.append(AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), move(removed), AST::StringLiteral::EnclosureType::None));
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ RefPtr<AST::Node> Shell::immediate_remove_suffix(AST::ImmediateExpression& invok
|
||||||
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), move(nodes));
|
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), move(nodes));
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_remove_prefix(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_remove_prefix(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to remove_prefix", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to remove_prefix", invoking_node.position());
|
||||||
|
@ -274,30 +274,30 @@ RefPtr<AST::Node> Shell::immediate_remove_prefix(AST::ImmediateExpression& invok
|
||||||
}
|
}
|
||||||
|
|
||||||
auto prefix = const_cast<AST::Node&>(arguments[0]).run(this);
|
auto prefix = const_cast<AST::Node&>(arguments[0]).run(this);
|
||||||
auto value = const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
auto value = TRY(const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this));
|
||||||
|
|
||||||
if (!prefix->is_string()) {
|
if (!prefix->is_string()) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected the remove_prefix prefix string to be a string", arguments[0].position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected the remove_prefix prefix string to be a string", arguments[0].position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto prefix_str = prefix->resolve_as_list(this).release_value_but_fixme_should_propagate_errors()[0];
|
auto prefix_str = TRY(prefix->resolve_as_list(this))[0];
|
||||||
auto values = value->resolve_as_list(this).release_value_but_fixme_should_propagate_errors();
|
auto values = TRY(value->resolve_as_list(this));
|
||||||
|
|
||||||
Vector<NonnullRefPtr<AST::Node>> nodes;
|
Vector<NonnullRefPtr<AST::Node>> nodes;
|
||||||
|
|
||||||
for (auto& value_str : values) {
|
for (auto& value_str : values) {
|
||||||
String removed = String::from_utf8(value_str).release_value_but_fixme_should_propagate_errors();
|
String removed = TRY(String::from_utf8(value_str));
|
||||||
|
|
||||||
if (value_str.bytes_as_string_view().starts_with(prefix_str))
|
if (value_str.bytes_as_string_view().starts_with(prefix_str))
|
||||||
removed = removed.substring_from_byte_offset(prefix_str.bytes_as_string_view().length()).release_value_but_fixme_should_propagate_errors();
|
removed = TRY(removed.substring_from_byte_offset(prefix_str.bytes_as_string_view().length()));
|
||||||
nodes.append(AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), move(removed), AST::StringLiteral::EnclosureType::None));
|
nodes.append(AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), move(removed), AST::StringLiteral::EnclosureType::None));
|
||||||
}
|
}
|
||||||
|
|
||||||
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), move(nodes));
|
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), move(nodes));
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_split(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_split(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to split", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to split", invoking_node.position());
|
||||||
|
@ -305,14 +305,14 @@ RefPtr<AST::Node> Shell::immediate_split(AST::ImmediateExpression& invoking_node
|
||||||
}
|
}
|
||||||
|
|
||||||
auto delimiter = const_cast<AST::Node&>(arguments[0]).run(this);
|
auto delimiter = const_cast<AST::Node&>(arguments[0]).run(this);
|
||||||
auto value = const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
auto value = TRY(const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this));
|
||||||
|
|
||||||
if (!delimiter->is_string()) {
|
if (!delimiter->is_string()) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected the split delimiter string to be a string", arguments[0].position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected the split delimiter string to be a string", arguments[0].position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto delimiter_str = delimiter->resolve_as_list(this).release_value_but_fixme_should_propagate_errors()[0];
|
auto delimiter_str = TRY(delimiter->resolve_as_list(this))[0];
|
||||||
|
|
||||||
auto transform = [&](auto const& values) {
|
auto transform = [&](auto const& values) {
|
||||||
// Translate to a list of applications of `split <delimiter>`
|
// Translate to a list of applications of `split <delimiter>`
|
||||||
|
@ -338,7 +338,7 @@ RefPtr<AST::Node> Shell::immediate_split(AST::ImmediateExpression& invoking_node
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, just resolve to a list and transform that.
|
// Otherwise, just resolve to a list and transform that.
|
||||||
auto list = value->resolve_as_list(this).release_value_but_fixme_should_propagate_errors();
|
auto list = TRY(value->resolve_as_list(this));
|
||||||
if (!value->is_list()) {
|
if (!value->is_list()) {
|
||||||
if (list.is_empty())
|
if (list.is_empty())
|
||||||
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), NonnullRefPtrVector<AST::Node> {});
|
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), NonnullRefPtrVector<AST::Node> {});
|
||||||
|
@ -349,14 +349,14 @@ RefPtr<AST::Node> Shell::immediate_split(AST::ImmediateExpression& invoking_node
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
for (auto code_point : Utf8View { value }) {
|
for (auto code_point : Utf8View { value }) {
|
||||||
builder.append_code_point(code_point);
|
builder.append_code_point(code_point);
|
||||||
split_strings.append(builder.to_string().release_value_but_fixme_should_propagate_errors());
|
split_strings.append(TRY(builder.to_string()));
|
||||||
builder.clear();
|
builder.clear();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto split = StringView { value }.split_view(delimiter_str, options.inline_exec_keep_empty_segments ? SplitBehavior::KeepEmpty : SplitBehavior::Nothing);
|
auto split = StringView { value }.split_view(delimiter_str, options.inline_exec_keep_empty_segments ? SplitBehavior::KeepEmpty : SplitBehavior::Nothing);
|
||||||
split_strings.ensure_capacity(split.size());
|
split_strings.ensure_capacity(split.size());
|
||||||
for (auto& entry : split)
|
for (auto& entry : split)
|
||||||
split_strings.append(String::from_utf8(entry).release_value_but_fixme_should_propagate_errors());
|
split_strings.append(TRY(String::from_utf8(entry)));
|
||||||
}
|
}
|
||||||
return AST::make_ref_counted<AST::SyntheticNode>(invoking_node.position(), AST::make_ref_counted<AST::ListValue>(move(split_strings)));
|
return AST::make_ref_counted<AST::SyntheticNode>(invoking_node.position(), AST::make_ref_counted<AST::ListValue>(move(split_strings)));
|
||||||
}
|
}
|
||||||
|
@ -364,7 +364,7 @@ RefPtr<AST::Node> Shell::immediate_split(AST::ImmediateExpression& invoking_node
|
||||||
return transform(AST::make_ref_counted<AST::ListValue>(list)->values());
|
return transform(AST::make_ref_counted<AST::ListValue>(list)->values());
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_concat_lists(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_concat_lists(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
NonnullRefPtrVector<AST::Node> result;
|
NonnullRefPtrVector<AST::Node> result;
|
||||||
|
|
||||||
|
@ -372,12 +372,12 @@ RefPtr<AST::Node> Shell::immediate_concat_lists(AST::ImmediateExpression& invoki
|
||||||
if (auto* list = dynamic_cast<const AST::ListConcatenate*>(&argument)) {
|
if (auto* list = dynamic_cast<const AST::ListConcatenate*>(&argument)) {
|
||||||
result.extend(list->list());
|
result.extend(list->list());
|
||||||
} else {
|
} else {
|
||||||
auto list_of_values = const_cast<AST::Node&>(argument).run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
auto list_of_values = TRY(const_cast<AST::Node&>(argument).run(this)->resolve_without_cast(this));
|
||||||
if (auto* list = dynamic_cast<AST::ListValue*>(list_of_values.ptr())) {
|
if (auto* list = dynamic_cast<AST::ListValue*>(list_of_values.ptr())) {
|
||||||
for (auto& entry : static_cast<Vector<NonnullRefPtr<AST::Value>>&>(list->values()))
|
for (auto& entry : static_cast<Vector<NonnullRefPtr<AST::Value>>&>(list->values()))
|
||||||
result.append(AST::make_ref_counted<AST::SyntheticNode>(argument.position(), entry));
|
result.append(AST::make_ref_counted<AST::SyntheticNode>(argument.position(), entry));
|
||||||
} else {
|
} else {
|
||||||
auto values = list_of_values->resolve_as_list(this).release_value_but_fixme_should_propagate_errors();
|
auto values = TRY(list_of_values->resolve_as_list(this));
|
||||||
for (auto& entry : values)
|
for (auto& entry : values)
|
||||||
result.append(AST::make_ref_counted<AST::StringLiteral>(argument.position(), entry, AST::StringLiteral::EnclosureType::None));
|
result.append(AST::make_ref_counted<AST::StringLiteral>(argument.position(), entry, AST::StringLiteral::EnclosureType::None));
|
||||||
}
|
}
|
||||||
|
@ -387,7 +387,7 @@ RefPtr<AST::Node> Shell::immediate_concat_lists(AST::ImmediateExpression& invoki
|
||||||
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), move(result));
|
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_filter_glob(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_filter_glob(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
// filter_glob string list
|
// filter_glob string list
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
|
@ -395,7 +395,7 @@ RefPtr<AST::Node> Shell::immediate_filter_glob(AST::ImmediateExpression& invokin
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto glob_list = const_cast<AST::Node&>(arguments[0]).run(*this)->resolve_as_list(*this).release_value_but_fixme_should_propagate_errors();
|
auto glob_list = TRY(const_cast<AST::Node&>(arguments[0]).run(*this)->resolve_as_list(*this));
|
||||||
if (glob_list.size() != 1) {
|
if (glob_list.size() != 1) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected the <glob> argument to filter_glob to be a single string", arguments[0].position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected the <glob> argument to filter_glob to be a single string", arguments[0].position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -431,7 +431,7 @@ RefPtr<AST::Node> Shell::immediate_filter_glob(AST::ImmediateExpression& invokin
|
||||||
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), move(result));
|
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_join(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_join(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to join", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to join", invoking_node.position());
|
||||||
|
@ -444,166 +444,166 @@ RefPtr<AST::Node> Shell::immediate_join(AST::ImmediateExpression& invoking_node,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto value = const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
auto value = TRY(const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this));
|
||||||
if (!value->is_list()) {
|
if (!value->is_list()) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected the joined list to be a list", arguments[1].position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected the joined list to be a list", arguments[1].position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto delimiter_str = delimiter->resolve_as_list(this).release_value_but_fixme_should_propagate_errors()[0];
|
auto delimiter_str = TRY(delimiter->resolve_as_list(this))[0];
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
builder.join(delimiter_str, value->resolve_as_list(*this).release_value_but_fixme_should_propagate_errors());
|
builder.join(delimiter_str, TRY(value->resolve_as_list(*this)));
|
||||||
|
|
||||||
return AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), builder.to_string().release_value_but_fixme_should_propagate_errors(), AST::StringLiteral::EnclosureType::None);
|
return AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), TRY(builder.to_string()), AST::StringLiteral::EnclosureType::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_value_or_default(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_value_or_default(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to value_or_default", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to value_or_default", invoking_node.position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
auto name = TRY(const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this));
|
||||||
if (!local_variable_or(name, ""sv).is_empty())
|
if (!local_variable_or(name, ""sv).is_empty())
|
||||||
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||||
|
|
||||||
return arguments.last();
|
return arguments.last();
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_assign_default(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_assign_default(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to assign_default", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to assign_default", invoking_node.position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
auto name = TRY(const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this));
|
||||||
if (!local_variable_or(name, ""sv).is_empty())
|
if (!local_variable_or(name, ""sv).is_empty())
|
||||||
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||||
|
|
||||||
auto value = const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_without_cast(*this).release_value_but_fixme_should_propagate_errors();
|
auto value = TRY(const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_without_cast(*this));
|
||||||
set_local_variable(name.to_deprecated_string(), value);
|
set_local_variable(name.to_deprecated_string(), value);
|
||||||
|
|
||||||
return make_ref_counted<AST::SyntheticNode>(invoking_node.position(), value);
|
return make_ref_counted<AST::SyntheticNode>(invoking_node.position(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_error_if_empty(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_error_if_empty(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to error_if_empty", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to error_if_empty", invoking_node.position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
auto name = TRY(const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this));
|
||||||
if (!local_variable_or(name, ""sv).is_empty())
|
if (!local_variable_or(name, ""sv).is_empty())
|
||||||
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||||
|
|
||||||
auto error_value = const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
auto error_value = TRY(const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_as_string(*this));
|
||||||
if (error_value.is_empty())
|
if (error_value.is_empty())
|
||||||
error_value = String::formatted("Expected {} to be non-empty", name).release_value_but_fixme_should_propagate_errors();
|
error_value = TRY(String::formatted("Expected {} to be non-empty", name));
|
||||||
|
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, error_value.bytes_as_string_view(), invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, error_value.bytes_as_string_view(), invoking_node.position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_null_or_alternative(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_null_or_alternative(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to null_or_alternative", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to null_or_alternative", invoking_node.position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto value = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_without_cast(*this).release_value_but_fixme_should_propagate_errors();
|
auto value = TRY(const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_without_cast(*this));
|
||||||
if ((value->is_string() && value->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors().is_empty()) || (value->is_list() && value->resolve_as_list(*this).release_value_but_fixme_should_propagate_errors().is_empty()))
|
if ((value->is_string() && TRY(value->resolve_as_string(*this)).is_empty()) || (value->is_list() && TRY(value->resolve_as_list(*this)).is_empty()))
|
||||||
return make_ref_counted<AST::SyntheticNode>(invoking_node.position(), value);
|
return make_ref_counted<AST::SyntheticNode>(invoking_node.position(), value);
|
||||||
|
|
||||||
return arguments.last();
|
return arguments.last();
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_defined_value_or_default(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_defined_value_or_default(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to defined_value_or_default", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to defined_value_or_default", invoking_node.position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
auto name = TRY(const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this));
|
||||||
if (!find_frame_containing_local_variable(name))
|
if (!find_frame_containing_local_variable(name))
|
||||||
return arguments.last();
|
return arguments.last();
|
||||||
|
|
||||||
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_assign_defined_default(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_assign_defined_default(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to assign_defined_default", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to assign_defined_default", invoking_node.position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
auto name = TRY(const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this));
|
||||||
if (find_frame_containing_local_variable(name))
|
if (find_frame_containing_local_variable(name))
|
||||||
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||||
|
|
||||||
auto value = const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_without_cast(*this).release_value_but_fixme_should_propagate_errors();
|
auto value = TRY(const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_without_cast(*this));
|
||||||
set_local_variable(name.to_deprecated_string(), value);
|
set_local_variable(name.to_deprecated_string(), value);
|
||||||
|
|
||||||
return make_ref_counted<AST::SyntheticNode>(invoking_node.position(), value);
|
return make_ref_counted<AST::SyntheticNode>(invoking_node.position(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_error_if_unset(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_error_if_unset(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to error_if_unset", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to error_if_unset", invoking_node.position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
auto name = TRY(const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this));
|
||||||
if (find_frame_containing_local_variable(name))
|
if (find_frame_containing_local_variable(name))
|
||||||
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||||
|
|
||||||
auto error_value = const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
auto error_value = TRY(const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_as_string(*this));
|
||||||
if (error_value.is_empty())
|
if (error_value.is_empty())
|
||||||
error_value = String::formatted("Expected {} to be set", name).release_value_but_fixme_should_propagate_errors();
|
error_value = TRY(String::formatted("Expected {} to be set", name));
|
||||||
|
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, error_value.bytes_as_string_view(), invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, error_value.bytes_as_string_view(), invoking_node.position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_null_if_unset_or_alternative(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_null_if_unset_or_alternative(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2) {
|
if (arguments.size() != 2) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to null_if_unset_or_alternative", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 2 arguments to null_if_unset_or_alternative", invoking_node.position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
auto name = TRY(const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this));
|
||||||
if (!find_frame_containing_local_variable(name))
|
if (!find_frame_containing_local_variable(name))
|
||||||
return arguments.last();
|
return arguments.last();
|
||||||
|
|
||||||
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_reexpand(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_reexpand(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1) {
|
if (arguments.size() != 1) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 1 argument to reexpand", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 1 argument to reexpand", invoking_node.position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto value = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
auto value = TRY(const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this));
|
||||||
return parse(value, m_is_interactive, false);
|
return parse(value, m_is_interactive, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::immediate_length_of_variable(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::immediate_length_of_variable(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1) {
|
if (arguments.size() != 1) {
|
||||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 1 argument to length_of_variable", invoking_node.position());
|
raise_error(ShellError::EvaluatedSyntaxError, "Expected exactly 1 argument to length_of_variable", invoking_node.position());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
auto name = TRY(const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this));
|
||||||
auto variable = make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
auto variable = make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||||
|
|
||||||
return immediate_length_impl(
|
return immediate_length_impl(
|
||||||
|
@ -612,7 +612,7 @@ RefPtr<AST::Node> Shell::immediate_length_of_variable(AST::ImmediateExpression&
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AST::Node> Shell::run_immediate_function(StringView str, AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
ErrorOr<RefPtr<AST::Node>> Shell::run_immediate_function(StringView str, AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||||
{
|
{
|
||||||
#define __ENUMERATE_SHELL_IMMEDIATE_FUNCTION(name) \
|
#define __ENUMERATE_SHELL_IMMEDIATE_FUNCTION(name) \
|
||||||
if (str == #name) \
|
if (str == #name) \
|
||||||
|
|
|
@ -156,7 +156,7 @@ public:
|
||||||
bool run_file(DeprecatedString const&, bool explicitly_invoked = true);
|
bool run_file(DeprecatedString const&, bool explicitly_invoked = true);
|
||||||
ErrorOr<bool> run_builtin(const AST::Command&, NonnullRefPtrVector<AST::Rewiring> const&, int& retval);
|
ErrorOr<bool> run_builtin(const AST::Command&, NonnullRefPtrVector<AST::Rewiring> const&, int& retval);
|
||||||
bool has_builtin(StringView) const;
|
bool has_builtin(StringView) const;
|
||||||
RefPtr<AST::Node> run_immediate_function(StringView name, AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const&);
|
ErrorOr<RefPtr<AST::Node>> run_immediate_function(StringView name, AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const&);
|
||||||
static bool has_immediate_function(StringView);
|
static bool has_immediate_function(StringView);
|
||||||
void block_on_job(RefPtr<Job>);
|
void block_on_job(RefPtr<Job>);
|
||||||
void block_on_pipeline(RefPtr<AST::Pipeline>);
|
void block_on_pipeline(RefPtr<AST::Pipeline>);
|
||||||
|
@ -423,13 +423,13 @@ private:
|
||||||
virtual void custom_event(Core::CustomEvent&) override;
|
virtual void custom_event(Core::CustomEvent&) override;
|
||||||
|
|
||||||
#define __ENUMERATE_SHELL_IMMEDIATE_FUNCTION(name) \
|
#define __ENUMERATE_SHELL_IMMEDIATE_FUNCTION(name) \
|
||||||
RefPtr<AST::Node> immediate_##name(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const&);
|
ErrorOr<RefPtr<AST::Node>> immediate_##name(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const&);
|
||||||
|
|
||||||
ENUMERATE_SHELL_IMMEDIATE_FUNCTIONS();
|
ENUMERATE_SHELL_IMMEDIATE_FUNCTIONS();
|
||||||
|
|
||||||
#undef __ENUMERATE_SHELL_IMMEDIATE_FUNCTION
|
#undef __ENUMERATE_SHELL_IMMEDIATE_FUNCTION
|
||||||
|
|
||||||
RefPtr<AST::Node> immediate_length_impl(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const&, bool across);
|
ErrorOr<RefPtr<AST::Node>> immediate_length_impl(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const&, bool across);
|
||||||
|
|
||||||
#define __ENUMERATE_SHELL_BUILTIN(builtin) \
|
#define __ENUMERATE_SHELL_BUILTIN(builtin) \
|
||||||
ErrorOr<int> builtin_##builtin(Main::Arguments);
|
ErrorOr<int> builtin_##builtin(Main::Arguments);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue