Browse Source

Env: Add string/number conversion functions

master
Riyyi 1 year ago
parent
commit
9db041946e
  1. 90
      src/env/functions/convert.cpp

90
src/env/functions/convert.cpp vendored

@ -4,6 +4,9 @@
* SPDX-License-Identifier: MIT
*/
#include <charconv> // std::from_chars, std::to_chars
#include <system_error> // std::errc
#include "ast.h"
#include "env/macro.h"
#include "util.h"
@ -12,6 +15,79 @@ namespace blaze {
void Environment::loadConvert()
{
// (number-to-string 123) -> "123"
ADD_FUNCTION(
"number-to-string",
{
CHECK_ARG_COUNT_IS("number-to-string", SIZE(), 1);
VALUE_CAST(number, Number, (*begin));
char result[32];
auto conversion = std::to_chars(result,
result + sizeof(result),
number->number());
if (conversion.ec != std::errc()) {
return makePtr<Constant>(Constant::Nil);
}
return makePtr<String>(std::string(result, conversion.ptr - result));
});
// (string-to-char "123") -> 49
ADD_FUNCTION(
"string-to-char",
{
CHECK_ARG_COUNT_IS("string-to-char", SIZE(), 1);
VALUE_CAST(string_value, String, (*begin));
std::string data = string_value->data();
return makePtr<Number>(data.c_str()[0]);
});
// (string-to-number "123") -> 123
ADD_FUNCTION(
"string-to-number",
{
CHECK_ARG_COUNT_IS("string-to-number", SIZE(), 1);
VALUE_CAST(string_value, String, (*begin));
std::string data = string_value->data();
int64_t result;
auto conversion = std::from_chars(data.c_str(),
data.c_str() + data.size(),
result);
if (conversion.ec != std::errc()) {
return makePtr<Constant>(Constant::Nil);
}
return makePtr<Number>(result);
});
#define STRING_TO_COLLECTION(name, type) \
{ \
CHECK_ARG_COUNT_IS(name, SIZE(), 1); \
\
VALUE_CAST(string_value, String, (*begin)); \
std::string data = string_value->data(); \
\
ValueVector nodes(data.size()); \
for (size_t i = 0; i < data.size(); ++i) { \
nodes.at(i) = makePtr<Number>(data.c_str()[i]); \
} \
\
return makePtr<type>(nodes); \
}
// (string-to-list "foo") -> (102 111 111)
// (string-to-vector "foo") -> [102 111 111]
ADD_FUNCTION("string-to-list", STRING_TO_COLLECTION("string-to-list", List));
ADD_FUNCTION("string-to-vector", STRING_TO_COLLECTION("string-to-vector", Vector));
// -------------------------------------
// (symbol "foo") -> foo
ADD_FUNCTION(
"symbol",
@ -22,9 +98,9 @@ void Environment::loadConvert()
return *begin;
}
VALUE_CAST(stringValue, String, (*begin));
VALUE_CAST(string_value, String, (*begin));
return makePtr<Symbol>(stringValue->data());
return makePtr<Symbol>(string_value->data());
});
// (keyword "foo") -> :foo
@ -32,20 +108,20 @@ void Environment::loadConvert()
ADD_FUNCTION(
"keyword",
{
CHECK_ARG_COUNT_IS("symbol", SIZE(), 1);
CHECK_ARG_COUNT_IS("keyword", SIZE(), 1);
if (is<Keyword>(begin->get())) {
return *begin;
}
else if (is<Number>(begin->get())) {
VALUE_CAST(numberValue, Number, (*begin));
VALUE_CAST(number_value, Number, (*begin));
return makePtr<Keyword>(numberValue->number());
return makePtr<Keyword>(number_value->number());
}
VALUE_CAST(stringValue, String, (*begin));
VALUE_CAST(string_value, String, (*begin));
return makePtr<Keyword>(stringValue->data());
return makePtr<Keyword>(string_value->data());
});
}

Loading…
Cancel
Save