#include "Relooper.h"
#include <string.h>
#include <stdlib.h>
#include <list>
#include <stack>
#include "ministring.h"
// TODO: move all set to unorderedset
#if DEBUG
static void PrintDebug(const char *Format, ...);
#define DebugDump(x, ...) Debugging::Dump(x, __VA_ARGS__)
#else
#define PrintDebug(x, ...)
#define DebugDump(x, ...)
#endif
struct Indenter {
static int CurrIndent;
static void Indent() { CurrIndent++; }
static void Unindent() { CurrIndent--; }
};
static void PrintIndented(const char *Format, ...);
static void PutIndented(const char *String);
static char *OutputBufferRoot = NULL;
static char *OutputBuffer = NULL;
static int OutputBufferSize = 0;
void PrintIndented(const char *Format, ...) {
assert(OutputBuffer);
assert(OutputBuffer + Indenter::CurrIndent*2 - OutputBufferRoot < OutputBufferSize);
for (int i = 0; i < Indenter::CurrIndent*2; i++, OutputBuffer++) *OutputBuffer = ' ';
va_list Args;
va_start(Args, Format);
int left = OutputBufferSize - (OutputBuffer - OutputBufferRoot);
int written = vsnprintf(OutputBuffer, left, Format, Args);
assert(written < left);
OutputBuffer += written;
va_end(Args);
}
void PutIndented(const char *String) {
assert(OutputBuffer);
assert(OutputBuffer + Indenter::CurrIndent*2 - OutputBufferRoot < OutputBufferSize);
for (int i = 0; i < Indenter::CurrIndent*2; i++, OutputBuffer++) *OutputBuffer = ' ';
int left = OutputBufferSize - (OutputBuffer - OutputBufferRoot);
int needed = strlen(String)+1;
assert(needed < left);
strcpy(OutputBuffer, String);
OutputBuffer += strlen(String);
*OutputBuffer++ = '\n';
*OutputBuffer = 0;
}
static int AsmJS = 0;
// Indenter
#if EMSCRIPTEN
int Indenter::CurrIndent = 1;
#else
int Indenter::CurrIndent = 0;
#endif
// Branch
Branch::Branch(const char *ConditionInit, const char *CodeInit) : Ancestor(NULL), Labeled(false) {
Condition = ConditionInit ? strdup(ConditionInit) : NULL;
Code = CodeInit ? strdup(CodeInit) : NULL;
}
Branch::~Branch() {
if (Condition) free((void*)Condition);
if (Code) free((void*)Code);
}
void Branch::Render(Block *Target, bool SetLabel) {
if (Code) PrintIndented("%s\n", Code);
if (SetLabel) PrintIndented("label = %d;\n", Target->Id);
if (Ancestor) {
if (Type != Direct) {
if (Labeled) {
PrintIndented("%s L%d;\n", Type == Break ? "break" : "continue", Ancestor->Id);
} else {
PrintIndented("%s;\n", Type == Break ? "break" : "continue");