Skip to content

Commit

Permalink
debugger stepper
Browse files Browse the repository at this point in the history
  • Loading branch information
marcj committed Jun 23, 2022
1 parent bf2b724 commit 57900ee
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 113 deletions.
10 changes: 10 additions & 0 deletions libs/imgui-texteditor-fork/TextEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1085,11 +1085,21 @@ void TextEditor::Render()
// Render inline errors
if (true) {
for (auto &&inlineError: inlineErrors) {
if (inlineError.line < lineStart || inlineError.line > lineMax) continue;

ImVec2 lineStartScreenPos = ImVec2(cursorScreenPos.x, cursorScreenPos.y + inlineError.line * mCharAdvance.y);
auto start = ImVec2(lineStartScreenPos.x + mTextStart + scrollX + (mCharAdvance.x * inlineError.charPos), lineStartScreenPos.y + mCharAdvance.y);
auto end = ImVec2(lineStartScreenPos.x + mTextStart + scrollX + (mCharAdvance.x * inlineError.charEnd), lineStartScreenPos.y + mCharAdvance.y);
drawList->AddLine(start, end, mPalette[(int) PaletteIndex::ErrorMarker], 2);
}

for (auto &&highlight: highlights) {
if (highlight.line < lineStart || highlight.line > lineMax) continue;
ImVec2 lineStartScreenPos = ImVec2(cursorScreenPos.x, cursorScreenPos.y + highlight.line * mCharAdvance.y);
auto start = ImVec2(lineStartScreenPos.x + mTextStart + scrollX + (mCharAdvance.x * highlight.charPos), lineStartScreenPos.y);
auto end = ImVec2(lineStartScreenPos.x + mTextStart + scrollX + (mCharAdvance.x * highlight.charEnd), lineStartScreenPos.y + mCharAdvance.y);
drawList->AddRectFilled(start, end, mPalette[(int)PaletteIndex::Selection]);
}
}

// Draw a tooltip on known identifiers/preprocessor symbols
Expand Down
7 changes: 7 additions & 0 deletions libs/imgui-texteditor-fork/TextEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ class TextEditor
void *data = nullptr;
};

struct Highlight {
int line;
int charPos;
int charEnd;
};

struct LanguageDefinition
{
typedef std::pair<std::string, PaletteIndex> TokenRegexString;
Expand Down Expand Up @@ -274,6 +280,7 @@ class TextEditor
static const Palette& GetRetroBluePalette();

std::vector<InlineError> inlineErrors;
std::vector<Highlight> highlights;
std::function<void(ImVec2&, ImVec2&, InlineError&)> inlineErrorHover;
private:
typedef std::vector<std::pair<std::regex, PaletteIndex>> RegexList;
Expand Down
8 changes: 7 additions & 1 deletion src/checker/checks.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ namespace ts::vm {
}

DiagnosticMessage errorMessage() {
auto [left, right] = stack.back();
// auto [left, right] = stack.back();
auto [left, right] = stack.front();
auto message = fmt::format("Type '{}' is not assignable to type '{}'", stringify(left), stringify(right));

return DiagnosticMessage(message, left->ip);
Expand Down Expand Up @@ -187,6 +188,11 @@ namespace ts::vm {
if (left->kind == TypeKind::Literal) return to<TypeLiteral>(left)->type == TypeLiteralType::Number ? stack.valid() : stack.failed();
return stack.failed();
}
case TypeKind::Boolean: {
if (left->kind == TypeKind::Boolean) return stack.valid();
if (left->kind == TypeKind::Literal) return to<TypeLiteral>(left)->type == TypeLiteralType::Boolean ? stack.valid() : stack.failed();
return stack.failed();
}
case TypeKind::Literal: {
if (left->kind == TypeKind::Literal) {
return to<TypeLiteral>(left)->type == to<TypeLiteral>(right)->type && to<TypeLiteral>(left)->text() == to<TypeLiteral>(right)->text() ? stack.valid() : stack.failed();
Expand Down
22 changes: 13 additions & 9 deletions src/checker/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,10 @@ namespace ts::checker {
}

void pushError(ErrorCode code, const shared<Node> &node) {
pushOp(OP::Error, node);
pushUint16((unsigned int)code);
//errors need to be part of main
sourceMap.push(0, node->pos, node->end);
ops.push_back(OP::Error);
writeUint16(ops, ops.size(), (unsigned int)code);
}

void pushSymbolAddress(Symbol &symbol) {
Expand Down Expand Up @@ -241,9 +243,9 @@ namespace ts::checker {
ops.push_back(op);
}

void pushOp(OP op, const shared<Node> &node) {
void pushOp(OP op, const sharedOpt<Node> &node) {
auto &ops = getOPs();
pushSourceMap(node);
if (node) pushSourceMap(node);
ops.push_back(op);
}

Expand Down Expand Up @@ -431,6 +433,8 @@ namespace ts::checker {
}
break;
}
case types::SyntaxKind::NeverKeyword: program.pushOp(OP::Never, node);
break;
case types::SyntaxKind::BooleanKeyword: program.pushOp(OP::Boolean, node);
break;
case types::SyntaxKind::StringKeyword: program.pushOp(OP::String, node);
Expand Down Expand Up @@ -514,7 +518,7 @@ namespace ts::checker {
const auto name = to<Identifier>(n->typeName)->escapedText;
auto symbol = program.findSymbol(name);
if (!symbol) {
program.pushOp(OP::Never);
program.pushOp(OP::Never, n->typeName);
program.pushError(ErrorCode::CannotFind, n->typeName);
} else {
if (symbol->type == SymbolType::TypeVariable) {
Expand Down Expand Up @@ -675,7 +679,7 @@ namespace ts::checker {
const auto n = to<Identifier>(node);
auto symbol = program.findSymbol(n->escapedText);
if (!symbol) {
program.pushOp(OP::Never);
program.pushOp(OP::Never, n);
program.pushError(ErrorCode::CannotFind, n);
} else {
if (symbol->type == SymbolType::TypeVariable) {
Expand Down Expand Up @@ -863,12 +867,12 @@ namespace ts::checker {
//in the subroutine of the conditional type we place a new type variable, which acts as input.
//the `Distribute` OP makes then sure that the current stack entry is used as input
program.pushSymbol(distributiveOverIdentifier->escapedText, SymbolType::TypeVariable, distributiveOverIdentifier);
program.pushOp(instructions::TypeArgument);
program.pushOp(instructions::TypeArgument, distributiveOverIdentifier);
}

handle(n->checkType, program);
handle(n->extendsType, program);
program.pushOp(instructions::Extends);
program.pushOp(instructions::Extends, n);

auto trueProgram = program.pushSubroutineNameLess(n->trueType);
handle(n->trueType, program);
Expand Down Expand Up @@ -950,7 +954,7 @@ namespace ts::checker {
const auto name = to<Identifier>(n->left)->escapedText;
auto symbol = program.findSymbol(name);
if (!symbol) {
program.pushOp(OP::Never);
program.pushOp(OP::Never, n->left);
program.pushError(ErrorCode::CannotFind, n->left);
} else {
if (!symbol->routine) throw runtime_error("Symbol has no routine");
Expand Down
17 changes: 12 additions & 5 deletions src/checker/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@ namespace ts::checker {
return ops.substr(address + 2, size);
}

struct PrintSubroutineOp {
string text;
unsigned int address;
};

struct PrintSubroutine {
string name;
unsigned int address;
vector<string> operations;
vector<PrintSubroutineOp> operations;
};

struct DebugSourceMapEntry {
Expand Down Expand Up @@ -176,16 +181,18 @@ namespace ts::checker {

string text;
if (params.empty()) {
text = fmt::format("[{}]{} ", startI, op);
text = fmt::format("{}", op);
} else {
text = fmt::format("([{}]{}{}) ", startI, op, params);
text = fmt::format("{}{}", op, params);
}
if (result.activeSubroutine) {
result.activeSubroutine->operations.push_back(text);
result.activeSubroutine->operations.push_back({.text = text, .address = startI});
} else {
result.operations.push_back(text);
}
if (print) std::cout << text;
if (print) {
std::cout << "[" << startI << "] (" << text << ") ";
}
}
if (print) fmt::print("\n");
return result;
Expand Down
41 changes: 26 additions & 15 deletions src/checker/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ namespace ts::vm {
struct FoundSourceMap {
unsigned int pos;
unsigned int end;

bool found() {
return pos != 0 && end != 0;
}
};

struct FoundSourceLineCharacter {
Expand Down Expand Up @@ -144,6 +148,7 @@ namespace ts::vm {

void clear() {
errors.clear();
subroutines.clear();
}

ModuleSubroutine *getSubroutine(unsigned int index) {
Expand All @@ -156,16 +161,20 @@ namespace ts::vm {

string findIdentifier(unsigned int ip) {
auto map = findNormalizedMap(ip);
if (map.end == 0) return "";
if (!map.found()) return "";
return code.substr(map.pos, map.end - map.pos);
}

FoundSourceMap findMap(unsigned int ip) {
unsigned int found = 0;
for (unsigned int i = sourceMapAddress; i < sourceMapAddressEnd; i += 3 * 4) {
auto mapIp = readUint32(bin, i);
if (mapIp > ip) break;
found = i;
if (mapIp == ip) {
found = i;
break;
}
// if (mapIp > ip) break;
// found = i;
}

if (found) {
Expand All @@ -176,7 +185,7 @@ namespace ts::vm {

FoundSourceMap findNormalizedMap(unsigned int ip) {
auto map = findMap(ip);
omitWhitespace(code, map);
if (map.found()) omitWhitespace(code, map);
return map;
}

Expand Down Expand Up @@ -205,18 +214,20 @@ namespace ts::vm {
if (e.ip) {
auto map = findNormalizedMap(e.ip);

std::size_t lineStart = code.rfind('\n', map.pos);
lineStart = lineStart == std::string::npos ? 0 : lineStart + 1;

std::size_t lineEnd = code.find('\n', map.end);
if (lineEnd == std::string::npos) lineEnd = code.size();
std::cout << cyan << fileName << ":" << yellow << map.pos << ":" << map.end << reset << " - " << red << "error" << reset << " TS0000: " << e.message << "\n\n";
std::cout << code.substr(lineStart, lineEnd - lineStart - 1) << "\n";
auto space = map.pos - lineStart;
std::cout << std::string(space, ' ') << red << "^" << reset << "\n\n";
} else {
std::cout << " " << e.message << "\n";
if (map.found()) {
std::size_t lineStart = code.rfind('\n', map.pos);
lineStart = lineStart == std::string::npos ? 0 : lineStart + 1;

std::size_t lineEnd = code.find('\n', map.end);
if (lineEnd == std::string::npos) lineEnd = code.size();
std::cout << cyan << fileName << ":" << yellow << map.pos << ":" << map.end << reset << " - " << red << "error" << reset << " TS0000: " << e.message << "\n\n";
std::cout << code.substr(lineStart, lineEnd - lineStart - 1) << "\n";
auto space = map.pos - lineStart;
std::cout << std::string(space, ' ') << red << "^" << reset << "\n\n";
continue;
}
}
std::cout << " " << e.message << "\n";
}
std::cout << "Found " << errors.size() << " errors in " << fileName << "\n";
}
Expand Down
Loading

0 comments on commit 57900ee

Please sign in to comment.