diff --git a/src/headers/runtime/AssignmentUtils.h b/src/headers/runtime/AssignmentUtils.h new file mode 100644 index 0000000..d3f2210 --- /dev/null +++ b/src/headers/runtime/AssignmentUtils.h @@ -0,0 +1,35 @@ +#pragma once + +#include "Value.h" +#include "Lexer.h" + +// Utility to compute the result of a compound assignment (e.g., +=, -=, etc.) +// Leaves error reporting to callers; throws std::runtime_error on unknown operator +inline Value computeCompoundAssignment(const Value& currentValue, TokenType opType, const Value& rhs) { + switch (opType) { + case PLUS_EQUAL: + return currentValue + rhs; + case MINUS_EQUAL: + return currentValue - rhs; + case STAR_EQUAL: + return currentValue * rhs; + case SLASH_EQUAL: + return currentValue / rhs; + case PERCENT_EQUAL: + return currentValue % rhs; + case BIN_AND_EQUAL: + return currentValue & rhs; + case BIN_OR_EQUAL: + return currentValue | rhs; + case BIN_XOR_EQUAL: + return currentValue ^ rhs; + case BIN_SLEFT_EQUAL: + return currentValue << rhs; + case BIN_SRIGHT_EQUAL: + return currentValue >> rhs; + default: + throw std::runtime_error("Unknown compound assignment operator"); + } +} + + diff --git a/src/headers/runtime/Environment.h b/src/headers/runtime/Environment.h index f291d19..567e50e 100644 --- a/src/headers/runtime/Environment.h +++ b/src/headers/runtime/Environment.h @@ -41,19 +41,11 @@ public: // Enhanced get with error reporting Value get(const Token& name); - // Get by string name with error reporting - Value get(const std::string& name); - // Prune heavy containers in a snapshot to avoid capture cycles void pruneForClosureCapture(); std::shared_ptr getParent() const { return parent; } - inline void clear() { variables.clear(); } - // Set parent environment for TCO environment reuse - inline void setParent(std::shared_ptr newParent) { - parent = newParent; - } private: std::unordered_map variables; diff --git a/src/headers/runtime/Interpreter.h b/src/headers/runtime/Interpreter.h index 3fcbb76..b37c107 100644 --- a/src/headers/runtime/Interpreter.h +++ b/src/headers/runtime/Interpreter.h @@ -1,15 +1,4 @@ #pragma once -#include "Expression.h" -#include "Statement.h" -#include "helperFunctions/ShortHands.h" -#include "TypeWrapper.h" -#include "Environment.h" -#include "Value.h" -#include "BobStdLib.h" -#include "ErrorReporter.h" -#include "ExecutionContext.h" -#include "RuntimeDiagnostics.h" - #include #include #include @@ -17,6 +6,21 @@ #include #include +#include "Value.h" +#include "RuntimeDiagnostics.h" + +struct Expr; +struct Stmt; +struct Environment; +struct BuiltinFunction; +struct Function; +struct Thunk; +class ErrorReporter; +struct ExecutionContext; +struct CallExpr; + + + // Forward declaration class Evaluator; @@ -66,9 +70,8 @@ private: bool inThunkExecution = false; // Automatic cleanup tracking - int functionCreationCount = 0; int thunkCreationCount = 0; - static const int CLEANUP_THRESHOLD = 1000000; + static const int CLEANUP_THRESHOLD = 10000; RuntimeDiagnostics diagnostics; // Utility functions for runtime operations std::unique_ptr evaluator; @@ -93,25 +96,17 @@ public: bool isInteractiveMode() const; std::shared_ptr getEnvironment(); void setEnvironment(std::shared_ptr env); - void addThunk(std::shared_ptr thunk); + void addFunction(std::shared_ptr function); void reportError(int line, int column, const std::string& errorType, const std::string& message, const std::string& lexeme = ""); void addBuiltinFunction(std::shared_ptr func); void cleanupUnusedFunctions(); void cleanupUnusedThunks(); void forceCleanup(); + void addStdLibFunctions(); - // Function creation count management - void incrementFunctionCreationCount(); - int getFunctionCreationCount() const; - void resetFunctionCreationCount(); - int getCleanupThreshold() const; - // Public access for Evaluator - bool& getInThunkExecutionRef() { return inThunkExecution; } private: - Value evaluateWithoutTrampoline(const std::shared_ptr& expr); - void addStdLibFunctions(); Value runTrampoline(Value initialResult); }; diff --git a/src/headers/runtime/RuntimeDiagnostics.h b/src/headers/runtime/RuntimeDiagnostics.h index e94bbd0..08fd773 100644 --- a/src/headers/runtime/RuntimeDiagnostics.h +++ b/src/headers/runtime/RuntimeDiagnostics.h @@ -28,8 +28,6 @@ public: void cleanupUnusedFunctions(std::vector>& functions); void cleanupUnusedFunctions(std::vector>& functions); void cleanupUnusedThunks(std::vector>& thunks); - void forceCleanup(std::vector>& functions, - std::vector>& thunks); void forceCleanup(std::vector>& builtinFunctions, std::vector>& functions, std::vector>& thunks); diff --git a/src/headers/runtime/TypeWrapper.h b/src/headers/runtime/TypeWrapper.h index bb3c136..5bbc555 100644 --- a/src/headers/runtime/TypeWrapper.h +++ b/src/headers/runtime/TypeWrapper.h @@ -10,38 +10,7 @@ struct Stmt; struct Environment; -struct Object -{ - virtual ~Object(){}; -}; - -struct Number : Object -{ - double value; - explicit Number(double value) : value(value) {} -}; - -struct String : Object -{ - std::string value; - explicit String(std::string str) : value(str) {} - ~String(){ - - } -}; - -struct Boolean : Object -{ - bool value; - explicit Boolean(bool value) : value(value) {} -}; - -struct None : public Object -{ - -}; - -struct Function : public Object +struct Function { const std::string name; const std::vector params; @@ -54,7 +23,7 @@ struct Function : public Object : name(name), params(params), body(body), closure(closure) {} }; -struct BuiltinFunction : public Object +struct BuiltinFunction { const std::string name; const std::function, int, int)> func; diff --git a/src/headers/runtime/Value.h b/src/headers/runtime/Value.h index 91a72ad..bb64c2b 100644 --- a/src/headers/runtime/Value.h +++ b/src/headers/runtime/Value.h @@ -423,6 +423,4 @@ struct Value { // Global constants for common values extern const Value NONE_VALUE; extern const Value TRUE_VALUE; -extern const Value FALSE_VALUE; -extern const Value ZERO_VALUE; -extern const Value ONE_VALUE; \ No newline at end of file +extern const Value FALSE_VALUE; \ No newline at end of file diff --git a/src/sources/cli/bob.cpp b/src/sources/cli/bob.cpp index 67588b0..d74fcf8 100644 --- a/src/sources/cli/bob.cpp +++ b/src/sources/cli/bob.cpp @@ -22,8 +22,8 @@ void Bob::runFile(const std::string& path) // Load source code into error reporter for context errorReporter.loadSource(source, path); - // Connect error reporter to interpreter interpreter->setErrorReporter(&errorReporter); + interpreter->addStdLibFunctions(); this->run(source); } @@ -52,6 +52,7 @@ void Bob::runPrompt() // Connect error reporter to interpreter interpreter->setErrorReporter(&errorReporter); + interpreter->addStdLibFunctions(); this->run(line); } diff --git a/src/sources/runtime/Environment.cpp b/src/sources/runtime/Environment.cpp index d3f122e..86ee0f4 100644 --- a/src/sources/runtime/Environment.cpp +++ b/src/sources/runtime/Environment.cpp @@ -37,27 +37,14 @@ Value Environment::get(const Token& name) { throw std::runtime_error("Undefined variable '" + name.lexeme + "'"); } -Value Environment::get(const std::string& name) { - auto it = variables.find(name); - if (it != variables.end()) { - return it->second; - } - - if (parent != nullptr) { - return parent->get(name); - } - - throw std::runtime_error("Undefined variable '" + name + "'"); -} + void Environment::pruneForClosureCapture() { for (auto &entry : variables) { Value &v = entry.second; if (v.isArray()) { - // Replace with a new empty array to avoid mutating original shared storage entry.second = Value(std::vector{}); } else if (v.isDict()) { - // Replace with a new empty dict to avoid mutating original shared storage entry.second = Value(std::unordered_map{}); } } diff --git a/src/sources/runtime/Evaluator.cpp b/src/sources/runtime/Evaluator.cpp index b45cb2c..5369b1d 100644 --- a/src/sources/runtime/Evaluator.cpp +++ b/src/sources/runtime/Evaluator.cpp @@ -1,5 +1,7 @@ #include "Evaluator.h" #include "Interpreter.h" +#include "Environment.h" +#include "AssignmentUtils.h" #include "helperFunctions/HelperFunctions.h" Evaluator::Evaluator(Interpreter* interpreter) : interpreter(interpreter) {} @@ -212,76 +214,26 @@ Value Evaluator::visitIncrementExpr(const std::shared_ptr& expres Value Evaluator::visitAssignExpr(const std::shared_ptr& expression) { Value value = interpreter->evaluate(expression->value); - - if (expression->op.type == EQUAL) { - try { - // Check if the variable existed and whether it held a collection - bool existed = false; - bool wasCollection = false; - try { - Value oldValue = interpreter->getEnvironment()->get(expression->name); - existed = true; - wasCollection = oldValue.isArray() || oldValue.isDict(); - } catch (...) { - existed = false; - } - // Assign first to release references held by the old values - interpreter->getEnvironment()->assign(expression->name, value); + if (expression->op.type == EQUAL) { + // Assign first to release references held by the old values + interpreter->getEnvironment()->assign(expression->name, value); + // Perform cleanup on any reassignment + interpreter->forceCleanup(); + return value; + } - // Now that the old values are released, perform cleanup on any reassignment - interpreter->forceCleanup(); - } catch (const std::exception& e) { - std::cerr << "Error during assignment: " << e.what() << std::endl; - throw; // Re-throw to see the full stack trace - } - } else { - // Handle compound assignment operators - Value currentValue = interpreter->getEnvironment()->get(expression->name); - Value newValue; - - switch (expression->op.type) { - case PLUS_EQUAL: - newValue = currentValue + value; - break; - case MINUS_EQUAL: - newValue = currentValue - value; - break; - case STAR_EQUAL: - newValue = currentValue * value; - break; - case SLASH_EQUAL: - newValue = currentValue / value; - break; - case PERCENT_EQUAL: - newValue = currentValue % value; - break; - case BIN_AND_EQUAL: - newValue = currentValue & value; - break; - case BIN_OR_EQUAL: - newValue = currentValue | value; - break; - case BIN_XOR_EQUAL: - newValue = currentValue ^ value; - break; - case BIN_SLEFT_EQUAL: - newValue = currentValue << value; - break; - case BIN_SRIGHT_EQUAL: - newValue = currentValue >> value; - break; - default: - interpreter->reportError(expression->op.line, expression->op.column, "Runtime Error", - "Unknown assignment operator: " + expression->op.lexeme, ""); - throw std::runtime_error("Unknown assignment operator: " + expression->op.lexeme); - } - + // Compound assignment operators + Value currentValue = interpreter->getEnvironment()->get(expression->name); + try { + Value newValue = computeCompoundAssignment(currentValue, expression->op.type, value); interpreter->getEnvironment()->assign(expression->name, newValue); return newValue; + } catch (const std::runtime_error&) { + interpreter->reportError(expression->op.line, expression->op.column, "Runtime Error", + "Unknown assignment operator: " + expression->op.lexeme, ""); + throw; } - - return value; } Value Evaluator::visitTernaryExpr(const std::shared_ptr& expression) { @@ -453,10 +405,8 @@ Value Evaluator::visitFunctionExpr(const std::shared_ptr& expressi paramNames.push_back(param.lexeme); } - // Capture a snapshot of the current environment so loop vars like 'i' are frozen per iteration auto closureEnv = std::make_shared(*interpreter->getEnvironment()); closureEnv->pruneForClosureCapture(); - auto function = std::make_shared("", paramNames, expression->body, closureEnv); return Value(function); } diff --git a/src/sources/runtime/Executor.cpp b/src/sources/runtime/Executor.cpp index 71eb015..a9489b7 100644 --- a/src/sources/runtime/Executor.cpp +++ b/src/sources/runtime/Executor.cpp @@ -1,6 +1,8 @@ #include "Executor.h" #include "Evaluator.h" #include "Interpreter.h" +#include "Environment.h" +#include "AssignmentUtils.h" #include Executor::Executor(Interpreter* interpreter, Evaluator* evaluator) @@ -194,66 +196,24 @@ void Executor::visitContinueStmt(const std::shared_ptr& statement, } void Executor::visitAssignStmt(const std::shared_ptr& statement, ExecutionContext* context) { - try { - Value value = statement->value->accept(evaluator); - - if (statement->op.type == EQUAL) { - try { - // Assign first to release references held by the old value - interpreter->getEnvironment()->assign(statement->name, value); - - // Clean up on any reassignment, regardless of old/new type - interpreter->forceCleanup(); - } catch (const std::exception& e) { - std::cerr << "Error during assignment: " << e.what() << std::endl; - throw; // Re-throw to see the full stack trace - } - } else { - // Handle compound assignment operators - Value currentValue = interpreter->getEnvironment()->get(statement->name); - Value newValue; - - switch (statement->op.type) { - case PLUS_EQUAL: - newValue = currentValue + value; - break; - case MINUS_EQUAL: - newValue = currentValue - value; - break; - case STAR_EQUAL: - newValue = currentValue * value; - break; - case SLASH_EQUAL: - newValue = currentValue / value; - break; - case PERCENT_EQUAL: - newValue = currentValue % value; - break; - case BIN_AND_EQUAL: - newValue = currentValue & value; - break; - case BIN_OR_EQUAL: - newValue = currentValue | value; - break; - case BIN_XOR_EQUAL: - newValue = currentValue ^ value; - break; - case BIN_SLEFT_EQUAL: - newValue = currentValue << value; - break; - case BIN_SRIGHT_EQUAL: - newValue = currentValue >> value; - break; - default: - interpreter->reportError(statement->op.line, statement->op.column, "Runtime Error", - "Unknown assignment operator: " + statement->op.lexeme, ""); - throw std::runtime_error("Unknown assignment operator: " + statement->op.lexeme); - } - - interpreter->getEnvironment()->assign(statement->name, newValue); + Value value = statement->value->accept(evaluator); + + if (statement->op.type == EQUAL) { + // Assign first to release references held by the old value + interpreter->getEnvironment()->assign(statement->name, value); + // Clean up on any reassignment + interpreter->forceCleanup(); + return; } - } catch (const std::exception& e) { - std::cerr << "Error in visitAssignStmt: " << e.what() << std::endl; - throw; // Re-throw to see the full stack trace + + // Compound assignment operators + Value currentValue = interpreter->getEnvironment()->get(statement->name); + try { + Value newValue = computeCompoundAssignment(currentValue, statement->op.type, value); + interpreter->getEnvironment()->assign(statement->name, newValue); + } catch (const std::runtime_error&) { + interpreter->reportError(statement->op.line, statement->op.column, "Runtime Error", + "Unknown assignment operator: " + statement->op.lexeme, ""); + throw; } } diff --git a/src/sources/runtime/Interpreter.cpp b/src/sources/runtime/Interpreter.cpp index be15274..6a8d48d 100644 --- a/src/sources/runtime/Interpreter.cpp +++ b/src/sources/runtime/Interpreter.cpp @@ -2,6 +2,8 @@ #include "Evaluator.h" #include "Executor.h" #include "BobStdLib.h" +#include "ErrorReporter.h" +#include "Environment.h" #include Interpreter::Interpreter(bool isInteractive) @@ -61,9 +63,7 @@ void Interpreter::addBuiltinFunction(std::shared_ptr func) { builtinFunctions.push_back(func); } -void Interpreter::addThunk(std::shared_ptr thunk) { - thunks.push_back(thunk); -} + void Interpreter::addFunction(std::shared_ptr function) { functions.push_back(function); @@ -74,7 +74,6 @@ void Interpreter::setErrorReporter(ErrorReporter* reporter) { if (environment) { environment->setErrorReporter(reporter); } - addStdLibFunctions(); } bool Interpreter::isInteractiveMode() const { @@ -121,7 +120,6 @@ Value Interpreter::evaluateCallExprInline(const std::shared_ptr& expre } if (!callee.isFunction()) { - // Provide better error message with type information (like original) std::string errorMsg = "Can only call functions, got " + callee.getType(); if (errorReporter) { errorReporter->reportError(expression->paren.line, expression->paren.column, "Runtime Error", @@ -150,9 +148,8 @@ Value Interpreter::evaluateCallExprInline(const std::shared_ptr& expre // Check if this is a tail call for inline TCO if (expression->isTailCall) { - // Create a thunk for tail call optimization - original inline version + auto thunk = std::make_shared([this, function, arguments]() -> Value { - // Use RAII to manage environment (exactly like original) ScopedEnv _env(environment); environment = std::make_shared(function->closure); environment->setErrorReporter(errorReporter); @@ -164,12 +161,10 @@ Value Interpreter::evaluateCallExprInline(const std::shared_ptr& expre ExecutionContext context; context.isFunctionBody = true; - // Use RAII to manage thunk execution flag ScopedThunkFlag _inThunk(inThunkExecution); - // Execute function body (inline like original - direct accept for performance) for (const auto& stmt : function->body) { - stmt->accept(executor.get(), &context); // Direct call like original + stmt->accept(executor.get(), &context); if (context.hasReturn) { return context.returnValue; } @@ -178,10 +173,8 @@ Value Interpreter::evaluateCallExprInline(const std::shared_ptr& expre return context.returnValue; }); - // Store the thunk to keep it alive and return as Value (exactly like original) thunks.push_back(thunk); - // Automatic cleanup check thunkCreationCount++; if (thunkCreationCount >= CLEANUP_THRESHOLD) { cleanupUnusedThunks(); @@ -190,7 +183,6 @@ Value Interpreter::evaluateCallExprInline(const std::shared_ptr& expre return Value(thunk); } else { - // Normal function call - create new environment (exactly like original) ScopedEnv _env(environment); environment = std::make_shared(function->closure); environment->setErrorReporter(errorReporter); @@ -202,9 +194,8 @@ Value Interpreter::evaluateCallExprInline(const std::shared_ptr& expre ExecutionContext context; context.isFunctionBody = true; - // Execute function body (exactly like original - direct accept for performance) for (const auto& stmt : function->body) { - stmt->accept(executor.get(), &context); // Direct call like original + stmt->accept(executor.get(), &context); if (context.hasReturn) { return context.returnValue; } @@ -213,20 +204,4 @@ Value Interpreter::evaluateCallExprInline(const std::shared_ptr& expre return context.returnValue; } } - -// Function creation count management -void Interpreter::incrementFunctionCreationCount() { - functionCreationCount++; -} - -int Interpreter::getFunctionCreationCount() const { - return functionCreationCount; -} - -void Interpreter::resetFunctionCreationCount() { - functionCreationCount = 0; -} - -int Interpreter::getCleanupThreshold() const { - return 1000000; // Same as CLEANUP_THRESHOLD used for thunks -} + diff --git a/src/sources/runtime/RuntimeDiagnostics.cpp b/src/sources/runtime/RuntimeDiagnostics.cpp index c4ee001..cbd34dd 100644 --- a/src/sources/runtime/RuntimeDiagnostics.cpp +++ b/src/sources/runtime/RuntimeDiagnostics.cpp @@ -13,122 +13,19 @@ #include -bool RuntimeDiagnostics::isTruthy(Value object) { - if(object.isBoolean()) { - return object.asBoolean(); - } - - if(object.isNone()) { - return false; - } - - if(object.isNumber()) { - return object.asNumber() != 0; - } - - if(object.isString()) { - return object.asString().length() > 0; - } - - return true; -} +bool RuntimeDiagnostics::isTruthy(Value object) { return object.isTruthy(); } bool RuntimeDiagnostics::isEqual(Value a, Value b) { - // Handle none comparisons first - if (a.isNone() || b.isNone()) { - return a.isNone() && b.isNone(); - } - - // Handle same type comparisons - if (a.isNumber() && b.isNumber()) { - return a.asNumber() == b.asNumber(); - } - - if (a.isBoolean() && b.isBoolean()) { - return a.asBoolean() == b.asBoolean(); - } - - if (a.isString() && b.isString()) { - return a.asString() == b.asString(); - } - - if (a.isArray() && b.isArray()) { - const std::vector& arrA = a.asArray(); - const std::vector& arrB = b.asArray(); - - if (arrA.size() != arrB.size()) { - return false; - } - - for (size_t i = 0; i < arrA.size(); i++) { - if (!isEqual(arrA[i], arrB[i])) { - return false; - } - } - return true; - } - - if (a.isFunction() && b.isFunction()) { - // Functions are equal only if they are the same object - return a.asFunction() == b.asFunction(); - } - - if (a.isBuiltinFunction() && b.isBuiltinFunction()) { - // Builtin functions are equal only if they are the same object - return a.asBuiltinFunction() == b.asBuiltinFunction(); - } - - // Cross-type comparisons that make sense if (a.isNumber() && b.isBoolean()) { - // Numbers and booleans: 0 and false are equal, non-zero and true are equal - if (b.asBoolean()) { - return a.asNumber() != 0.0; - } else { - return a.asNumber() == 0.0; - } + return b.asBoolean() ? (a.asNumber() != 0.0) : (a.asNumber() == 0.0); } - if (a.isBoolean() && b.isNumber()) { - // Same as above, but reversed - if (a.asBoolean()) { - return b.asNumber() != 0.0; - } else { - return b.asNumber() == 0.0; - } + return a.asBoolean() ? (b.asNumber() != 0.0) : (b.asNumber() == 0.0); } - - // For all other type combinations, return false - return false; + return a.equals(b); } -std::string RuntimeDiagnostics::stringify(Value object) { - if(object.isNone()) { - return "none"; - } - else if(object.isNumber()) { - return formatNumber(object.asNumber()); - } - else if(object.isString()) { - return object.asString(); - } - else if(object.isBoolean()) { - return object.asBoolean() == 1 ? "true" : "false"; - } - else if(object.isFunction()) { - return "name + ">"; - } - else if(object.isBuiltinFunction()) { - return "name + ">"; - } - else if(object.isArray()) { - return formatArray(object.asArray()); - } - else if(object.isDict()) { - return formatDict(object.asDict()); - } - - throw std::runtime_error("Could not convert object to string"); -} +std::string RuntimeDiagnostics::stringify(Value object) { return object.toString(); } std::string RuntimeDiagnostics::formatNumber(double value) { double integral = value; @@ -150,31 +47,9 @@ std::string RuntimeDiagnostics::formatNumber(double value) { } } -std::string RuntimeDiagnostics::formatArray(const std::vector& arr) { - std::string result = "["; - - for (size_t i = 0; i < arr.size(); i++) { - if (i > 0) result += ", "; - result += stringify(arr[i]); - } - - result += "]"; - return result; -} +std::string RuntimeDiagnostics::formatArray(const std::vector& arr) { return Value(arr).toString(); } -std::string RuntimeDiagnostics::formatDict(const std::unordered_map& dict) { - std::string result = "{"; - - bool first = true; - for (const auto& pair : dict) { - if (!first) result += ", "; - result += "\"" + pair.first + "\": " + stringify(pair.second); - first = false; - } - - result += "}"; - return result; -} +std::string RuntimeDiagnostics::formatDict(const std::unordered_map& dict) { return Value(dict).toString(); } void RuntimeDiagnostics::cleanupUnusedFunctions(std::vector>& functions) { // Only remove functions that are definitely not referenced anywhere (use_count == 1) @@ -212,25 +87,7 @@ void RuntimeDiagnostics::cleanupUnusedThunks(std::vector> ); } -void RuntimeDiagnostics::forceCleanup(std::vector>& functions, - std::vector>& thunks) { - // More aggressive cleanup when breaking array references - functions.erase( - std::remove_if(functions.begin(), functions.end(), - [](const std::shared_ptr& func) { - return func.use_count() <= 2; // More aggressive than == 1 - }), - functions.end() - ); - - thunks.erase( - std::remove_if(thunks.begin(), thunks.end(), - [](const std::shared_ptr& thunk) { - return thunk.use_count() <= 2; // More aggressive than == 1 - }), - thunks.end() - ); -} + void RuntimeDiagnostics::forceCleanup(std::vector>& builtinFunctions, std::vector>& functions, diff --git a/src/sources/runtime/TypeWrapper.cpp b/src/sources/runtime/TypeWrapper.cpp index 8f9bd2a..a23571d 100644 --- a/src/sources/runtime/TypeWrapper.cpp +++ b/src/sources/runtime/TypeWrapper.cpp @@ -1,4 +1,4 @@ - +#include "TypeWrapper.h" #include "TypeWrapper.h" #include diff --git a/src/sources/runtime/Value.cpp b/src/sources/runtime/Value.cpp index 404b670..324b37e 100644 --- a/src/sources/runtime/Value.cpp +++ b/src/sources/runtime/Value.cpp @@ -4,5 +4,4 @@ const Value NONE_VALUE = Value(); const Value TRUE_VALUE = Value(true); const Value FALSE_VALUE = Value(false); -const Value ZERO_VALUE = Value(0.0); -const Value ONE_VALUE = Value(1.0); \ No newline at end of file + \ No newline at end of file diff --git a/tests.bob b/tests.bob index 8f2211a..d6f0a8f 100644 --- a/tests.bob +++ b/tests.bob @@ -42,7 +42,7 @@ if (len(a[3692]) > 0) { if (a[3693]["func"]) { a[3693]["func"](); // Nested dict function } -print(a); +//print(a); //writeFile("array_contents.txt", toString(a)); print("Array contents written to array_contents.txt"); print("Memory before cleanup: " + memoryUsage() + " MB");