mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-05 22:48:42 +00:00
builtin functions partial fix
This commit is contained in:
parent
bad48a1da0
commit
e6a03ef9bf
7 changed files with 80 additions and 91 deletions
|
|
@ -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_;
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
BIN
tests/.test_code.lang.kate-swp
Normal file
BIN
tests/.test_code.lang.kate-swp
Normal file
Binary file not shown.
|
|
@ -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"
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue