crappy loops (we segfaulting)
This commit is contained in:
parent
330a511f85
commit
2686f88d52
|
@ -1,30 +0,0 @@
|
||||||
{
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"type": "command",
|
|
||||||
"name": "Compile",
|
|
||||||
"program": "bob"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "command",
|
|
||||||
"name": "Run",
|
|
||||||
"program": "$PROJECT_DIR$/mx",
|
|
||||||
"workingDir": "$PROJECT_DIR$",
|
|
||||||
"args": ["test.mx"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "command",
|
|
||||||
"name": "Compile and run",
|
|
||||||
"program": "fish",
|
|
||||||
"workingDir": "$PROJECT_DIR$",
|
|
||||||
"args": ["test.fish"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "command",
|
|
||||||
"name": "Run with --debug",
|
|
||||||
"program": "$PROJECT_DIR$/mx",
|
|
||||||
"workingDir": "$PROJECT_DIR$",
|
|
||||||
"args": ["--debug", "test.mx"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"plugins": [
|
|
||||||
{
|
|
||||||
"type": "add",
|
|
||||||
"pluginName": "fleet.vim"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
6
examples/loop.bo
Normal file
6
examples/loop.bo
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
print "What is the secret word?";
|
||||||
|
|
||||||
|
while input != "dingus" {
|
||||||
|
println "That is not the secret word!";
|
||||||
|
print "What is the secret word?";
|
||||||
|
}
|
|
@ -18,10 +18,11 @@ void Interpreter::convertToTokens(vector<Token> tokenList) {
|
||||||
tokens = tokenList;
|
tokens = tokenList;
|
||||||
log.debug("Alright we got " + to_string(tokens.size()) + " tokens");
|
log.debug("Alright we got " + to_string(tokens.size()) + " tokens");
|
||||||
|
|
||||||
|
whileLoopStartIndex = -1;
|
||||||
|
|
||||||
while (tokenIndex < static_cast<int>(tokens.size() - 1)) {
|
while (tokenIndex < static_cast<int>(tokens.size() - 1)) {
|
||||||
auto currentToken = consume();
|
auto currentToken = consume();
|
||||||
if (!currentToken) break;
|
if (!currentToken) break;
|
||||||
|
|
||||||
vector<Token> currentInstruction;
|
vector<Token> currentInstruction;
|
||||||
currentInstruction.push_back(currentToken.value());
|
currentInstruction.push_back(currentToken.value());
|
||||||
|
|
||||||
|
@ -140,6 +141,7 @@ void Interpreter::convertToTokens(vector<Token> tokenList) {
|
||||||
i -= 1;
|
i -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
currentInstructionForWhileLoop = currentInstruction;
|
||||||
// Detect any comparisons and convert
|
// Detect any comparisons and convert
|
||||||
// Start at 1 to avoid having to do more crappy memory safety stuff
|
// Start at 1 to avoid having to do more crappy memory safety stuff
|
||||||
for (int i = 1; i < currentInstruction.size(); i++) {
|
for (int i = 1; i < currentInstruction.size(); i++) {
|
||||||
|
@ -216,6 +218,99 @@ void Interpreter::convertToTokens(vector<Token> tokenList) {
|
||||||
i -= 1;
|
i -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentInstruction[0].keyword == keywords::WHILE) {
|
||||||
|
Loop whileLoop;
|
||||||
|
whileLoopStartIndex = tokenIndex;
|
||||||
|
|
||||||
|
// Store the condition
|
||||||
|
for (size_t i = 1; i < currentInstruction.size(); i++) {
|
||||||
|
if (currentInstruction[i].keyword == keywords::OBRAC) break;
|
||||||
|
whileLoop.condition.push_back(currentInstruction[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect loop body instructions
|
||||||
|
int bracketCount = 1;
|
||||||
|
vector<Token> currentBody;
|
||||||
|
|
||||||
|
while (bracketCount > 0 && tokenIndex < tokens.size()) {
|
||||||
|
auto token = peek(1);
|
||||||
|
if (!token) break;
|
||||||
|
|
||||||
|
if (token->keyword == keywords::OBRAC) bracketCount++;
|
||||||
|
if (token->keyword == keywords::CBRAC) bracketCount--;
|
||||||
|
|
||||||
|
if (bracketCount == 0) break;
|
||||||
|
consume();
|
||||||
|
|
||||||
|
currentBody.push_back(token.value());
|
||||||
|
|
||||||
|
if (token->keyword == keywords::SEMICOLON ||
|
||||||
|
token->keyword == keywords::CBRAC) {
|
||||||
|
if (!currentBody.empty()) {
|
||||||
|
whileLoop.instructions.push_back(currentBody);
|
||||||
|
currentBody.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the start position of the while loop
|
||||||
|
whileLoopStartIndex = tokenIndex;
|
||||||
|
vector<Token> whileCondition;
|
||||||
|
// The condition should be everything after WHILE until OBRAC
|
||||||
|
whileCondition.clear();
|
||||||
|
for (size_t i = 1; i < currentInstruction.size(); i++) {
|
||||||
|
if (currentInstruction[i].keyword == keywords::OBRAC) break;
|
||||||
|
whileCondition.push_back(currentInstruction[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip processing until we find the matching closing brace
|
||||||
|
while (bracketCount > 0 && tokenIndex < tokens.size()) {
|
||||||
|
auto token = consume();
|
||||||
|
if (!token) break;
|
||||||
|
if (token->keyword == keywords::OBRAC) bracketCount++;
|
||||||
|
if (token->keyword == keywords::CBRAC) bracketCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the loop
|
||||||
|
loops.push_back(whileLoop);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// Check condition
|
||||||
|
bool conditionMet = false;
|
||||||
|
for (const auto& condToken : whileLoop.condition) {
|
||||||
|
if (condToken.type == valtype::BOOL) {
|
||||||
|
conditionMet = get<bool>(condToken.value.value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!conditionMet) break;
|
||||||
|
|
||||||
|
// Execute body
|
||||||
|
for (const auto& instruction : whileLoop.instructions) {
|
||||||
|
currentInstructionForWhileLoop = instruction;
|
||||||
|
// Process each instruction using your existing logic
|
||||||
|
// You might want to create a helper method for this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loops.pop_back();
|
||||||
|
|
||||||
|
// Skip to end of loop
|
||||||
|
while (bracketCount >= 0) {
|
||||||
|
auto token = consume();
|
||||||
|
if (!token) break;
|
||||||
|
if (token->keyword == keywords::CBRAC) bracketCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the closing brace of while loop
|
||||||
|
if (currentInstruction[0].keyword == keywords::CBRAC && whileLoopStartIndex != -1) {
|
||||||
|
// Go back to evaluate the condition again
|
||||||
|
tokenIndex = whileLoopStartIndex;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// Execute the instruction
|
// Execute the instruction
|
||||||
executeCode(currentInstruction);
|
executeCode(currentInstruction);
|
||||||
}
|
}
|
||||||
|
@ -232,6 +327,17 @@ void Interpreter::executeCode(vector<Token> tokens) {
|
||||||
skipScope --;
|
skipScope --;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (repeatScope > 0) {
|
||||||
|
vector<Token> buffer;
|
||||||
|
while (tokens[i].keyword != keywords::CBRAC) {
|
||||||
|
buffer.push_back(tokens[i]);
|
||||||
|
i++;
|
||||||
|
if (tokens[i].keyword == keywords::SEMICOLON) {
|
||||||
|
loops[i].instructions.push_back(buffer);
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (tokens[i].keyword == keywords::PRINTLN) {
|
if (tokens[i].keyword == keywords::PRINTLN) {
|
||||||
i++;
|
i++;
|
||||||
if (tokens.size() <= i) break;
|
if (tokens.size() <= i) break;
|
||||||
|
@ -364,6 +470,16 @@ void Interpreter::executeCode(vector<Token> tokens) {
|
||||||
skipScope ++;
|
skipScope ++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if (tokens[i].keyword == keywords::WHILE) {
|
||||||
|
i++;
|
||||||
|
if (tokens.size() < i) syntaxError.fnNotSufficientArgs("while", 1, 1, 0);
|
||||||
|
if (tokens[i].keyword != keywords::VALUE) syntaxError.generalError("while needs a value, not a keyword");
|
||||||
|
if (tokens[i].type != valtype::BOOL) syntaxError.comparisonTypeError("in a while statement");
|
||||||
|
Loop newLoop;
|
||||||
|
vector<Token> condition;
|
||||||
|
for (int i = 0; i < currentInstructionForWhileLoop.size(); i++) if (currentInstructionForWhileLoop[i].keyword == keywords::VALUE || currentInstructionForWhileLoop[i].keyword == keywords::EQUAL || currentInstructionForWhileLoop[i].keyword == keywords::INEQUAL) condition.push_back(currentInstructionForWhileLoop[i]);
|
||||||
|
newLoop.condition = condition;
|
||||||
|
repeatScope ++;
|
||||||
} else {
|
} else {
|
||||||
if (tokens[i].keyword == keywords::VALUE && tokens[i].value.type == valtype::STR && variables.find(get<string>(tokens[i].value.value)) != variables.end()) {
|
if (tokens[i].keyword == keywords::VALUE && tokens[i].value.type == valtype::STR && variables.find(get<string>(tokens[i].value.value)) != variables.end()) {
|
||||||
log.debug("Manipulating variable...");
|
log.debug("Manipulating variable...");
|
||||||
|
|
|
@ -4,10 +4,18 @@
|
||||||
#include "SyntaxError.h"
|
#include "SyntaxError.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
|
||||||
|
struct Loop {
|
||||||
|
vector<vector<Token>> instructions;
|
||||||
|
vector<Token> condition;
|
||||||
|
};
|
||||||
|
|
||||||
class Interpreter {
|
class Interpreter {
|
||||||
private:
|
private:
|
||||||
int skipScope = 0;
|
int skipScope = 0;
|
||||||
int repeatScope = 0;
|
int repeatScope = 0;
|
||||||
|
vector<Loop> loops;
|
||||||
|
vector<Token> currentInstructionForWhileLoop;
|
||||||
|
int whileLoopStartIndex;
|
||||||
SyntaxError syntaxError;
|
SyntaxError syntaxError;
|
||||||
vector<Token> tokens;
|
vector<Token> tokens;
|
||||||
map<string, Value> variables;
|
map<string, Value> variables;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user