type_check_visitor value types maybe fixed

This commit is contained in:
ProgramSnail 2023-05-22 19:14:17 +03:00
parent 6bf64acc4d
commit 43b2993e2a
5 changed files with 76 additions and 65 deletions

View file

@ -50,7 +50,7 @@ public:
}
void ModifiyValue(utils::IdType value_id, utils::ValueType new_value_type) {
GetValueType(value_id) = new_value_type;
value_manager_.SetValueType(value_id, new_value_type);
}
utils::IdType ToModifiedValue(utils::IdType value_id, utils::ValueType new_value_type) {
@ -61,7 +61,7 @@ public:
utils::IdType ToModifiedValueCopy(utils::IdType value_id,
utils::ValueType new_value_type) {
Value* value = GetAnyValue(value_id);
return value->DeepCopy(value_manager_, new_value_type);
return value->DeepCopy(&value_manager_, new_value_type);
}
// make deep copy if not temporary

View file

@ -377,10 +377,14 @@ public:
return &types_.at(type_id).first;
}
utils::ValueType& GetValueType(utils::IdType type_id) {
utils::ValueType GetValueType(utils::IdType type_id) {
return types_.at(type_id).second;
}
void SetValueType(utils::IdType type_id, utils::ValueType value_type) {
types_.at(type_id).second = value_type;
}
bool EqualValues(utils::IdType first_type, utils::IdType second_type) {
return GetAnyValue(first_type)->Same(*GetAnyValue(second_type));
}

View file

@ -223,10 +223,14 @@ public:
return &values_.at(value_id).first;
}
utils::ValueType& GetValueType(utils::IdType value_id) {
utils::ValueType GetValueType(utils::IdType value_id) {
return values_.at(value_id).second;
}
void SetValueType(utils::IdType value_id, utils::ValueType value_type) {
values_.at(value_id).second = value_type;
}
bool EqualValues(utils::IdType first_value, utils::IdType second_value) {
return GetAnyValue(first_value)->Same(*GetAnyValue(second_value));
}

View file

@ -509,7 +509,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
if (maybe_internal_type.has_value()) {
if (HandleBuiltinTypeFunctionCall(node, maybe_internal_type.value())) {
context_manager_.ExitContext();
return; // TODO: always return from end of function
return; // TODO: return from end of function
}
error_handling::HandleRuntimeError("Type function definition not found (builtin type)", node->base);
}
@ -995,6 +995,8 @@ 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());
@ -1009,8 +1011,8 @@ 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;
error_handling::DebugPrint(info::type::ToString(type));
std::cout << std::endl;
switch (type) {
case info::type::InternalType::Float:
@ -1035,10 +1037,22 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
info::value::InternalValue(1.0),
utils::ValueType::Tmp);
} else if (name == "+=") {
// TODO
error_handling::HandleInternalError("+= not implemented yet (float)",
"ExecuteVisitor.HandleBuiltinTypeFunctionCall",
&node->base);
*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(
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(
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(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
@ -1063,7 +1077,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: best 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);
@ -1076,10 +1090,17 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
info::value::InternalValue(1),
utils::ValueType::Tmp);
} else if (name == "+=") {
// TODO
error_handling::HandleInternalError("+= not implemented yet (int)",
"ExecuteVisitor.HandleBuiltinTypeFunctionCall",
&node->base);
*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();
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);

View file

@ -34,11 +34,11 @@ void TypeCheckVisitor::Visit(NamespaceSources* node) {
}
void TypeCheckVisitor::Visit(Namespace* node) {
context_manager_.EnterContext();
if (node->link_typeclass_id_.has_value()) {
utils::IdType graph_id = global_info_.GetTypeclassInfo(node->link_typeclass_id_.value()).graph_id_;
context_manager_.EnterContext();
utils::IdType abstract_type = AddGraphIdLocalAbstractTypes(graph_id);
abstract_type = context_manager_.ToModifiedValue(abstract_type,
ClassInternalsModifierToValueType(node->modifier));
@ -67,11 +67,10 @@ void TypeCheckVisitor::Visit(Namespace* node) {
ClassInternalsModifierToValueType(node->modifier));
if (node->modifier != utils::ClassInternalsModifier::Static) {
context_manager_.EnterVariableContext(utils::ClassInternalVarName, type);
} else {
context_manager_.EnterContext();
context_manager_.DefineVariable(utils::ClassInternalVarName, type);
}
type = context_manager_.ToModifiedValue(type, utils::ValueType::Tmp);
AddGraphIdLocalTypes(type_info->type.node->graph_id_, type);
if (type_namespaces_.count(node->link_type_id_.value()) != 0) {
@ -106,16 +105,12 @@ void TypeCheckVisitor::Visit(AliasDefinitionStatement* node) {
&node->base);
}
// TODO: move, etc.
void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) {
// TODO: remove variable on move
is_in_statement_ = true;
Visitor::Visit(node->value);
// current_type from value automatically passed to name definitions
if (node->assignment_modifier == utils::AssignmentModifier::Assign) {
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp);
// TODO: make type tmp recursively ??
}
is_const_definition_ = node->modifier;
Visitor::Visit(node->name);
@ -127,7 +122,7 @@ void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) {
node->base.type_ = current_type_;
}
void TypeCheckVisitor::Visit(FunctionDeclaration* node) {
void TypeCheckVisitor::Visit(FunctionDeclaration* node) { // function declaration check needed ??
bool was_in_statement = is_in_statement_;
is_in_statement_ = true;
@ -141,7 +136,7 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) {
}
context_manager_.EnterContext();
for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed??
for (auto& parameter : node->parameters) {
current_type_ = context_manager_.AddValue(
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
parameter->graph_id_,
@ -212,7 +207,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
&node->base);
}
declaration = maybe_function_info.value()->declaration; // TODO: save declaration to global info ??
declaration = maybe_function_info.value()->declaration;
}
context_manager_.EnterContext();
@ -233,7 +228,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
for (size_t i = 0; i < node->definition->arguments.size(); ++i) {
Visitor::Visit(declaration->type->types[i]);
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Const); // TODO: Var??
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Const);
if (!context_manager_.DefineVariable(node->definition->arguments[i], current_type_)) {
error_handling::HandleTypecheckError("Can't define function argument variable: name redefinition", node->base);
}
@ -277,7 +272,7 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) {
std::string& type_name = node->definition->type->type;
for (auto& function : required_functions) {
if (function.second.definition.has_value()) { // TODO: check
if (function.second.definition.has_value()) {
continue;
}
@ -326,9 +321,11 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
is_in_statement_ = false;
// --- can't work always, because "visit" can be called for internal types
// current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit);
// node->base.type_ = current_type_;
// otherwise function called from VisitSourceFile
if (!maybe_internal_type.has_value()) {
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit);
node->base.type_ = current_type_;
}
}
void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) {
@ -376,8 +373,7 @@ void TypeCheckVisitor::Visit(AnyAnnotatedType* node) {
void TypeCheckVisitor::Visit(TypeConstructorPatternParameter*) {} // Handled in TypeConstructorPattern
// TODO
// TODO: check for tuples
// TODO: check ??
void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match named constructor
if (!node->constructor->constructor_id_.has_value()) {
error_handling::HandleTypecheckError("Type constructor pattern constructor name not found", node->base);
@ -450,7 +446,7 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name
void TypeCheckVisitor::Visit(MatchCase* node) {
// value type passed as current_type_
is_const_definition_ = utils::IsConstModifier::Const; // TODO: or var??
is_const_definition_ = utils::IsConstModifier::Const;
Visitor::Visit(node->value);
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp);
@ -473,7 +469,8 @@ void TypeCheckVisitor::Visit(MatchCase* node) {
node->base.type_ = current_type_;
}
void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match
// TODO: move, etc.
void TypeCheckVisitor::Visit(Match* node) {
// TODO: types can be different in block statement
context_manager_.EnterContext();
@ -484,9 +481,8 @@ void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match
Visitor::Visit(node->value);
utils::IdType value_type = current_type_;
// TODO: several matches with one statement typecheck <- check proposed solution
std::optional<Expression*> nearest_statement;
for (ssize_t i = (ssize_t)node->matches.size() - 1; i >= 0; --i) { // TODO: internal contexts ??
for (ssize_t i = (ssize_t)node->matches.size() - 1; i >= 0; --i) {
ResetReturnedAndBroughtTypes();
current_type_ = value_type;
@ -570,7 +566,7 @@ void TypeCheckVisitor::Visit(Condition* node) {
} else {
current_type_ = context_manager_.AddValue(
info::type::OptionalType(type, context_manager_.GetValueManager()),
utils::ValueType::Tmp); // ??
context_manager_.GetValueType(type)); // optional with "reference" to result type
}
context_manager_.ExitContext();
@ -616,6 +612,7 @@ void TypeCheckVisitor::Visit(WhileLoop* node) {
node->base.type_ = current_type_;
}
// TODO: variable with reference to interval element + check
void TypeCheckVisitor::Visit(ForLoop* node) {
context_manager_.EnterContext();
@ -707,7 +704,7 @@ void TypeCheckVisitor::Visit(ReferenceExpression* node) {
info::type::ReferenceToType({node->reference},
current_type_,
context_manager_.GetValueManager()),
context_manager_.GetValueType(current_type_)); // ??
context_manager_.GetValueType(current_type_));
}
// TODO: redifinitions for other types and tuples (with const index) ??
@ -723,7 +720,7 @@ void TypeCheckVisitor::Visit(AccessExpression* node) {
auto maybe_type_value = context_manager_.GetValue<info::type::ArrayType>(current_type_);
if (maybe_type_value.has_value()) {
current_type_ = maybe_type_value.value()->GetElementsType();
current_type_ = maybe_type_value.value()->GetElementsType(); // "reference" to element
} else {
auto maybe_internal_type_value = context_manager_.GetValue<info::type::InternalType>(current_type_);
@ -740,7 +737,6 @@ void TypeCheckVisitor::Visit(AccessExpression* node) {
// Other Expressions
// TODO: more builtin functions, better handling (??)
void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
context_manager_.EnterContext();
@ -842,7 +838,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
Visitor::Visit(function_declaration->type->types.back());
current_type_ = TypeInContext(current_type_, context);
node->base.type_ = current_type_;
node->base.type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp);
}
void TypeCheckVisitor::Visit(TupleExpression* node) {
@ -916,6 +912,7 @@ void TypeCheckVisitor::Visit(ReturnExpression* node) {
void TypeCheckVisitor::Visit(TypeConstructorParameter*) {} // Handeled in TypeConstructor visit
// TODO: check for tuples
// TODO: move, etc.
void TypeCheckVisitor::Visit(TypeConstructor* node) {
if (!node->constructor->constructor_id_.has_value()) {
error_handling::HandleTypecheckError("Type constructor name not found", node->base);
@ -929,7 +926,6 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
utils::IdType constructor_id = node->constructor->constructor_id_.value();
// TODO: take type_id_ ??
info::definition::Constructor constructor_info = global_info_.GetConstructorInfo(constructor_id);
utils::IdType type_id = constructor_info.type_id;
@ -940,7 +936,7 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
std::optional<info::definition::AnyType*> maybe_type_info =
global_info_.GetTypeInfo<info::definition::AnyType>(type_id);
if (!maybe_type_info.has_value()) { // TODO
if (!maybe_type_info.has_value()) {
error_handling::HandleInternalError("Implemented only for AnyType",
"TypeCheckVisitor.TypeConstructor",
&node->base);
@ -957,7 +953,6 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
}
for (size_t i = 0; i < node->parameters.size(); ++i) {
// TODO: remove variable on move
if (node->parameters[i].name.has_value()) {
if (!constructor_fields->entities[i].first.has_value()
|| constructor_fields->entities[i].first.value() != node->parameters[i].name.value()) {
@ -1088,6 +1083,7 @@ void TypeCheckVisitor::Visit(NameExpression* node) {
node->base.type_ = current_type_;
}
// TODO: move, etc.
void TypeCheckVisitor::Visit(TupleName* node) {
utils::IdType type = current_type_;
@ -1113,15 +1109,11 @@ void TypeCheckVisitor::Visit(TupleName* node) {
}
utils::ValueType value_type = context_manager_.GetValueType(type);
if (value_type == utils::ValueType::Const
&& is_const_definition_.value() == utils::IsConstModifier::Var) {
error_handling::HandleTypecheckError("TupleName: value type expression not match variable definition modifier", node->base);
}
for (size_t i = 0; i < node->names.size(); ++i) {
current_type_ = type_value->GetFields()[i].second;
if (value_type == utils::ValueType::Tmp) { // TODO: ??
if (value_type == utils::ValueType::Tmp) { // TODO: instead of recusive modification ??
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp);
}
@ -1133,6 +1125,7 @@ void TypeCheckVisitor::Visit(TupleName* node) {
node->base.type_ = current_type_;
}
// TODO: move, etc.
void TypeCheckVisitor::Visit(VariantName* node) {
utils::IdType type = current_type_;
@ -1157,12 +1150,6 @@ void TypeCheckVisitor::Visit(VariantName* node) {
&node->base);
}
utils::ValueType value_type = context_manager_.GetValueType(type);
if (value_type == utils::ValueType::Const
&& is_const_definition_.value() == utils::IsConstModifier::Var) {
error_handling::HandleTypecheckError("VariantName: value type of type and value type are different", node->base);
}
for (size_t i = 0; i < node->names.size(); ++i) {
if (type_value->GetConstructors()[i].GetFields().empty()) {
current_type_ = context_manager_.AddValue(
@ -1189,6 +1176,7 @@ void TypeCheckVisitor::Visit(VariantName* node) {
node->base.type_ = current_type_;
}
// TODO: move, etc.
void TypeCheckVisitor::Visit(AnnotatedName* node) {
utils::IdType type = current_type_;
@ -1198,12 +1186,6 @@ void TypeCheckVisitor::Visit(AnnotatedName* node) {
&node->base);
}
utils::ValueType value_type = context_manager_.GetValueType(type);
if (value_type == utils::ValueType::Const
&& is_const_definition_.value() == utils::IsConstModifier::Var) {
error_handling::HandleTypecheckError("AnnotatedName: value type expression not match variable definition modifier", node->base);
}
type = context_manager_.ToModifiedValue(type, utils::IsConstModifierToValueType(is_const_definition_.value()));
if (!context_manager_.DefineVariable(node->name, type)) {
error_handling::HandleTypecheckError("Variable name already present in context", node->base);