#pragma once #include enum class IndentAction { Indent, Dedent, None }; constexpr int TAB_WIDTH = 8; constexpr char TAB = '\t'; class IndentStack { std::stack indent_stack; int dedent_queue = 0; public: IndentStack() { indent_stack.push(0); } IndentAction updateIndentation(int spaces) { int current = indent_stack.top(); if (spaces == current) { return IndentAction::None; } if (spaces > current) { indent_stack.push(spaces); return IndentAction::Indent; } while (!indent_stack.empty() && indent_stack.top() > spaces) { indent_stack.pop(); dedent_queue++; } if (dedent_queue > 0) { dedent_queue--; return IndentAction::Dedent; } return IndentAction::None; } bool popDedent() { if (dedent_queue <= 0) { return false; } dedent_queue--; return true; } static int calculateColumn(const char *text, int length) { int spaces = 0; for (int i = 0; i < length; i++) { if (text[i] == TAB) { spaces += TAB_WIDTH - (spaces % TAB_WIDTH); continue; } spaces++; } return spaces; } bool hasRemainingDedents() { return dedent_queue > 0; } IndentAction closeBlock() { // Force indentation reset at EOF return updateIndentation(0); } };