diff --git a/include/ast/BlockNode.h b/include/ast/BlockNode.h index 1fb8bbb77d6f0bcb2e2143302b7ba2b6728f36cd..90d26e7bdbb24834dd30da102da61b336fccb230 100644 --- a/include/ast/BlockNode.h +++ b/include/ast/BlockNode.h @@ -2,6 +2,8 @@ #include "ast/Node.h" #include "ast/control/ReturnNode.h" +#include "ast/declaration/DeclarationNode.h" +#include "ast/declaration/FunctionNode.h" #include "parser/Scope.h" namespace funk diff --git a/include/ast/declaration/FunctionNode.h b/include/ast/declaration/FunctionNode.h index 9711e82e59784c2517b361b6b32484ce5b589750..51a40687403bc4f492a0c61b47c350cd180a53e4 100644 --- a/include/ast/declaration/FunctionNode.h +++ b/include/ast/declaration/FunctionNode.h @@ -11,6 +11,8 @@ namespace funk { +class BlockNode; + class FunctionNode : public Node { public: diff --git a/include/parser/Scope.h b/include/parser/Scope.h index b02738e9ad58fc32e932ca48911e88de97953c1e..b025cc36ce263494e9dbee10f0a6f5e9a57eb7b2 100644 --- a/include/parser/Scope.h +++ b/include/parser/Scope.h @@ -3,6 +3,7 @@ #include "ast/Node.h" #include "logging/LogMacros.h" #include "utils/Common.h" +#include "utils/Exception.h" namespace funk { @@ -11,6 +12,7 @@ class Scope { public: static Scope& instance(); + static const int MAX_DEPTH = 1000; void push(); void pop(); diff --git a/source/ast/BlockNode.cc b/source/ast/BlockNode.cc index e945c01af71bdd5de88f1ff7cd7734ae42c971cd..6a3a4a9cb64bc48f9062a8db21c97309280ed4a0 100644 --- a/source/ast/BlockNode.cc +++ b/source/ast/BlockNode.cc @@ -28,15 +28,28 @@ Vector<Node*> BlockNode::get_statements() const Node* BlockNode::evaluate() const { - Scope::instance().push(); + bool push_scope{false}; + + for (Node* statement : statements) + { + if (dynamic_cast<DeclarationNode*>(statement) || dynamic_cast<FunctionNode*>(statement)) + { + push_scope = true; + break; + } + } + + if (push_scope) { Scope::instance().push(); } Node* result{}; + for (Node* statement : statements) { result = statement->evaluate(); if (dynamic_cast<ReturnNode*>(statement)) { break; } result = nullptr; } - Scope::instance().pop(); + + if (push_scope) { Scope::instance().pop(); } return result; } diff --git a/source/logging/Logger.cc b/source/logging/Logger.cc index 90f923f96e34653eb0128d9b41e2b44632b4104a..a19a2c677448fc813545c9ca5960e18bdeb65313 100644 --- a/source/logging/Logger.cc +++ b/source/logging/Logger.cc @@ -21,7 +21,6 @@ Logger& Logger::instance() void Logger::log(LogLevel level, const std::string& message) { - file_open(); if (level < log_level) return; auto now = std::chrono::system_clock::now(); diff --git a/source/parser/Scope.cc b/source/parser/Scope.cc index d771d5c74fcfd0c9663cb19a2698e4f7e2805a5a..c964ba35d01075d579872db788b2a076c68a4b76 100644 --- a/source/parser/Scope.cc +++ b/source/parser/Scope.cc @@ -21,15 +21,15 @@ Scope& Scope::instance() void Scope::push() { LOG_DEBUG("Pushing scope at depth " + to_str(depth) + " -> " + to_str(depth + 1)); + if (depth++ >= MAX_DEPTH) { throw RuntimeError("Scope stack overflow, max depth is " + to_str(MAX_DEPTH)); } scopes.push_back({}); - depth++; } void Scope::pop() { LOG_DEBUG("Popping scope at depth " + to_str(depth) + " -> " + to_str(depth - 1)); + if (depth-- <= 0) { throw RuntimeError("Scope stack underflow, can't go below 0"); } scopes.pop_back(); - depth--; } void Scope::add(const String& name, Node* node)