//============================================================================//
// //
// 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 . //
// //
//============================================================================//
#pragma once
#include
#include
#include
template
requires(
std::is_convertible_v, std::string_view> and
std::is_same_v, std::ranges::range_value_t>
)
arti::lang::Generator>
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
WhitespaceGenerator(uint32_t maxLen = 5) {
constexpr std::array spaceChars{ ' ', '\t', '\n' };
std::string str;
std::random_device device;
std::mt19937 engine(device());
std::uniform_int_distribution dist(1, maxLen);
std::uniform_int_distribution 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
requires(std::is_same_v, std::string_view>)
static std::string SourceFromTokens(R &&tokens) {
return InterleaveRanges(tokens, WhitespaceGenerator(10)) | std::views::join |
std::ranges::to();
}