mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-05 22:48:42 +00:00
part of execute_visitor, fixes
This commit is contained in:
parent
359a65310b
commit
fcff4f9103
7 changed files with 249 additions and 65 deletions
|
|
@ -140,6 +140,7 @@ private:
|
|||
void Visit(BoolLiteral* node) override;
|
||||
|
||||
bool HandleCondition(Expression& condition, const BaseNode& base_node);
|
||||
void CollectTypeContext(const ParametrizedType& type);
|
||||
|
||||
template<typename T>
|
||||
T* ExtractValue(utils::IdType value, const BaseNode& base_node) {
|
||||
|
|
@ -167,6 +168,7 @@ private:
|
|||
utils::IdType current_value_;
|
||||
std::optional<LoopControlExpression> active_loop_control_expression_;
|
||||
std::optional<utils::IdType> return_value_; // TODO: work outside block ??
|
||||
std::optional<utils::IsConstModifier> is_const_definition_;
|
||||
};
|
||||
|
||||
} // namespace interpreter
|
||||
|
|
|
|||
|
|
@ -501,6 +501,7 @@ struct BinaryOperatorExpression {
|
|||
SubExpression right_expression;
|
||||
|
||||
utils::IdType function_id_;
|
||||
bool is_method_ = false;
|
||||
};
|
||||
|
||||
struct UnaryOperatorExpression {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace utils {
|
||||
|
|
@ -10,6 +11,8 @@ using std::size_t;
|
|||
|
||||
using IdType = size_t;
|
||||
|
||||
const std::string ClassInternalVarName = "self";
|
||||
|
||||
enum class ReferenceModifier { Reference = 0, UniqueReference = 1 };
|
||||
enum class IsConstModifier { Const = 0, Var = 1 };
|
||||
enum class ClassModifier { Struct = 0, Class = 1 };
|
||||
|
|
|
|||
|
|
@ -48,11 +48,11 @@ public:
|
|||
struct VariantValue {
|
||||
public:
|
||||
VariantValue() = default;
|
||||
VariantValue(TupleValue value) // TODO: add type & constructor??
|
||||
VariantValue(utils::IdType value) // TupleValue ?? // TODO: add type & constructor??
|
||||
: value(value) {}
|
||||
|
||||
public:
|
||||
TupleValue value;
|
||||
utils::IdType value;
|
||||
};
|
||||
|
||||
struct ReferenceToValue {
|
||||
|
|
|
|||
BIN
src/.type_check_visitor.cpp.kate-swp
Normal file
BIN
src/.type_check_visitor.cpp.kate-swp
Normal file
Binary file not shown.
|
|
@ -35,8 +35,11 @@ void ExecuteVisitor::Visit(ImportStatement* node) {} // no value
|
|||
void ExecuteVisitor::Visit(AliasDefinitionStatement* node) {} // no value
|
||||
|
||||
void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { // visited on function call
|
||||
Visitor::Visit(node->name);
|
||||
Visitor::Visit(node->value);
|
||||
|
||||
is_const_definition_ = node->modifier;
|
||||
Visitor::Visit(node->name); // current_type_ passed from value
|
||||
is_const_definition_ = std::nullopt;
|
||||
}
|
||||
|
||||
void ExecuteVisitor::Visit(FunctionDeclaration* node) {} // no value
|
||||
|
|
@ -57,6 +60,7 @@ void ExecuteVisitor::Visit(PartitionStatement* node) {
|
|||
|
||||
// Flow control -----------------
|
||||
|
||||
// TODO
|
||||
void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) {
|
||||
if (node->name.has_value()) {
|
||||
// Visit(&node->name.value());
|
||||
|
|
@ -73,6 +77,7 @@ void ExecuteVisitor::Visit(TypeConstructorPattern* node) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
void ExecuteVisitor::Visit(MatchCase* node) {
|
||||
Visitor::Visit(node->value);
|
||||
if (node->condition.has_value()) {
|
||||
|
|
@ -83,6 +88,7 @@ void ExecuteVisitor::Visit(MatchCase* node) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
void ExecuteVisitor::Visit(Match* node) {
|
||||
Visitor::Visit(node->value);
|
||||
for (auto& match_case : node->matches) {
|
||||
|
|
@ -156,7 +162,7 @@ void ExecuteVisitor::Visit(WhileLoop* node) {
|
|||
void ExecuteVisitor::Visit(ForLoop* node) {
|
||||
std::vector<utils::IdType> result;
|
||||
|
||||
// TODO: extend on different interval types (not only array)
|
||||
// TODO: extend to different interval types (not only array)
|
||||
Visitor::Visit(node->interval);
|
||||
info::value::ArrayValue* interval = ExtractValue<info::value::ArrayValue>(current_value_, node->base);
|
||||
|
||||
|
|
@ -206,7 +212,6 @@ void ExecuteVisitor::Visit(LoopLoop* node) {
|
|||
// Statements, expressions, blocks, etc. -----------------
|
||||
|
||||
void ExecuteVisitor::Visit(Block* node) {
|
||||
// type_info_context_manager_.EnterContext(); // not needed ??
|
||||
context_manager_.EnterContext();
|
||||
|
||||
for (auto& statement : node->statements) {
|
||||
|
|
@ -217,8 +222,7 @@ void ExecuteVisitor::Visit(Block* node) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
// context_manager_.ExitContext();
|
||||
// type_info_context_manager_.ExitContext(); // not needed ??
|
||||
context_manager_.ExitContext();
|
||||
|
||||
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
|
||||
info::value::InternalValue(info::value::Unit()),
|
||||
|
|
@ -226,7 +230,7 @@ void ExecuteVisitor::Visit(Block* node) {
|
|||
}
|
||||
|
||||
void ExecuteVisitor::Visit(ScopedStatement* node) {
|
||||
Visitor::Visit(node->statement);
|
||||
Visitor::Visit(node->statement); // current_value_ passed from statement
|
||||
}
|
||||
|
||||
void ExecuteVisitor::Visit(LoopControlExpression& node) {
|
||||
|
|
@ -239,18 +243,55 @@ void ExecuteVisitor::Visit(LoopControlExpression& node) {
|
|||
// Operators
|
||||
|
||||
void ExecuteVisitor::Visit(BinaryOperatorExpression* node) {
|
||||
context_manager_.EnterContext();
|
||||
|
||||
auto maybe_function_definition = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_).definition;
|
||||
|
||||
if (maybe_function_definition.has_value()) {
|
||||
Visitor::Visit(node->left_expression);
|
||||
Visitor::Visit(&node->operator_name);
|
||||
Visitor::Visit(node->right_expression);
|
||||
// TODO: custom argument value types, references, etc.
|
||||
current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const);
|
||||
context_manager_.DefineVariable(
|
||||
node->is_method_ ? utils::ClassInternalVarName : maybe_function_definition.value().argument_names[0],
|
||||
current_value_);
|
||||
|
||||
Visitor::Visit(node->left_expression);
|
||||
// TODO: custom argument value types, references, etc.
|
||||
current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const);
|
||||
context_manager_.DefineVariable(maybe_function_definition.value().argument_names[node->is_method_ ? 0 : 1], current_value_);
|
||||
|
||||
Visit(maybe_function_definition.value().node);
|
||||
} else {
|
||||
// TODO: builtin operators, etc. (imports?)
|
||||
error_handling::HandleRuntimeError("Binary operator definition not found", node->base);
|
||||
}
|
||||
|
||||
context_manager_.ExitContext();
|
||||
}
|
||||
|
||||
// TODO: methods??
|
||||
void ExecuteVisitor::Visit(UnaryOperatorExpression* node) {
|
||||
// Visit(&node->operator_name);
|
||||
context_manager_.EnterContext();
|
||||
|
||||
auto maybe_function_definition = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_).definition;
|
||||
|
||||
if (maybe_function_definition.has_value()) {
|
||||
Visitor::Visit(node->expression);
|
||||
// TODO: custom argument value types, references, etc.
|
||||
current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const);
|
||||
context_manager_.DefineVariable(maybe_function_definition.value().argument_names[0], current_value_);
|
||||
|
||||
Visit(maybe_function_definition.value().node);
|
||||
} else {
|
||||
// TODO: builtin operators, etc. (imports?)
|
||||
error_handling::HandleRuntimeError("Unary operator definition not found", node->base);
|
||||
}
|
||||
|
||||
context_manager_.ExitContext();
|
||||
}
|
||||
|
||||
void ExecuteVisitor::Visit(ReferenceExpression* node) {
|
||||
// TODO: check, that therie is no references to "Tmp"
|
||||
// TODO: check, that there is no references to "Tmp"??
|
||||
Visit(node->expression.get());
|
||||
|
||||
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
|
||||
|
|
@ -279,25 +320,51 @@ void ExecuteVisitor::Visit(AccessExpression* node) {
|
|||
// Other Expressions
|
||||
|
||||
void ExecuteVisitor::Visit(FunctionCallExpression* node) {
|
||||
context_manager_.EnterContext();
|
||||
if (node->prefix.has_value()) {
|
||||
if (std::holds_alternative<std::unique_ptr<SubExpressionToken>>(node->prefix.value())) {
|
||||
Visitor::Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()));
|
||||
// modify value on const methods, etc. ??
|
||||
context_manager_.DefineVariable(utils::ClassInternalVarName, current_value_);
|
||||
} else if (std::holds_alternative<std::unique_ptr<TypeExpression>>(node->prefix.value())) {
|
||||
Visit(std::get<std::unique_ptr<TypeExpression>>(node->prefix.value()).get());
|
||||
TypeExpression& prefix = *std::get<std::unique_ptr<TypeExpression>>(node->prefix.value());
|
||||
|
||||
// TODO: abstract types, local abstract types, abstract types, ... as path entities
|
||||
for (auto& path_type : prefix.path) {
|
||||
CollectTypeContext(path_type);
|
||||
}
|
||||
|
||||
CollectTypeContext(prefix.type);
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
}
|
||||
|
||||
// Visit(&node->name);
|
||||
auto function_declaration = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_).declaration.value(); // checked in type_check_visitor
|
||||
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
for (size_t i = 0; i < node->parameters.size(); ++i) {
|
||||
// TODO: local bastract types, absract types, etc.
|
||||
|
||||
context_manager_.DefineLocalType(function_declaration.parameters[i].type, node->parameters[i]->type_id_.value()); // TODO: check
|
||||
}
|
||||
|
||||
for (auto& argument : node->arguments) {
|
||||
Visitor::Visit(argument);
|
||||
auto maybe_function_definition = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_).definition;
|
||||
|
||||
if (maybe_function_definition.has_value()) {
|
||||
for (size_t i = 0; i < node->arguments.size(); ++i) {
|
||||
Visitor::Visit(node->arguments[i]);
|
||||
// TODO: custom argument value types, references, etc.
|
||||
current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const);
|
||||
context_manager_.DefineVariable(maybe_function_definition.value().argument_names[i], current_value_);
|
||||
}
|
||||
|
||||
Visit(maybe_function_definition.value().node);
|
||||
} else {
|
||||
// TODO: builtin functions, etc. (imports?)
|
||||
error_handling::HandleRuntimeError("Function definition not found", node->base);
|
||||
}
|
||||
|
||||
context_manager_.ExitContext();
|
||||
}
|
||||
|
||||
void ExecuteVisitor::Visit(TupleExpression* node) {
|
||||
|
|
@ -313,16 +380,26 @@ void ExecuteVisitor::Visit(TupleExpression* node) {
|
|||
utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
// TODO
|
||||
void ExecuteVisitor::Visit(VariantExpression* node) { // ??
|
||||
void ExecuteVisitor::Visit(VariantExpression* node) {
|
||||
// TODO: decide about return type (variant)
|
||||
for (auto& expression : node->expressions) {
|
||||
Visitor::Visit(expression);
|
||||
info::value::OptionalValue* expression_value = ExtractValue<info::value::OptionalValue>(current_value_, node->base);
|
||||
if (expression_value->value.has_value()) {
|
||||
current_value_ = context_manager_.AddValue<info::value::VariantValue>(
|
||||
info::value::VariantValue(expression_value->value.value()),
|
||||
utils::ValueType::Tmp);
|
||||
|
||||
break;
|
||||
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
||||
info::value::OptionalValue(current_value_),
|
||||
utils::ValueType::Tmp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
||||
info::value::OptionalValue(),
|
||||
utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
void ExecuteVisitor::Visit(ReturnExpression* node) {
|
||||
|
|
@ -330,6 +407,7 @@ void ExecuteVisitor::Visit(ReturnExpression* node) {
|
|||
return_value_ = current_value_;
|
||||
}
|
||||
|
||||
// TODO
|
||||
void ExecuteVisitor::Visit(TypeConstructorParameter* node) {
|
||||
if (node->name.has_value()) {
|
||||
// Visit(&node->name.value());
|
||||
|
|
@ -368,28 +446,105 @@ void ExecuteVisitor::Visit(ArrayExpression* node) {
|
|||
|
||||
// Name
|
||||
|
||||
void ExecuteVisitor::Visit(NameExpression* node) {
|
||||
for (auto& name : node->names) {
|
||||
// Visit(&name);
|
||||
void ExecuteVisitor::Visit(NameExpression* node) { // TODO
|
||||
if (node->names.empty()) {
|
||||
error_handling::HandleInternalError("Names array is empty", "ExecuteVisitor.NameExpression");
|
||||
}
|
||||
|
||||
std::optional<utils::IdType> maybe_variable_value =
|
||||
context_manager_.GetVariableInfo(node->names[0].name);
|
||||
|
||||
if (!maybe_variable_value.has_value()) {
|
||||
error_handling::HandleRuntimeError("Variable not found", node->base);
|
||||
}
|
||||
|
||||
current_value_ = maybe_variable_value.value();
|
||||
|
||||
if (node->names.size() > 1) {
|
||||
utils::ValueType variable_value_type = context_manager_.GetValueType(current_value_);
|
||||
|
||||
for (size_t i = 1; i < node->names.size(); ++i) {
|
||||
std::optional<utils::IdType> maybe_field_value = context_manager_.GetAnyValue(current_value_)->GetFieldValue(node->names[i].name); // TODO
|
||||
if (!maybe_field_value.has_value()) {
|
||||
error_handling::HandleRuntimeError("Variable field not found", node->names[i].base);
|
||||
}
|
||||
|
||||
current_value_ = maybe_field_value.value();
|
||||
}
|
||||
|
||||
current_value_ = context_manager_.ToModifiedValue(current_value_, variable_value_type);
|
||||
}
|
||||
}
|
||||
|
||||
void ExecuteVisitor::Visit(TupleName* node) {
|
||||
for (auto& name : node->names) {
|
||||
Visitor::Visit(name);
|
||||
}
|
||||
void ExecuteVisitor::Visit(TupleName* node) { // TODO: check
|
||||
utils::IdType value = current_value_;
|
||||
|
||||
std::optional<info::value::TupleValue*> maybe_tuple_value = context_manager_.GetValue<info::value::TupleValue>(value);
|
||||
|
||||
if (maybe_tuple_value.has_value()) {
|
||||
error_handling::HandleRuntimeError("Mismatched value types in tuple variable definition", node->base);
|
||||
}
|
||||
|
||||
if (maybe_tuple_value.value()->fields.size() != node->names.size()) {
|
||||
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");
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
current_value_ = value;
|
||||
}
|
||||
|
||||
// TODO
|
||||
void ExecuteVisitor::Visit(VariantName* node) {
|
||||
for (auto& name : node->names) {
|
||||
Visitor::Visit(name);
|
||||
}
|
||||
utils::IdType value = current_value_;
|
||||
|
||||
std::optional<info::value::VariantValue*> maybe_variant_value = context_manager_.GetValue<info::value::VariantValue>(value);
|
||||
|
||||
if (!maybe_variant_value.has_value()) {
|
||||
error_handling::HandleRuntimeError("Mismatched value types in variant variable definition", node->base);
|
||||
}
|
||||
|
||||
void ExecuteVisitor::Visit(AnnotatedName* node) {
|
||||
// Visit(&node->name);
|
||||
if (node->type.has_value()) {
|
||||
Visitor::Visit(node->type.value());
|
||||
// TODO: find out, which constructor used
|
||||
// set value to that constructor and None (empty OptionalValue) to others
|
||||
|
||||
current_value_ = value;
|
||||
}
|
||||
|
||||
void ExecuteVisitor::Visit(AnnotatedName* node) { // TODO: check
|
||||
utils::IdType value = current_value_;
|
||||
|
||||
if (!is_const_definition_.has_value()) {
|
||||
error_handling::HandleInternalError("No value in is_const_definition_",
|
||||
"TypeCheckVisitor.AnnotatedName");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
current_value_ = context_manager_.ToModifiedValue(value, utils::IsConstModifierToValueType(is_const_definition_.value()));
|
||||
if (!context_manager_.DefineVariable(node->name, current_value_)) {
|
||||
error_handling::HandleRuntimeError("Variable name already present in context", node->base);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -460,5 +615,26 @@ bool ExecuteVisitor::HandleCondition(Expression& node, const BaseNode& base_node
|
|||
return *ExtractInternalValue<bool>(current_value_, base_node);
|
||||
}
|
||||
|
||||
// TODO: handle abstract types, handle local abstract types, etc.
|
||||
void ExecuteVisitor::CollectTypeContext(const ParametrizedType& type) {
|
||||
if (!type.type_id_.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(type.type_id_.value());
|
||||
|
||||
if (!maybe_type_info.has_value()) {
|
||||
error_handling::HandleInternalError("CollectTypeContext unimplemented anything except AnyType", "ExecuteVisitor.CollectTYpeContext");
|
||||
}
|
||||
|
||||
info::definition::AnyType& type_info = *maybe_type_info.value(); // check, that has value ??
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace interpreter
|
||||
|
||||
|
|
|
|||
|
|
@ -41,14 +41,14 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
|
|||
info::type::AbstractType(utils::AbstractTypeModifier::Abstract, node->type, requirements),
|
||||
IsConstModifierToValueType(node->modifier.value()));
|
||||
|
||||
context_manager_.EnterVariableContext("self", // TODO: different name ??
|
||||
context_manager_.EnterVariableContext(utils::ClassInternalVarName,
|
||||
abstract_type);
|
||||
context_manager_.DefineLocalType(node->type, abstract_type);
|
||||
} else if (node->link_type_id_.has_value()) {
|
||||
Visitor::Visit(*namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(node->link_type_id_.value()).value()->value); // handle error?
|
||||
|
||||
context_manager_.EnterVariableContext(
|
||||
"self", // TODO: different name
|
||||
utils::ClassInternalVarName, // TODO: different name
|
||||
context_manager_.AddValue(
|
||||
info::type::DefinedType(node->link_type_id_.value(), current_type_, context_manager_.GetValueManager()),
|
||||
IsConstModifierToValueType(node->modifier.value())));
|
||||
|
|
@ -574,11 +574,11 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
|||
auto maybe_operator_id = namespace_visitor_.FindFunction(std::nullopt, node->operator_name);
|
||||
const info::definition::Function* operator_info = nullptr;
|
||||
|
||||
bool is_method = false;
|
||||
node->is_method_ = false;
|
||||
|
||||
if (maybe_operator_id.has_value()) {
|
||||
operator_info = &namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
|
||||
is_method = false;
|
||||
node->is_method_ = false;
|
||||
} else {
|
||||
Visitor::Visit(node->left_expression);
|
||||
auto maybe_left_type = context_manager_.GetValue<info::type::DefinedType>(current_type_);
|
||||
|
|
@ -618,7 +618,7 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
|||
}
|
||||
|
||||
operator_info = &namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
|
||||
is_method = true;
|
||||
node->is_method_ = true;
|
||||
}
|
||||
|
||||
if (!operator_info->declaration.has_value()) {
|
||||
|
|
@ -629,7 +629,7 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
|||
error_handling::HandleTypecheckError("Operator definition not found", node->base);
|
||||
}
|
||||
|
||||
if (operator_info->argument_count != (is_method ? 2 : 3)) { // 2 + return type
|
||||
if (operator_info->argument_count != (node->is_method_ ? 2 : 3)) { // 2 + return type
|
||||
error_handling::HandleTypecheckError("Operator wrong argument count", node->base);
|
||||
}
|
||||
|
||||
|
|
@ -637,10 +637,10 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
|||
error_handling::HandleTypecheckError("Operator with parameters", node->base);
|
||||
}
|
||||
|
||||
if (!is_method) {
|
||||
if (!node->is_method_) {
|
||||
|
||||
Visitor::Visit(*operator_info->declaration.value().argument_types[0]);
|
||||
utils::IdType left_expression_type = current_type_; // TODO: type in context of deduced types
|
||||
utils::IdType left_expression_type = current_type_;
|
||||
|
||||
Visitor::Visit(node->left_expression);
|
||||
if (!context_manager_.AddValueRequirement(current_type_, left_expression_type)) {
|
||||
|
|
@ -649,8 +649,8 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
|||
|
||||
}
|
||||
|
||||
Visitor::Visit(*operator_info->declaration.value().argument_types[is_method ? 0 : 1]);
|
||||
utils::IdType right_expression_type = current_type_; // TODO: type in context of deduced types
|
||||
Visitor::Visit(*operator_info->declaration.value().argument_types[node->is_method_ ? 0 : 1]);
|
||||
utils::IdType right_expression_type = current_type_;
|
||||
|
||||
Visitor::Visit(node->right_expression);
|
||||
if (!context_manager_.AddValueRequirement(current_type_, right_expression_type)) {
|
||||
|
|
@ -692,7 +692,7 @@ void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) {
|
|||
}
|
||||
|
||||
Visitor::Visit(*operator_info.declaration.value().argument_types[0]);
|
||||
utils::IdType expression_type = current_type_; // TODO: type in context of deduced types
|
||||
utils::IdType expression_type = current_type_;
|
||||
|
||||
Visitor::Visit(node->expression);
|
||||
if (!context_manager_.AddValueRequirement(current_type_, expression_type)) {
|
||||
|
|
@ -793,15 +793,19 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
|||
maybe_function_id = maybe_const_function_id;
|
||||
}
|
||||
} else if (std::holds_alternative<std::unique_ptr<TypeExpression>>(node->prefix.value())) {
|
||||
TypeExpression* type_expression = std::get<std::unique_ptr<TypeExpression>>(node->prefix.value()).get();
|
||||
TypeExpression& type_expression = *std::get<std::unique_ptr<TypeExpression>>(node->prefix.value());
|
||||
|
||||
if (type_expression.array_size.has_value()) {
|
||||
error_handling::HandleTypecheckError("Can't call function from array type namespace", node->base);
|
||||
}
|
||||
|
||||
std::vector<std::string> path;
|
||||
path.reserve(type_expression->path.size() + 1);
|
||||
path.reserve(type_expression.path.size() + 1);
|
||||
|
||||
for (auto& path_type : type_expression->path) {
|
||||
for (auto& path_type : type_expression.path) {
|
||||
path.push_back(path_type.type);
|
||||
}
|
||||
path.push_back(type_expression->type.type);
|
||||
path.push_back(type_expression.type.type);
|
||||
|
||||
maybe_function_id = namespace_visitor_.FindFunction(path, node->name.name);
|
||||
|
||||
|
|
@ -814,7 +818,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
|||
}
|
||||
|
||||
if (!maybe_function_id.has_value()) {
|
||||
error_handling::HandleTypecheckError("Can't find function", node->base); // InterlnalError ??
|
||||
error_handling::HandleTypecheckError("Can't find function", node->base); // InternalError ??
|
||||
}
|
||||
|
||||
std::optional<info::definition::FunctionDeclaration> maybe_function_declaration =
|
||||
|
|
@ -1038,10 +1042,7 @@ void TypeCheckVisitor::Visit(NameExpression* node) {
|
|||
|
||||
current_type_ = maybe_variable_type.value();
|
||||
|
||||
if (node->names.size() == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->names.size() > 1) {
|
||||
utils::ValueType variable_value_type = context_manager_.GetValueType(current_type_);
|
||||
|
||||
for (size_t i = 1; i < node->names.size(); ++i) {
|
||||
|
|
@ -1054,6 +1055,7 @@ void TypeCheckVisitor::Visit(NameExpression* node) {
|
|||
}
|
||||
|
||||
current_type_ = context_manager_.ToModifiedValue(current_type_, variable_value_type);
|
||||
}
|
||||
|
||||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
|
@ -1083,7 +1085,7 @@ 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 from variable definition modifier", node->base);
|
||||
error_handling::HandleTypecheckError("TupleName: value type expression not match variable definition modifier", node->base);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||
|
|
@ -1126,7 +1128,7 @@ void TypeCheckVisitor::Visit(VariantName* 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("VariantName: value type of type and value type are diifferent", node->base);
|
||||
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) {
|
||||
|
|
@ -1163,7 +1165,7 @@ void TypeCheckVisitor::Visit(AnnotatedName* 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 from variable definition modifier", node->base);
|
||||
error_handling::HandleTypecheckError("TupleName: value type expression not match variable definition modifier", node->base);
|
||||
}
|
||||
|
||||
type = context_manager_.ToModifiedValue(type, utils::IsConstModifierToValueType(is_const_definition_.value()));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue