#pragma once #include namespace lispoo { inline std::shared_ptr sum(const std::shared_ptr& args) { len_eq(args, 2); auto a = args->value()[0], b = args->value()[1]; if (a->type() == Type::Float && b->type() == Type::Float) { return std::make_shared(std::static_pointer_cast(a)->value() + std::static_pointer_cast(b)->value()); } if (a->type() == Type::Integer && b->type() == Type::Integer) { return std::make_shared(std::static_pointer_cast(a)->value() + std::static_pointer_cast(b)->value()); } if (a->type() == Type::Float) { return std::make_shared(std::static_pointer_cast(a)->value() + std::static_pointer_cast(b)->value()); } if (b->type() == Type::Float) { return std::make_shared(std::static_pointer_cast(a)->value() + std::static_pointer_cast(b)->value()); } } inline std::shared_ptr message(const std::shared_ptr& expr) { if (!expr) { return null_expr; } auto type = expr->type(); switch (type) { case Type::Null: { std::cout << "nil"; break; } case Type::Integer: { std::cout << std::static_pointer_cast(expr)->value(); break; } case Type::Float: { std::cout << std::static_pointer_cast(expr)->value(); break; } case Type::Symbol: { std::cout << std::static_pointer_cast(expr)->value(); break; } case Type::Callable: { std::cout << ": " << expr.get(); break; } case Type::List: { auto& value = std::static_pointer_cast(expr)->value(); std::cout << "("; for (auto i = 0; i < value.size(); ++i) { if (i > 0) { std::cout << " "; } message(value[i]); } std::cout << ")"; } default: break; } return null_expr; } } // namespace lispoo