diff --git a/include/build_visitor.hpp b/include/build_visitor.hpp index 06672d4..9bd948b 100644 --- a/include/build_visitor.hpp +++ b/include/build_visitor.hpp @@ -61,7 +61,6 @@ private: void Visit(ForLoop* node) override; void Visit(LoopLoop* node) override; - void Visit(PatternToken& node) override; // variant void Visit(Pattern& node) override; // variant void Visit(FlowControl& node) override; // variant diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index 5a7a13e..bcf3539 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -246,15 +246,13 @@ struct ExtendedName { std::string name; }; -using PatternToken = std::variant< +using Pattern = std::variant< std::unique_ptr, std::unique_ptr, std::unique_ptr>; -using Pattern = std::variant< - std::unique_ptr, - std::unique_ptr>; +using ScopedPattern = Pattern; //////////////////////////////////////////////////////////////////////////////////////////// @@ -413,7 +411,7 @@ struct TypeConstructorPatternParameter { BaseNode base; std::optional name; - PatternToken value; + ScopedPattern value; }; struct TypeConstructorPattern { @@ -462,6 +460,7 @@ struct WhileLoop { struct ForLoop { BaseNode base; + utils::IsConstModifier variable_modifier; AnyName variable; Expression interval; Expression statement; diff --git a/include/visitor.hpp b/include/visitor.hpp index f4fed98..899e07a 100644 --- a/include/visitor.hpp +++ b/include/visitor.hpp @@ -58,7 +58,6 @@ protected: virtual void Visit(ForLoop* node); virtual void Visit(LoopLoop* node); - virtual void Visit(PatternToken& node); // variant virtual void Visit(Pattern& node); // variant virtual void Visit(FlowControl& node); // variant diff --git a/src/build_visitor.cpp b/src/build_visitor.cpp index 4d88370..fc4bec4 100644 --- a/src/build_visitor.cpp +++ b/src/build_visitor.cpp @@ -504,7 +504,7 @@ void BuildVisitor::Visit(TypeConstructorPattern* node) { } -void BuildVisitor::Visit(PatternToken& node) { +void BuildVisitor::Visit(Pattern& node) { // <-> ScopedPattern auto parse_node = current_node_; current_node_ = parse_node.NthNamedChild(0); @@ -527,26 +527,6 @@ void BuildVisitor::Visit(PatternToken& node) { current_node_ = parse_node; } -void BuildVisitor::Visit(Pattern& node) { - auto parse_node = current_node_; - - current_node_ = parse_node.NthNamedChild(0); - - std::string current_node_type = current_node_.GetType(); - - if (current_node_type == parser::tokens::TypeConstructorPattern) { // optimize ?? - node = std::make_unique(); - Visit(std::get>(node).get()); - } else if (current_node_type == parser::tokens::PatternToken) { - node = std::make_unique(); - Visit(*std::get>(node)); - } else { - // error - } - - current_node_ = parse_node; -} - void BuildVisitor::Visit(MatchCase* node) { SetPosition(node->base, current_node_); @@ -653,6 +633,13 @@ void BuildVisitor::Visit(ForLoop* node) { auto parse_node = current_node_; + std::string modifier = parse_node.NthChild(1).GetValue(); + if (modifier == "const") { + node->variable_modifier = utils::IsConstModifier::Const; + } else if (modifier == "var") { + node->variable_modifier = utils::IsConstModifier::Var; + } + current_node_ = parse_node.ChildByFieldName("variable"); Visit(node->variable); diff --git a/src/print_visitor.cpp b/src/print_visitor.cpp index c3d73e1..91b4a1a 100644 --- a/src/print_visitor.cpp +++ b/src/print_visitor.cpp @@ -331,7 +331,16 @@ void PrintVisitor::Visit(WhileLoop* node) { out_ << ")\n"; } void PrintVisitor::Visit(ForLoop* node) { - out_ << "[For] ("; + out_ << "[For "; + switch (node->variable_modifier) { + case utils::IsConstModifier::Const: + out_ << "const"; + break; + case utils::IsConstModifier::Var: + out_ << "var"; + break; + } + out_ << "] ("; Visitor::Visit(node->variable); out_ << ") [in] ("; Visitor::Visit(node->interval); diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index f74da56..e7c1627 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -319,16 +319,19 @@ void TypeCheckVisitor::Visit(MatchCase* node) { is_const_definition_ = true; // TODO: or var?? Visitor::Visit(node->value); + utils::IdType value_type = current_type_; + switch (node->value.index()) { case 0: - context_manager_.DefineVariable(std::get<0>(node->value)->name, + context_manager_.DefineVariable(std::get>(node->value)->name, current_type_, is_const_definition_.value()); break; case 1: - - Visitor::Visit(*std::get<1>(node->value).get()); - + Visitor::Visit(*std::get>(node->value)); + if (context_manager_.EqualTypes(current_type_, value_type)) { + error_handling::HandleTypecheckError("Literal and value have different types", node->base); + } break; case 2: Visit(std::get>(node->value).get()); @@ -452,7 +455,9 @@ void TypeCheckVisitor::Visit(ForLoop* node) { } current_type_ = context_manager_.AddType(maybe_interval_type.value()->GetElementsType()); + is_const_definition_ = (node->modifier == utils::IsConstModifier::Const); Visitor::Visit(node->variable); // type passed to variable definition throught current_type_ + is_const_definition_ = std::nullopt; Visitor::Visit(node->statement); diff --git a/src/visitor.cpp b/src/visitor.cpp index a188895..060cfd5 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -64,13 +64,13 @@ void Visitor::Visit(SourceStatement& node) { // Flow control ----------------- -void Visitor::Visit(PatternToken& node) { +void Visitor::Visit(Pattern& node) { // <-> ScopedPattern switch (node.index()) { case 0: Visit(std::get>(node).get()); break; case 1: - Visit(*std::get>(node).get()); + Visit(*std::get>(node)); break; case 2: Visit(std::get>(node).get()); @@ -81,20 +81,6 @@ void Visitor::Visit(PatternToken& node) { } } -void Visitor::Visit(Pattern& node) { - switch (node.index()) { - case 0: - Visit(std::get>(node).get()); - break; - case 1: - Visit(*std::get>(node)); - break; - default: - // error - break; - } -} - void Visitor::Visit(FlowControl& node) { switch (node.index()) { case 0: