diff --git a/include/builtin_functions.hpp b/include/builtin_functions.hpp index 8c4d868..cfba119 100644 --- a/include/builtin_functions.hpp +++ b/include/builtin_functions.hpp @@ -24,7 +24,7 @@ inline T Read() { template inline void Error(const T& value) { // only for strings ?? - std::cout << "\x1b[1;33mError:\x1b[0m "; + std::cout << "\x1b[1;35mError:\x1b[0m "; std::cout << value; std::cout << '\n'; exit(1); diff --git a/include/contexts.hpp b/include/contexts.hpp index f5737aa..9c5c862 100644 --- a/include/contexts.hpp +++ b/include/contexts.hpp @@ -16,7 +16,8 @@ template class ContextManager { public: ContextManager() { - contexts_.emplace_back(true); // no difference ?? + contexts_.emplace_back(false); // global context + contexts_.emplace_back(true); // first context } size_t ContextCount() { @@ -86,8 +87,8 @@ public: } void ExitContext() { - if (contexts_.empty()) { - error_handling::HandleInternalError("contexts_ is empty", + if (contexts_.size() <= 2) { + error_handling::HandleInternalError("only global context & first context in contexts_", "ContextManager.ExitContext", std::nullopt); } @@ -103,6 +104,10 @@ public: return contexts_.back().DefineVariable(name, value_id); } + bool DefineGlobalType(const std::string& name, utils::IdType type_id) { + return contexts_.front().DefineLocalType(name, type_id); + } + bool DefineLocalType(const std::string& name, utils::IdType type_id) { return contexts_.back().DefineLocalType(name, type_id); } @@ -113,8 +118,8 @@ public: return true; } - if (contexts_[i].IsHidingPrevious()) { - break; + if (contexts_[i].IsHidingPrevious() && i > 0) { // not for global context + i = 1; // go to global context after --i } } return false; @@ -126,8 +131,8 @@ public: return true; } - if (contexts_[i].IsHidingPrevious()) { - break; + if (contexts_[i].IsHidingPrevious() && i > 0) { // not for global context + i = 1; // go to global context after --i } } return false; @@ -139,8 +144,8 @@ public: return true; } - if (contexts_[i].IsHidingPrevious()) { - break; + if (contexts_[i].IsHidingPrevious() && i > 0) { // not for global context + i = 1; // go to global context after --i } } return false; @@ -161,8 +166,8 @@ public: return maybe_variable.value(); } - if (contexts_[i].IsHidingPrevious()) { - break; + if (contexts_[i].IsHidingPrevious() && i > 0) { // not for global context + i = 1; // go to global context after --i } } return std::nullopt; @@ -175,9 +180,9 @@ public: return maybe_type.value(); } - // if (contexts_[i].IsHidingPrevious()) { // TODO: old types automatically shadowed by new ?? - // break; - // } + if (contexts_[i].IsHidingPrevious() && i > 0) { // not for global context + i = 1; // go to global context after --i + } } return std::nullopt; } diff --git a/include/execute_visitor.hpp b/include/execute_visitor.hpp index e6e00be..690e9b6 100644 --- a/include/execute_visitor.hpp +++ b/include/execute_visitor.hpp @@ -34,7 +34,7 @@ public: for (size_t i = 0; i < info::type::InternalTypesCount; ++i) { info::type::InternalType type = static_cast(i); std::string type_name = info::type::ToString(type); - context_manager_.DefineLocalType(type_name, global_info_.FindAbstractType(type_name).value()->node->type->graph_id_); + context_manager_.DefineGlobalType(type_name, global_info_.FindAbstractType(type_name).value()->node->type->graph_id_); } Visit(partition); } diff --git a/src/execute_visitor.cpp b/src/execute_visitor.cpp index 491bd90..1b0e278 100644 --- a/src/execute_visitor.cpp +++ b/src/execute_visitor.cpp @@ -219,9 +219,7 @@ void ExecuteVisitor::Visit(Match* node) { void ExecuteVisitor::Visit(Condition* node) { bool branch_visited = false; for (size_t i = 0; i < node->conditions.size(); ++i) { - error_handling::DebugPrint("in loop"); if (HandleCondition(node->conditions[i], node->base)) { - error_handling::DebugPrint("in condition"); context_manager_.EnterContext(); Visitor::Visit(node->statements[i]); context_manager_.ExitContext(); @@ -234,11 +232,8 @@ void ExecuteVisitor::Visit(Condition* node) { branch_visited = true; break; } - error_handling::DebugPrint("out of condition"); } - error_handling::DebugPrint("after conditions"); - if (!branch_visited) { if (node->statements.size() > node->conditions.size()) { context_manager_.EnterContext(); @@ -592,7 +587,6 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { auto maybe_parameter_graph_id = context_manager_.FindLocalType(node->parameters[i]->type.type); if (!maybe_parameter_graph_id.has_value()) { - error_handling::DebugPrint(node->parameters[i]->type.type); error_handling::HandleInternalError("Parameter type not found", "ExecuteVisitor.FunctionCallExpression", &node->base); @@ -994,9 +988,7 @@ void ExecuteVisitor::Visit(BoolLiteral* node) { // bool ExecuteVisitor::HandleCondition(Expression& node, const BaseNode& base_node) { - error_handling::DebugPrint("handle condition begin"); Visitor::Visit(node); - error_handling::DebugPrint("handle condition end"); return *ExtractInternalValue(current_value_, base_node); } @@ -1090,17 +1082,17 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, const std::string& name = node->name; if (utils::IsBuiltinFunction(name)) { - std::vector arguments; + std::vector arguments; arguments.reserve(node->arguments.size()); if (node->prefix.has_value() && std::holds_alternative>(node->prefix.value())) { Visitor::Visit(*std::get>(node->prefix.value())); - arguments.push_back(*ExtractValue(current_value_, node->base)); + arguments.push_back(current_value_); } for (auto& argument : node->arguments) { Visitor::Visit(argument.second); - arguments.push_back(*ExtractValue(current_value_, node->base)); + arguments.push_back(current_value_); } switch (type) { @@ -1108,22 +1100,22 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, if (name == "show") { try { current_value_ = context_manager_.AddValue( - info::value::InternalValue(std::to_string(*arguments[0].GetValue().value())), + info::value::InternalValue(std::to_string(*ExtractInternalValue(arguments[0], node->base))), utils::ValueType::Tmp); } catch(...) { error_handling::HandleRuntimeError("Can't read Float", node->base); } } else if (name == "read") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(std::stod(*arguments[0].GetValue().value())), + info::value::InternalValue(std::stod(*ExtractInternalValue(arguments[0], node->base))), utils::ValueType::Tmp); } else if (name == "<") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value() < *arguments[1].GetValue().value()), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base) < *ExtractInternalValue(arguments[1], node->base)), utils::ValueType::Tmp); } else if (name == "==") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value() == *arguments[1].GetValue().value()), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base) == *ExtractInternalValue(arguments[1], node->base)), utils::ValueType::Tmp); } else if (name == "zero") { current_value_ = context_manager_.AddValue( @@ -1134,27 +1126,27 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, info::value::InternalValue(1.0), utils::ValueType::Tmp); } else if (name == "=") { - *arguments[0].GetValue().value() = *arguments[1].GetValue().value(); + *ExtractInternalValue(arguments[0], node->base) = *ExtractInternalValue(arguments[1], node->base); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "+=") { - *arguments[0].GetValue().value() += *arguments[1].GetValue().value(); + *ExtractInternalValue(arguments[0], node->base) += *ExtractInternalValue(arguments[1], node->base); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "-=") { - *arguments[0].GetValue().value() -= *arguments[1].GetValue().value(); + *ExtractInternalValue(arguments[0], node->base) -= *ExtractInternalValue(arguments[1], node->base); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "*=") { - *arguments[0].GetValue().value() *= *arguments[1].GetValue().value(); + *ExtractInternalValue(arguments[0], node->base) *= *ExtractInternalValue(arguments[1], node->base); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "/=") { - *arguments[0].GetValue().value() /= *arguments[1].GetValue().value(); + *ExtractInternalValue(arguments[0], node->base) /= *ExtractInternalValue(arguments[1], node->base); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -1165,35 +1157,31 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, case info::type::InternalType::Int: if (name == "show") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(std::to_string(*arguments[0].GetValue().value())), + info::value::InternalValue(std::to_string(*ExtractInternalValue(arguments[0], node->base))), utils::ValueType::Tmp); } else if (name == "read") { try { current_value_ = context_manager_.AddValue( - info::value::InternalValue(std::stoi(*arguments[0].GetValue().value())), + info::value::InternalValue(std::stoi(*ExtractInternalValue(arguments[0], node->base))), utils::ValueType::Tmp); } catch(...) { error_handling::HandleRuntimeError("Can't read Int", node->base); } } else if (name == "<") { - error_handling::DebugPrint("< Args:"); - error_handling::DebugPrint(*arguments[0].GetValue().value()); - error_handling::DebugPrint(*arguments[1].GetValue().value()); current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value() < *arguments[1].GetValue().value()), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base) < *ExtractInternalValue(arguments[1], node->base)), utils::ValueType::Tmp); - error_handling::DebugPrint(*ExtractInternalValue(current_value_, node->base)); } else if (name == "==") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value() == *arguments[1].GetValue().value()), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base) == *ExtractInternalValue(arguments[1], node->base)), utils::ValueType::Tmp); } else if (name == "div") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value() / *arguments[1].GetValue().value()), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base) / *ExtractInternalValue(arguments[1], node->base)), utils::ValueType::Tmp); } else if (name == "mod") { // TODO: better implementation of mod (read "%" specification) current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value() % *arguments[1].GetValue().value()), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base) % *ExtractInternalValue(arguments[1], node->base)), utils::ValueType::Tmp); } else if (name == "zero") { current_value_ = context_manager_.AddValue( @@ -1204,22 +1192,22 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, info::value::InternalValue(1), utils::ValueType::Tmp); } else if (name == "=") { - *arguments[0].GetValue().value() = *arguments[1].GetValue().value(); + *ExtractInternalValue(arguments[0], node->base) = *ExtractInternalValue(arguments[1], node->base); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "+=") { - *arguments[0].GetValue().value() += *arguments[1].GetValue().value(); + *ExtractInternalValue(arguments[0], node->base) += *ExtractInternalValue(arguments[1], node->base); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "-=") { - *arguments[0].GetValue().value() -= *arguments[1].GetValue().value(); + *ExtractInternalValue(arguments[0], node->base) -= *ExtractInternalValue(arguments[1], node->base); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "*=") { - *arguments[0].GetValue().value() *= *arguments[1].GetValue().value(); + *ExtractInternalValue(arguments[0], node->base) *= *ExtractInternalValue(arguments[1], node->base); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -1230,30 +1218,30 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, case info::type::InternalType::String: if (name == "show") { // do not copy ?? current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value()), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base)), utils::ValueType::Tmp); } else if (name == "read") { // do not copy ?? current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value()), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base)), utils::ValueType::Tmp); } else if (name == "<") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value() < *arguments[1].GetValue().value()), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base) < *ExtractInternalValue(arguments[1], node->base)), utils::ValueType::Tmp); } else if (name == "==") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value() == *arguments[1].GetValue().value()), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base) == *ExtractInternalValue(arguments[1], node->base)), utils::ValueType::Tmp); } else if (name == "size") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(static_cast(arguments[0].GetValue().value()->size())), + info::value::InternalValue(static_cast(ExtractInternalValue(arguments[0], node->base)->size())), utils::ValueType::Tmp); } else if (name == "at") { current_value_ = context_manager_.AddValue( - info::value::InternalValue((*arguments[0].GetValue().value())[*arguments[1].GetValue().value()]), + info::value::InternalValue((*ExtractInternalValue(arguments[0], node->base))[*ExtractInternalValue(arguments[0], node->base)]), utils::ValueType::Tmp); } else if (name == "=") { - *arguments[0].GetValue().value() = *arguments[1].GetValue().value(); + *ExtractInternalValue(arguments[0], node->base) = *ExtractInternalValue(arguments[1], node->base); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -1264,26 +1252,26 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, case info::type::InternalType::Char: if (name == "show") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(std::string{*arguments[0].GetValue().value()}), + info::value::InternalValue(std::string{*ExtractInternalValue(arguments[0], node->base)}), utils::ValueType::Tmp); } else if (name == "read") { - if (arguments[0].GetValue().value()->size() != 1) { + if (ExtractInternalValue(arguments[0], node->base)->size() != 1) { error_handling::HandleRuntimeError("Can't read Char", node->base); } else { current_value_ = context_manager_.AddValue( - info::value::InternalValue((*arguments[0].GetValue().value())[0]), + info::value::InternalValue((*ExtractInternalValue(arguments[0], node->base))[0]), utils::ValueType::Tmp); } } else if (name == "<") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value() < *arguments[1].GetValue().value()), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base) < *ExtractInternalValue(arguments[1], node->base)), utils::ValueType::Tmp); } else if (name == "==") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value() == *arguments[1].GetValue().value()), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base) == *ExtractInternalValue(arguments[1], node->base)), utils::ValueType::Tmp); } else if (name == "=") { - *arguments[0].GetValue().value() = *arguments[1].GetValue().value(); + *ExtractInternalValue(arguments[0], node->base) = *ExtractInternalValue(arguments[1], node->base); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -1294,14 +1282,14 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, case info::type::InternalType::Bool: if (name == "show") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0].GetValue().value() ? "true" : "false"), + info::value::InternalValue(*ExtractInternalValue(arguments[0], node->base) ? "true" : "false"), utils::ValueType::Tmp); } else if (name == "read") { - if (*arguments[0].GetValue().value() == "true") { + if (*ExtractInternalValue(arguments[0], node->base) == "true") { current_value_ = context_manager_.AddValue( info::value::InternalValue(true), utils::ValueType::Tmp); - } else if (*arguments[0].GetValue().value() == "false") { + } else if (*ExtractInternalValue(arguments[0], node->base) == "false") { current_value_ = context_manager_.AddValue( info::value::InternalValue(false), utils::ValueType::Tmp); @@ -1309,7 +1297,7 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, error_handling::HandleRuntimeError("Can't read Bool", node->base); } } else if (name == "=") { - *arguments[0].GetValue().value() = *arguments[1].GetValue().value(); + *ExtractInternalValue(arguments[0], node->base) = *ExtractInternalValue(arguments[1], node->base); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -1323,7 +1311,7 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, info::value::InternalValue("()"), utils::ValueType::Tmp); } else if (name == "read") { - if (*arguments[0].GetValue().value() != "()") { + if (*ExtractInternalValue(arguments[0], node->base) != "()") { error_handling::HandleRuntimeError("Can't read Unit", node->base); } current_value_ = context_manager_.AddValue( diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index e41d337..66faced 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -1387,6 +1387,7 @@ void TypeCheckVisitor::Visit(TypeExpression* node) { std::optional maybe_local_abstract_type = context_manager_.FindLocalType(node->type.type); + if (node->path.empty() && maybe_local_abstract_type.has_value()) { current_type_ = maybe_local_abstract_type.value(); } else if (node->type.type_id_.has_value()) { // TODO: check that names are different (always true ??) @@ -1648,7 +1649,7 @@ std::optional &node->base); } - VisitDefinedType(maybe_type_info.value(), context, utils::ValueType::Tmp, true); + VisitDefinedType(maybe_type_info.value(), context, utils::ValueType::Tmp, false); // TODO: scoped ?? (the paramter types are blocked) maybe_function_declaration = FindDefinedTypeFunctionAndUpdate(node, maybe_type_info.value(), diff --git a/tests/test_code.lang b/tests/test_code.lang index bcb91ca..27d0eb8 100644 --- a/tests/test_code.lang +++ b/tests/test_code.lang @@ -19,17 +19,10 @@ decl error : \string -> \unit // decl not : \bool -> \bool -def not : x = { - ; print-anything:[bool] x - ; print-anything:[bool] - (match x with - | true -> false - | false -> true) - - return (match x with - | true -> false - | false -> true) -} +def not : x = + (match x with + | true -> false + | false -> true) // @@ -195,10 +188,6 @@ decl ( -- ) : \int -> \int -> \int`0 def ( -- ) : begin end = { var current = begin return (while current < end do { - ; print-anything:[string] "iteration:" - ; print-anything:[int] begin - ; print-anything:[int] current - ; print-anything:[int] end ; current += 1 bring current - 1 }) @@ -253,12 +242,12 @@ def print-anything : x = \io..print: (x..show:) // return a-copy // } -// struct \array 'a = & 'a // 'a`0 +struct \array 'a = & 'a`0 -// namespace \array { -// decl of : 'a`0 -> \array['a] -// def of : x = $array['a] & data = x -// } +namespace \array { + decl of : 'a`0 -> \array['a] + def of : x = $array['a] & x +} struct \three-tuple = & \string & \string & \string @@ -273,18 +262,20 @@ exec main { if n <= 0 then error: "n can't be less then 1" - // var x = (for _ in 0--n do scan-int:) // $array[int] & 0 + // var x = (for _ in 0--n do scan-int:) + var x = \array[int]..of: (for _ in 0--n do scan-int:) -// var k? = if n < 2 then n * 2 +. 3 in -// , print-anything:[string] "n < 2" -// , print-anything:[int] k -// -// ; print-anything:[int] n -// -// ; print-int: ::x 123 -// -// var & a & b & c = scan-three-t: -// ; \io..print: b -// var & d & e & f = scan-three: -// ; \io..print: e + + var k? = if n < 2 then n * 2 +. 3 in + , print-anything:[string] "n < 2" + , print-anything:[int] k + + ; print-anything:[int] n + + ; print-int: ::x 123 + + var & a & b & c = scan-three-t: + ; \io..print: b + var & d & e & f = scan-three: + ; \io..print: e }