mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-09 16:38:45 +00:00
part of execute_visitor, minor fixes, function & operator fixes
This commit is contained in:
parent
d31979166e
commit
78de51f6f2
6 changed files with 345 additions and 247 deletions
|
|
@ -42,6 +42,14 @@ inline void HandleTypecheckError(const std::string& message,
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void HandleRuntimeError(const std::string& message,
|
||||||
|
const interpreter::tokens::BaseNode& node) { // TODO: place in code
|
||||||
|
std::cout << "Runtime Error: " << message << " at ";
|
||||||
|
PrintPosition(std::cout, node.start_position, node.end_position);
|
||||||
|
std::cout << ".\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
} // namespace error_handling
|
} // namespace error_handling
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
#include "global_info.hpp"
|
#include "global_info.hpp"
|
||||||
#include "interpreter_tree.hpp"
|
#include "interpreter_tree.hpp"
|
||||||
#include "type_info_contexts.hpp"
|
#include "type_info_contexts.hpp"
|
||||||
|
#include "utils.hpp"
|
||||||
|
#include "values.hpp"
|
||||||
#include "visitor.hpp"
|
#include "visitor.hpp"
|
||||||
#include "error_handling.hpp"
|
#include "error_handling.hpp"
|
||||||
|
|
||||||
|
|
@ -54,9 +56,9 @@ private:
|
||||||
|
|
||||||
// Definition parts
|
// Definition parts
|
||||||
|
|
||||||
void Visit(FunctionDefinition* node) override;
|
// // void Visit(FunctionDefinition* node) override;
|
||||||
void Visit(TypeDefinition* node) override;
|
// // void Visit(TypeDefinition* node) override;
|
||||||
void Visit(AnyAnnotatedType* node) override;
|
// // void Visit(AnyAnnotatedType* node) override;
|
||||||
|
|
||||||
// Flow control -----------------
|
// Flow control -----------------
|
||||||
|
|
||||||
|
|
@ -99,7 +101,7 @@ private:
|
||||||
|
|
||||||
// Name
|
// Name
|
||||||
|
|
||||||
void Visit(PartitionName* node) override;
|
// // void Visit(PartitionName* node) override;
|
||||||
void Visit(NameExpression* node) override;
|
void Visit(NameExpression* node) override;
|
||||||
void Visit(TupleName* node) override;
|
void Visit(TupleName* node) override;
|
||||||
void Visit(VariantName* node) override;
|
void Visit(VariantName* node) override;
|
||||||
|
|
@ -126,9 +128,9 @@ private:
|
||||||
|
|
||||||
// Identifiers, constants, etc. -----------------
|
// Identifiers, constants, etc. -----------------
|
||||||
|
|
||||||
void Visit(ExtendedName* node) override;
|
// // void Visit(ExtendedName* node) override;
|
||||||
|
|
||||||
void Visit(std::string* node) override; // std::string
|
// // void Visit(std::string* node) override; // std::string
|
||||||
|
|
||||||
void Visit(FloatNumberLiteral* node) override;
|
void Visit(FloatNumberLiteral* node) override;
|
||||||
void Visit(NumberLiteral* node) override;
|
void Visit(NumberLiteral* node) override;
|
||||||
|
|
@ -137,10 +139,34 @@ private:
|
||||||
void Visit(UnitLiteral* node) override;
|
void Visit(UnitLiteral* node) override;
|
||||||
void Visit(BoolLiteral* node) override;
|
void Visit(BoolLiteral* node) override;
|
||||||
|
|
||||||
|
bool HandleCondition(Expression& condition, const BaseNode& base_node);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* ExtractValue(utils::IdType value, const BaseNode& base_node) {
|
||||||
|
std::optional<T*> maybe_value_info = context_manager_.GetValue<T>(value);
|
||||||
|
if (!maybe_value_info.has_value()) {
|
||||||
|
error_handling::HandleRuntimeError("Value has value class that is different from exprected one", base_node);
|
||||||
|
}
|
||||||
|
return maybe_value_info.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* ExtractInternalValue(utils::IdType value, const BaseNode& base_node) {
|
||||||
|
info::value::InternalValue* value_info = ExtractValue<info::value::InternalValue>(value, base_node);
|
||||||
|
std::optional<T*> maybe_internal_value_info = value_info->GetValue<T>();
|
||||||
|
if (!maybe_internal_value_info.has_value()) {
|
||||||
|
error_handling::HandleRuntimeError("Value has internal value class that is different from exprected one", base_node);
|
||||||
|
}
|
||||||
|
return maybe_internal_value_info.value();
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
info::GlobalInfo::NamespaceVisitor namespace_visitor_;
|
info::GlobalInfo::NamespaceVisitor namespace_visitor_;
|
||||||
info::TypeInfoContextManager& type_info_context_manager_;
|
info::TypeInfoContextManager& type_info_context_manager_;
|
||||||
info::ContextManager& context_manager_;
|
info::ContextManager& context_manager_;
|
||||||
|
|
||||||
|
utils::IdType current_value_;
|
||||||
|
std::optional<LoopControlExpression> active_loop_control_expression_;
|
||||||
|
std::optional<utils::IdType> return_value_; // TODO: work outside block ??
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace interpreter
|
} // namespace interpreter
|
||||||
|
|
|
||||||
|
|
@ -499,6 +499,8 @@ struct BinaryOperatorExpression {
|
||||||
OperatorIdentifier operator_name;
|
OperatorIdentifier operator_name;
|
||||||
SubExpression left_expression;
|
SubExpression left_expression;
|
||||||
SubExpression right_expression;
|
SubExpression right_expression;
|
||||||
|
|
||||||
|
utils::IdType function_id_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UnaryOperatorExpression {
|
struct UnaryOperatorExpression {
|
||||||
|
|
@ -506,6 +508,8 @@ struct UnaryOperatorExpression {
|
||||||
|
|
||||||
OperatorIdentifier operator_name;
|
OperatorIdentifier operator_name;
|
||||||
Expression expression;
|
Expression expression;
|
||||||
|
|
||||||
|
utils::IdType function_id_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReferenceExpression {
|
struct ReferenceExpression {
|
||||||
|
|
@ -532,6 +536,8 @@ struct FunctionCallExpression {
|
||||||
ExtendedName name;
|
ExtendedName name;
|
||||||
std::vector<std::unique_ptr<TypeExpression>> parameters;
|
std::vector<std::unique_ptr<TypeExpression>> parameters;
|
||||||
std::vector<SubExpressionToken> arguments;
|
std::vector<SubExpressionToken> arguments;
|
||||||
|
|
||||||
|
utils::IdType function_id_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TupleExpression {
|
struct TupleExpression {
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,20 @@ struct Unit {};
|
||||||
struct InternalValue {
|
struct InternalValue {
|
||||||
public:
|
public:
|
||||||
InternalValue() = default;
|
InternalValue() = default;
|
||||||
InternalValue(std::variant<double,
|
explicit InternalValue(std::variant<double,
|
||||||
long long,
|
long long,
|
||||||
std::string,
|
std::string,
|
||||||
char,
|
char,
|
||||||
bool,
|
bool,
|
||||||
Unit>&& value) : value(std::move(value)) {}
|
Unit>&& value) : value(std::move(value)) {}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::optional<T*> GetValue() {
|
||||||
|
if (!std::holds_alternative<T>(value)) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
return std::get<T>(value);
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
std::variant<double,
|
std::variant<double,
|
||||||
long long,
|
long long,
|
||||||
|
|
@ -37,20 +44,19 @@ public:
|
||||||
struct TupleValue {
|
struct TupleValue {
|
||||||
public:
|
public:
|
||||||
TupleValue() = default;
|
TupleValue() = default;
|
||||||
TupleValue(std::unordered_map<std::string, utils::IdType>&& fields) : fields(fields) {}
|
explicit TupleValue(std::vector<std::pair<std::optional<std::string>, utils::IdType>>&& fields) : fields(std::move(fields)) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::unordered_map<std::string, utils::IdType> fields;
|
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VariantValue {
|
struct VariantValue {
|
||||||
public:
|
public:
|
||||||
VariantValue() = default;
|
VariantValue() = default;
|
||||||
VariantValue(size_t constructor, TupleValue value)
|
VariantValue(TupleValue value) // TODO: add type & constructor??
|
||||||
: constructor(constructor), value(value) {}
|
: value(value) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
size_t constructor;
|
|
||||||
TupleValue value;
|
TupleValue value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -58,7 +64,7 @@ struct ReferenceToValue {
|
||||||
public:
|
public:
|
||||||
ReferenceToValue() = default;
|
ReferenceToValue() = default;
|
||||||
ReferenceToValue(const std::vector<utils::ReferenceModifier>& references,
|
ReferenceToValue(const std::vector<utils::ReferenceModifier>& references,
|
||||||
utils::IdType value)
|
utils::IdType value)
|
||||||
: references(references), value(value) {}
|
: references(references), value(value) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -70,7 +76,7 @@ struct FunctionValue {
|
||||||
public:
|
public:
|
||||||
FunctionValue() = default;
|
FunctionValue() = default;
|
||||||
FunctionValue(std::variant<interpreter::tokens::FunctionDeclaration*,
|
FunctionValue(std::variant<interpreter::tokens::FunctionDeclaration*,
|
||||||
interpreter::tokens::LambdaFunction*> function)
|
interpreter::tokens::LambdaFunction*> function)
|
||||||
: function(function) {}
|
: function(function) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -82,17 +88,19 @@ public:
|
||||||
struct ArrayValue {
|
struct ArrayValue {
|
||||||
public:
|
public:
|
||||||
ArrayValue() = default;
|
ArrayValue() = default;
|
||||||
ArrayValue(const std::vector<utils::IdType>& elements)
|
explicit ArrayValue(const std::vector<utils::IdType>& elements,
|
||||||
: elements(elements) {}
|
bool is_constant_size)
|
||||||
|
: elements(elements), is_constant_size(is_constant_size) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<utils::IdType> elements;
|
std::vector<utils::IdType> elements;
|
||||||
|
bool is_constant_size = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OptionalValue {
|
struct OptionalValue {
|
||||||
public:
|
public:
|
||||||
OptionalValue() = default;
|
OptionalValue() = default;
|
||||||
OptionalValue(utils::IdType value) : value(value) {}
|
explicit OptionalValue(utils::IdType value) : value(value) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::optional<utils::IdType> value;
|
std::optional<utils::IdType> value;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
// for clangd
|
// for clangd
|
||||||
#include "../include/execute_visitor.hpp"
|
#include "../include/execute_visitor.hpp"
|
||||||
|
#include <cwchar>
|
||||||
|
#include <optional>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
|
|
@ -7,7 +10,7 @@ namespace interpreter {
|
||||||
|
|
||||||
// Sources -----------------
|
// Sources -----------------
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(SourceFile* node) {
|
void ExecuteVisitor::Visit(SourceFile* node) { // never used ??
|
||||||
for (auto& statement : node->statements) {
|
for (auto& statement : node->statements) {
|
||||||
Visitor::Visit(statement);
|
Visitor::Visit(statement);
|
||||||
}
|
}
|
||||||
|
|
@ -15,97 +18,48 @@ void ExecuteVisitor::Visit(SourceFile* node) {
|
||||||
|
|
||||||
// Namespaces, partitions -----------------
|
// Namespaces, partitions -----------------
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(NamespaceSources* node) {
|
void ExecuteVisitor::Visit(NamespaceSources* node) { // never used ??
|
||||||
for (auto& statement : node->statements) {
|
for (auto& statement : node->statements) {
|
||||||
Visitor::Visit(statement);
|
Visitor::Visit(statement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(Namespace* node) {
|
void ExecuteVisitor::Visit(Namespace* node) { // never used ??
|
||||||
Visit(&node->type);
|
// Visit(&node->type);
|
||||||
Visit(&node->scope);
|
Visit(&node->scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Definitions -----------------
|
// Definitions -----------------
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(ImportStatement* node) {
|
void ExecuteVisitor::Visit(ImportStatement* node) {} // no value
|
||||||
for (auto& symbol : node->symbols) {
|
void ExecuteVisitor::Visit(AliasDefinitionStatement* node) {} // no value
|
||||||
Visit(&symbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(AliasDefinitionStatement* node) {
|
|
||||||
Visit(&node->type);
|
|
||||||
Visit(node->value.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(VariableDefinitionStatement* node) {
|
void ExecuteVisitor::Visit(VariableDefinitionStatement* node) {
|
||||||
Visitor::Visit(node->name);
|
Visitor::Visit(node->name);
|
||||||
Visitor::Visit(node->value);
|
Visitor::Visit(node->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(FunctionDeclaration* node) {
|
void ExecuteVisitor::Visit(FunctionDeclaration* node) {} // no value
|
||||||
Visit(&node->name);
|
|
||||||
for (auto& parameter : node->parameters) {
|
|
||||||
Visit(parameter.get());
|
|
||||||
}
|
|
||||||
Visit(node->type.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) {
|
void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) {
|
||||||
Visit(node->definition.get());
|
// Visit(node->definition.get());
|
||||||
Visitor::Visit(node->value);
|
Visitor::Visit(node->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(TypeDefinitionStatement* node) {
|
void ExecuteVisitor::Visit(TypeDefinitionStatement* node) {} // no value
|
||||||
Visit(node->definition.get());
|
void ExecuteVisitor::Visit(AbstractTypeDefinitionStatement* node) {} // no value
|
||||||
Visitor::Visit(node->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
void ExecuteVisitor::Visit(TypeclassDefinitionStatement* node) {} // no value
|
||||||
Visit(node->type.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(TypeclassDefinitionStatement* node) {
|
|
||||||
Visit(node->definition.get());
|
|
||||||
for (auto& requirement : node->requirements) {
|
|
||||||
Visit(requirement.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(PartitionStatement* node) {
|
void ExecuteVisitor::Visit(PartitionStatement* node) {
|
||||||
Visit(&node->name);
|
|
||||||
Visitor::Visit(node->value);
|
Visitor::Visit(node->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Definition parts
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(FunctionDefinition* node) {
|
|
||||||
Visit(&node->name);
|
|
||||||
for (auto& argument : node->arguments) {
|
|
||||||
Visit(&argument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(TypeDefinition* node) {
|
|
||||||
Visit(node->type.get());
|
|
||||||
for (auto& parameter : node->parameters) {
|
|
||||||
Visit(parameter.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(AnyAnnotatedType* node) {
|
|
||||||
Visit(&node->type);
|
|
||||||
for (auto& typeclass : node->typeclasses) {
|
|
||||||
Visit(typeclass.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flow control -----------------
|
// Flow control -----------------
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) {
|
void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) {
|
||||||
if (node->name.has_value()) {
|
if (node->name.has_value()) {
|
||||||
Visit(&node->name.value());
|
// Visit(&node->name.value());
|
||||||
}
|
}
|
||||||
Visitor::Visit(node->value);
|
Visitor::Visit(node->value);
|
||||||
}
|
}
|
||||||
|
|
@ -145,37 +99,122 @@ void ExecuteVisitor::Visit(Condition* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(DoWhileLoop* node) {
|
void ExecuteVisitor::Visit(DoWhileLoop* node) {
|
||||||
Visitor::Visit(node->statement);
|
std::vector<utils::IdType> result;
|
||||||
Visitor::Visit(node->condition);
|
do {
|
||||||
|
Visitor::Visit(node->statement);
|
||||||
|
if (active_loop_control_expression_.has_value()) {
|
||||||
|
if (active_loop_control_expression_.value() == LoopControlExpression::Break) {
|
||||||
|
active_loop_control_expression_ = std::nullopt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
active_loop_control_expression_ = std::nullopt;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
result.push_back(current_value_);
|
||||||
|
} while(HandleCondition(node->condition, node->base));
|
||||||
|
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
||||||
|
info::value::ArrayValue(result, false),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(WhileLoop* node) {
|
void ExecuteVisitor::Visit(WhileLoop* node) {
|
||||||
Visitor::Visit(node->condition);
|
std::vector<utils::IdType> result;
|
||||||
Visitor::Visit(node->statement);
|
while(HandleCondition(node->condition, node->base)) {
|
||||||
|
Visitor::Visit(node->statement);
|
||||||
|
if (active_loop_control_expression_.has_value()) {
|
||||||
|
if (active_loop_control_expression_.value() == LoopControlExpression::Break) {
|
||||||
|
active_loop_control_expression_ = std::nullopt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
active_loop_control_expression_ = std::nullopt;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
result.push_back(current_value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
||||||
|
info::value::ArrayValue(result, false),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
}
|
}
|
||||||
void ExecuteVisitor::Visit(ForLoop* node) {
|
void ExecuteVisitor::Visit(ForLoop* node) {
|
||||||
Visitor::Visit(node->variable);
|
std::vector<utils::IdType> result;
|
||||||
|
|
||||||
|
// TODO: extend on different interval types (not only array)
|
||||||
Visitor::Visit(node->interval);
|
Visitor::Visit(node->interval);
|
||||||
Visitor::Visit(node->statement);
|
info::value::ArrayValue* interval = ExtractValue<info::value::ArrayValue>(current_value_, node->base);
|
||||||
|
|
||||||
|
for (auto& value : interval->elements) {
|
||||||
|
current_value_ = value;
|
||||||
|
Visitor::Visit(node->variable);
|
||||||
|
|
||||||
|
Visitor::Visit(node->statement);
|
||||||
|
if (active_loop_control_expression_.has_value()) {
|
||||||
|
if (active_loop_control_expression_.value() == LoopControlExpression::Break) {
|
||||||
|
active_loop_control_expression_ = std::nullopt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
active_loop_control_expression_ = std::nullopt;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
result.push_back(current_value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
||||||
|
info::value::ArrayValue(result, false),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(LoopLoop* node) {
|
void ExecuteVisitor::Visit(LoopLoop* node) {
|
||||||
Visitor::Visit(node->statement);
|
std::vector<utils::IdType> result;
|
||||||
|
while(true) {
|
||||||
|
Visitor::Visit(node->statement);
|
||||||
|
if (active_loop_control_expression_.has_value()) {
|
||||||
|
if (active_loop_control_expression_.value() == LoopControlExpression::Break) {
|
||||||
|
active_loop_control_expression_ = std::nullopt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
active_loop_control_expression_ = std::nullopt;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
result.push_back(current_value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
||||||
|
info::value::ArrayValue(result, false),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statements, expressions, blocks, etc. -----------------
|
// Statements, expressions, blocks, etc. -----------------
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(Block* node) {
|
void ExecuteVisitor::Visit(Block* node) {
|
||||||
for (auto& statement : node->statements) {
|
for (auto& statement : node->statements) {
|
||||||
|
return_value_ = std::nullopt;
|
||||||
Visitor::Visit(statement);
|
Visitor::Visit(statement);
|
||||||
|
if (return_value_.has_value()) {
|
||||||
|
current_value_ = return_value_.value();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
|
||||||
|
info::value::InternalValue(info::value::Unit()),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(ScopedStatement* node) {
|
void ExecuteVisitor::Visit(ScopedStatement* node) {
|
||||||
Visitor::Visit(node->statement);
|
Visitor::Visit(node->statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(LoopControlExpression& node) {} // enum
|
void ExecuteVisitor::Visit(LoopControlExpression& node) {
|
||||||
|
active_loop_control_expression_ = node;
|
||||||
|
|
||||||
|
current_value_ = context_manager_.AddValue(info::value::InternalValue(info::value::Unit()),
|
||||||
|
utils::ValueType::Tmp); // ??
|
||||||
|
}
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
|
|
||||||
|
|
@ -186,17 +225,35 @@ void ExecuteVisitor::Visit(BinaryOperatorExpression* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(UnaryOperatorExpression* node) {
|
void ExecuteVisitor::Visit(UnaryOperatorExpression* node) {
|
||||||
Visit(&node->operator_name);
|
// Visit(&node->operator_name);
|
||||||
Visitor::Visit(node->expression);
|
Visitor::Visit(node->expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(ReferenceExpression* node) {
|
void ExecuteVisitor::Visit(ReferenceExpression* node) {
|
||||||
|
// TODO: check, that therie is no references to "Tmp"
|
||||||
Visit(node->expression.get());
|
Visit(node->expression.get());
|
||||||
|
|
||||||
|
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
|
||||||
|
|
||||||
|
current_value_ = context_manager_.AddValue(
|
||||||
|
info::value::ReferenceToValue(node->references, current_value_),
|
||||||
|
value_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(AccessExpression* node) {
|
void ExecuteVisitor::Visit(AccessExpression* node) {
|
||||||
|
// TODO: extend to other types
|
||||||
Visit(node->name.get());
|
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_);
|
||||||
|
|
||||||
Visitor::Visit(node->id);
|
Visitor::Visit(node->id);
|
||||||
|
long long index = *ExtractInternalValue<long long>(current_value_, node->base); // TODO: size_t
|
||||||
|
|
||||||
|
if (index < 0 || index >= array_value->elements.size()) {
|
||||||
|
error_handling::HandleRuntimeError("Access index out of range", node->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_value_ = context_manager_.ToModifiedValue(array_value->elements[index], value_type); // needed ??
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other Expressions
|
// Other Expressions
|
||||||
|
|
@ -212,7 +269,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Visit(&node->name);
|
// Visit(&node->name);
|
||||||
|
|
||||||
for (auto& parameter : node->parameters) {
|
for (auto& parameter : node->parameters) {
|
||||||
Visit(parameter.get());
|
Visit(parameter.get());
|
||||||
|
|
@ -224,24 +281,37 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(TupleExpression* node) {
|
void ExecuteVisitor::Visit(TupleExpression* node) {
|
||||||
|
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
|
||||||
|
fields.reserve(node->expressions.size());
|
||||||
for (auto& expression : node->expressions) {
|
for (auto& expression : node->expressions) {
|
||||||
Visitor::Visit(expression);
|
Visitor::Visit(expression);
|
||||||
|
fields.push_back({std::nullopt, current_value_});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::TupleValue>(info::value::TupleValue(std::move(fields)),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(VariantExpression* node) {
|
// TODO
|
||||||
|
void ExecuteVisitor::Visit(VariantExpression* node) { // ??
|
||||||
for (auto& expression : node->expressions) {
|
for (auto& expression : node->expressions) {
|
||||||
Visitor::Visit(expression);
|
Visitor::Visit(expression);
|
||||||
|
info::value::OptionalValue* expression_value = ExtractValue<info::value::OptionalValue>(current_value_, node->base);
|
||||||
|
if (expression_value->value.has_value()) {
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(ReturnExpression* node) {
|
void ExecuteVisitor::Visit(ReturnExpression* node) {
|
||||||
Visitor::Visit(node->expression);
|
Visitor::Visit(node->expression);
|
||||||
|
return_value_ = current_value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(TypeConstructorParameter* node) {
|
void ExecuteVisitor::Visit(TypeConstructorParameter* node) {
|
||||||
if (node->name.has_value()) {
|
if (node->name.has_value()) {
|
||||||
Visit(&node->name.value());
|
// Visit(&node->name.value());
|
||||||
}
|
}
|
||||||
Visitor::Visit(node->value);
|
Visitor::Visit(node->value);
|
||||||
}
|
}
|
||||||
|
|
@ -253,14 +323,10 @@ void ExecuteVisitor::Visit(TypeConstructor* node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
void ExecuteVisitor::Visit(LambdaFunction* node) {
|
void ExecuteVisitor::Visit(LambdaFunction* node) {
|
||||||
for (auto& parameter : node->parameters) {
|
error_handling::HandleInternalError("Lambda function are not implemented yet",
|
||||||
Visit(parameter.get());
|
"ExecuteVisitor.LambdaFunction");
|
||||||
}
|
|
||||||
for (auto& argument : node->arguments) {
|
|
||||||
Visit(&argument);
|
|
||||||
}
|
|
||||||
Visitor::Visit(node->expression);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(ArrayExpression* node) {
|
void ExecuteVisitor::Visit(ArrayExpression* node) {
|
||||||
|
|
@ -271,17 +337,9 @@ void ExecuteVisitor::Visit(ArrayExpression* node) {
|
||||||
|
|
||||||
// Name
|
// Name
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(PartitionName* node) {
|
|
||||||
for (auto& path_namespace : node->path) {
|
|
||||||
Visit(&path_namespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
Visit(&node->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(NameExpression* node) {
|
void ExecuteVisitor::Visit(NameExpression* node) {
|
||||||
for (auto& name : node->names) {
|
for (auto& name : node->names) {
|
||||||
Visit(&name);
|
// Visit(&name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -298,7 +356,7 @@ void ExecuteVisitor::Visit(VariantName* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(AnnotatedName* node) {
|
void ExecuteVisitor::Visit(AnnotatedName* node) {
|
||||||
Visit(&node->name);
|
// Visit(&node->name);
|
||||||
if (node->type.has_value()) {
|
if (node->type.has_value()) {
|
||||||
Visitor::Visit(node->type.value());
|
Visitor::Visit(node->type.value());
|
||||||
}
|
}
|
||||||
|
|
@ -308,85 +366,68 @@ void ExecuteVisitor::Visit(AnnotatedName* node) {
|
||||||
|
|
||||||
// Type
|
// Type
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(FunctionType* node) {
|
void ExecuteVisitor::Visit(FunctionType* node) {} // no value
|
||||||
for (auto& type : node->types) {
|
void ExecuteVisitor::Visit(TupleType* node) {} // no value
|
||||||
Visitor::Visit(type);
|
void ExecuteVisitor::Visit(VariantType* node) {} // no value
|
||||||
}
|
void ExecuteVisitor::Visit(TypeExpression* node) {} // no value
|
||||||
}
|
void ExecuteVisitor::Visit(ExtendedScopedAnyType* node) {} // no value
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(TupleType* node) {
|
|
||||||
if (node->type.has_value()) {
|
|
||||||
Visit(&node->type.value());
|
|
||||||
}
|
|
||||||
for (auto& entity : node->entities) {
|
|
||||||
if (entity.first.has_value()) {
|
|
||||||
Visit(&entity.first.value());
|
|
||||||
}
|
|
||||||
Visit(entity.second.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(VariantType* node) {
|
|
||||||
if (node->type.has_value()) {
|
|
||||||
Visit(&node->type.value());
|
|
||||||
}
|
|
||||||
for (auto& constructor : node->constructors) {
|
|
||||||
if (std::holds_alternative<Constructor>(constructor)) {
|
|
||||||
Visit(&std::get<Constructor>(constructor));
|
|
||||||
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
|
|
||||||
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
|
|
||||||
} else {
|
|
||||||
// error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(TypeExpression* node) {
|
|
||||||
for (auto& type : node->path) {
|
|
||||||
Visit(&type);
|
|
||||||
}
|
|
||||||
Visit(&node->type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(ExtendedScopedAnyType* node) {
|
|
||||||
Visitor::Visit(node->type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Typeclass
|
// Typeclass
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(ParametrizedTypeclass* node) {
|
void ExecuteVisitor::Visit(ParametrizedTypeclass* node) {} // no value
|
||||||
Visit(&node->typeclass);
|
|
||||||
for (auto& parameter : node->parameters) {
|
|
||||||
Visit(parameter.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Typeclass & Type -----------------
|
// Typeclass & Type -----------------
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(ParametrizedType* node) {
|
void ExecuteVisitor::Visit(ParametrizedType* node) {} // no value
|
||||||
Visit(&node->type);
|
|
||||||
for (auto& parameter : node->parameters) {
|
|
||||||
Visit(parameter.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Identifiers, constants, etc. -----------------
|
// Identifiers, constants, etc. -----------------
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(ExtendedName* node) {}
|
// void ExecuteVisitor::Visit(ExtendedName* node) {}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(std::string* node) {} // std::string
|
// void ExecuteVisitor::Visit(std::string* node) {} // std::string
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(FloatNumberLiteral* node) {}
|
void ExecuteVisitor::Visit(FloatNumberLiteral* node) {
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
|
||||||
|
info::value::InternalValue(node->value),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(NumberLiteral* node) {}
|
void ExecuteVisitor::Visit(NumberLiteral* node) {
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
|
||||||
|
info::value::InternalValue(node->value),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(StringLiteral* node) {}
|
void ExecuteVisitor::Visit(StringLiteral* node) {
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
|
||||||
|
info::value::InternalValue(node->value),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(CharLiteral* node) {}
|
void ExecuteVisitor::Visit(CharLiteral* node) {
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
|
||||||
|
info::value::InternalValue(node->value),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(UnitLiteral* node) {}
|
void ExecuteVisitor::Visit(UnitLiteral* node) {
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
|
||||||
|
info::value::InternalValue(info::value::Unit()),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(BoolLiteral* node) {}
|
void ExecuteVisitor::Visit(BoolLiteral* node) {
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
|
||||||
|
info::value::InternalValue(node->value),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
bool ExecuteVisitor::HandleCondition(Expression& node, const BaseNode& base_node) {
|
||||||
|
Visitor::Visit(node);
|
||||||
|
return *ExtractInternalValue<bool>(current_value_, base_node);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace interpreter
|
} // namespace interpreter
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -541,6 +541,7 @@ void TypeCheckVisitor::Visit(Block* node) {
|
||||||
error_handling::HandleTypecheckError("Different return types in block", node->base);
|
error_handling::HandleTypecheckError("Different return types in block", node->base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// returned_type_ = std::nullopt; // not needed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
context_manager_.EnterContext();
|
context_manager_.EnterContext();
|
||||||
|
|
@ -571,27 +572,28 @@ void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum
|
||||||
void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
||||||
// TODO: Check, that type is not abstract ??
|
// TODO: Check, that type is not abstract ??
|
||||||
auto maybe_operator_id = namespace_visitor_.FindFunction(std::nullopt, node->operator_name);
|
auto maybe_operator_id = namespace_visitor_.FindFunction(std::nullopt, node->operator_name);
|
||||||
|
const info::definition::Function* operator_info = nullptr;
|
||||||
|
|
||||||
if (maybe_operator_id.has_value()) {
|
if (maybe_operator_id.has_value()) {
|
||||||
const info::definition::Function& operator_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
|
operator_info = &namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
|
||||||
|
|
||||||
if (!operator_info.declaration.has_value()) {
|
if (!operator_info->declaration.has_value()) {
|
||||||
error_handling::HandleTypecheckError("Operator declaration not found", node->base);
|
error_handling::HandleTypecheckError("Operator declaration not found", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!operator_info.definition.has_value()) { // TODO: builtin, etc.
|
if (!operator_info->definition.has_value()) { // TODO: builtin, etc.
|
||||||
error_handling::HandleTypecheckError("Operator definition not found", node->base);
|
error_handling::HandleTypecheckError("Operator definition not found", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operator_info.argument_count != 3) { // 2 + return type
|
if (operator_info->argument_count != 3) { // 2 + return type
|
||||||
error_handling::HandleTypecheckError("Operator wrong argument count", node->base);
|
error_handling::HandleTypecheckError("Operator wrong argument count", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operator_info.declaration->parameters.size() > 0) {
|
if (operator_info->declaration->parameters.size() > 0) {
|
||||||
error_handling::HandleTypecheckError("Operator with parameters", node->base);
|
error_handling::HandleTypecheckError("Operator with parameters", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
Visitor::Visit(*operator_info.declaration.value().argument_types[0]);
|
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_; // TODO: type in context of deduced types
|
||||||
|
|
||||||
Visitor::Visit(node->left_expression);
|
Visitor::Visit(node->left_expression);
|
||||||
|
|
@ -599,82 +601,82 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
||||||
error_handling::HandleTypecheckError("Operator left expression has wrong type", node->base);
|
error_handling::HandleTypecheckError("Operator left expression has wrong type", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
Visitor::Visit(*operator_info.declaration.value().argument_types[1]);
|
Visitor::Visit(*operator_info->declaration.value().argument_types[1]);
|
||||||
utils::IdType right_expression_type = current_type_; // TODO: type in context of deduced types
|
utils::IdType right_expression_type = current_type_; // TODO: type in context of deduced types
|
||||||
|
|
||||||
Visitor::Visit(node->right_expression);
|
Visitor::Visit(node->right_expression);
|
||||||
if (!context_manager_.AddTypeRequirement(current_type_, right_expression_type)) {
|
if (!context_manager_.AddTypeRequirement(current_type_, right_expression_type)) {
|
||||||
error_handling::HandleTypecheckError("Operator right expression has wrong type", node->base);
|
error_handling::HandleTypecheckError("Operator right expression has wrong type", node->base);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
Visitor::Visit(*operator_info.declaration.value().argument_types.back());
|
Visitor::Visit(node->left_expression);
|
||||||
return;
|
auto maybe_left_type = context_manager_.GetType<info::type::DefinedType>(current_type_);
|
||||||
|
|
||||||
|
utils::ValueType left_value_type = context_manager_.GetValueType(current_type_);
|
||||||
|
|
||||||
|
if (!maybe_left_type.has_value()) {
|
||||||
|
error_handling::HandleTypecheckError("Operator not found (type is not DefinedType)", node->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto maybe_left_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(maybe_left_type.value()->GetTypeId());
|
||||||
|
|
||||||
|
std::string left_type_name = maybe_left_type_info.value()->type.type;
|
||||||
|
|
||||||
|
auto maybe_const_operator_id = namespace_visitor_.FindMethod(std::nullopt,
|
||||||
|
left_type_name,
|
||||||
|
node->operator_name,
|
||||||
|
utils::IsConstModifier::Const);
|
||||||
|
|
||||||
|
if (left_value_type != utils::ValueType::Const) {
|
||||||
|
maybe_operator_id = namespace_visitor_.FindMethod(std::nullopt,
|
||||||
|
left_type_name,
|
||||||
|
node->operator_name,
|
||||||
|
utils::IsConstModifier::Var);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!maybe_operator_id.has_value() && !maybe_const_operator_id.has_value()) {
|
||||||
|
error_handling::HandleTypecheckError("Operator not found (method name not found)", node->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maybe_operator_id.has_value() && maybe_const_operator_id.has_value()) {
|
||||||
|
error_handling::HandleTypecheckError("Ambigious operator (const and var method)", node->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!maybe_operator_id.has_value()) {
|
||||||
|
maybe_operator_id = maybe_const_operator_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator_info = &namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
|
||||||
|
|
||||||
|
if (!operator_info->declaration.has_value()) {
|
||||||
|
error_handling::HandleTypecheckError("Operator declaration not found", node->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!operator_info->definition.has_value()) { // TODO: builtin, etc.
|
||||||
|
error_handling::HandleTypecheckError("Operator definition not found", node->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operator_info->argument_count != 2) { // argument + return type
|
||||||
|
error_handling::HandleTypecheckError("Operator wrong argument count", node->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operator_info->declaration->parameters.size() > 0) {
|
||||||
|
error_handling::HandleTypecheckError("Operator with parameters", node->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
Visitor::Visit(*operator_info->declaration.value().argument_types[9]);
|
||||||
|
utils::IdType right_expression_type = current_type_; // TODO: type in context of deduced types
|
||||||
|
|
||||||
|
Visitor::Visit(node->right_expression);
|
||||||
|
if (!context_manager_.AddTypeRequirement(current_type_, right_expression_type)) {
|
||||||
|
error_handling::HandleTypecheckError("Operator right expression has wrong type", node->base);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Visitor::Visit(node->left_expression);
|
node->function_id_ = maybe_operator_id.value(); // IMPORTANT
|
||||||
auto maybe_left_type = context_manager_.GetType<info::type::DefinedType>(current_type_);
|
|
||||||
|
|
||||||
utils::ValueType left_value_type = context_manager_.GetValueType(current_type_);
|
Visitor::Visit(*operator_info->declaration.value().argument_types.back());
|
||||||
|
|
||||||
if (!maybe_left_type.has_value()) {
|
|
||||||
error_handling::HandleTypecheckError("Operator not found (type is not DefinedType)", node->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto maybe_left_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(maybe_left_type.value()->GetTypeId());
|
|
||||||
|
|
||||||
std::string left_type_name = maybe_left_type_info.value()->type.type;
|
|
||||||
|
|
||||||
auto maybe_const_operator_id = namespace_visitor_.FindMethod(std::nullopt,
|
|
||||||
left_type_name,
|
|
||||||
node->operator_name,
|
|
||||||
utils::IsConstModifier::Const);
|
|
||||||
|
|
||||||
if (left_value_type != utils::ValueType::Const) {
|
|
||||||
maybe_operator_id = namespace_visitor_.FindMethod(std::nullopt,
|
|
||||||
left_type_name,
|
|
||||||
node->operator_name,
|
|
||||||
utils::IsConstModifier::Var);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!maybe_operator_id.has_value() && !maybe_const_operator_id.has_value()) {
|
|
||||||
error_handling::HandleTypecheckError("Operator not found (method name not found)", node->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maybe_operator_id.has_value() && maybe_const_operator_id.has_value()) {
|
|
||||||
error_handling::HandleTypecheckError("Ambigious operator (const and var method)", node->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!maybe_operator_id.has_value()) {
|
|
||||||
maybe_operator_id = maybe_const_operator_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const info::definition::Function& operator_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
|
|
||||||
|
|
||||||
if (!operator_info.declaration.has_value()) {
|
|
||||||
error_handling::HandleTypecheckError("Operator declaration not found", node->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!operator_info.definition.has_value()) { // TODO: builtin, etc.
|
|
||||||
error_handling::HandleTypecheckError("Operator definition not found", node->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (operator_info.argument_count != 2) { // argument + return type
|
|
||||||
error_handling::HandleTypecheckError("Operator wrong argument count", node->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (operator_info.declaration->parameters.size() > 0) {
|
|
||||||
error_handling::HandleTypecheckError("Operator with parameters", node->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
Visitor::Visit(*operator_info.declaration.value().argument_types[9]);
|
|
||||||
utils::IdType right_expression_type = current_type_; // TODO: type in context of deduced types
|
|
||||||
|
|
||||||
Visitor::Visit(node->right_expression);
|
|
||||||
if (!context_manager_.AddTypeRequirement(current_type_, right_expression_type)) {
|
|
||||||
error_handling::HandleTypecheckError("Operator right expression has wrong type", node->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
Visitor::Visit(*operator_info.declaration.value().argument_types.back());
|
|
||||||
|
|
||||||
node->base.type_ = current_type_;
|
node->base.type_ = current_type_;
|
||||||
}
|
}
|
||||||
|
|
@ -714,6 +716,8 @@ void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) {
|
||||||
error_handling::HandleTypecheckError("Operator expression has wrong type", node->base);
|
error_handling::HandleTypecheckError("Operator expression has wrong type", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node->function_id_ = maybe_operator_id.value(); // IMPORTANT
|
||||||
|
|
||||||
Visitor::Visit(*operator_info.declaration.value().argument_types.back());
|
Visitor::Visit(*operator_info.declaration.value().argument_types.back());
|
||||||
|
|
||||||
node->base.type_ = current_type_;
|
node->base.type_ = current_type_;
|
||||||
|
|
@ -867,6 +871,8 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
||||||
context_manager_.AddTypeRequirement(current_type_, argument_type);
|
context_manager_.AddTypeRequirement(current_type_, argument_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node->function_id_ = maybe_function_id.value(); // IMPORTANT
|
||||||
|
|
||||||
Visitor::Visit(*function_declaration.argument_types.back());
|
Visitor::Visit(*function_declaration.argument_types.back());
|
||||||
current_type_ = TypeInContext(current_type_, context);
|
current_type_ = TypeInContext(current_type_, context);
|
||||||
}
|
}
|
||||||
|
|
@ -899,6 +905,9 @@ void TypeCheckVisitor::Visit(VariantExpression* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
current_type_ = context_manager_.AddType(info::type::VariantType(std::nullopt, constructors, -1),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
current_type_ = context_manager_.AddType(info::type::VariantType(std::nullopt, constructors, -1),
|
current_type_ = context_manager_.AddType(info::type::VariantType(std::nullopt, constructors, -1),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue