diff --git a/include/.type_info_contexts.hpp.kate-swp b/include/.type_info_contexts.hpp.kate-swp new file mode 100644 index 0000000..126d73c Binary files /dev/null and b/include/.type_info_contexts.hpp.kate-swp differ diff --git a/include/contexts.hpp b/include/contexts.hpp index 29406e6..f47f6dc 100644 --- a/include/contexts.hpp +++ b/include/contexts.hpp @@ -70,6 +70,12 @@ public: return contexts_.back().DefineVariable(name, value_id); } + bool DefineLocalType(const std::string& name, utils::IdType type_id) { + if (GetLocalType(name).has_value()) { + return false; + } + return contexts_.back().DefineLocalType(name, type_id); + } bool RemoveVariable(const std::string& name) { for (ssize_t i = (ssize_t)contexts_.size() - 1; i >= 0; --i) { @@ -97,6 +103,16 @@ public: return std::nullopt; } + std::optional GetLocalType(const std::string& name) { + for (ssize_t i = (ssize_t)contexts_.size() - 1; i >= 0; --i) { + auto maybe_type = contexts_[i].GetLocalType(name); + if (maybe_type.has_value()) { + return maybe_type.value(); + } + } + return std::nullopt; + } + private: class Context { public: @@ -114,6 +130,14 @@ private: return true; } + bool DefineLocalType(const std::string& name, utils::IdType type_id) { + if (local_types_.count(name) > 0) { + return false; + } + local_types_[name] = type_id; + return true; + } + bool RemoveVariable(const std::string& name) { return variables_.erase(name); } @@ -128,8 +152,19 @@ private: return variable_iter->second; } + std::optional GetLocalType(const std::string& name) { + auto local_abstract_type_iter = local_types_.find(name); + + if (local_abstract_type_iter == local_types_.end()) { + return std::nullopt; + } + + return local_abstract_type_iter->second; + } + private: std::unordered_map variables_; + std::unordered_map local_types_; }; std::vector contexts_; diff --git a/include/values.hpp b/include/values.hpp index 07ace42..bd9af09 100644 --- a/include/values.hpp +++ b/include/values.hpp @@ -88,9 +88,9 @@ public: struct ArrayValue { public: ArrayValue() = default; - explicit ArrayValue(const std::vector& elements, + explicit ArrayValue(std::vector&& elements, bool is_constant_size) - : elements(elements), is_constant_size(is_constant_size) {} + : elements(std::move(elements)), is_constant_size(is_constant_size) {} public: std::vector elements; diff --git a/src/execute_visitor.cpp b/src/execute_visitor.cpp index 14e3cee..985d92e 100644 --- a/src/execute_visitor.cpp +++ b/src/execute_visitor.cpp @@ -34,14 +34,14 @@ void ExecuteVisitor::Visit(Namespace* node) { // never used ?? void ExecuteVisitor::Visit(ImportStatement* node) {} // no value void ExecuteVisitor::Visit(AliasDefinitionStatement* node) {} // no value -void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { +void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { // visited on function call Visitor::Visit(node->name); Visitor::Visit(node->value); } void ExecuteVisitor::Visit(FunctionDeclaration* node) {} // no value -void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) { +void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) { // visited on function call // Visit(node->definition.get()); Visitor::Visit(node->value); } @@ -64,7 +64,9 @@ void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) { Visitor::Visit(node->value); } +// TODO void ExecuteVisitor::Visit(TypeConstructorPattern* node) { + // TODO: not only tuples Visit(node->constructor.get()); for (auto& parameter : node->parameters) { Visit(¶meter); @@ -90,11 +92,23 @@ void ExecuteVisitor::Visit(Match* node) { void ExecuteVisitor::Visit(Condition* node) { for (size_t i = 0; i < node->conditions.size(); ++i) { - Visitor::Visit(node->conditions[i]); + if (HandleCondition(node->conditions[i], node->base)) { Visitor::Visit(node->statements[i]); + + if (node->statements.size() == node->conditions.size()) { + current_value_ = context_manager_.AddValue( + info::value::OptionalValue(current_value_), + utils::ValueType::Tmp); // take value type from current_value_ ?? + } + return; // current_value_ passed from statement + } } if (node->statements.size() > node->conditions.size()) { Visitor::Visit(node->statements[node->conditions.size()]); + } else { + current_value_ = context_manager_.AddValue( + info::value::OptionalValue(), + utils::ValueType::Tmp); } } @@ -115,7 +129,7 @@ void ExecuteVisitor::Visit(DoWhileLoop* node) { } while(HandleCondition(node->condition, node->base)); current_value_ = context_manager_.AddValue( - info::value::ArrayValue(result, false), + info::value::ArrayValue(std::move(result), false), utils::ValueType::Tmp); } @@ -136,7 +150,7 @@ void ExecuteVisitor::Visit(WhileLoop* node) { } current_value_ = context_manager_.AddValue( - info::value::ArrayValue(result, false), + info::value::ArrayValue(std::move(result), false), utils::ValueType::Tmp); } void ExecuteVisitor::Visit(ForLoop* node) { @@ -164,7 +178,7 @@ void ExecuteVisitor::Visit(ForLoop* node) { } current_value_ = context_manager_.AddValue( - info::value::ArrayValue(result, false), + info::value::ArrayValue(std::move(result), false), utils::ValueType::Tmp); } @@ -185,13 +199,16 @@ void ExecuteVisitor::Visit(LoopLoop* node) { } current_value_ = context_manager_.AddValue( - info::value::ArrayValue(result, false), + info::value::ArrayValue(std::move(result), false), utils::ValueType::Tmp); } // Statements, expressions, blocks, etc. ----------------- void ExecuteVisitor::Visit(Block* node) { + // type_info_context_manager_.EnterContext(); // not needed ?? + context_manager_.EnterContext(); + for (auto& statement : node->statements) { return_value_ = std::nullopt; Visitor::Visit(statement); @@ -200,6 +217,9 @@ void ExecuteVisitor::Visit(Block* node) { return; } } + // context_manager_.ExitContext(); + // type_info_context_manager_.ExitContext(); // not needed ?? + current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -288,8 +308,9 @@ void ExecuteVisitor::Visit(TupleExpression* node) { fields.push_back({std::nullopt, current_value_}); } - current_value_ = context_manager_.AddValue(info::value::TupleValue(std::move(fields)), - utils::ValueType::Tmp); + current_value_ = context_manager_.AddValue( + info::value::TupleValue(std::move(fields)), + utils::ValueType::Tmp); } // TODO @@ -316,7 +337,9 @@ void ExecuteVisitor::Visit(TypeConstructorParameter* node) { Visitor::Visit(node->value); } +// TODO void ExecuteVisitor::Visit(TypeConstructor* node) { + // TODO: not only tuples Visit(node->constructor.get()); for (auto& parameter : node->parameters) { Visit(¶meter); @@ -330,9 +353,17 @@ void ExecuteVisitor::Visit(LambdaFunction* node) { } void ExecuteVisitor::Visit(ArrayExpression* node) { + std::vector elements; + + elements.reserve(node->elements.size()); for (auto& element : node->elements) { Visitor::Visit(element); + elements.push_back(current_value_); } + + current_value_ = context_manager_.AddValue( + info::value::ArrayValue(std::move(elements), true), // maybe size not fixed?? + utils::ValueType::Tmp); } // Name diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 7f7bbd2..6d1ae12 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -736,7 +736,7 @@ void TypeCheckVisitor::Visit(AccessExpression* node) { // Other Expressions -// TODO +// TODO: better structure, ... // TODO: builtin functions/methods // TODO: alias types, abstract types, etc. // TODO: deduce function parameter types