diff --git a/include/contexts.hpp b/include/contexts.hpp index c5fc083..29406e6 100644 --- a/include/contexts.hpp +++ b/include/contexts.hpp @@ -1,40 +1,139 @@ #pragma once #include +#include #include #include // for clangd -#include "symbols_info.hpp" +#include "values.hpp" +#include "utils.hpp" namespace info { class ContextManager { public: - void CallFunction(const std::vector&); - void EnterContext(); - void ExitContext(); + ContextManager() { + contexts_.emplace_back(); + } + + template + utils::IdType AddValue(const T& value, utils::ValueType value_type) { + return value_manager_.AddValue(value, value_type); + } + + utils::IdType AddAnyValue(value::Value&& value, utils::ValueType value_type) { + return value_manager_.AddAnyValue(std::move(value), value_type); + } + + template + std::optional GetValue(utils::IdType value_id) { + return value_manager_.GetValue(value_id); + } + + value::Value* GetAnyValue(utils::IdType value_id) { + return value_manager_.GetAnyValue(value_id); + } + + utils::ValueType GetValueType(utils::IdType value_id) { + return value_manager_.GetValueType(value_id); + } + + utils::IdType ToModifiedValue(utils::IdType value_id, utils::ValueType new_value_type) { + value::Value value = *GetAnyValue(value_id); + return AddAnyValue(std::move(value), new_value_type); + } + + value::ValueManager* GetValueManager() { + return &value_manager_; + } + + void EnterContext() { + contexts_.emplace_back(); + } + + void ExitContext() { + if (contexts_.empty()) { + // error + } + + contexts_.pop_back(); + } + + void ExitFromAllContexts() { + contexts_.clear(); + contexts_.emplace_back(); + } + + bool DefineVariable(const std::string& name, utils::IdType value_id) { + // check in previous contexts ?? + return contexts_.back().DefineVariable(name, value_id); + } + + + bool RemoveVariable(const std::string& name) { + for (ssize_t i = (ssize_t)contexts_.size() - 1; i >= 0; --i) { + if (contexts_[i].RemoveVariable(name)) { + return true; + } + } + return false; + } + + void EnterVariableContext(const std::string& name, utils::IdType value_id) { + // for variable namespaces, for loops + contexts_.emplace_back(); + + DefineVariable(name, value_id); + } + + std::optional GetVariableInfo(const std::string& name) { + for (ssize_t i = (ssize_t)contexts_.size() - 1; i >= 0; --i) { + auto maybe_type = contexts_[i].GetVariableInfo(name); + if (maybe_type.has_value()) { + return maybe_type.value(); + } + } + return std::nullopt; + } - void DefineVariable(const VariableInfo& variable); - void ChangeVariableValue(const std::string& name, const Value& new_value); - const Value& GetVariableValue(const std::string& name); private: class Context { public: - Context(bool hide_previous = false) : hide_previous_(hide_previous) {} + Context() = default; - void DefineVariable(const VariableInfo& variable); - void ChangeVaraibleValue(const std::string& name, const Value& neew_value); - const Value& GetVariableValue(const std::string& name); + bool DefineVariable(const std::string& name, utils::IdType value_id) { + if (name == "_") { // placeholder // TODO: ?? + return true; + } + + if (variables_.count(name) > 0) { + return false; + } + variables_[name] = value_id; + return true; + } + + bool RemoveVariable(const std::string& name) { + return variables_.erase(name); + } + + std::optional GetVariableInfo(const std::string& name) { + auto variable_iter = variables_.find(name); + + if (variable_iter == variables_.end()) { + return std::nullopt; + } + + return variable_iter->second; + } - bool IsFirst() { return hide_previous_; } private: - bool hide_previous_; - std::unordered_map variables_; + std::unordered_map variables_; }; - // Context global_context_; // ?? std::vector contexts_; + value::ValueManager value_manager_; }; } // namespace info diff --git a/include/type_check_visitor.hpp b/include/type_check_visitor.hpp index 715d88e..434dede 100644 --- a/include/type_check_visitor.hpp +++ b/include/type_check_visitor.hpp @@ -7,6 +7,8 @@ #include "visitor.hpp" #include "global_info.hpp" +// TODO: class fields and constructors can't be accessed not from associated namespace + namespace interpreter { class TypeCheckVisitor : public Visitor { diff --git a/include/type_info_contexts.hpp b/include/type_info_contexts.hpp index 6cf445b..e846db0 100644 --- a/include/type_info_contexts.hpp +++ b/include/type_info_contexts.hpp @@ -71,6 +71,7 @@ public: void ExitFromAllContexts() { contexts_.clear(); + contexts_.emplace_back(); } bool DefineVariable(const std::string& name, utils::IdType type_id) { diff --git a/include/values.hpp b/include/values.hpp index cf121f7..10ab0b0 100644 --- a/include/values.hpp +++ b/include/values.hpp @@ -111,25 +111,25 @@ struct Value { // DefinedValue ?? class ValueManager { public: template - utils::IdType AddType(const T& value, utils::ValueType value_type) { + utils::IdType AddValue(const T& value, utils::ValueType value_type) { values_.push_back(std::pair {value, value_type}); return values_.size() - 1; } - utils::IdType AddAnyType(Value&& value, utils::ValueType value_type) { + utils::IdType AddAnyValue(Value&& value, utils::ValueType value_type) { values_.push_back(std::pair {std::move(value), value_type}); return values_.size() - 1; } template - std::optional GetType(utils::IdType value_id) { + std::optional GetValue(utils::IdType value_id) { if (!std::holds_alternative(values_.at(value_id).first.value)) { return std::nullopt; } return &std::get(values_.at(value_id).first.value); } - Value* GetAnyType(utils::IdType value_id) { + Value* GetAnyValue(utils::IdType value_id) { return &values_.at(value_id).first; } diff --git a/src/execute_visitor.cpp b/src/execute_visitor.cpp index e69de29..edcd36e 100644 --- a/src/execute_visitor.cpp +++ b/src/execute_visitor.cpp @@ -0,0 +1,387 @@ +// for clangd +#include "../include/execute_visitor.hpp" + +// TODO + +namespace interpreter { + +// Sources ----------------- + +void ExecuteVisitor::Visit(SourceFile* node) { + for (auto& statement : node->statements) { + Visitor::Visit(statement); + } +} + +// Namespaces, partitions ----------------- + +void ExecuteVisitor::Visit(PartitionSources* node) { + for (auto& statement : node->statements) { + Visitor::Visit(statement); + } +} + +void ExecuteVisitor::Visit(Partition* node) { + Visit(&node->scope); +} + +void ExecuteVisitor::Visit(NamespaceSources* node) { + for (auto& statement : node->statements) { + Visitor::Visit(statement); + } +} + +void ExecuteVisitor::Visit(Namespace* node) { + Visit(&node->type); + Visit(&node->scope); +} + +// Definitions ----------------- + +void ExecuteVisitor::Visit(ImportStatement* node) { + for (auto& symbol : node->symbols) { + Visit(&symbol); + } +} + +void ExecuteVisitor::Visit(AliasDefinitionStatement* node) { + Visit(&node->type); + Visit(node->value.get()); +} + +void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { + Visitor::Visit(node->name); + Visitor::Visit(node->value); +} + +void ExecuteVisitor::Visit(FunctionDeclaration* node) { + Visit(&node->name); + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + } + Visit(node->type.get()); +} + +void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) { + Visit(node->definition.get()); + Visitor::Visit(node->value); +} + +void ExecuteVisitor::Visit(TypeDefinitionStatement* node) { + Visit(node->definition.get()); + Visitor::Visit(node->value); +} + +void ExecuteVisitor::Visit(AbstractTypeDefinitionStatement* node) { + Visit(node->type.get()); +} + +void ExecuteVisitor::Visit(TypeclassDefinitionStatement* node) { + Visit(node->definition.get()); + for (auto& requirement : node->requirements) { + Visit(requirement.get()); + } +} + +// Definition parts + +void ExecuteVisitor::Visit(FunctionDefinition* node) { + Visit(&node->name); + for (auto& argument : node->arguments) { + Visit(&argument); + } +} + +void ExecuteVisitor::Visit(TypeDefinition* node) { + Visit(node->type.get()); + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + } +} + +void ExecuteVisitor::Visit(AnyAnnotatedType* node) { + Visit(&node->type); + for (auto& typeclass : node->typeclasses) { + Visit(typeclass.get()); + } +} + +// Flow control ----------------- + +void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) { + if (node->name.has_value()) { + Visit(&node->name.value()); + } + Visitor::Visit(node->value); +} + +void ExecuteVisitor::Visit(TypeConstructorPattern* node) { + Visit(node->constructor.get()); + for (auto& parameter : node->parameters) { + Visit(¶meter); + } +} + +void ExecuteVisitor::Visit(MatchCase* node) { + Visitor::Visit(node->value); + if (node->condition.has_value()) { + Visitor::Visit(node->condition.value()); + } + if (node->statement.has_value()) { + Visitor::Visit(node->statement.value()); + } +} + +void ExecuteVisitor::Visit(Match* node) { + Visitor::Visit(node->value); + for (auto& match_case : node->matches) { + Visit(&match_case); + } +} + +void ExecuteVisitor::Visit(Condition* node) { + for (size_t i = 0; i < node->conditions.size(); ++i) { + Visitor::Visit(node->conditions[i]); + Visitor::Visit(node->statements[i]); + } + if (node->statements.size() > node->conditions.size()) { + Visitor::Visit(node->statements[node->conditions.size()]); + } +} + +void ExecuteVisitor::Visit(DoWhileLoop* node) { + Visitor::Visit(node->statement); + Visitor::Visit(node->condition); +} + +void ExecuteVisitor::Visit(WhileLoop* node) { + Visitor::Visit(node->condition); + Visitor::Visit(node->statement); +} +void ExecuteVisitor::Visit(ForLoop* node) { + Visitor::Visit(node->variable); + Visitor::Visit(node->interval); + Visitor::Visit(node->statement); +} + +void ExecuteVisitor::Visit(LoopLoop* node) { + Visitor::Visit(node->statement); +} + +// Statements, expressions, blocks, etc. ----------------- + +void ExecuteVisitor::Visit(Block* node) { + for (auto& statement : node->statements) { + Visitor::Visit(statement); + } +} + +void ExecuteVisitor::Visit(ScopedStatement* node) { + Visitor::Visit(node->statement); +} + +void ExecuteVisitor::Visit(LoopControlExpression& node) {} // enum + +// Operators + +void ExecuteVisitor::Visit(BinaryOperatorExpression* node) { + Visitor::Visit(node->left_expression); + Visitor::Visit(&node->operator_name); + Visitor::Visit(node->right_expression); +} + +void ExecuteVisitor::Visit(UnaryOperatorExpression* node) { + Visit(&node->operator_name); + Visitor::Visit(node->expression); +} + +void ExecuteVisitor::Visit(ReferenceExpression* node) { + Visit(node->expression.get()); +} + +void ExecuteVisitor::Visit(AccessExpression* node) { + Visit(node->name.get()); + Visitor::Visit(node->id); +} + +// Other Expressions + +void ExecuteVisitor::Visit(FunctionCallExpression* node) { + if (node->prefix.has_value()) { + if (std::holds_alternative>(node->prefix.value())) { + Visitor::Visit(*std::get>(node->prefix.value())); + } else if (std::holds_alternative>(node->prefix.value())) { + Visit(std::get>(node->prefix.value()).get()); + } else { + // error + } + } + + Visit(&node->name); + + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + } + + for (auto& argument : node->arguments) { + Visitor::Visit(argument); + } +} + +void ExecuteVisitor::Visit(TupleExpression* node) { + for (auto& expression : node->expressions) { + Visitor::Visit(expression); + } +} + +void ExecuteVisitor::Visit(VariantExpression* node) { + for (auto& expression : node->expressions) { + Visitor::Visit(expression); + } +} + +void ExecuteVisitor::Visit(ReturnExpression* node) { + Visitor::Visit(node->expression); +} + +void ExecuteVisitor::Visit(TypeConstructorParameter* node) { + if (node->name.has_value()) { + Visit(&node->name.value()); + } + Visitor::Visit(node->value); +} + +void ExecuteVisitor::Visit(TypeConstructor* node) { + Visit(node->constructor.get()); + for (auto& parameter : node->parameters) { + Visit(¶meter); + } +} + +void ExecuteVisitor::Visit(LambdaFunction* node) { + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + } + for (auto& argument : node->arguments) { + Visit(&argument); + } + Visitor::Visit(node->expression); +} + +void ExecuteVisitor::Visit(ArrayExpression* node) { + for (auto& element : node->elements) { + Visitor::Visit(element); + } +} + +// Name + +void ExecuteVisitor::Visit(NameExpression* node) { + for (auto& name : node->names) { + Visit(&name); + } +} + +void ExecuteVisitor::Visit(TupleName* node) { + for (auto& name : node->names) { + Visitor::Visit(name); + } +} + +void ExecuteVisitor::Visit(VariantName* node) { + for (auto& name : node->names) { + Visitor::Visit(name); + } +} + +void ExecuteVisitor::Visit(AnnotatedName* node) { + Visit(&node->name); + if (node->type.has_value()) { + Visitor::Visit(node->type.value()); + } +} + +// Type, typeclass, etc. ----------------- + +// Type + +void ExecuteVisitor::Visit(FunctionType* node) { + for (auto& type : node->types) { + Visitor::Visit(type); + } +} + +void ExecuteVisitor::Visit(TupleType* node) { + if (node->type.has_value()) { + Visit(&node->type.value()); + } + for (auto& entity : node->entities) { + if (entity.first.has_value()) { + Visit(&entity.first.value()); + } + Visit(entity.second.get()); + } +} + +void ExecuteVisitor::Visit(VariantType* node) { + if (node->type.has_value()) { + Visit(&node->type.value()); + } + for (auto& constructor : node->constructors) { + if (std::holds_alternative(constructor)) { + Visit(&std::get(constructor)); + } else if (std::holds_alternative>(constructor)) { + Visit(std::get>(constructor).get()); + } else { + // error + } + } +} + +void ExecuteVisitor::Visit(TypeExpression* node) { + for (auto& type : node->path) { + Visit(&type); + } + Visit(&node->type); +} + +void ExecuteVisitor::Visit(ExtendedScopedAnyType* node) { + Visitor::Visit(node->type); +} + +// Typeclass + +void ExecuteVisitor::Visit(ParametrizedTypeclass* node) { + Visit(&node->typeclass); + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + } +} + +// Typeclass & Type ----------------- + +void ExecuteVisitor::Visit(ParametrizedType* node) { + Visit(&node->type); + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + } +} + +// Identifiers, constants, etc. ----------------- + +void ExecuteVisitor::Visit(ExtendedName* node) {} + +void ExecuteVisitor::Visit(std::string* node) {} // std::string + +void ExecuteVisitor::Visit(FloatNumberLiteral* node) {} + +void ExecuteVisitor::Visit(NumberLiteral* node) {} + +void ExecuteVisitor::Visit(StringLiteral* node) {} + +void ExecuteVisitor::Visit(CharLiteral* node) {} + +void ExecuteVisitor::Visit(UnitLiteral* node) {} + +} // namespace interpreter + diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 01e63f7..36a7c05 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -8,8 +8,6 @@ #include "../include/type_check_visitor.hpp" #include "../include/error_handling.hpp" -// TODO - namespace interpreter { // Sources ----------------- diff --git a/src/visitor.cpp b/src/visitor.cpp index 060cfd5..3ebdb29 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -597,7 +597,7 @@ void Visitor::Visit(VariantName* node) { void Visitor::Visit(AnnotatedName* node) { Visit(&node->name); if (node->type.has_value()) { - Visitor::Visit(node->type.value()); + Visit(node->type.value()); } } @@ -607,7 +607,7 @@ void Visitor::Visit(AnnotatedName* node) { void Visitor::Visit(FunctionType* node) { for (auto& type : node->types) { - Visitor::Visit(type); + Visit(type); } }