builtin functions partial fix

This commit is contained in:
ProgramSnail 2023-05-21 14:58:18 +03:00
parent bad48a1da0
commit e6a03ef9bf
7 changed files with 80 additions and 91 deletions

View file

@ -174,10 +174,6 @@ private:
// //
bool HandleBuiltinFunctionCall(FunctionCallExpression* node);
bool HandleBuiltinTypeclassFunctionCall(FunctionCallExpression* node);
private: private:
info::GlobalInfo::NamespaceVisitor namespace_visitor_; info::GlobalInfo::NamespaceVisitor namespace_visitor_;
info::GlobalInfo& global_info_; info::GlobalInfo& global_info_;

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <cstdlib> #include <cstdlib>
#include <unordered_set>
#include <vector> #include <vector>
#include <string> #include <string>
#include <memory> #include <memory>
@ -54,6 +55,39 @@ inline ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifi
exit(1); // unreachable exit(1); // unreachable
} }
inline bool IsBuiltinFunction(const std::string& name) { // optimize ??
std::unordered_set<std::string> 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<typename T> template<typename T>
class Storage { class Storage {
public: public:

View file

@ -975,7 +975,7 @@ bool ExecuteVisitor::HandleBuiltinFunctionCall(FunctionCallExpression* node) {
current_value_ = context_manager_.AddValue(info::value::InternalValue(info::value::Unit()), current_value_ = context_manager_.AddValue(info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp); utils::ValueType::Tmp);
return true; return true;
} else if (node->name == "read") { } else if (node->name == "scan") {
current_value_ = context_manager_.AddValue(info::value::InternalValue(info::builtin::Read<std::string>()), current_value_ = context_manager_.AddValue(info::value::InternalValue(info::builtin::Read<std::string>()),
utils::ValueType::Tmp); utils::ValueType::Tmp);
return true; return true;

View file

@ -231,9 +231,9 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type,
utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& abstract_type, utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& abstract_type,
definition::AbstractType&& abstract_type_info, definition::AbstractType&& abstract_type_info,
const interpreter::tokens::BaseNode& base_node) { const interpreter::tokens::BaseNode& base_node) {
if (type::ToInternalType(abstract_type).has_value()) { // if (type::ToInternalType(abstract_type).has_value()) {
error_handling::HandleNamesError("Can't redefine basic type as abstract type", base_node); // error_handling::HandleNamesError("Can't redefine basic type as abstract type", base_node);
} // }
if (FindAbstractType(abstract_type).has_value()) { if (FindAbstractType(abstract_type).has_value()) {
error_handling::HandleNamesError("More then one abstract type with the same name in namespace", base_node); error_handling::HandleNamesError("More then one abstract type with the same name in namespace", base_node);

View file

@ -319,7 +319,7 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier, node->type->type, requirements), current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier, node->type->type, requirements),
utils::ValueType::Tmp); utils::ValueType::Tmp);
if (!context_manager_.DefineLocalType(node->type->type, current_type_)) { 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); 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] == '_') { 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 // try to find function declaration
@ -799,40 +799,36 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
context_manager_.AddValueRequirement(current_type_, argument_type); context_manager_.AddValueRequirement(current_type_, argument_type);
} }
if (node->function_id_.has_value()) { if (!utils::IsBuiltinFunction(node->name)) {
if (!global_info_.GetFunctionInfo(node->function_id_.value()).definition.has_value()) { if (node->function_id_.has_value()) {
if (HandleBuiltinFunctionCall(node)) { if (!global_info_.GetFunctionInfo(node->function_id_.value()).definition.has_value()) {
return; // current_type_ - from HandleBuiltinFunctionCall 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); if (!maybe_graph_function_info.has_value()) {
} error_handling::HandleInternalError("FunctionInfo by graph_id_ not found",
} else if (node->graph_id_.has_value()) { "TypeCheckVisitor.FunctionCallExpression",
if (typeclass_graph_.GetVertex(node->graph_id_.value()).modifier != info::TypeclassGraph::Modifier::Typeclass) { &node->base);
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
} }
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()); Visitor::Visit(function_declaration->type->types.back());
current_type_ = TypeInContext(current_type_, context); current_type_ = TypeInContext(current_type_, context);
node->base.type_ = current_type_;
} }
void TypeCheckVisitor::Visit(TupleExpression* node) { void TypeCheckVisitor::Visit(TupleExpression* node) {
@ -1681,41 +1677,4 @@ std::optional<FunctionDeclaration*>
return maybe_function_declaration; 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 } // namespace interpreter

Binary file not shown.

View file

@ -1,9 +1,9 @@
// basic Float basic (Float : #Ord)
// basic Int basic (Int : #Ord)
// basic String basic (String : #Ord)
// basic Char basic (Char : #Ord)
// basic Bool basic (Bool : #Ord)
// basic Unit basic Unit
// //
@ -76,11 +76,11 @@ namespace var Ord {
// //
// typeclass Print = typeclass Show =
// & var print : -> String & var show : -> String
//
// typeclass Read = typeclass Read =
// & var read : String -> Read & var read : String -> Read
typeclass Debug = typeclass Debug =
& debug : -> String & debug : -> String
@ -123,16 +123,16 @@ typeclass Enum =
// //
decl ( -- ) : Int -> Int -> Int_0 decl ( -- ) : Int -> Int -> Int_0
// def ( -- ) : begin end = { def ( -- ) : begin end = {
// var current = begin var current = begin
// return (while current < end do { return (while current < end do {
// ; current += 1 ; current += 1
// return current - 1 return current - 1
// }) })
// } }
decl print : String -> Unit decl print : String -> Unit
decl read : -> String decl scan : -> String
decl func : String -> Int decl func : String -> Int
def func : s = { def func : s = {
@ -143,7 +143,7 @@ def func : s = {
exec main { exec main {
for i in (,0 ,1 ,2 ,3) do func: "abacaba" for i in (,0 ,1 ,2 ,3) do func: "abacaba"
; print: ({ ; print: ({
if true then bring read: else { ; print: "aaa" } if true then bring scan: else { ; print: "aaa" }
bring "nothing" bring "nothing"
; print: "aaa" ; print: "aaa"
}) })