From d7cd4947b37a168034e9fca2501d98553fdcc137 Mon Sep 17 00:00:00 2001
From: Ferenc Szontágh <szf@fsociety.hu>
Date: Mon, 14 Apr 2025 19:49:49 +0000
Subject: [PATCH] refactor phase1
---
src/ScriptInterpreter.cpp | 142 ++++++++++++++++++++---------------------------
1 files changed, 61 insertions(+), 81 deletions(-)
diff --git a/src/ScriptInterpreter.cpp b/src/ScriptInterpreter.cpp
index 1f353cf..8af8d43 100644
--- a/src/ScriptInterpreter.cpp
+++ b/src/ScriptInterpreter.cpp
@@ -14,37 +14,40 @@
}
Value ScriptInterpreter::evaluateExpression(const Token & token) const {
- if (token.type == TokenType::StringLiteral) {
- return Value::fromString(token);
+ switch (token.type) {
+ case TokenType::StringLiteral:
+ return Value::fromString(token);
+
+ case TokenType::IntLiteral:
+ try {
+ return Value::fromInt(token);
+ } catch (const std::invalid_argument & e) {
+ throw std::runtime_error("Invalid integer literal: " + token.lexeme);
+ } catch (const std::out_of_range & e) {
+ throw std::runtime_error("Integer literal out of range: " + token.lexeme);
+ }
+
+ case TokenType::DoubleLiteral:
+ try {
+ return Value::fromDouble(token);
+ } catch (const std::invalid_argument & e) {
+ throw std::runtime_error("Invalid double literal: " + token.lexeme);
+ } catch (const std::out_of_range & e) {
+ throw std::runtime_error("Double literal out of range: " + token.lexeme);
+ }
+
+ case TokenType::BooleanLiteral:
+ case TokenType::Identifier:
+ {
+ return Value::fromBoolean(token);
+ }
+
+ case TokenType::Variable:
+ return this->getVariable(token, this->contextPrefix, __FILE__, __LINE__);
+
+ default:
+ THROW_UNEXPECTED_TOKEN_ERROR(token, "string, integer, double, or variable");
}
- if (token.type == TokenType::IntLiteral) {
- try {
- return Value::fromInt(token);
- } catch (const std::invalid_argument & e) {
- throw std::runtime_error("Invalid integer literal: " + token.lexeme);
- } catch (const std::out_of_range & e) {
- throw std::runtime_error("Integer literal out of range: " + token.lexeme);
- }
- }
- if (token.type == TokenType::DoubleLiteral) {
- try {
- return Value::fromDouble(token);
- } catch (const std::invalid_argument & e) {
- throw std::runtime_error("Invalid double literal: " + token.lexeme);
- } catch (const std::out_of_range & e) {
- throw std::runtime_error("Double literal out of range: " + token.lexeme);
- }
- }
- if (token.type == TokenType::BooleanLiteral || token.type == TokenType::Identifier) {
- std::string lowered = token.lexeme;
- std::transform(lowered.begin(), lowered.end(), lowered.begin(),
- [](unsigned char c) { return std::tolower(c); });
- return Value::fromBoolean(token, (lowered == "true" ? true : false));
- }
- if (token.type == TokenType::Variable) {
- return this->getVariable(token, this->contextPrefix, __FILE__, __LINE__);
- }
- THROW_UNEXPECTED_TOKEN_ERROR(token, "string, integer, double, or variable");
return Value();
}
@@ -81,62 +84,39 @@
return args;
}
-void ScriptInterpreter::handleBooleanDeclaration(const std::vector<Token> & tokens, std::size_t & i) {
- const auto & varToken = tokens[i];
- i++; // Skip variable name
- if (i < tokens.size() && tokens[i].type == TokenType::Equals) {
- i++; // Skip '='
+void ScriptInterpreter::handleBooleanDeclaration(const std::vector<Token> & tokens, size_t & i) {
+ if (tokens.size() <= i || tokens[i].type != TokenType::Identifier) {
+ THROW_UNEXPECTED_TOKEN_ERROR(tokens[i], "variable name");
+ }
- if (i < tokens.size() && tokens[i].type == TokenType::Variable) {
- auto variable = this->getVariable(tokens[i], this->contextPrefix, __FILE__, __LINE__);
+ const Token & varToken = tokens[i++];
+ if (i >= tokens.size()) {
+ THROW_UNEXPECTED_TOKEN_ERROR(tokens[i + 1], "semicolon or assignment after variable name");
+ }
- if (variable.type != Variables::Type::VT_BOOLEAN) {
- THROW_VARIABLE_TYPE_MISSMATCH_ERROR(varToken.lexeme,
- Variables::TypeToString(Variables::Type::VT_BOOLEAN),
- tokens[i].lexeme, variable.TypeToString(), tokens[i]);
- }
- this->setVariable(varToken.lexeme, variable, this->contextPrefix, true);
- i++; // Skip variable name
- EXPECT_SEMICOLON(tokens, i, "after bool variable declaration");
-
- } else if (i < tokens.size() &&
- (tokens[i].type == TokenType::Identifier || tokens[i].type == TokenType::StringLiteral)) {
- std::string lowered = tokens[i].lexeme;
- std::transform(lowered.begin(), lowered.end(), lowered.begin(),
- [](unsigned char c) { return std::tolower(c); });
-
- if (lowered == "true") {
- auto value = Value::fromBoolean(tokens[i], true);
- this->setVariable(varToken.lexeme, value, this->contextPrefix, true);
- } else if (lowered == "false") {
- auto value = Value::fromBoolean(tokens[i], false);
- this->setVariable(varToken.lexeme, value, this->contextPrefix, true);
- } else {
- THROW_UNEXPECTED_TOKEN_ERROR(tokens[i], "true or false after '='");
- }
- i++; // Skip boolean literal
- EXPECT_SEMICOLON(tokens, i, "after bool declaration");
- } else if (i < tokens.size() && tokens[i].type == TokenType::IntLiteral) {
- const auto test = std::stoi(tokens[i].lexeme);
- if (test == 0) {
- auto value = Value::fromBoolean(tokens[i], false);
- this->setVariable(varToken.lexeme, value, this->contextPrefix, true);
- } else if (test > 0) {
- auto value = Value::fromBoolean(tokens[i], false);
- this->setVariable(varToken.lexeme, value, this->contextPrefix, true);
- } else {
- THROW_UNEXPECTED_TOKEN_ERROR(tokens[i], "bool literal after '='");
- }
- i++;
- EXPECT_SEMICOLON(tokens, i, "after bool declaration");
- } else {
- THROW_UNEXPECTED_TOKEN_ERROR(tokens[i], "bool literal after '='");
+ if (tokens[i].type == TokenType::Semicolon) {
+ auto val = Value::fromBoolean(tokens[i]);
+ this->setVariable(varToken.lexeme, val, this->contextPrefix, true);
+ i++;
+ } else if (tokens[i].type == TokenType::Equal) {
+ i++;
+ if (i >= tokens.size()) {
+ //throw InterpreterException("Expected value after assignment.", tokens[i - 1]);
+ THROW_UNEXPECTED_TOKEN_ERROR(tokens[i - 1], "value after assignment");
}
+ auto value = evaluateExpression(tokens[i]);
+ if (value.type != Variables::Type::VT_BOOLEAN) {
+ THROW_VARIABLE_TYPE_MISSMATCH_ERROR(varToken.lexeme, Variables::TypeToString(Variables::Type::VT_BOOLEAN),
+ tokens[i].lexeme, value.TypeToString(), tokens[i]);
+ }
+ this->setVariable(varToken.lexeme, value, this->contextPrefix, true);
+ i++;
+ EXPECT_SEMICOLON(tokens, i, "after bool declaration");
} else {
- THROW_UNEXPECTED_TOKEN_ERROR(tokens[i], "= after bool declaration");
+ EXPECT_SEMICOLON(tokens, i, "after bool declaration");
}
-};
+}
void ScriptInterpreter::handleStringDeclaration(const std::vector<Token> & tokens, std::size_t & i) {
const auto & varToken = tokens[i];
@@ -242,7 +222,7 @@
size_t end;
ScriptInterpreterHelpers::getFunctionBody(tokens, i, start, end);
- const std::string function_body = ScriptInterpreterHelpers::extractSubstring(this->source, start, end);
+ const std::string function_body = StringHelpers::extractSubstring(this->source, start, end);
if (function_body.empty()) {
std::cout << this->source << '\n';
THROW_FUNCTION_BODY_EMPTY(funcToken.lexeme, tokens[i - 1]);
--
Gitblit v1.9.3