erick-alcachofa b99f3586dc
chore(license): Added NOTICE header to all source files
Signed-off-by: erick-alcachofa <erick@artichoke.dev>
2025-12-25 13:12:41 -06:00

82 lines
3.1 KiB
C++

//============================================================================//
// //
// artichoke programming language //
// //
// Copyright (C) 2025 Erick Saul Guzman Ramos, whoami.artichoke.dev //
// //
// //
// This program is free software: you can redistribute it and/or modify //
// it under the terms of the GNU Affero General Public License as published //
// by the Free Software Foundation, either version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU Affero General Public License for more details. //
// //
// You should have received a copy of the GNU Affero General Public License //
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
// //
//============================================================================//
#pragma once
#include <random>
#include <ranges>
#include <artichoke/Coroutine/Generator.hpp>
template <std::ranges::range R1, std::ranges::range R2>
requires(
std::is_convertible_v<std::ranges::range_value_t<R1>, std::string_view> and
std::is_same_v<std::ranges::range_value_t<R1>, std::ranges::range_value_t<R2>>
)
arti::lang::Generator<std::ranges::range_value_t<R1>>
InterleaveRanges(R1 &&r1, R2 &&r2) {
auto it1 = std::ranges::begin(r1);
auto end1 = std::ranges::end(r1);
auto it2 = std::ranges::begin(r2);
auto end2 = std::ranges::end(r2);
while (it1 != end1 && it2 != end2) {
yield *it1;
++it1;
yield *it2;
++it2;
}
}
static arti::lang::Generator<std::string_view>
WhitespaceGenerator(uint32_t maxLen = 5) {
constexpr std::array<char, 3> spaceChars{ ' ', '\t', '\n' };
std::string str;
std::random_device device;
std::mt19937 engine(device());
std::uniform_int_distribution<uint32_t> dist(1, maxLen);
std::uniform_int_distribution<uint32_t> distChars(0, 2);
str.reserve(maxLen);
while (true) {
str.resize(0);
auto sz = dist(engine);
for (uint32_t i = 0; i < sz; ++i) {
str += spaceChars[distChars(engine)];
}
yield str;
}
}
template <std::ranges::range R>
requires(std::is_same_v<std::ranges::range_value_t<R>, std::string_view>)
static std::string SourceFromTokens(R &&tokens) {
return InterleaveRanges(tokens, WhitespaceGenerator(10)) | std::views::join |
std::ranges::to<std::string>();
}