diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index ff1f42c..9446f86 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -307,6 +307,7 @@ struct VariableDefinitionStatement { utils::AssignmentModifier assignment_modifier; AnyName name; SuperExpression value; + std::optional in_expression; }; struct FunctionDeclaration { diff --git a/lang-parser b/lang-parser index 24bcf6e..ab391d2 160000 --- a/lang-parser +++ b/lang-parser @@ -1 +1 @@ -Subproject commit 24bcf6e960957daf5662b764480f1d56637b1712 +Subproject commit ab391d2d8d5251422abc94b80a51438faddb19c7 diff --git a/src/build_visitor.cpp b/src/build_visitor.cpp index 180ec1b..2d256a7 100644 --- a/src/build_visitor.cpp +++ b/src/build_visitor.cpp @@ -167,6 +167,14 @@ void BuildVisitor::Visit(VariableDefinitionStatement* node) { // error } + size_t child_count = parse_node.NamedChildCount(); + + if (child_count > 2) { // name, value [, in_expression] + current_node_ = parse_node.ChildByFieldName("in_expression"); + node->in_expression.emplace(); + Visit(node->in_expression.value()); + } + current_node_ = parse_node; } diff --git a/src/execute_visitor.cpp b/src/execute_visitor.cpp index a033d0f..1fc025e 100644 --- a/src/execute_visitor.cpp +++ b/src/execute_visitor.cpp @@ -47,11 +47,22 @@ void ExecuteVisitor::Visit(AliasDefinitionStatement* node) { } void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { + // TODO: optional variable definitions + + if (node->in_expression.has_value()) { + context_manager_.EnterContext(); + } + Visitor::Visit(node->value); is_const_definition_ = node->modifier; Visitor::Visit(node->name); // current_type_ passed from value is_const_definition_ = std::nullopt; + + if (node->in_expression.has_value()) { + Visitor::Visit(node->in_expression.value()); + context_manager_.ExitContext(); + } } void ExecuteVisitor::Visit(FunctionDeclaration* node) { diff --git a/src/print_visitor.cpp b/src/print_visitor.cpp index ddf8fb0..59b37e3 100644 --- a/src/print_visitor.cpp +++ b/src/print_visitor.cpp @@ -93,6 +93,12 @@ void PrintVisitor::Visit(VariableDefinitionStatement* node) { Visitor::Visit(node->name); out_ << "] = ("; Visitor::Visit(node->value); + + if (node->in_expression.has_value()) { + out_ << ") in ("; + Visitor::Visit(node->in_expression.value()); + } + out_ << ")\n"; } diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 5665a91..5030186 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -101,7 +101,11 @@ void TypeCheckVisitor::Visit(AliasDefinitionStatement* node) { // TODO: move, etc. void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) { - is_in_statement_ = true; + // TODO: optional variable definitions + + if (node->in_expression.has_value()) { + context_manager_.EnterContext(); + } Visitor::Visit(node->value); // current_type from value automatically passed to name definitions @@ -110,8 +114,12 @@ void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) { Visitor::Visit(node->name); is_const_definition_ = std::nullopt; + if (node->in_expression.has_value()) { + Visitor::Visit(node->in_expression.value()); + context_manager_.ExitContext(); + } + current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit); - is_in_statement_ = false; node->base.type_ = current_type_; } diff --git a/src/typed_print_visitor.cpp b/src/typed_print_visitor.cpp index ef3e27b..49f5124 100644 --- a/src/typed_print_visitor.cpp +++ b/src/typed_print_visitor.cpp @@ -123,6 +123,12 @@ void TypedPrintVisitor::Visit(VariableDefinitionStatement* node) { Visitor::Visit(node->name); out_ << "] = ("; Visitor::Visit(node->value); + + if (node->in_expression.has_value()) { + out_ << ") in ("; + Visitor::Visit(node->in_expression.value()); + } + out_ << ")\n"; } diff --git a/src/visitor.cpp b/src/visitor.cpp index fb45600..b356592 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -328,6 +328,9 @@ void Visitor::Visit(AliasDefinitionStatement* node) { void Visitor::Visit(VariableDefinitionStatement* node) { Visit(node->name); Visit(node->value); + if (node->in_expression.has_value()) { + Visit(node->in_expression.value()); + } } void Visitor::Visit(FunctionDeclaration* node) { diff --git a/tests/test_code.lang b/tests/test_code.lang index 971738b..3b6958a 100644 --- a/tests/test_code.lang +++ b/tests/test_code.lang @@ -106,10 +106,10 @@ namespace var \div { typeclass \eq = & var ( == ) : \eq -> \bool - & var ( != ) : \eq -> \bool + & var ( <> ) : \eq -> \bool namespace var \eq { - def ( != ) : x = not: (self == x) + def ( <> ) : x = not: (self == x) } // diff --git a/tests/variables.lang b/tests/variables.lang new file mode 100644 index 0000000..e85b2c4 --- /dev/null +++ b/tests/variables.lang @@ -0,0 +1,11 @@ +decl test-variables : \int -> \unit +def test-variables : a = { + var x = if a < 123 then "aaa" else "bbb" + + var y = 543.32 in do-something: + + var z = 543.32 in { + for x in 1--10 do print: 111 + if scan:[int] < 11 then do-something-another: z "aaa" + } +}