diff --git a/alib2cli/src/grammar/AltCliParser.g4 b/alib2cli/src/grammar/AltCliParser.g4
index 088e9052b189e4333e94117b66cdb63ee933a354..41a5dd7a228991e709a8435c54281ea69e2c2b2b 100644
--- a/alib2cli/src/grammar/AltCliParser.g4
+++ b/alib2cli/src/grammar/AltCliParser.g4
@@ -6,7 +6,7 @@ options {
 
 // Initial rule
 parse
-	: NEWLINE* command (NEWLINE command?)* EOF
+	: NEWLINE* top_level_command (NEWLINE top_level_command?)* EOF
 	| NEWLINE* EOF;
 
 arg
@@ -80,7 +80,7 @@ semicolon_command
 	:	block # BlockSemicolonCommand
 	| 	command_if # IfSemicolonCommand
 	| 	command_while # WhileSemicolonCommand
-	|	command SEMICOLON # SemicolonCommand
+	|	nested_level_command SEMICOLON # SemicolonCommand
 	;
 
 introspect_cast_from_to
@@ -97,7 +97,7 @@ introspect_command
 	|	KW_DENORMALIZATIONS # IntrospectDeormalizations
 	|	KW_VARIABLES variable? # IntrospectVariables
 	|	KW_BINDINGS binding_name? # IntrospectBindings
-	|	KW_AST command # IntrospectAst
+	|	KW_AST top_level_command # IntrospectAst
 	;
 
 batch
@@ -147,13 +147,21 @@ command
 	|	block # BlockCommand
 	|	KW_EVAL ( INTEGER | identifier | string ) # Eval
 	|	KW_INTERPRET ( identifier | string ) # Interpret
-	|	command_if # If
+	|	KW_DECLARE qualified_type DOLAR_SIGN arg ASSIGN_OPERATOR expression # Declare // Should be top-level command?
+	;
+
+nested_level_command
+	: 	command # NestedLevelCommand
+	| 	command_if # If
 	|	command_while # While
 	|	(KW_BREAK | KW_CONTINUE) # CycleControl
-	|	KW_DECLARE qualified_type DOLAR_SIGN arg ASSIGN_OPERATOR expression # Declare
-	|   KW_UNDECLARE ( INTEGER | identifier | string ) LEFT_PAREN (qualified_type (COMMA qualified_type)*)? RIGHT_PAREN # UndeclareFunction
-	|	KW_PROCEDURE ( INTEGER | identifier | string ) LEFT_PAREN ( (runnable_param ( COMMA runnable_param )*)? ) RIGHT_PAREN command # Procedure
-	|	KW_FUNCTION ( INTEGER | identifier | string ) LEFT_PAREN ( (runnable_param ( COMMA runnable_param )*)? ) RIGHT_PAREN KW_RETURNING qualified_type command # Function
+	;
+
+top_level_command
+	:	command # TopLevelCommand
+	| 	KW_UNDECLARE ( INTEGER | identifier | string ) LEFT_PAREN (qualified_type (COMMA qualified_type)*)? RIGHT_PAREN # UndeclareFunction
+	|	KW_PROCEDURE ( INTEGER | identifier | string ) LEFT_PAREN ( (runnable_param ( COMMA runnable_param )*)? ) RIGHT_PAREN nested_level_command # Procedure
+	|	KW_FUNCTION ( INTEGER | identifier | string ) LEFT_PAREN ( (runnable_param ( COMMA runnable_param )*)? ) RIGHT_PAREN KW_RETURNING qualified_type nested_level_command # Function
 	;
 
 expression
diff --git a/alib2cli/src/parser/AltVisitor.Command.cpp b/alib2cli/src/parser/AltVisitor.Command.cpp
index b219d843327ce6dc411c9e032b9dcae572b15358..1d35504655d8077bb6cb78e21bbddc73dd8be336 100644
--- a/alib2cli/src/parser/AltVisitor.Command.cpp
+++ b/alib2cli/src/parser/AltVisitor.Command.cpp
@@ -40,8 +40,6 @@ using QualifedType = std::pair<abstraction::TypeQualifiers::TypeQualifierSet, st
 
 std::any AltVisitor::visitIfCommand(AltCliParser::IfCommandContext* ctx)
 {
-    ensureScope("if", Scope::Local);
-
     auto expression = castToUnique<Expression>(visit(ctx->condition));
     auto thenBranch = castToUnique<Command>(visit(ctx->then_branch));
 
@@ -55,8 +53,6 @@ std::any AltVisitor::visitIfCommand(AltCliParser::IfCommandContext* ctx)
 
 std::any AltVisitor::visitWhileCommand(AltCliParser::WhileCommandContext* ctx)
 {
-    ensureScope("while", Scope::Local);
-
     auto condition = castToUnique<Expression>(visit(ctx->condition));
     auto body = castToUnique<Command>(visit(ctx->body));
 
@@ -67,10 +63,10 @@ std::any AltVisitor::visitParse(AltCliParser::ParseContext* ctx)
 {
     ext::vector<std::unique_ptr<Command>> commands;
 
-    if (ctx->command().empty()) {
+    if (ctx->top_level_command().empty()) {
         commands.emplace_back(new EOTCommand());
     } else {
-        fillList<Command>(commands, ctx->command());
+        fillList<Command>(commands, ctx->top_level_command());
     }
 
     return new CommandList(std::move(commands));
@@ -85,13 +81,9 @@ std::any AltVisitor::visitPrint(AltCliParser::PrintContext* ctx)
 
 std::any AltVisitor::visitBlock(AltCliParser::BlockContext* ctx)
 {
-    incNestedLevel();
-
     ext::vector<std::unique_ptr<Command>> list;
-
     fillList<Command>(list, ctx->semicolon_command());
 
-    decNestedLevel();
     return retPtr<Command, CommandList>(std::move(list));
 }
 
@@ -117,7 +109,7 @@ std::any AltVisitor::visitWhileSemicolonCommand(AltCliParser::WhileSemicolonComm
 
 std::any AltVisitor::visitSemicolonCommand(AltCliParser::SemicolonCommandContext* ctx)
 {
-    return visit(ctx->command());
+    return visit(ctx->nested_level_command());
 }
 
 std::any AltVisitor::visitQuit(AltCliParser::QuitContext* ctx)
@@ -140,8 +132,6 @@ std::any AltVisitor::visitReturn(AltCliParser::ReturnContext* ctx)
 
 std::any AltVisitor::visitCycleControl(AltCliParser::CycleControlContext* ctx)
 {
-    ensureScope("break/continue", Scope::Local);
-
     if (ctx->KW_BREAK() != nullptr)
         return retPtr<Command, BreakCommand>();
 
@@ -209,8 +199,6 @@ std::any AltVisitor::visitHelp(AltCliParser::HelpContext* ctx)
 
 std::any AltVisitor::visitFunction(AltCliParser::FunctionContext* ctx)
 {
-    ensureScope("function", Scope::Global);
-
     std::string name;
     if (ctx->string() != nullptr)
         name = cast<std::string>(visit(ctx->string()));
@@ -223,15 +211,13 @@ std::any AltVisitor::visitFunction(AltCliParser::FunctionContext* ctx)
 
     auto params = visitRunnableParams(ctx->runnable_param());
     auto retType = visitQualifiedType(ctx->qualified_type());
-    auto body = castToUnique<Command>(visit(ctx->command()));
+    auto body = castToUnique<Command>(visit(ctx->nested_level_command()));
 
     return retPtr<Command, DeclareRunnableCommand>(std::move(name), std::move(params), std::move(retType), std::move(body));
 }
 
 std::any AltVisitor::visitProcedure(AltCliParser::ProcedureContext* ctx)
 {
-    ensureScope("procedure", Scope::Global);
-
     std::string name;
     if (ctx->string() != nullptr)
         name = cast<std::string>(visit(ctx->string()));
@@ -243,15 +229,13 @@ std::any AltVisitor::visitProcedure(AltCliParser::ProcedureContext* ctx)
         invalidParse("Invalid procedure name");
 
     auto params = visitRunnableParams(ctx->runnable_param());
-    auto body = castToUnique<Command>(visit(ctx->command()));
+    auto body = castToUnique<Command>(visit(ctx->nested_level_command()));
 
     return retPtr<Command, DeclareRunnableCommand>(std::move(name), std::move(params), std::move(body));
 }
 
 std::any AltVisitor::visitUndeclareFunction(AltCliParser::UndeclareFunctionContext* ctx)
 {
-    ensureScope("undeclare", Scope::Global);
-
     std::string name;
     if (ctx->identifier() != nullptr)
         name = ctx->identifier()->getText();
@@ -400,7 +384,7 @@ std::any AltVisitor::visitCalc(AltCliParser::CalcContext* ctx)
 
 std::any AltVisitor::visitIntrospectAst(AltCliParser::IntrospectAstContext* ctx)
 {
-    auto command = castToUnique<Command>(visit(ctx->command()));
+    auto command = castToUnique<Command>(visit(ctx->top_level_command()));
 
     return retPtr<Command, AstIntrospectionCommand>(std::move(command));
 }
diff --git a/alib2cli/src/parser/AltVisitor.h b/alib2cli/src/parser/AltVisitor.h
index 718fe2ea9d94bf58e849cf9ea7c4b7f730f38ba2..78577768a2918d78d58fe3a085922186f8f5a9c0 100644
--- a/alib2cli/src/parser/AltVisitor.h
+++ b/alib2cli/src/parser/AltVisitor.h
@@ -193,41 +193,6 @@ struct AltVisitor : public AltCliParserBaseVisitor {
 
     std::any visitContainerStatement(AltCliParser::ContainerStatementContext* ctx) override;
 
-private:
-    enum class Scope {
-        Global,
-        Local,
-    };
-
-    size_t nestedLevel = 0;
-
-    void incNestedLevel()
-    {
-        nestedLevel++;
-    }
-
-    void decNestedLevel()
-    {
-        nestedLevel--;
-    }
-
-    Scope isGlobalScope() const
-    {
-        return nestedLevel == 0 ? Scope::Global : Scope::Local;
-    }
-
-    void ensureScope(const std::string& commandName, const Scope& scope, const std::source_location location = std::source_location::current()) const
-    {
-        if (scope != isGlobalScope()) {
-            std::string scopeName = scope == Scope::Global ? "global" : "local";
-            std::ostringstream out;
-            out << "Invalid scope for " << commandName << " command. Expected scope was '" << scopeName << "'." << std::endl;
-            out << "At " << location.file_name() << ":" << location.line() << std::endl;
-            out << "\t" << location.function_name() << std::endl;
-            throw std::runtime_error(out.str());
-        }
-    }
-
 protected:
     std::any defaultResult() override;
 
diff --git a/alib2cli/test-src/aql/InvalidGrammarTest.cpp b/alib2cli/test-src/aql/InvalidGrammarTest.cpp
index e329bec63e82c6d1106876dbecebb2076708acb9..55fdc5d084be1b20d81a94ea86cb8490d9c68821 100644
--- a/alib2cli/test-src/aql/InvalidGrammarTest.cpp
+++ b/alib2cli/test-src/aql/InvalidGrammarTest.cpp
@@ -13,44 +13,44 @@ TEST_CASE("Invalid grammar - Scope")
 {
     SECTION("Undeclare")
     {
-        CHECK_THROWS_AS(newParseString("begin undeclare a (); end"), std::runtime_error);
+        CHECK_THROWS_AS(newParseString("begin undeclare a (); end"), exception::CommonException);
         CHECK_NOTHROW(newParseString("undeclare a ()"));
     }
 
     SECTION("If")
     {
-        CHECK_THROWS_AS(newParseString("if (1) then begin print 1; end"), std::runtime_error);
+        CHECK_THROWS_AS(newParseString("if (1) then begin print 1; end"), exception::CommonException);
         CHECK_NOTHROW(newParseString("begin if (1) then print 1; end"));
     }
 
 
     SECTION("While")
     {
-        CHECK_THROWS_AS(newParseString("while (1) do begin print 1; end"), std::runtime_error);
+        CHECK_THROWS_AS(newParseString("while (1) do begin print 1; end"), exception::CommonException);
         CHECK_NOTHROW(newParseString("begin while (1) do print 1; end"));
     }
 
     SECTION("Break")
     {
-        CHECK_THROWS_AS(newParseString("break"), std::runtime_error);
+        CHECK_THROWS_AS(newParseString("break"), exception::CommonException);
         CHECK_NOTHROW(newParseString("begin break; end"));
     }
 
     SECTION("Continue")
     {
-        CHECK_THROWS_AS(newParseString("continue"), std::runtime_error);
+        CHECK_THROWS_AS(newParseString("continue"), exception::CommonException);
         CHECK_NOTHROW(newParseString("begin continue; end"));
     }
 
     SECTION("Function")
     {
-        CHECK_THROWS_AS(newParseString("begin function func () returning auto return 1; end"), std::runtime_error);
+        CHECK_THROWS_AS(newParseString("begin function func () returning auto return 1; end"), exception::CommonException);
         CHECK_NOTHROW(newParseString("function func () returning auto return 1"));
     }
 
     SECTION("Procedure")
     {
-        CHECK_THROWS_AS(newParseString("begin procedure func () print 1; end"), std::runtime_error);
+        CHECK_THROWS_AS(newParseString("begin procedure func () print 1; end"), exception::CommonException);
         CHECK_NOTHROW(newParseString("procedure func () print 1"));
     }
 }
diff --git a/alib2cli/test-src/cli/AutocompleteTest.cpp b/alib2cli/test-src/cli/AutocompleteTest.cpp
index 7d815e7da444e37ab778fa353af468020eefebeb..1f212c37d4e31789f0f3c44cc9f3bd8621babd25 100644
--- a/alib2cli/test-src/cli/AutocompleteTest.cpp
+++ b/alib2cli/test-src/cli/AutocompleteTest.cpp
@@ -10,7 +10,7 @@ TEST_CASE("Autocomplete")
 
         auto suggestions = autocomplete.getSuggestions("", "");
 
-        CHECK(suggestions.size() == 26);
+        CHECK(suggestions.size() == 22);
     }
 
     SECTION("pri")