trying to fix basic types local types

This commit is contained in:
ProgramSnail 2023-05-22 21:00:43 +03:00
parent 25583d3edd
commit 24ff9a30d8
8 changed files with 132 additions and 54 deletions

View file

@ -160,6 +160,16 @@ private:
return maybe_internal_value_info.value();
}
utils::IdType GraphIdByTypeId(utils::IdType type_id) {
auto maybe_any_type = global_info_.GetTypeInfo<info::definition::AnyType>(type_id);
if (!maybe_any_type.has_value()) {
error_handling::HandleInternalError("Only AnyType implemented",
"ExecuteVisitor.ExtractInternalValue",
std::nullopt);
}
return maybe_any_type.value()->node->definition->type->graph_id_;
}
//
bool HandleBuiltinFunctionCall(FunctionCallExpression* node);
@ -170,7 +180,9 @@ private:
info::GlobalInfo& global_info_;
info::TypeclassGraph& typeclass_graph_;
info::ContextManager<info::type::Type, info::type::TypeManager>& type_context_manager_;
info::ContextManager<info::value::Value, info::value::ValueManager>& context_manager_;
// local types store types graph ids
utils::IdType current_value_;
std::optional<LoopControlExpression> active_loop_control_expression_;

View file

@ -32,6 +32,7 @@ public:
std::unordered_map<std::string, FunctionInfo> functions;
std::unordered_set<std::string> dependencies; // TODO: parameters
interpreter::tokens::BaseNode* base_node; // for error handling
std::optional<utils::IdType> type_id; // for defined types
Modifier modifier;
};

Binary file not shown.

View file

@ -490,10 +490,27 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
function_definition = maybe_function_definition_info.value().node;
} else if (node->graph_id_.has_value()) {
error_handling::DebugPrint(typeclass_graph_.GetVertex(node->graph_id_.value()).name);
utils::IdType defined_type_graph_id; // try to find defined or basic type
if (typeclass_graph_.GetVertex(node->graph_id_.value()).type_id.has_value()
|| (node->abstract_type_name_.has_value()
&& info::type::ToInternalType(node->abstract_type_name_.value()).has_value())) {
defined_type_graph_id = node->graph_id_.value();
}
else {
auto maybe_defined_type_graph_id = context_manager_.FindLocalType(node->abstract_type_name_.value());
if (!maybe_defined_type_graph_id.has_value()) {
error_handling::HandleRuntimeError("Function's defined / basic abstract type not found (by abstract_type_name_ and in typeclass graph)", node->base);
}
defined_type_graph_id = maybe_defined_type_graph_id.value();
}
std::optional<FunctionDefinitionStatement*> maybe_function_definition;
auto maybe_function_graph_info = typeclass_graph_.GetFunctionInfo(node->name,
node->graph_id_.value());
node->defined_type_graph_id.value());
if (!maybe_function_graph_info.has_value()) {
error_handling::HandleRuntimeError("Function info not found (by graph_id_)", node->base);
@ -517,17 +534,20 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
error_handling::HandleRuntimeError("Type function definition not found (by graph_id_)", node->base);
}
if (!node->abstract_type_name_.has_value()) {
error_handling::HandleInternalError("Typeclass function's abstract_type_name_ has no value",
// if (!node->abstract_type_name_.has_value()) {
// error_handling::HandleInternalError("Typeclass function's abstract_type_name_ has no value",
// "ExecuteVisitor.FunctionCallExpression",
// &node->base);
// }
auto maybe_type_id = typeclass_graph_.GetVertex(defined_type_graph_id).type_id;
if (!maybe_type_id.has_value()) {
error_handling::HandleInternalError("Function's abstract type type_id not found",
"ExecuteVisitor.FunctionCallExpression",
&node->base);
}
auto maybe_type_id = context_manager_.FindLocalType(node->abstract_type_name_.value());
if (!maybe_type_id.has_value()) {
error_handling::HandleRuntimeError("Function's abstract type not found (by abstract_type_name_)", node->base);
}
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(maybe_type_id.value());
if (!maybe_type_info.has_value()) {
@ -548,36 +568,48 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
}
function_definition = maybe_function_definition.value();
auto dependency_graph_ids = typeclass_graph_.GetDependenciesSet(node->graph_id_.value());
dependency_graph_ids.insert(node->graph_id_.value()); // TODO: ??
for (auto& dependency_graph_id : dependency_graph_ids) {
context_manager_.DefineLocalType(typeclass_graph_.GetVertex(dependency_graph_id).name, defined_type_graph_id);
}
}
// handle choosen type typclasses
// handle parameters
for (size_t i = 0; i < node->parameters.size(); ++i) {
utils::IdType type_id = 0;
utils::IdType graph_id = 0;
if (node->parameters[i]->type_id_.has_value()) {
type_id = node->parameters[i]->type_id_.value();
graph_id = GraphIdByTypeId(node->parameters[i]->type_id_.value());
} else {
auto maybe_parameter_type_id = context_manager_.FindLocalType(node->parameters[i]->type.type);
auto maybe_parameter_graph_id = context_manager_.FindLocalType(node->parameters[i]->type.type);
if (!maybe_parameter_type_id.has_value()) {
if (!maybe_parameter_graph_id.has_value()) {
error_handling::HandleInternalError("Parameter type not found",
"ExecuteVisitor.FunctionCallExpression",
&node->base);
}
type_id = maybe_parameter_type_id.value();
graph_id = maybe_parameter_graph_id.value();
}
if (!context_manager_.DefineLocalType(function_declaration->parameters[i]->type, type_id)) {
if (!context_manager_.DefineLocalType(function_declaration->parameters[i]->type, graph_id)) {
error_handling::HandleRuntimeError("Type redefinition (function argument)", node->base);
}
}
for (size_t i = (node->is_method_of_first_argument_ ? 1 : 0); i < node->arguments.size(); ++i) {
size_t index_shift = (node->is_method_of_first_argument_ ? 1 : 0);
// handle arguments
for (size_t i = index_shift; i < node->arguments.size(); ++i) {
Visitor::Visit(node->arguments[i]);
// function arguments can't be changed inside function
current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const);
if (!context_manager_.DefineVariable(function_definition->definition->arguments[i],
if (!context_manager_.DefineVariable(function_definition->definition->arguments[i - index_shift],
current_value_)) {
error_handling::HandleRuntimeError("Variable redefinition (function argument)", node->base);
}
@ -915,11 +947,8 @@ void ExecuteVisitor::CollectTypeContext(const ParametrizedType& type) {
utils::IdType type_id = 0;
if (!type.type_id_.has_value()) {
auto maybe_local_type_id = context_manager_.FindLocalType(type.type);
if (!maybe_local_type_id.has_value()) {
return;
}
type_id = maybe_local_type_id.value(); // TODO: check
// abstract types have no parameters
return;
} else {
type_id = type.type_id_.has_value();
}
@ -937,7 +966,7 @@ void ExecuteVisitor::CollectTypeContext(const ParametrizedType& type) {
for (size_t i = 0; i < type.parameters.size(); ++i) {
if (type.parameters[i]->type_id_.has_value()) {
context_manager_.DefineLocalType(type_info.parameters[i].type,
type.parameters[i]->type_id_.value());
GraphIdByTypeId(type.parameters[i]->type_id_.value()));
}
}
}
@ -995,13 +1024,11 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
info::type::InternalType type) {
const std::string& name = node->name;
error_handling::DebugPrint(name);
if (utils::IsBuiltinFunction(name)) {
std::vector<info::value::InternalValue*> arguments;
arguments.reserve(node->arguments.size());
if (std::holds_alternative<std::unique_ptr<SubExpressionToken>>(node->prefix.value())) {
if (node->prefix.has_value() && std::holds_alternative<std::unique_ptr<SubExpressionToken>>(node->prefix.value())) {
Visitor::Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()));
arguments.push_back(ExtractValue<info::value::InternalValue>(current_value_, node->base));
}
@ -1011,9 +1038,6 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
arguments.push_back(ExtractValue<info::value::InternalValue>(current_value_, node->base));
}
error_handling::DebugPrint(info::type::ToString(type));
std::cout << std::endl;
switch (type) {
case info::type::InternalType::Float:
if (name == "show") {
@ -1036,6 +1060,11 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
current_value_ = context_manager_.AddValue(
info::value::InternalValue(1.0),
utils::ValueType::Tmp);
} else if (name == "=") {
*arguments[0]->GetValue<double>().value() = *arguments[1]->GetValue<double>().value();
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
} else if (name == "+=") {
*arguments[0]->GetValue<double>().value() += *arguments[1]->GetValue<double>().value();
current_value_ = context_manager_.AddValue(
@ -1077,7 +1106,7 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
current_value_ = context_manager_.AddValue(
info::value::InternalValue(*arguments[0]->GetValue<int64_t>().value() / *arguments[1]->GetValue<int64_t>().value()),
utils::ValueType::Tmp);
} else if (name == "mod") { // TODO: better implementation of mod (read % specification)
} else if (name == "mod") { // TODO: better implementation of mod (read "%" specification)
current_value_ = context_manager_.AddValue(
info::value::InternalValue(*arguments[0]->GetValue<int64_t>().value() % *arguments[1]->GetValue<int64_t>().value()),
utils::ValueType::Tmp);
@ -1089,18 +1118,23 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
current_value_ = context_manager_.AddValue(
info::value::InternalValue(1),
utils::ValueType::Tmp);
} else if (name == "=") {
*arguments[0]->GetValue<int64_t>().value() = *arguments[1]->GetValue<int64_t>().value();
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
} else if (name == "+=") {
*arguments[0]->GetValue<int64_t>().value() += *arguments[1]->GetValue<int64_t>().value();
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
} else if (name == "-=") {
*arguments[0]->GetValue<int64_t>().value() += *arguments[1]->GetValue<int64_t>().value();
*arguments[0]->GetValue<int64_t>().value() -= *arguments[1]->GetValue<int64_t>().value();
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
} else if (name == "*=") {
*arguments[0]->GetValue<int64_t>().value() += *arguments[1]->GetValue<int64_t>().value();
*arguments[0]->GetValue<int64_t>().value() *= *arguments[1]->GetValue<int64_t>().value();
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
@ -1108,7 +1142,7 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
return false;
}
break;
case info::type::InternalType::String: // TODO: string is array ??
case info::type::InternalType::String:
if (name == "show") { // do not copy ??
current_value_ = context_manager_.AddValue(
info::value::InternalValue(*arguments[0]->GetValue<std::string>().value()),
@ -1129,6 +1163,11 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
current_value_ = context_manager_.AddValue(
info::value::InternalValue((*arguments[0]->GetValue<std::string>().value())[*arguments[1]->GetValue<int64_t>().value()]),
utils::ValueType::Tmp);
} else if (name == "=") {
*arguments[0]->GetValue<std::string>().value() = *arguments[1]->GetValue<std::string>().value();
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
} else {
return false;
}
@ -1146,6 +1185,11 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
current_value_ = context_manager_.AddValue(
info::value::InternalValue(*arguments[0]->GetValue<char>().value() == *arguments[1]->GetValue<char>().value()),
utils::ValueType::Tmp);
} else if (name == "=") {
*arguments[0]->GetValue<char>().value() = *arguments[1]->GetValue<char>().value();
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
} else {
return false;
}
@ -1155,6 +1199,11 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
current_value_ = context_manager_.AddValue(
info::value::InternalValue(*arguments[0]->GetValue<bool>().value() ? "true" : "false"),
utils::ValueType::Tmp);
} else if (name == "=") {
*arguments[0]->GetValue<bool>().value() = *arguments[1]->GetValue<bool>().value();
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
} else {
return false;
}
@ -1164,16 +1213,22 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
current_value_ = context_manager_.AddValue(
info::value::InternalValue("()"),
utils::ValueType::Tmp);
} else if (name == "=") {
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
} else {
return false;
}
break;
default:
// error
error_handling::HandleInternalError("Unknown basic type",
"ExecuteVisitor.HandleBuiltinTypeFunctionCall",
&node->base);
break;
}
return false;
return true;
}
return false;

View file

@ -121,6 +121,16 @@ void FindSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
node->type_id_ = namespace_visitor_.AddType(type, std::move(info), node->base);
auto maybe_graph_type_vertex = namespace_visitor_.GetTypeclassGraph()->GetTypeVertex(node->definition->type->graph_id_);
if (!maybe_graph_type_vertex.has_value()) {
error_handling::HandleInternalError("Type vertex in TypeclassGraph is not type vertex",
"FindSymbolsVisitor.FunctionDefinitionStatement",
&node->base);
}
maybe_graph_type_vertex.value()->type_id = node->type_id_;
// definition visited earlier
Visitor::Visit(node->value); // to visit all tree
}

View file

@ -797,16 +797,21 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
context[parameter_name] = current_type_;
}
size_t index_shift = (node->is_method_of_first_argument_ ? 1 : 0);
// check arguments
if (function_declaration->type->types.size() != node->arguments.size() + (node->is_method_of_first_argument_ ? 0 : 1)) {
if (function_declaration->type->types.size() != node->arguments.size() + 1 - index_shift) {
error_handling::HandleTypecheckError("Mismatched argument count in function call expression", node->base);
}
for (size_t i = (node->is_method_of_first_argument_ ? 1 : 0); i < node->arguments.size(); ++i) {
Visitor::Visit(function_declaration->type->types[i]);
for (size_t i = index_shift; i < node->arguments.size(); ++i) {
Visitor::Visit(function_declaration->type->types[i - index_shift]);
utils::IdType argument_type = TypeInContext(current_type_, context);
Visitor::Visit(node->arguments[i]);
context_manager_.AddValueRequirement(current_type_, argument_type);
if (!context_manager_.AddValueRequirement(current_type_, argument_type)) {
error_handling::HandleTypecheckError("Wrong argument type (argument " + std::to_string(i - index_shift + 1) + ")", node->base);
}
}
if (!utils::IsBuiltinFunction(node->name)) {

View file

@ -18,15 +18,7 @@ bool AbstractType::Same(const AbstractType& type) const {
}
bool AbstractType::operator<(const AbstractType& type) const { // TODO: cache DependenciesSet
auto requirement_graph_ids = typeclass_graph_.GetDependenciesSet(graph_id_);
auto other_requirement_graph_ids = type.typeclass_graph_.GetDependenciesSet(type.graph_id_);
for (auto& graph_id : requirement_graph_ids) {
if (other_requirement_graph_ids.count(graph_id) == 0) {
return false;
}
}
return true;
return typeclass_graph_.GetDependenciesSet(graph_id_).count(type.graph_id_) != 0 || graph_id_ == type.graph_id_;
}
bool AbstractType::operator>(const AbstractType& type) const {

View file

@ -1,9 +1,9 @@
basic (Float : #Ord #Div #Show)
basic (Int : #Ord #IDiv #Show)
basic (String : #Ord #Show #CharContainer)
basic (Char : #Ord #Show)
basic (Bool : #Ord #Show)
basic (Unit : #Show)
basic (String : #Ord #Show #CharContainer #Copy)
basic (Char : #Ord #Show #Copy)
basic (Bool : #Ord #Show #Copy)
basic (Unit : #Show #Copy)
//
@ -197,13 +197,16 @@ decl random : -> Int // TODO
//
decl ret_one : -> Int
def ret_one = 1
decl ( -- ) : Int -> Int -> Int_0
def ( -- ) : begin end = {
var current = begin
return (while current < end do {
//; current += 1
; current += 1
bring current
//bring current - 1
bring 1
})
}
@ -215,7 +218,7 @@ def func : s i = {
}
exec main {
for i in 0--9 do func: "abacaba" i
for i in 0--9 do func: "abacaba" (i - 1)
; print: ({
if true then bring scan: else { ; print: "aaa" }
bring "nothing"