Skip to content

Commit

Permalink
feat: add builtin type() (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
hrzlgnm authored Dec 15, 2024
1 parent 80d300a commit 8612ea3
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 8 deletions.
21 changes: 19 additions & 2 deletions source/eval/ast_eval.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <algorithm>
#include <cstdint>
#include <deque>
#include <sstream>
#include <variant>

#include <ast/array_expression.hpp>
Expand Down Expand Up @@ -490,10 +491,23 @@ const builtin_function_expression builtin_push {
}
return make_error("argument of type {} and {} to push() are not supported", lhs->type(), rhs->type());
}};
const builtin_function_expression builtin_type {
"type",
{"val"},
[](const array_object::array& arguments) -> const object*
{
if (arguments.size() != 1) {
return make_error("wrong number of arguments to type(): expected=1, got={}", arguments.size());
}
const auto& val = arguments[0];
std::ostringstream strm;
strm << val->type();
return make<string_object>(strm.str());
}};
} // namespace

const std::vector<const builtin_function_expression*> builtin_function_expression::builtins {
&builtin_len, &builtin_puts, &builtin_first, &builtin_last, &builtin_rest, &builtin_push};
&builtin_len, &builtin_puts, &builtin_first, &builtin_last, &builtin_rest, &builtin_push, &builtin_type};

auto callable_expression::eval(environment* env) const -> const object*
{
Expand Down Expand Up @@ -584,7 +598,7 @@ auto run(std::string_view input) -> const object*
auto [prgrm, _] = check_program(input);
environment env;
for (const auto& builtin : builtin_function_expression::builtins) {
env.set(builtin->name, make<function_object>(builtin, nullptr));
env.set(builtin->name, make<builtin_object>(builtin));
}
auto result = prgrm->eval(&env);
return result;
Expand Down Expand Up @@ -931,6 +945,9 @@ TEST_CASE("builtinFunctions")
bt {R"(push([], "abc"))", array {{"abc"}}},
bt {R"(push("", "a"))", "a"},
bt {R"(push("c", "abc"))", "cabc"},
bt {R"(type("c"))", "string"},
bt {R"(type())", error {"wrong number of arguments to type(): expected=1, got=0"}},
bt {R"(type(type))", {"builtin"}},
};

for (const auto& test : tests) {
Expand Down
7 changes: 7 additions & 0 deletions source/eval/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
#include <fmt/ranges.h>
#include <overloaded.hpp>

builtin_object::builtin_object(const builtin_function_expression* bltn)

: function_object {bltn, nullptr}
, builtin {bltn}
{
}

auto operator<<(std::ostream& ostrm, object::object_type type) -> std::ostream&
{
using enum object::object_type;
Expand Down
9 changes: 3 additions & 6 deletions source/eval/object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,20 +300,17 @@ struct closure_object : object

[[nodiscard]] auto type() const -> object_type override { return object_type::closure; }

[[nodiscard]] auto inspect() const -> std::string override { return "closure{...}"; }
[[nodiscard]] auto inspect() const -> std::string override { return "fn<closure>{...}"; }

const compiled_function_object* fn {};
std::vector<const object*> free;
};

struct builtin_function_expression;

struct builtin_object : object
struct builtin_object : function_object
{
explicit builtin_object(const builtin_function_expression* bltn)
: builtin {bltn}
{
}
explicit builtin_object(const builtin_function_expression* bltn);

[[nodiscard]] auto type() const -> object_type override { return object_type::builtin; }

Expand Down
1 change: 1 addition & 0 deletions source/vm/vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,7 @@ TEST_CASE("callBuiltins")
vt<int64_t, null_type, std::string, std::vector<int>> {R"(rest([]))", null_value},
vt<int64_t, null_type, std::string, std::vector<int>> {R"(push([], 1))", maker<int>({1})},
vt<int64_t, null_type, std::string, std::vector<int>> {R"(last([1, 2, 3]))", 3},
vt<int64_t, null_type, std::string, std::vector<int>> {R"(type([]))", "array"},
};
const std::array errortests {
vt<error> {
Expand Down

0 comments on commit 8612ea3

Please sign in to comment.