Skip to content

Commit

Permalink
fixed bug related to struct literals, implemented builtin function `t…
Browse files Browse the repository at this point in the history
…rim()`
  • Loading branch information
mgerhold committed Dec 2, 2023
1 parent 138bd98 commit 1ec8421
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/builtin_function_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ enum class BuiltinFunctionType {
Delete,
Write,
Read,
Trim,
};

[[nodiscard]] constexpr std::string_view to_view(BuiltinFunctionType const type) {
Expand All @@ -23,6 +24,8 @@ enum class BuiltinFunctionType {
return "write";
case BuiltinFunctionType::Read:
return "read";
case BuiltinFunctionType::Trim:
return "trim";
}
assert(false and "unreachable");
return "";
Expand Down
5 changes: 3 additions & 2 deletions src/expressions/struct_literal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ values::Value expressions::StructLiteral::evaluate(ScopeStack& scope_stack) cons
auto value_members = std::unordered_map<std::string, values::Value>{};

for (auto const& [name, value] : m_initializers) {
auto const& [iterator, inserted] =
value_members.insert({ std::string{ name.lexeme() }, value->evaluate(scope_stack) });
auto evaluated = value->evaluate(scope_stack);
evaluated->promote_to_lvalue();
auto const& [iterator, inserted] = value_members.insert({ std::string{ name.lexeme() }, std::move(evaluated) });
if (not inserted) {
// todo: throw different exception type
throw std::runtime_error{ "duplicate struct initializer" };
Expand Down
3 changes: 3 additions & 0 deletions src/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ void interpret(statements::Statements const& program) {
scope_stack.top().insert(
{ "read", values::BuiltinFunction::make(BuiltinFunctionType::Read, values::ValueCategory::Rvalue) }
);
scope_stack.top().insert(
{ "trim", values::BuiltinFunction::make(BuiltinFunctionType::Trim, values::ValueCategory::Rvalue) }
);
for (auto const& statement : program) {
statement->execute(scope_stack);
}
Expand Down
39 changes: 39 additions & 0 deletions src/values/builtin_function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ namespace values {
return write(scope_stack, arguments);
case BuiltinFunctionType::Read:
return read(scope_stack, arguments);
case BuiltinFunctionType::Trim:
return trim(scope_stack, arguments);
}
throw std::runtime_error{ "unreachable" };
}
Expand Down Expand Up @@ -276,6 +278,43 @@ namespace values {

return String::make(stream.str(), ValueCategory::Rvalue);
}

[[nodiscard]] Value trim(
ScopeStack& scope_stack,
std::vector<std::unique_ptr<expressions::Expression>> const& arguments
) const { // clang-format on
if (arguments.size() != 1) {
throw WrongNumberOfArguments{ to_view(m_type), 2, arguments.size() };
}

auto values = std::vector<Value>{};
values.reserve(arguments.size());
for (auto const& argument : arguments) {
values.push_back(argument->evaluate(scope_stack));
}

if (values.at(0)->type() != types::make_string()) {
throw WrongArgumentType{ to_view(m_type), "to_be_trimmed", values.at(0)->type() };
}

auto string = values.at(0)->as_string().string_representation();
auto const left_find_iterator =
std::find_if(string.cbegin(), string.cend(), [](char const c) { return not std::isspace(c); });
if (left_find_iterator == string.cend()) {
// only whitespace found
return String::make("", ValueCategory::Rvalue);
}
string.erase(string.cbegin(), left_find_iterator);

auto const right_find_iterator =
std::find_if(string.crbegin(), string.crend(), [](char const c) { return not std::isspace(c); });
if (right_find_iterator == string.crend()) {
return String::make(std::move(string), ValueCategory::Rvalue);
}
string.erase(right_find_iterator.base(), string.cend());

return String::make(std::move(string), ValueCategory::Rvalue);
}
};

} // namespace values

0 comments on commit 1ec8421

Please sign in to comment.