sdl_runtime_compiler git · main
SDL3 game for running and compiling code at runtime
C++ 72.3% C 26.2%git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gzsrc/systems/carry_lex.cpp raw
#include "carry_lex.hpp"
#include <SDL3/SDL.h>
#include <string>
#include "systems/carry_system.hpp"
#include "text/text.hpp"
#include "text/token.hpp"
namespace
Nimbin
{
// Re-lex the entire carried line as ONE source string, then assign each word a
// context colour by mapping highlight spans onto its byte range. Mirrors
// Handler::apply_Highlight, but synchronous and scoped to a single joined line.
void
CarryLex::lex_CarriedLine(CarriedLine& carry)
{
// 1) Build the joined source + per-token byte spans, in reading order.
// NOTE: nodes() is front->back. If the carried line reads right-to-left
// on screen (get_SlotPosition lays out from `last` with decreasing
// offset), switch this to reverse_nodes() so "int x" lexes as "int x"
// and not "x int". Verify against the on-screen order once.
std::string src;
DynArray<Text::Token::Data*> toks;
for (CarriedWordNode* n : carry.nodes()) {
if (!n->word) continue;
Text::Token::Data* t = n->word.get();
if (!src.empty()) src += ' ';
t->byte_begin = src.size();
src += t->text;
t->byte_end = src.size();
toks.push_back(t);
}
if (toks.empty()) return;
// 2) Classify the whole line as one context.
DynArray<Text::HiSpan> spans = Text::CppHighlight::classify(src);
// 3) Map spans -> tokens by maximum byte overlap.
for (Text::Token::Data* t : toks) {
size_t best = 0;
Text::Token::Type type = Text::Token::Type::Identifier;
bool found = false;
for (const Text::HiSpan& s : spans) {
size_t lo = (t->byte_begin > s.byte_begin) ? t->byte_begin : s.byte_begin;
size_t hi = (t->byte_end < s.byte_end) ? t->byte_end : s.byte_end;
if (lo < hi) {
size_t ov = hi - lo;
if (ov > best) { best = ov; type = s.type; found = true; }
}
}
t->set_ColorSource(Text::ColorSource::Lexed); // carried line is a context
if (found) t->set_Context(Text::Token::get_Color(type));
else t->clear_Context(); // no span -> single fallback
}
}
// A word that leaves the carried line is no longer in a context: drop the
// context flag and select its lone (single) colour, the same colour it shows on
// the floor or as a projectile.
void
CarryLex::revert_ToSingle(Text::Token::Data* word)
{
if (!word) return;
word->clear_Context();
word->set_ColorSource(Text::ColorSource::Lint);
}
} // namespace Nimbin