mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-05 22:48:42 +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
|
|
@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
# find_package(Catch2 2 REQUIRED)
|
# find_package(Catch2 2 REQUIRED)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
|
||||||
|
|
||||||
include_directories(include
|
include_directories(include
|
||||||
tree-sitter/lib/src
|
tree-sitter/lib/src
|
||||||
|
|
|
||||||
|
|
@ -164,8 +164,8 @@ private:
|
||||||
|
|
||||||
bool HandleBuiltinFunctionCall(FunctionCallExpression* node);
|
bool HandleBuiltinFunctionCall(FunctionCallExpression* node);
|
||||||
|
|
||||||
bool HandleBuiltinTypeclassFunctionCall(FunctionCallExpression* node);
|
bool HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
|
||||||
|
info::type::InternalType type);
|
||||||
private:
|
private:
|
||||||
info::GlobalInfo& global_info_;
|
info::GlobalInfo& global_info_;
|
||||||
info::TypeclassGraph& typeclass_graph_;
|
info::TypeclassGraph& typeclass_graph_;
|
||||||
|
|
|
||||||
|
|
@ -506,6 +506,8 @@ struct AccessExpression {
|
||||||
|
|
||||||
std::unique_ptr<NameExpression> name;
|
std::unique_ptr<NameExpression> name;
|
||||||
SubExpressionToken id;
|
SubExpressionToken id;
|
||||||
|
|
||||||
|
bool is_string_access_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Other Expressions -----------------
|
// Other Expressions -----------------
|
||||||
|
|
|
||||||
|
|
@ -198,8 +198,8 @@ private:
|
||||||
|
|
||||||
utils::IdType abstract_type = context_manager_.AddValue(
|
utils::IdType abstract_type = context_manager_.AddValue(
|
||||||
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
|
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
|
||||||
typeclass_graph_.GetVertex(graph_id).name,
|
graph_id,
|
||||||
requirement_graph_ids),
|
typeclass_graph_),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
for (auto& requirement_graph_id : requirement_graph_ids) {
|
for (auto& requirement_graph_id : requirement_graph_ids) {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
// for clangd
|
// for clangd
|
||||||
#include "error_handling.hpp"
|
#include "error_handling.hpp"
|
||||||
|
#include "typeclass_graph.hpp"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
|
|
||||||
namespace info::type {
|
namespace info::type {
|
||||||
|
|
@ -19,23 +20,12 @@ class TypeManager;
|
||||||
|
|
||||||
class AbstractType { // latter will be found in context
|
class AbstractType { // latter will be found in context
|
||||||
public:
|
public:
|
||||||
AbstractType() = default;
|
|
||||||
AbstractType(utils::AbstractTypeModifier modifier,
|
AbstractType(utils::AbstractTypeModifier modifier,
|
||||||
const std::string& name,
|
utils::IdType graph_id,
|
||||||
const std::vector<utils::IdType>& requirement_graph_ids)
|
info::TypeclassGraph& typeclass_graph)
|
||||||
: modifier_(modifier),
|
: modifier_(modifier),
|
||||||
name_(name) {
|
graph_id_(graph_id),
|
||||||
for (auto& requirement_graph_id : requirement_graph_ids) {
|
typeclass_graph_(typeclass_graph) {}
|
||||||
requirement_graph_ids_.insert(requirement_graph_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractType(utils::AbstractTypeModifier modifier,
|
|
||||||
const std::string& name,
|
|
||||||
const std::unordered_set<utils::IdType>& requirement_graph_ids)
|
|
||||||
: modifier_(modifier),
|
|
||||||
name_(name),
|
|
||||||
requirement_graph_ids_(requirement_graph_ids) {}
|
|
||||||
|
|
||||||
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
|
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
|
||||||
bool Same(const AbstractType& type) const;
|
bool Same(const AbstractType& type) const;
|
||||||
|
|
@ -45,21 +35,21 @@ public:
|
||||||
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
||||||
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
||||||
|
|
||||||
const std::string& GetName() {
|
utils::IdType GetGraphId() {
|
||||||
return name_;
|
return graph_id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasTypeclass(utils::IdType graph_id) {
|
bool HasTypeclass(utils::IdType graph_id) { // TODO: cache dependencies set
|
||||||
return requirement_graph_ids_.count(graph_id) != 0;
|
return graph_id == graph_id_ || typeclass_graph_.GetDependenciesSet(graph_id_).count(graph_id) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToString() {
|
std::string ToString() {
|
||||||
return "Abstract " + name_;
|
return "Abstract " + std::to_string(graph_id_);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
utils::AbstractTypeModifier modifier_;
|
utils::AbstractTypeModifier modifier_;
|
||||||
std::string name_;
|
utils::IdType graph_id_;
|
||||||
std::unordered_set<utils::IdType> requirement_graph_ids_; // TODO: all typeclasses from tree
|
info::TypeclassGraph& typeclass_graph_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DefinedType {
|
class DefinedType {
|
||||||
|
|
@ -324,8 +314,6 @@ private:
|
||||||
|
|
||||||
class Type {
|
class Type {
|
||||||
public:
|
public:
|
||||||
Type() = default;
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
explicit Type(const T& type) : type_(type) {}
|
explicit Type(const T& type) : type_(type) {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
@ -32,16 +33,19 @@ public:
|
||||||
|
|
||||||
bool Same(const InternalValue& value) const;
|
bool Same(const InternalValue& value) const;
|
||||||
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
||||||
|
|
||||||
|
utils::IdType DeepCopy(ValueManager* value_manager);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::variant<double,
|
std::variant<double,
|
||||||
long long,
|
int64_t,
|
||||||
std::string,
|
std::string,
|
||||||
char,
|
char,
|
||||||
bool,
|
bool,
|
||||||
Unit> value;
|
Unit> value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TupleValue {
|
struct TupleValue { /// TODO: no need to store strings (only store associated type) ??
|
||||||
public:
|
public:
|
||||||
TupleValue() = default;
|
TupleValue() = default;
|
||||||
|
|
||||||
|
|
@ -51,6 +55,9 @@ public:
|
||||||
|
|
||||||
bool Same(const TupleValue& other_value) const;
|
bool Same(const TupleValue& other_value) const;
|
||||||
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
||||||
|
|
||||||
|
utils::IdType DeepCopy(ValueManager* value_manager); // TODO
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
|
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
|
||||||
|
|
||||||
|
|
@ -65,12 +72,14 @@ public:
|
||||||
VariantValue(TupleValue&& value, size_t current_constructor)
|
VariantValue(TupleValue&& value, size_t current_constructor)
|
||||||
: value(std::move(value)), current_constructor(current_constructor) {}
|
: value(std::move(value)), current_constructor(current_constructor) {}
|
||||||
|
|
||||||
|
bool Same(const VariantValue& other_value) const;
|
||||||
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
||||||
|
|
||||||
|
utils::IdType DeepCopy(ValueManager* value_manager);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TupleValue value;
|
TupleValue value;
|
||||||
size_t current_constructor;
|
size_t current_constructor;
|
||||||
|
|
||||||
bool Same(const VariantValue& other_value) const;
|
|
||||||
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReferenceToValue {
|
struct ReferenceToValue {
|
||||||
|
|
@ -82,13 +91,15 @@ public:
|
||||||
ValueManager* value_manager)
|
ValueManager* value_manager)
|
||||||
: references(references), value(value), value_manager_(value_manager) {}
|
: references(references), value(value), value_manager_(value_manager) {}
|
||||||
|
|
||||||
|
bool Same(const ReferenceToValue& other_value) const;
|
||||||
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
||||||
|
|
||||||
|
utils::IdType DeepCopy(ValueManager* value_manager);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<utils::ReferenceModifier> references;
|
std::vector<utils::ReferenceModifier> references;
|
||||||
utils::IdType value;
|
utils::IdType value;
|
||||||
|
|
||||||
bool Same(const ReferenceToValue& other_value) const;
|
|
||||||
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ValueManager* value_manager_ = nullptr;
|
ValueManager* value_manager_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
@ -101,13 +112,15 @@ public:
|
||||||
FunctionValue(const T& function, ValueManager* value_manager)
|
FunctionValue(const T& function, ValueManager* value_manager)
|
||||||
: function(function), value_manager_(value_manager) {}
|
: function(function), value_manager_(value_manager) {}
|
||||||
|
|
||||||
|
bool Same(const FunctionValue& other_value) const;
|
||||||
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
||||||
|
|
||||||
|
utils::IdType DeepCopy(ValueManager* value_manager);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::variant<interpreter::tokens::FunctionDeclaration*,
|
std::variant<interpreter::tokens::FunctionDeclaration*,
|
||||||
interpreter::tokens::LambdaFunction*> function;
|
interpreter::tokens::LambdaFunction*> function;
|
||||||
|
|
||||||
bool Same(const FunctionValue& other_value) const;
|
|
||||||
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ValueManager* value_manager_ = nullptr;
|
ValueManager* value_manager_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
@ -122,13 +135,15 @@ public:
|
||||||
ValueManager* value_manager)
|
ValueManager* value_manager)
|
||||||
: elements(std::move(elements)), is_constant_size(is_constant_size), value_manager_(value_manager) {}
|
: elements(std::move(elements)), is_constant_size(is_constant_size), value_manager_(value_manager) {}
|
||||||
|
|
||||||
|
bool Same(const ArrayValue& other_value) const;
|
||||||
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
||||||
|
|
||||||
|
utils::IdType DeepCopy(ValueManager* value_manager);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<utils::IdType> elements;
|
std::vector<utils::IdType> elements;
|
||||||
bool is_constant_size = false;
|
bool is_constant_size = false;
|
||||||
|
|
||||||
bool Same(const ArrayValue& other_value) const;
|
|
||||||
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ValueManager* value_manager_ = nullptr;
|
ValueManager* value_manager_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
@ -143,6 +158,8 @@ public:
|
||||||
bool Same(const OptionalValue& other_value) const;
|
bool Same(const OptionalValue& other_value) const;
|
||||||
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
||||||
|
|
||||||
|
utils::IdType DeepCopy(ValueManager* value_manager);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::optional<utils::IdType> value;
|
std::optional<utils::IdType> value;
|
||||||
|
|
||||||
|
|
@ -160,6 +177,8 @@ public:
|
||||||
bool Same(const Value& other_value) const;
|
bool Same(const Value& other_value) const;
|
||||||
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
||||||
|
|
||||||
|
utils::IdType DeepCopy(ValueManager* value_manager);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::variant<InternalValue,
|
std::variant<InternalValue,
|
||||||
TupleValue,
|
TupleValue,
|
||||||
|
|
@ -173,16 +192,25 @@ public:
|
||||||
class ValueManager {
|
class ValueManager {
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
utils::IdType AddValue(const T& value, utils::ValueType value_type) {
|
utils::IdType ExplicitAddValue(const T& value, utils::ValueType value_type) {
|
||||||
values_.push_back(std::pair<Value, utils::ValueType> {Value(value), value_type});
|
values_.push_back(std::pair<Value, utils::ValueType> {Value(value), value_type});
|
||||||
return values_.size() - 1;
|
return values_.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::IdType AddAnyValue(Value&& value, utils::ValueType value_type) {
|
utils::IdType ExplicitAddAnyValue(Value&& value, utils::ValueType value_type) {
|
||||||
values_.push_back(std::pair<Value, utils::ValueType> {std::move(value), value_type});
|
values_.push_back(std::pair<Value, utils::ValueType> {std::move(value), value_type});
|
||||||
return values_.size() - 1;
|
return values_.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
utils::IdType AddValue(const T& value, utils::ValueType value_type) {
|
||||||
|
return ExplicitAddValue(std::move(value), value_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::IdType AddAnyValue(Value&& value, utils::ValueType value_type) {
|
||||||
|
return ExplicitAddAnyValue(std::move(value), value_type);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::optional<T*> GetValue(utils::IdType value_id) {
|
std::optional<T*> GetValue(utils::IdType value_id) {
|
||||||
if (!std::holds_alternative<T>(values_.at(value_id).first.value)) {
|
if (!std::holds_alternative<T>(values_.at(value_id).first.value)) {
|
||||||
|
|
|
||||||
|
|
@ -392,20 +392,37 @@ void ExecuteVisitor::Visit(ReferenceExpression* node) {
|
||||||
value_type);
|
value_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(AccessExpression* node) {
|
|
||||||
// TODO: extend to other types
|
// TODO: extend to other types
|
||||||
|
// TODO: string should be array
|
||||||
|
void ExecuteVisitor::Visit(AccessExpression* node) {
|
||||||
Visit(node->name.get());
|
Visit(node->name.get());
|
||||||
info::value::ArrayValue* array_value = ExtractValue<info::value::ArrayValue>(current_value_, node->base);
|
utils::IdType array_value = current_value_;
|
||||||
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
|
utils::ValueType value_type = context_manager_.GetValueType(array_value);
|
||||||
|
|
||||||
Visitor::Visit(node->id);
|
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()) {
|
if (index < 0) {
|
||||||
error_handling::HandleRuntimeError("Access index out of range", node->base);
|
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
|
// Other Expressions
|
||||||
|
|
@ -462,6 +479,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
|
||||||
|
|
||||||
if (!maybe_function_definition_info.has_value()) {
|
if (!maybe_function_definition_info.has_value()) {
|
||||||
if (HandleBuiltinFunctionCall(node)) {
|
if (HandleBuiltinFunctionCall(node)) {
|
||||||
|
context_manager_.ExitContext();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -485,6 +503,16 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
|
||||||
|
|
||||||
if (!maybe_function_definition.has_value()) {
|
if (!maybe_function_definition.has_value()) {
|
||||||
if (typeclass_graph_.GetVertex(node->graph_id_.value()).modifier == info::TypeclassGraph::Modifier::Type) {
|
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);
|
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 (!maybe_function_definition.has_value()) {
|
||||||
if (HandleBuiltinTypeclassFunctionCall(node)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
error_handling::HandleRuntimeError("Function definition not found (by graph_id_)", node->base);
|
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);
|
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) {
|
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||||
current_value_ = maybe_tuple_value.value()->fields[i].second;
|
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]);
|
Visitor::Visit(node->names[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -798,11 +806,13 @@ void ExecuteVisitor::Visit(AnnotatedName* node) { // TODO: check
|
||||||
&node->base);
|
&node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
|
// utils::ValueType value_type = context_manager_.GetValueType(current_value_);
|
||||||
if (value_type == utils::ValueType::Const
|
|
||||||
&& is_const_definition_.value() == utils::IsConstModifier::Var) {
|
// TODO: only on move
|
||||||
error_handling::HandleRuntimeError("AnnotatedName: value type expression not match variable definition modifier", node->base);
|
// 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()));
|
current_value_ = context_manager_.ToModifiedValue(value, utils::IsConstModifierToValueType(is_const_definition_.value()));
|
||||||
if (!context_manager_.DefineVariable(node->name, current_value_)) {
|
if (!context_manager_.DefineVariable(node->name, current_value_)) {
|
||||||
|
|
@ -963,28 +973,189 @@ void ExecuteVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) {
|
||||||
|
|
||||||
bool ExecuteVisitor::HandleBuiltinFunctionCall(FunctionCallExpression* node) {
|
bool ExecuteVisitor::HandleBuiltinFunctionCall(FunctionCallExpression* node) {
|
||||||
if (node->name == "print") {
|
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]);
|
Visitor::Visit(node->arguments[0]);
|
||||||
info::builtin::Print(*ExtractInternalValue<std::string>(current_value_, node->base));
|
info::builtin::Print(*ExtractInternalValue<std::string>(current_value_, node->base));
|
||||||
|
|
||||||
current_value_ = context_manager_.AddValue(info::value::InternalValue(info::value::Unit()),
|
current_value_ = context_manager_.AddValue(info::value::InternalValue(info::value::Unit()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
return true;
|
|
||||||
} else if (node->name == "scan") {
|
} else if (node->name == "scan") {
|
||||||
current_value_ = context_manager_.AddValue(info::value::InternalValue(info::builtin::Read<std::string>()),
|
current_value_ = context_manager_.AddValue(info::value::InternalValue(info::builtin::Read<std::string>()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
} else if (node->name == "random") { // TODO
|
||||||
|
current_value_ = context_manager_.AddValue(info::value::InternalValue(rand()),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -142,11 +142,10 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) {
|
||||||
|
|
||||||
context_manager_.EnterContext();
|
context_manager_.EnterContext();
|
||||||
for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed??
|
for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed??
|
||||||
auto requirements = typeclass_graph_.GetDependenciesSet(parameter->graph_id_);
|
|
||||||
current_type_ = context_manager_.AddValue(
|
current_type_ = context_manager_.AddValue(
|
||||||
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
|
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
|
||||||
parameter->type,
|
parameter->graph_id_,
|
||||||
requirements),
|
typeclass_graph_),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
context_manager_.DefineLocalType(parameter->type, current_type_);
|
context_manager_.DefineLocalType(parameter->type, current_type_);
|
||||||
}
|
}
|
||||||
|
|
@ -223,10 +222,9 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& parameter : declaration->parameters) {
|
for (auto& parameter : declaration->parameters) {
|
||||||
auto requirements = typeclass_graph_.GetDependenciesSet(parameter->graph_id_);
|
|
||||||
current_type_ = context_manager_.AddValue(info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
|
current_type_ = context_manager_.AddValue(info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
|
||||||
parameter->type,
|
parameter->graph_id_,
|
||||||
requirements),
|
typeclass_graph_),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
if (!context_manager_.DefineLocalType(parameter->type, current_type_)) {
|
if (!context_manager_.DefineLocalType(parameter->type, current_type_)) {
|
||||||
error_handling::HandleTypecheckError("Can't define function parameter type: abstract type redefinition", node->base);
|
error_handling::HandleTypecheckError("Can't define function parameter type: abstract type redefinition", node->base);
|
||||||
|
|
@ -313,7 +311,9 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
||||||
|
|
||||||
auto requirements = typeclass_graph_.GetDependenciesSet(node->type->graph_id_);
|
auto requirements = typeclass_graph_.GetDependenciesSet(node->type->graph_id_);
|
||||||
|
|
||||||
current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier, node->type->type, requirements),
|
current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier,
|
||||||
|
node->type->graph_id_,
|
||||||
|
typeclass_graph_),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
if (maybe_internal_type.has_value()) {
|
if (maybe_internal_type.has_value()) {
|
||||||
|
|
@ -710,6 +710,8 @@ void TypeCheckVisitor::Visit(ReferenceExpression* node) {
|
||||||
context_manager_.GetValueType(current_type_)); // ??
|
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) {
|
void TypeCheckVisitor::Visit(AccessExpression* node) {
|
||||||
Visitor::Visit(node->id);
|
Visitor::Visit(node->id);
|
||||||
if (!context_manager_.EqualValues(internal_to_abstract_type_.at(info::type::InternalType::Int), current_type_)) {
|
if (!context_manager_.EqualValues(internal_to_abstract_type_.at(info::type::InternalType::Int), current_type_)) {
|
||||||
|
|
@ -718,14 +720,20 @@ void TypeCheckVisitor::Visit(AccessExpression* node) {
|
||||||
|
|
||||||
Visitor::Visit(node->name.get());
|
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()) {
|
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);
|
error_handling::HandleTypecheckError("Access type is not array", node->base);
|
||||||
// TODO: redifinitions for other types and tuples (with const index) ??
|
|
||||||
}
|
}
|
||||||
|
|
||||||
current_type_ = maybe_type_value.value()->GetElementsType();
|
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Char);
|
||||||
|
node->is_string_access_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
node->base.type_ = current_type_;
|
node->base.type_ = current_type_;
|
||||||
}
|
}
|
||||||
|
|
@ -1643,22 +1651,16 @@ std::optional<FunctionDeclaration*>
|
||||||
bool is_method) {
|
bool is_method) {
|
||||||
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
||||||
|
|
||||||
auto maybe_typeclass_graph_id = typeclass_graph_.FindFunctionTypeclass(node->name);
|
utils::IdType graph_id = abstract_type_info->GetGraphId();
|
||||||
if (!maybe_typeclass_graph_id.has_value()) {
|
|
||||||
|
if (!typeclass_graph_.IsFunctionInVertex(node->name, graph_id)) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto maybe_typeclass_function_info = typeclass_graph_.GetFunctionInfo(node->name,
|
auto maybe_typeclass_function_info = typeclass_graph_.GetFunctionInfo(node->name, graph_id);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!maybe_typeclass_function_info.has_value()) {
|
if (!maybe_typeclass_function_info.has_value()) {
|
||||||
error_handling::HandleInternalError("Typeclass function info found, but typeclass id not found (abstract type)",
|
error_handling::HandleTypecheckError("Function not present in typeclass (abstract type)", node->base);
|
||||||
"TypeCheckVisitor.FindAbstractTypeTypeclassFunctionAndUpdate",
|
|
||||||
&node->base);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check that const functions not called on var expressions ??
|
// 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);
|
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
|
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;
|
maybe_function_declaration = maybe_typeclass_function_info.value()->declaration;
|
||||||
|
|
||||||
return maybe_function_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<TypeclassGraph::FunctionInfo*> TypeclassGraph::GetFunctionInfo(const std::string& name,
|
||||||
std::optional<utils::IdType> vertex_id) {
|
std::optional<utils::IdType> vertex_id) {
|
||||||
if (vertex_id.has_value()) {
|
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);
|
auto maybe_function_typeclass_id = FindFunctionTypeclass(name);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
namespace info::type {
|
namespace info::type {
|
||||||
|
|
||||||
std::optional<utils::IdType> AbstractType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
|
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()) {
|
if (type_iter != context.end()) {
|
||||||
return type_iter->second;
|
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 {
|
bool AbstractType::Same(const AbstractType& type) const {
|
||||||
return name_ == type.name_;
|
return graph_id_ == type.graph_id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AbstractType::operator<(const AbstractType& type) const {
|
bool AbstractType::operator<(const AbstractType& type) const { // TODO: cache DependenciesSet
|
||||||
for (auto& graph_id : requirement_graph_ids_) {
|
auto requirement_graph_ids = typeclass_graph_.GetDependenciesSet(graph_id_);
|
||||||
if (type.requirement_graph_ids_.count(graph_id) == 0) {
|
auto other_requirement_graph_ids = type.typeclass_graph_.GetDependenciesSet(type.graph_id_);
|
||||||
|
|
||||||
|
for (auto& graph_id : requirement_graph_ids) {
|
||||||
|
if (other_requirement_graph_ids.count(graph_id) == 0) {
|
||||||
return false;
|
return 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(">=");
|
|
||||||
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("div");
|
||||||
builtin_functions.insert("mod");
|
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("||");
|
|
||||||
builtin_functions.insert("size");
|
builtin_functions.insert("size");
|
||||||
builtin_functions.insert("random");
|
builtin_functions.insert("random");
|
||||||
builtin_functions.insert("print");
|
builtin_functions.insert("print");
|
||||||
builtin_functions.insert("scan");
|
builtin_functions.insert("scan");
|
||||||
builtin_functions.insert("zero");
|
builtin_functions.insert("zero");
|
||||||
builtin_functions.insert("one");
|
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;
|
return builtin_functions.count(name) != 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
// for clangd
|
// for clangd
|
||||||
#include "../include/values.hpp"
|
#include "../include/values.hpp"
|
||||||
|
#include "../include/error_handling.hpp"
|
||||||
|
|
||||||
namespace info::value {
|
namespace info::value {
|
||||||
|
|
||||||
|
|
@ -12,7 +15,7 @@ bool InternalValue::Same(const InternalValue& other_value) const {
|
||||||
case 0:
|
case 0:
|
||||||
return std::get<double>(value) == std::get<double>(other_value.value);
|
return std::get<double>(value) == std::get<double>(other_value.value);
|
||||||
case 1:
|
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:
|
case 2:
|
||||||
return std::get<std::string>(value) == std::get<std::string>(other_value.value);
|
return std::get<std::string>(value) == std::get<std::string>(other_value.value);
|
||||||
case 3:
|
case 3:
|
||||||
|
|
@ -34,6 +37,10 @@ std::optional<utils::IdType> InternalValue::GetFieldValue(const std::string&) co
|
||||||
return std::nullopt;
|
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 {
|
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;
|
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 {
|
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);
|
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 {
|
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);
|
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 {
|
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;
|
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 {
|
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;
|
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 {
|
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;
|
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 {
|
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;
|
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
|
}; // namespace info::value
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
basic (Float : #Ord #Div)
|
basic (Float : #Ord #Div #Show)
|
||||||
basic (Int : #Ord #IDiv)
|
basic (Int : #Ord #IDiv #Show)
|
||||||
basic (String : #Ord)
|
basic (String : #Ord #Show #CharContainer)
|
||||||
basic (Char : #Ord #Enum)
|
basic (Char : #Ord #Show)
|
||||||
basic (Bool : #Ord)
|
basic (Bool : #Ord #Show)
|
||||||
basic Unit
|
basic (Unit : #Show)
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
@ -35,6 +35,12 @@ def ( || ) : x y =
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
typeclass CharContainer =
|
||||||
|
& var size : -> Int
|
||||||
|
& var at : Int -> Char
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
typeclass Move =
|
typeclass Move =
|
||||||
& var ( <- ) : Move -> Unit // TODO
|
& var ( <- ) : Move -> Unit // TODO
|
||||||
|
|
||||||
|
|
@ -142,11 +148,11 @@ namespace var Ord {
|
||||||
typeclass Show =
|
typeclass Show =
|
||||||
& var show : -> String
|
& var show : -> String
|
||||||
|
|
||||||
typeclass Read =
|
// typeclass Read = // TODO
|
||||||
& var read : String -> Read
|
// & var read : String -> Read
|
||||||
|
|
||||||
typeclass DebugShow =
|
// typeclass DebugShow = // TODO
|
||||||
& debug_show : -> String
|
// & debug_show : -> String
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
@ -171,6 +177,12 @@ typeclass Enum =
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
decl print : String -> Unit
|
||||||
|
decl scan : -> String
|
||||||
|
decl random : -> Int // TODO
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
// // bad
|
// // bad
|
||||||
// typeclass Functor 'A =
|
// typeclass Functor 'A =
|
||||||
// & fmap 'B ('F : (#Functor 'B)) : ('A -> 'B) -> Functor -> 'F
|
// & fmap 'B ('F : (#Functor 'B)) : ('A -> 'B) -> Functor -> 'F
|
||||||
|
|
@ -189,22 +201,21 @@ decl ( -- ) : Int -> Int -> Int_0
|
||||||
def ( -- ) : begin end = {
|
def ( -- ) : begin end = {
|
||||||
var current = begin
|
var current = begin
|
||||||
return (while current < end do {
|
return (while current < end do {
|
||||||
; current += 1
|
//; current += 1
|
||||||
bring current - 1
|
//bring current - 1
|
||||||
|
bring 1
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
decl print : String -> Unit
|
decl func : String -> Int -> Int
|
||||||
decl scan : -> String
|
def func : s i = {
|
||||||
|
|
||||||
decl func : String -> Int
|
|
||||||
def func : s = {
|
|
||||||
; print: s
|
; print: s
|
||||||
|
; print: (i.show:)
|
||||||
return 5
|
return 5
|
||||||
}
|
}
|
||||||
|
|
||||||
exec main {
|
exec main {
|
||||||
for i in 0--9 do func: "abacaba"
|
for i in 0--9 do func: "abacaba" i
|
||||||
; print: ({
|
; print: ({
|
||||||
if true then bring scan: else { ; print: "aaa" }
|
if true then bring scan: else { ; print: "aaa" }
|
||||||
bring "nothing"
|
bring "nothing"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue