mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2026-03-12 03:47:08 +00:00
fixes, builtin function fixes, deep copy, string access
This commit is contained in:
parent
3af0772da6
commit
9aaac90ef6
13 changed files with 450 additions and 152 deletions
|
|
@ -392,20 +392,37 @@ void ExecuteVisitor::Visit(ReferenceExpression* node) {
|
|||
value_type);
|
||||
}
|
||||
|
||||
// TODO: extend to other types
|
||||
// TODO: string should be array
|
||||
void ExecuteVisitor::Visit(AccessExpression* node) {
|
||||
// TODO: extend to other types
|
||||
Visit(node->name.get());
|
||||
info::value::ArrayValue* array_value = ExtractValue<info::value::ArrayValue>(current_value_, node->base);
|
||||
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
|
||||
utils::IdType array_value = current_value_;
|
||||
utils::ValueType value_type = context_manager_.GetValueType(array_value);
|
||||
|
||||
Visitor::Visit(node->id);
|
||||
long long index = *ExtractInternalValue<long long>(current_value_, node->base); // TODO: size_t
|
||||
int64_t index = *ExtractInternalValue<int64_t>(current_value_, node->base); // TODO: size_t
|
||||
|
||||
if (index < 0 || index >= (long long)array_value->elements.size()) {
|
||||
error_handling::HandleRuntimeError("Access index out of range", node->base);
|
||||
if (index < 0) {
|
||||
error_handling::HandleRuntimeError("Access index is negative", node->base);
|
||||
}
|
||||
|
||||
current_value_ = context_manager_.ToModifiedValue(array_value->elements[index], value_type); // needed ??
|
||||
if (node->is_string_access_) {
|
||||
std::string* string_value_info = ExtractInternalValue<std::string>(current_value_, node->base);
|
||||
|
||||
if (index >= (int64_t)string_value_info->size()) {
|
||||
error_handling::HandleRuntimeError("Access index is out of range (string)", node->base);
|
||||
}
|
||||
|
||||
current_value_ = context_manager_.ToModifiedValue((*string_value_info)[index], value_type);
|
||||
} else {
|
||||
info::value::ArrayValue* array_value_info = ExtractValue<info::value::ArrayValue>(current_value_, node->base);
|
||||
|
||||
if (index >= (int64_t)array_value_info->elements.size()) {
|
||||
error_handling::HandleRuntimeError("Access index is out of range (array)", node->base);
|
||||
}
|
||||
|
||||
current_value_ = context_manager_.ToModifiedValue(array_value_info->elements[index], value_type);
|
||||
}
|
||||
}
|
||||
|
||||
// Other Expressions
|
||||
|
|
@ -462,6 +479,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
|
|||
|
||||
if (!maybe_function_definition_info.has_value()) {
|
||||
if (HandleBuiltinFunctionCall(node)) {
|
||||
context_manager_.ExitContext();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -485,6 +503,16 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
|
|||
|
||||
if (!maybe_function_definition.has_value()) {
|
||||
if (typeclass_graph_.GetVertex(node->graph_id_.value()).modifier == info::TypeclassGraph::Modifier::Type) {
|
||||
auto maybe_internal_type = info::type::ToInternalType(typeclass_graph_.GetVertex(node->graph_id_.value()).name);
|
||||
|
||||
if (maybe_internal_type.has_value()) {
|
||||
if (HandleBuiltinTypeFunctionCall(node, maybe_internal_type.value())) {
|
||||
context_manager_.ExitContext();
|
||||
return; // TODO: always return from end of function
|
||||
}
|
||||
error_handling::HandleRuntimeError("Type function definition not found (builtin type)", node->base);
|
||||
}
|
||||
|
||||
error_handling::HandleRuntimeError("Type function definition not found (by graph_id_)", node->base);
|
||||
}
|
||||
|
||||
|
|
@ -515,10 +543,6 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
|
|||
}
|
||||
|
||||
if (!maybe_function_definition.has_value()) {
|
||||
if (HandleBuiltinTypeclassFunctionCall(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
error_handling::HandleRuntimeError("Function definition not found (by graph_id_)", node->base);
|
||||
}
|
||||
|
||||
|
|
@ -723,25 +747,9 @@ void ExecuteVisitor::Visit(TupleName* node) { // TODO: check
|
|||
error_handling::HandleRuntimeError("Mismatched field count in tuple variable definition", node->base);
|
||||
}
|
||||
|
||||
if (!is_const_definition_.has_value()) {
|
||||
error_handling::HandleInternalError("No value in is_const_definition_",
|
||||
"TypeCheckVisitor.TupleName",
|
||||
&node->base);
|
||||
}
|
||||
|
||||
utils::ValueType value_type = context_manager_.GetValueType(value);
|
||||
if (value_type == utils::ValueType::Const
|
||||
&& is_const_definition_.value() == utils::IsConstModifier::Var) {
|
||||
error_handling::HandleRuntimeError("TupleName: value type expression not match variable definition modifier", node->base);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||
current_value_ = maybe_tuple_value.value()->fields[i].second;
|
||||
|
||||
if (value_type == utils::ValueType::Tmp) { // TODO: ??
|
||||
current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
Visitor::Visit(node->names[i]);
|
||||
}
|
||||
|
||||
|
|
@ -798,11 +806,13 @@ void ExecuteVisitor::Visit(AnnotatedName* node) { // TODO: check
|
|||
&node->base);
|
||||
}
|
||||
|
||||
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
|
||||
if (value_type == utils::ValueType::Const
|
||||
&& is_const_definition_.value() == utils::IsConstModifier::Var) {
|
||||
error_handling::HandleRuntimeError("AnnotatedName: value type expression not match variable definition modifier", node->base);
|
||||
}
|
||||
// utils::ValueType value_type = context_manager_.GetValueType(current_value_);
|
||||
|
||||
// TODO: only on move
|
||||
// if (value_type == utils::ValueType::Const
|
||||
// && is_const_definition_.value() == utils::IsConstModifier::Var) {
|
||||
// error_handling::HandleRuntimeError("AnnotatedName: value type expression not match variable definition modifier", node->base);
|
||||
// }
|
||||
|
||||
current_value_ = context_manager_.ToModifiedValue(value, utils::IsConstModifierToValueType(is_const_definition_.value()));
|
||||
if (!context_manager_.DefineVariable(node->name, current_value_)) {
|
||||
|
|
@ -963,30 +973,191 @@ void ExecuteVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) {
|
|||
|
||||
bool ExecuteVisitor::HandleBuiltinFunctionCall(FunctionCallExpression* node) {
|
||||
if (node->name == "print") {
|
||||
if (node->arguments.size() < 1) {
|
||||
error_handling::HandleInternalError("Builtin function \"print\" has 0 arguments",
|
||||
"ExecuteVisitor.HandleBuiltinFunctionCall",
|
||||
&node->base);
|
||||
}
|
||||
|
||||
Visitor::Visit(node->arguments[0]);
|
||||
info::builtin::Print(*ExtractInternalValue<std::string>(current_value_, node->base));
|
||||
|
||||
current_value_ = context_manager_.AddValue(info::value::InternalValue(info::value::Unit()),
|
||||
utils::ValueType::Tmp);
|
||||
return true;
|
||||
} else if (node->name == "scan") {
|
||||
current_value_ = context_manager_.AddValue(info::value::InternalValue(info::builtin::Read<std::string>()),
|
||||
utils::ValueType::Tmp);
|
||||
return true;
|
||||
} else if (node->name == "random") { // TODO
|
||||
current_value_ = context_manager_.AddValue(info::value::InternalValue(rand()),
|
||||
utils::ValueType::Tmp);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
|
||||
info::type::InternalType type) {
|
||||
const std::string& name = node->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())) {
|
||||
Visitor::Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()));
|
||||
arguments.push_back(ExtractValue<info::value::InternalValue>(current_value_, node->base));
|
||||
}
|
||||
|
||||
for (auto& argument : node->arguments) {
|
||||
Visitor::Visit(argument);
|
||||
arguments.push_back(ExtractValue<info::value::InternalValue>(current_value_, node->base));
|
||||
}
|
||||
|
||||
error_handling::DebugPrint(info::type::ToString(type));
|
||||
|
||||
switch (type) {
|
||||
case info::type::InternalType::Float:
|
||||
if (name == "show") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(std::to_string(*arguments[0]->GetValue<double>().value())),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "<") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(*arguments[0]->GetValue<double>().value() < *arguments[1]->GetValue<double>().value()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "==") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(*arguments[0]->GetValue<double>().value() == *arguments[1]->GetValue<double>().value()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "zero") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(0.0),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "one") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(1.0),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "+=") {
|
||||
// TODO
|
||||
error_handling::HandleInternalError("+= not implemented yet (float)",
|
||||
"ExecuteVisitor.HandleBuiltinTypeFunctionCall",
|
||||
&node->base);
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(info::value::Unit()),
|
||||
utils::ValueType::Tmp);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case info::type::InternalType::Int:
|
||||
if (name == "show") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(std::to_string(*arguments[0]->GetValue<int64_t>().value())),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "<") {
|
||||
error_handling::DebugPrint("_");/*
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(*arguments[0]->GetValue<int64_t>().value() < *arguments[1]->GetValue<int64_t>().value()),
|
||||
utils::ValueType::Tmp);*/
|
||||
error_handling::DebugPrint("aaaaaaaa");
|
||||
} else if (name == "==") {
|
||||
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 == "div") {
|
||||
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: best 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);
|
||||
} else if (name == "zero") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(0),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "one") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(1),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "+=") {
|
||||
// TODO
|
||||
error_handling::HandleInternalError("+= not implemented yet (int)",
|
||||
"ExecuteVisitor.HandleBuiltinTypeFunctionCall",
|
||||
&node->base);
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(info::value::Unit()),
|
||||
utils::ValueType::Tmp);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case info::type::InternalType::String: // TODO: string is array ??
|
||||
if (name == "show") { // do not copy ??
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(*arguments[0]->GetValue<std::string>().value()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "<") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(*arguments[0]->GetValue<std::string>().value() < *arguments[1]->GetValue<std::string>().value()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "==") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(*arguments[0]->GetValue<std::string>().value() == *arguments[1]->GetValue<std::string>().value()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "size") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(static_cast<int64_t>(arguments[0]->GetValue<std::string>().value()->size())),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "at") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue((*arguments[0]->GetValue<std::string>().value())[*arguments[1]->GetValue<int64_t>().value()]),
|
||||
utils::ValueType::Tmp);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case info::type::InternalType::Char:
|
||||
if (name == "show") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(std::string{*arguments[0]->GetValue<char>().value()}),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "<") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(*arguments[0]->GetValue<char>().value() < *arguments[1]->GetValue<char>().value()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "==") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(*arguments[0]->GetValue<char>().value() == *arguments[1]->GetValue<char>().value()),
|
||||
utils::ValueType::Tmp);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case info::type::InternalType::Bool:
|
||||
if (name == "show") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(*arguments[0]->GetValue<bool>().value() ? "true" : "false"),
|
||||
utils::ValueType::Tmp);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case info::type::InternalType::Unit:
|
||||
if (name == "show") {
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue("()"),
|
||||
utils::ValueType::Tmp);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// error
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ExecuteVisitor::HandleBuiltinTypeclassFunctionCall(FunctionCallExpression*) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace interpreter
|
||||
|
||||
|
|
|
|||
|
|
@ -142,11 +142,10 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) {
|
|||
|
||||
context_manager_.EnterContext();
|
||||
for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed??
|
||||
auto requirements = typeclass_graph_.GetDependenciesSet(parameter->graph_id_);
|
||||
current_type_ = context_manager_.AddValue(
|
||||
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
|
||||
parameter->type,
|
||||
requirements),
|
||||
parameter->graph_id_,
|
||||
typeclass_graph_),
|
||||
utils::ValueType::Tmp);
|
||||
context_manager_.DefineLocalType(parameter->type, current_type_);
|
||||
}
|
||||
|
|
@ -223,11 +222,10 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
|
|||
}
|
||||
|
||||
for (auto& parameter : declaration->parameters) {
|
||||
auto requirements = typeclass_graph_.GetDependenciesSet(parameter->graph_id_);
|
||||
current_type_ = context_manager_.AddValue(info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
|
||||
parameter->type,
|
||||
requirements),
|
||||
utils::ValueType::Tmp);
|
||||
parameter->graph_id_,
|
||||
typeclass_graph_),
|
||||
utils::ValueType::Tmp);
|
||||
if (!context_manager_.DefineLocalType(parameter->type, current_type_)) {
|
||||
error_handling::HandleTypecheckError("Can't define function parameter type: abstract type redefinition", node->base);
|
||||
}
|
||||
|
|
@ -313,8 +311,10 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
|||
|
||||
auto requirements = typeclass_graph_.GetDependenciesSet(node->type->graph_id_);
|
||||
|
||||
current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier, node->type->type, requirements),
|
||||
utils::ValueType::Tmp);
|
||||
current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier,
|
||||
node->type->graph_id_,
|
||||
typeclass_graph_),
|
||||
utils::ValueType::Tmp);
|
||||
|
||||
if (maybe_internal_type.has_value()) {
|
||||
internal_to_abstract_type_[maybe_internal_type.value()] = current_type_;
|
||||
|
|
@ -710,6 +710,8 @@ void TypeCheckVisitor::Visit(ReferenceExpression* node) {
|
|||
context_manager_.GetValueType(current_type_)); // ??
|
||||
}
|
||||
|
||||
// TODO: redifinitions for other types and tuples (with const index) ??
|
||||
// TODO: string should be array
|
||||
void TypeCheckVisitor::Visit(AccessExpression* node) {
|
||||
Visitor::Visit(node->id);
|
||||
if (!context_manager_.EqualValues(internal_to_abstract_type_.at(info::type::InternalType::Int), current_type_)) {
|
||||
|
|
@ -718,15 +720,21 @@ void TypeCheckVisitor::Visit(AccessExpression* node) {
|
|||
|
||||
Visitor::Visit(node->name.get());
|
||||
|
||||
std::optional<info::type::ArrayType*> maybe_type_value = context_manager_.GetValue<info::type::ArrayType>(current_type_);
|
||||
auto maybe_type_value = context_manager_.GetValue<info::type::ArrayType>(current_type_);
|
||||
|
||||
if (!maybe_type_value.has_value()) {
|
||||
error_handling::HandleTypecheckError("Access type is not array", node->base);
|
||||
// TODO: redifinitions for other types and tuples (with const index) ??
|
||||
if (maybe_type_value.has_value()) {
|
||||
current_type_ = maybe_type_value.value()->GetElementsType();
|
||||
} else {
|
||||
auto maybe_internal_type_value = context_manager_.GetValue<info::type::InternalType>(current_type_);
|
||||
|
||||
if (!maybe_internal_type_value.has_value() || *maybe_internal_type_value.value() != info::type::InternalType::String) {
|
||||
error_handling::HandleTypecheckError("Access type is not array", node->base);
|
||||
}
|
||||
|
||||
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Char);
|
||||
node->is_string_access_ = true;
|
||||
}
|
||||
|
||||
current_type_ = maybe_type_value.value()->GetElementsType();
|
||||
|
||||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
||||
|
|
@ -1643,22 +1651,16 @@ std::optional<FunctionDeclaration*>
|
|||
bool is_method) {
|
||||
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
||||
|
||||
auto maybe_typeclass_graph_id = typeclass_graph_.FindFunctionTypeclass(node->name);
|
||||
if (!maybe_typeclass_graph_id.has_value()) {
|
||||
utils::IdType graph_id = abstract_type_info->GetGraphId();
|
||||
|
||||
if (!typeclass_graph_.IsFunctionInVertex(node->name, graph_id)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto maybe_typeclass_function_info = typeclass_graph_.GetFunctionInfo(node->name,
|
||||
maybe_typeclass_graph_id.value());
|
||||
|
||||
if (!abstract_type_info->HasTypeclass(maybe_typeclass_graph_id.value())) {
|
||||
error_handling::HandleTypecheckError("Function typeclass not pesent in type typeclasses list (abstract type)", node->base);
|
||||
}
|
||||
auto maybe_typeclass_function_info = typeclass_graph_.GetFunctionInfo(node->name, graph_id);
|
||||
|
||||
if (!maybe_typeclass_function_info.has_value()) {
|
||||
error_handling::HandleInternalError("Typeclass function info found, but typeclass id not found (abstract type)",
|
||||
"TypeCheckVisitor.FindAbstractTypeTypeclassFunctionAndUpdate",
|
||||
&node->base);
|
||||
error_handling::HandleTypecheckError("Function not present in typeclass (abstract type)", node->base);
|
||||
}
|
||||
|
||||
// TODO: check that const functions not called on var expressions ??
|
||||
|
|
@ -1666,10 +1668,10 @@ std::optional<FunctionDeclaration*>
|
|||
error_handling::HandleTypecheckError("Typeclass function has wrong modifier (abstract type)", node->base);
|
||||
}
|
||||
|
||||
node->graph_id_ = maybe_typeclass_graph_id;
|
||||
node->graph_id_ = graph_id;
|
||||
AddGraphIdLocalAbstractTypes(node->graph_id_.value()); // check
|
||||
|
||||
node->abstract_type_name_ = abstract_type_info->GetName();
|
||||
node->abstract_type_name_ = typeclass_graph_.GetVertex(node->graph_id_.value()).name;
|
||||
maybe_function_declaration = maybe_typeclass_function_info.value()->declaration;
|
||||
|
||||
return maybe_function_declaration;
|
||||
|
|
|
|||
|
|
@ -73,7 +73,11 @@ std::optional<utils::IdType> TypeclassGraph::FindFunctionTypeclass(const std::st
|
|||
std::optional<TypeclassGraph::FunctionInfo*> TypeclassGraph::GetFunctionInfo(const std::string& name,
|
||||
std::optional<utils::IdType> vertex_id) {
|
||||
if (vertex_id.has_value()) {
|
||||
return &verticles_[vertex_id.value()].functions[name];
|
||||
auto function_info_iter = verticles_[vertex_id.value()].functions.find(name);
|
||||
return function_info_iter !=
|
||||
verticles_[vertex_id.value()].functions.end()
|
||||
? std::optional<TypeclassGraph::FunctionInfo*>(&function_info_iter->second)
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
auto maybe_function_typeclass_id = FindFunctionTypeclass(name);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
namespace info::type {
|
||||
|
||||
std::optional<utils::IdType> AbstractType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
|
||||
auto type_iter = context.find(name_);
|
||||
auto type_iter = context.find(typeclass_graph_.GetVertex(graph_id_).name);
|
||||
|
||||
if (type_iter != context.end()) {
|
||||
return type_iter->second;
|
||||
|
|
@ -14,12 +14,15 @@ std::optional<utils::IdType> AbstractType::InContext(const std::unordered_map<st
|
|||
}
|
||||
|
||||
bool AbstractType::Same(const AbstractType& type) const {
|
||||
return name_ == type.name_;
|
||||
return graph_id_ == type.graph_id_;
|
||||
}
|
||||
|
||||
bool AbstractType::operator<(const AbstractType& type) const {
|
||||
for (auto& graph_id : requirement_graph_ids_) {
|
||||
if (type.requirement_graph_ids_.count(graph_id) == 0) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,29 +38,22 @@ bool IsBuiltinFunction(const std::string& name) { // optimize ??
|
|||
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("div");
|
||||
builtin_functions.insert("mod");
|
||||
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");
|
||||
builtin_functions.insert("zero");
|
||||
builtin_functions.insert("one");
|
||||
builtin_functions.insert("show");
|
||||
// builtin_functions.insert("read"); // TODO
|
||||
// builtin_functions.insert("debug_show"); // TODO
|
||||
|
||||
return builtin_functions.count(name) != 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
#include <optional>
|
||||
|
||||
// for clangd
|
||||
#include "../include/values.hpp"
|
||||
#include "../include/error_handling.hpp"
|
||||
|
||||
namespace info::value {
|
||||
|
||||
|
|
@ -12,7 +15,7 @@ bool InternalValue::Same(const InternalValue& other_value) const {
|
|||
case 0:
|
||||
return std::get<double>(value) == std::get<double>(other_value.value);
|
||||
case 1:
|
||||
return std::get<long long>(value) == std::get<long long>(other_value.value);
|
||||
return std::get<int64_t>(value) == std::get<int64_t>(other_value.value);
|
||||
case 2:
|
||||
return std::get<std::string>(value) == std::get<std::string>(other_value.value);
|
||||
case 3:
|
||||
|
|
@ -34,6 +37,10 @@ std::optional<utils::IdType> InternalValue::GetFieldValue(const std::string&) co
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
utils::IdType InternalValue::DeepCopy(ValueManager* value_manager) {
|
||||
return value_manager->ExplicitAddValue(InternalValue(value), utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool TupleValue::Same(const TupleValue& other_value) const {
|
||||
|
|
@ -58,6 +65,18 @@ std::optional<utils::IdType> TupleValue::GetFieldValue(const std::string& name)
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
utils::IdType TupleValue::DeepCopy(ValueManager* value_manager) {
|
||||
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields_copy(fields.size());
|
||||
|
||||
for (size_t i = 0; i < fields.size(); ++i) {
|
||||
fields_copy[i] = {fields[i].first, value_manager_->GetAnyValue(fields[i].second)->DeepCopy(value_manager)};
|
||||
}
|
||||
|
||||
return value_manager->ExplicitAddValue(
|
||||
TupleValue(std::move(fields_copy), value_manager),
|
||||
utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool VariantValue::Same(const VariantValue& other_value) const {
|
||||
|
|
@ -73,6 +92,20 @@ std::optional<utils::IdType> VariantValue::GetFieldValue(const std::string& name
|
|||
return value.GetFieldValue(name);
|
||||
}
|
||||
|
||||
utils::IdType VariantValue::DeepCopy(ValueManager* value_manager) {
|
||||
auto maybe_tuple_deep_copy = value_manager->GetValue<TupleValue>(value.DeepCopy(value_manager));
|
||||
|
||||
if (!maybe_tuple_deep_copy) {
|
||||
error_handling::HandleInternalError("Deep copied TupleType in not TupleType",
|
||||
"VariantValue.DeepCopy",
|
||||
std::nullopt);
|
||||
}
|
||||
|
||||
return value_manager->ExplicitAddValue(
|
||||
VariantValue(TupleValue(*maybe_tuple_deep_copy.value()), current_constructor),
|
||||
utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool ReferenceToValue::Same(const ReferenceToValue& other_value) const {
|
||||
|
|
@ -91,6 +124,13 @@ std::optional<utils::IdType> ReferenceToValue::GetFieldValue(const std::string&
|
|||
return value_manager_->GetAnyValue(value)->GetFieldValue(name);
|
||||
}
|
||||
|
||||
utils::IdType ReferenceToValue::DeepCopy(ValueManager* value_manager) {
|
||||
return value_manager->ExplicitAddValue(
|
||||
ReferenceToValue(references, value_manager_->GetAnyValue(value)->DeepCopy(value_manager), value_manager),
|
||||
utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
bool FunctionValue::Same(const FunctionValue& other_value) const {
|
||||
|
|
@ -116,6 +156,12 @@ std::optional<utils::IdType> FunctionValue::GetFieldValue(const std::string&) co
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
utils::IdType FunctionValue::DeepCopy(ValueManager* value_manager) {
|
||||
return value_manager->ExplicitAddValue(
|
||||
FunctionValue(function, value_manager),
|
||||
utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool ArrayValue::Same(const ArrayValue& other_value) const {
|
||||
|
|
@ -135,6 +181,18 @@ std::optional<utils::IdType> ArrayValue::GetFieldValue(const std::string&) const
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
utils::IdType ArrayValue::DeepCopy(ValueManager* value_manager) {
|
||||
std::vector<utils::IdType> elements_copy(elements.size());
|
||||
|
||||
for (size_t i = 0; i < elements.size(); ++i) {
|
||||
elements_copy[i] = value_manager_->GetAnyValue(elements[i])->DeepCopy(value_manager);
|
||||
}
|
||||
|
||||
return value_manager->ExplicitAddValue(
|
||||
ArrayValue(std::move(elements_copy), is_constant_size, value_manager),
|
||||
utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool OptionalValue::Same(const OptionalValue& other_value) const {
|
||||
|
|
@ -152,6 +210,18 @@ std::optional<utils::IdType> OptionalValue::GetFieldValue(const std::string&) co
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
utils::IdType OptionalValue::DeepCopy(ValueManager* value_manager) {
|
||||
if (!value.has_value()) {
|
||||
return value_manager->ExplicitAddValue(
|
||||
OptionalValue(std::nullopt, value_manager),
|
||||
utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
return value_manager->ExplicitAddValue(
|
||||
OptionalValue(value_manager_->GetAnyValue(value.value())->DeepCopy(value_manager), value_manager),
|
||||
utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool Value::Same(const Value& other_value) const {
|
||||
|
|
@ -209,4 +279,30 @@ std::optional<utils::IdType> Value::GetFieldValue(const std::string& name) const
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
utils::IdType Value::DeepCopy(ValueManager* value_manager) {
|
||||
size_t index = value.index();
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
return std::get<InternalValue>(value).DeepCopy(value_manager);
|
||||
case 1:
|
||||
return std::get<TupleValue>(value).DeepCopy(value_manager);
|
||||
case 2:
|
||||
return std::get<VariantValue>(value).DeepCopy(value_manager);
|
||||
case 3:
|
||||
return std::get<ReferenceToValue>(value).DeepCopy(value_manager);
|
||||
case 4:
|
||||
return std::get<FunctionValue>(value).DeepCopy(value_manager);
|
||||
case 5:
|
||||
return std::get<ArrayValue>(value).DeepCopy(value_manager);
|
||||
case 6:
|
||||
return std::get<OptionalValue>(value).DeepCopy(value_manager);
|
||||
default:
|
||||
// error
|
||||
break;
|
||||
}
|
||||
|
||||
exit(1); // better error handling ??
|
||||
}
|
||||
|
||||
}; // namespace info::value
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue