python2ruby/src/indent_stack.hpp
2025-11-25 16:24:09 +01:00

86 lines
No EOL
1.6 KiB
C++

#pragma once
#include <stack>
enum class IndentAction
{
Indent,
Dedent,
None
};
constexpr int TAB_WIDTH = 8;
constexpr char TAB = '\t';
class IndentStack
{
std::stack<int> 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);
}
};