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;
|
||||
log.debug("Alright we got " + to_string(tokens.size()) + " tokens");
|
||||
|
||||
whileLoopStartIndex = -1;
|
||||
|
||||
while (tokenIndex < static_cast<int>(tokens.size() - 1)) {
|
||||
auto currentToken = consume();
|
||||
if (!currentToken) break;
|
||||
|
||||
vector<Token> currentInstruction;
|
||||
currentInstruction.push_back(currentToken.value());
|
||||
|
||||
|
@ -140,6 +141,7 @@ void Interpreter::convertToTokens(vector<Token> tokenList) {
|
|||
i -= 1;
|
||||
}
|
||||
}
|
||||
currentInstructionForWhileLoop = currentInstruction;
|
||||
// Detect any comparisons and convert
|
||||
// Start at 1 to avoid having to do more crappy memory safety stuff
|
||||
for (int i = 1; i < currentInstruction.size(); i++) {
|
||||
|
@ -216,6 +218,99 @@ void Interpreter::convertToTokens(vector<Token> tokenList) {
|
|||
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
|
||||
executeCode(currentInstruction);
|
||||
}
|
||||
|
@ -232,6 +327,17 @@ void Interpreter::executeCode(vector<Token> tokens) {
|
|||
skipScope --;
|
||||
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) {
|
||||
i++;
|
||||
if (tokens.size() <= i) break;
|
||||
|
@ -364,6 +470,16 @@ void Interpreter::executeCode(vector<Token> tokens) {
|
|||
skipScope ++;
|
||||
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 {
|
||||
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...");
|
||||
|
|
|
@ -4,10 +4,18 @@
|
|||
#include "SyntaxError.h"
|
||||
#include "Logger.h"
|
||||
|
||||
struct Loop {
|
||||
vector<vector<Token>> instructions;
|
||||
vector<Token> condition;
|
||||
};
|
||||
|
||||
class Interpreter {
|
||||
private:
|
||||
int skipScope = 0;
|
||||
int repeatScope = 0;
|
||||
vector<Loop> loops;
|
||||
vector<Token> currentInstructionForWhileLoop;
|
||||
int whileLoopStartIndex;
|
||||
SyntaxError syntaxError;
|
||||
vector<Token> tokens;
|
||||
map<string, Value> variables;
|
||||
|
@ -19,4 +27,4 @@ private:
|
|||
public:
|
||||
void convertToTokens(vector<Token> tokenList);
|
||||
void executeCode(vector<Token> tokens);
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user