From 56028cb9b4d85530b072cd026285627a81c9f15c Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Thu, 19 Sep 2019 12:46:20 +0200
Subject: [PATCH] Fix function arguments scope

Function has now its own symbol table so that arguments are locally defined
---
 src/language/ASTSymbolTableBuilder.cpp | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/src/language/ASTSymbolTableBuilder.cpp b/src/language/ASTSymbolTableBuilder.cpp
index 0d3c08232..8bbb6cf6d 100644
--- a/src/language/ASTSymbolTableBuilder.cpp
+++ b/src/language/ASTSymbolTableBuilder.cpp
@@ -10,10 +10,25 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable>
     if (!n.children.empty()) {
       std::shared_ptr block_symbol_table = std::make_shared<SymbolTable>(symbol_table);
       n.m_symbol_table                   = block_symbol_table;
+
       for (auto& child : n.children) {
         this->buildSymbolTable(*child, block_symbol_table);
       }
     }
+  } else if (n.is<language::let_declaration>()) {
+    std::shared_ptr local_symbol_table = std::make_shared<SymbolTable>(symbol_table);
+    n.m_symbol_table                   = local_symbol_table;
+    const std::string& symbol          = n.children[0]->string();
+    auto [i_symbol, success]           = symbol_table->add(symbol, n.children[0]->begin());
+    if (not success) {
+      std::ostringstream error_message;
+      error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << '\'' << " was already defined!";
+      throw parse_error(error_message.str(), std::vector{n.begin()});
+    }
+
+    for (auto& child : n.children) {
+      this->buildSymbolTable(*child, local_symbol_table);
+    }
   } else {
     n.m_symbol_table = symbol_table;
     if (n.has_content()) {
@@ -25,14 +40,6 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable>
           error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << '\'' << " was already defined!";
           throw parse_error(error_message.str(), std::vector{n.begin()});
         }
-      } else if (n.is<language::let_declaration>()) {
-        const std::string& symbol = n.children[0]->string();
-        auto [i_symbol, success]  = symbol_table->add(symbol, n.children[0]->begin());
-        if (not success) {
-          std::ostringstream error_message;
-          error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << '\'' << " was already defined!";
-          throw parse_error(error_message.str(), std::vector{n.begin()});
-        }
       } else if (n.is<language::function_definition>()) {
         const std::string& symbol = n.children[0]->string();
         auto [i_symbol, success]  = symbol_table->add(symbol, n.children[0]->begin());
-- 
GitLab