diff --git a/include/type_check_visitor.hpp b/include/type_check_visitor.hpp index 5174b45..0ff48be 100644 --- a/include/type_check_visitor.hpp +++ b/include/type_check_visitor.hpp @@ -174,10 +174,6 @@ private: // - bool HandleBuiltinFunctionCall(FunctionCallExpression* node); - - bool HandleBuiltinTypeclassFunctionCall(FunctionCallExpression* node); - private: info::GlobalInfo::NamespaceVisitor namespace_visitor_; info::GlobalInfo& global_info_; diff --git a/include/utils.hpp b/include/utils.hpp index 91c3838..b2c9802 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -54,6 +55,39 @@ inline ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifi exit(1); // unreachable } +inline bool IsBuiltinFunction(const std::string& name) { // optimize ?? + std::unordered_set builtin_functions; + + builtin_functions.insert("="); + builtin_functions.insert("<-"); + builtin_functions.insert("=="); + builtin_functions.insert("!="); + builtin_functions.insert("<"); + builtin_functions.insert(">"); + builtin_functions.insert("<="); + builtin_functions.insert(">="); + builtin_functions.insert("+="); + builtin_functions.insert("-="); + builtin_functions.insert("*="); + builtin_functions.insert("//="); + builtin_functions.insert("%="); + builtin_functions.insert("/="); + builtin_functions.insert("+"); + builtin_functions.insert("-"); + builtin_functions.insert("*"); + builtin_functions.insert("//"); + builtin_functions.insert("%"); + builtin_functions.insert("/"); + builtin_functions.insert("&&"); + builtin_functions.insert("||"); + builtin_functions.insert("size"); + builtin_functions.insert("random"); + builtin_functions.insert("print"); + builtin_functions.insert("scan"); + + return builtin_functions.count(name) != 0; +} + template class Storage { public: diff --git a/src/execute_visitor.cpp b/src/execute_visitor.cpp index 5ce5122..9798afe 100644 --- a/src/execute_visitor.cpp +++ b/src/execute_visitor.cpp @@ -975,7 +975,7 @@ bool ExecuteVisitor::HandleBuiltinFunctionCall(FunctionCallExpression* node) { current_value_ = context_manager_.AddValue(info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); return true; - } else if (node->name == "read") { + } else if (node->name == "scan") { current_value_ = context_manager_.AddValue(info::value::InternalValue(info::builtin::Read()), utils::ValueType::Tmp); return true; diff --git a/src/global_info.cpp b/src/global_info.cpp index 1206937..5b84250 100644 --- a/src/global_info.cpp +++ b/src/global_info.cpp @@ -231,9 +231,9 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type, utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& abstract_type, definition::AbstractType&& abstract_type_info, const interpreter::tokens::BaseNode& base_node) { - if (type::ToInternalType(abstract_type).has_value()) { - error_handling::HandleNamesError("Can't redefine basic type as abstract type", base_node); - } + // if (type::ToInternalType(abstract_type).has_value()) { + // error_handling::HandleNamesError("Can't redefine basic type as abstract type", base_node); + // } if (FindAbstractType(abstract_type).has_value()) { error_handling::HandleNamesError("More then one abstract type with the same name in namespace", base_node); diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 0086ef6..9f37969 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -319,7 +319,7 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier, node->type->type, requirements), utils::ValueType::Tmp); if (!context_manager_.DefineLocalType(node->type->type, current_type_)) { - error_handling::HandleTypecheckError("Can't define basic/bastract type: abstract type redefinition", node->base); + error_handling::HandleTypecheckError("Can't define basic / astract type: abstract type redefinition", node->base); } current_type_ = context_manager_.AddValue(info::type::InternalType::Unit, utils::ValueType::Tmp); @@ -742,7 +742,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { } if (node->name[0] == '_') { - error_handling::HandleTypecheckError("Only builtin functions can start with _. This function not found", node->base); + error_handling::HandleTypecheckError("Only builtin functions can start with _. This function is not found", node->base); } // try to find function declaration @@ -799,40 +799,36 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { context_manager_.AddValueRequirement(current_type_, argument_type); } - if (node->function_id_.has_value()) { - if (!global_info_.GetFunctionInfo(node->function_id_.value()).definition.has_value()) { - if (HandleBuiltinFunctionCall(node)) { - return; // current_type_ - from HandleBuiltinFunctionCall + if (!utils::IsBuiltinFunction(node->name)) { + if (node->function_id_.has_value()) { + if (!global_info_.GetFunctionInfo(node->function_id_.value()).definition.has_value()) { + error_handling::HandleTypecheckError("No function definition found (namespace function)", node->base); } + } else if (node->graph_id_.has_value()) { + if (typeclass_graph_.GetVertex(node->graph_id_.value()).modifier != info::TypeclassGraph::Modifier::Typeclass) { + auto maybe_graph_function_info = typeclass_graph_.GetFunctionInfo(node->name, node->graph_id_.value()); - error_handling::HandleTypecheckError("No function definition found (namespace function)", node->base); - } - } else if (node->graph_id_.has_value()) { - if (typeclass_graph_.GetVertex(node->graph_id_.value()).modifier != info::TypeclassGraph::Modifier::Typeclass) { - auto maybe_graph_function_info = typeclass_graph_.GetFunctionInfo(node->name, node->graph_id_.value()); - - if (!maybe_graph_function_info.has_value()) { - error_handling::HandleInternalError("FunctionInfo by graph_id_ not found", - "TypeCheckVisitor.FunctionCallExpression", - &node->base); - } - - if (!maybe_graph_function_info.value()->definition.has_value()) { - if (HandleBuiltinTypeclassFunctionCall(node)) { - return; // current_type_ - from HandleBuiltinTypeclassFunctionCall + if (!maybe_graph_function_info.has_value()) { + error_handling::HandleInternalError("FunctionInfo by graph_id_ not found", + "TypeCheckVisitor.FunctionCallExpression", + &node->base); } - error_handling::HandleTypecheckError("No function definition found (type function)", node->base); + if (!maybe_graph_function_info.value()->definition.has_value()) { + error_handling::HandleTypecheckError("No function definition found (type function)", node->base); + } } + } else { + error_handling::HandleInternalError("No function_id_ and graph_id_ found", + "TypeCheckVisitor.FunctionCallExpression", + &node->base); } - } else { - error_handling::HandleInternalError("No function_id_ and graph_id_ found", - "TypeCheckVisitor.FunctionCallExpression", - &node->base); } Visitor::Visit(function_declaration->type->types.back()); current_type_ = TypeInContext(current_type_, context); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(TupleExpression* node) { @@ -1681,41 +1677,4 @@ std::optional return maybe_function_declaration; } -// - -bool TypeCheckVisitor::HandleBuiltinFunctionCall(FunctionCallExpression* node) { - if (node->name == "print") { - if (node->prefix.has_value() - || !node->parameters.empty() - || node->arguments.size() != 1) { - error_handling::HandleTypecheckError("Wrong builtin function \"print\" usage", node->base); - } - - Visitor::Visit(node->arguments[0]); - if (!context_manager_.EqualValues( - current_type_, - context_manager_.AddValue(info::type::InternalType::String, utils::ValueType::Tmp))) { - error_handling::HandleTypecheckError("Wrong builtin function \"print\" argument (should be string)", node->base); - } - - current_type_ = context_manager_.AddValue(info::type::InternalType::Unit, utils::ValueType::Tmp); - return true; - } else if (node->name == "read") { - if (node->prefix.has_value() - || !node->parameters.empty() - || node->arguments.size() != 0) { - error_handling::HandleTypecheckError("Wrong builtin function \"read\" usage", node->base); - } - - current_type_ = context_manager_.AddValue(info::type::InternalType::String, utils::ValueType::Tmp); - return true; - } - - return false; -} - -bool TypeCheckVisitor::HandleBuiltinTypeclassFunctionCall(FunctionCallExpression*) { - return false; -} - } // namespace interpreter diff --git a/tests/.test_code.lang.kate-swp b/tests/.test_code.lang.kate-swp new file mode 100644 index 0000000..c343296 Binary files /dev/null and b/tests/.test_code.lang.kate-swp differ diff --git a/tests/test_code.lang b/tests/test_code.lang index 1c9f70d..7f574d3 100644 --- a/tests/test_code.lang +++ b/tests/test_code.lang @@ -1,9 +1,9 @@ -// basic Float -// basic Int -// basic String -// basic Char -// basic Bool -// basic Unit +basic (Float : #Ord) +basic (Int : #Ord) +basic (String : #Ord) +basic (Char : #Ord) +basic (Bool : #Ord) +basic Unit // @@ -76,11 +76,11 @@ namespace var Ord { // -// typeclass Print = -// & var print : -> String -// -// typeclass Read = -// & var read : String -> Read +typeclass Show = + & var show : -> String + +typeclass Read = + & var read : String -> Read typeclass Debug = & debug : -> String @@ -123,16 +123,16 @@ typeclass Enum = // decl ( -- ) : Int -> Int -> Int_0 -// def ( -- ) : begin end = { -// var current = begin -// return (while current < end do { -// ; current += 1 -// return current - 1 -// }) -// } +def ( -- ) : begin end = { + var current = begin + return (while current < end do { + ; current += 1 + return current - 1 + }) +} decl print : String -> Unit -decl read : -> String +decl scan : -> String decl func : String -> Int def func : s = { @@ -143,7 +143,7 @@ def func : s = { exec main { for i in (,0 ,1 ,2 ,3) do func: "abacaba" ; print: ({ - if true then bring read: else { ; print: "aaa" } + if true then bring scan: else { ; print: "aaa" } bring "nothing" ; print: "aaa" })