Merge pull request 'fixes' (#2) from dev into main

Reviewed-on: https://codeberg.org/ProgramSnail/lang-interpreter/pulls/2
This commit is contained in:
ProgramSnail 2023-05-23 08:55:10 +00:00
commit e48b6ec556
20 changed files with 476 additions and 164 deletions

View file

@ -31,6 +31,11 @@ public:
};
void ExecutePartition(interpreter::tokens::PartitionStatement* partition) {
for (size_t i = 0; i < info::type::InternalTypesCount; ++i) {
info::type::InternalType type = static_cast<info::type::InternalType>(i);
std::string type_name = info::type::ToString(type);
context_manager_.DefineLocalType(type_name, global_info_.FindAbstractType(type_name).value()->node->type->graph_id_);
}
Visit(partition);
}

View file

@ -93,8 +93,6 @@ public:
std::optional<utils::IdType> FindLocalTypeId(const std::string& type);
std::optional<utils::IdType> FindAbstractTypeId(const std::string& abstract_type);
std::optional<utils::IdType> FindTypeclassId(const std::string& typeclass);
std::optional<utils::IdType> FindConstructorId(const std::optional<std::vector<std::string>>& path,
@ -164,14 +162,6 @@ public:
return global_info_.GetTypeInfo<T>(id.value());
}
std::optional<definition::AbstractType*> FindAbstractType(const std::string& abstract_type) {
std::optional<utils::IdType> id = FindAbstractTypeId(abstract_type);
if (!id.has_value()) {
return std::nullopt;
}
return &global_info_.GetAbstractTypeInfo(id.value());
}
std::optional<definition::Typeclass*> FindTypeclass(const std::string& typeclass) {
std::optional<utils::IdType> id = FindTypeclassId(typeclass);
if (!id.has_value()) {
@ -368,6 +358,16 @@ public:
// function declarations & definitions should be added latter
std::optional<utils::IdType> AddAnnotatedTypeToGraph(interpreter::tokens::AnnotatedType* node);
std::optional<utils::IdType> FindAbstractTypeId(const std::string& abstract_type);
std::optional<definition::AbstractType*> FindAbstractType(const std::string& abstract_type) {
std::optional<utils::IdType> id = FindAbstractTypeId(abstract_type);
if (!id.has_value()) {
return std::nullopt;
}
return &GetAbstractTypeInfo(id.value());
}
private:
void CollectFunctionInfo(
utils::IdType current_namespace,

View file

@ -498,7 +498,7 @@ struct ReferenceExpression {
BaseNode base;
utils::ReferenceModifier reference;
std::unique_ptr<ScopedStatement> expression;
SubExpressionToken expression;
};
struct AccessExpression {
@ -654,6 +654,7 @@ struct TypeExpression {
ParametrizedType type;
std::optional<size_t> array_size; // if array; 0 - dynamic size
bool is_optional = false; // for optionals
std::optional<utils::IdType> type_id_;
std::optional<utils::IdType> constructor_id_;

View file

@ -27,7 +27,7 @@ public:
// init internal type abstrac types
for (size_t i = 0; i < info::type::InternalTypesCount; ++i) {
info::type::InternalType type = static_cast<info::type::InternalType>(i);
Visit(namespace_visitor_.FindAbstractType(info::type::ToString(type)).value()->node);
Visit(global_info_.FindAbstractType(info::type::ToString(type)).value()->node);
}
Visit(source_file);
@ -210,7 +210,10 @@ private:
}
void VisitDefinedType(info::definition::AnyType* defined_type,
const std::unordered_map<std::string, utils::IdType>& context) {
const std::unordered_map<std::string, utils::IdType>& context,
utils::ValueType modifier) {
context_manager_.EnterContext();
AddTypeParameterLocalTypes(defined_type);
Visitor::Visit(defined_type->node->value);
current_type_ = TypeInContext(current_type_, context);
current_type_ =
@ -218,7 +221,20 @@ private:
current_type_,
defined_type->modifier,
context_manager_.GetValueManager()),
utils::ValueType::Tmp);
modifier);
context_manager_.ExitContext();
}
void AddTypeParameterLocalTypes(info::definition::AnyType* type_info) {
for (auto& parameter : type_info->node->definition->parameters) {
context_manager_.DefineLocalType(
parameter->type,
context_manager_.AddValue(
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
parameter->graph_id_,
typeclass_graph_),
utils::ValueType::Tmp));
}
}
private:

View file

@ -43,7 +43,7 @@ public:
return graph_id == graph_id_ || typeclass_graph_.GetDependenciesSet(graph_id_).count(graph_id) != 0;
}
std::string ToString() {
std::string ToString() const {
return "Abstract " + std::to_string(graph_id_);
}
private:
@ -81,7 +81,7 @@ public:
return class_modifier_;
}
std::string ToString() {
std::string ToString() const {
return "Defined";
}
private:
@ -178,7 +178,7 @@ public:
return fields_;
}
std::string ToString();
std::string ToString() const;
private:
std::optional<std::string> name_;
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields_;
@ -209,7 +209,7 @@ public:
current_constructor_ = constructor;
}
std::string ToString();
std::string ToString() const;
private:
std::optional<std::string> name_;
std::vector<TupleType> constructors_;
@ -231,7 +231,7 @@ public:
std::optional<utils::IdType> GetFieldType(const std::string& name,
const std::unordered_set<utils::IdType>& type_namespaces) const;
std::string ToString();
std::string ToString() const;
private:
utils::IdType type_;
TypeManager* type_manager_ = nullptr;
@ -243,7 +243,11 @@ public:
ReferenceToType(const std::vector<utils::ReferenceModifier>& references,
utils::IdType type,
TypeManager* type_manager)
: references_(references), type_(type), type_manager_(type_manager) {}
: references_(references), type_(type), type_manager_(type_manager) {
if (references.empty()) {
error_handling::HandleInternalError("ReferenceToType with 0 references", "Type.ReferenceToType", std::nullopt);
}
}
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
bool Same(const ReferenceToType& type) const;
@ -253,7 +257,7 @@ public:
std::optional<utils::IdType> GetFieldType(const std::string& name,
const std::unordered_set<utils::IdType>& type_namespaces) const;
std::string ToString();
std::string ToString() const;
private:
std::vector<utils::ReferenceModifier> references_;
utils::IdType type_;
@ -278,7 +282,7 @@ public:
std::optional<utils::IdType> GetFieldType(const std::string& name,
const std::unordered_set<utils::IdType>& type_namespaces) const;
std::string ToString();
std::string ToString() const;
private:
std::vector<utils::IdType> argument_types_;
utils::IdType return_type_;
@ -305,7 +309,7 @@ public:
return elements_type_;
}
std::string ToString();
std::string ToString() const;
private:
size_t size_; // = 0 for dynamic
utils::IdType elements_type_;
@ -339,7 +343,7 @@ public:
return type_;
}
std::string ToString();
std::string ToString() const;
private:
std::variant<AbstractType,
DefinedType,

@ -1 +1 @@
Subproject commit ddb08e9b65123324800d1126d38764764363c0e5
Subproject commit e4696019cf4ec08e4d2c707297887ed9bc359499

View file

@ -53,19 +53,11 @@ void BuildVisitor::Visit(Namespace* node) {
auto parse_node = current_node_;
size_t child_count = parse_node.ChildCount();
if (child_count > 3) { // "namespace", ["var"/"const",] type, scope
std::string modifier = parse_node.NthChild(1).GetValue();
if (modifier == "const") {
node->modifier = utils::ClassInternalsModifier::Const;
} else if (modifier == "var") {
node->modifier = utils::ClassInternalsModifier::Var;
} else {
error_handling::HandleInternalError("Can't parse namespace modifier",
"BuildVisitor.Namespace",
&node->base);
}
std::string modifier = parse_node.NthChild(1).GetValue();
if (modifier == "const") {
node->modifier = utils::ClassInternalsModifier::Const;
} else if (modifier == "var") {
node->modifier = utils::ClassInternalsModifier::Var;
} else {
node->modifier = utils::ClassInternalsModifier::Static;
}
@ -932,8 +924,7 @@ void BuildVisitor::Visit(ReferenceExpression* node) {
}
current_node_ = parse_node.ChildByFieldName("expression");
node->expression = std::make_unique<ScopedStatement>();
Visit(node->expression.get());
Visit(node->expression);
current_node_ = parse_node;
}
@ -1061,7 +1052,8 @@ void BuildVisitor::Visit(TypeConstructorParameter* node) {
size_t child_count = parse_node.NamedChildCount();
if (child_count > 1) {
node->name = parse_node.ChildByFieldName("name").GetValue();
current_node_ = parse_node.ChildByFieldName("name");
node->name = current_node_.GetValue();
std::string assignment_modifier = current_node_.NextSibling().GetValue();
if (assignment_modifier == "=") {
@ -1380,17 +1372,50 @@ void BuildVisitor::Visit(TypeExpression* node) {
Visit(&node->type);
++excluded_child_count;
current_node_ = current_node_.NextSibling();
auto suffix_node1 = current_node_.NextSibling();
if (!current_node_.IsNull()) {
current_node_ = current_node_.NextSibling();
if (!current_node_.IsNull()) {
NumberLiteral literal;
Visit(&literal);
node->array_size = literal.value;
++excluded_child_count;
// TODO: better structure // TODO: check
if (!suffix_node1.IsNull()) {
auto suffix_node2 = suffix_node1.NextSibling();
if (!suffix_node2.IsNull()) {
auto suffix_node3 = suffix_node2.NextSibling();
if (!suffix_node3.IsNull()) {
current_node_ = suffix_node2;
NumberLiteral literal;
Visit(&literal);
node->array_size = literal.value;
++excluded_child_count;
node->is_optional = true;
} else {
if (suffix_node1.GetValue() == "_" && suffix_node2.GetValue() == "!") {
node->array_size = 0;
node->is_optional = true;
} else if (suffix_node1.GetValue() == "_") {
current_node_ = suffix_node2;
NumberLiteral literal;
Visit(&literal);
node->array_size = literal.value;
++excluded_child_count;
} else {
error_handling::HandleInternalError("Undefined suffix (2 elements)",
"BuildVisitor.TypeExpression",
std::nullopt);
}
}
} else {
node->array_size = 0;
if (suffix_node1.GetValue() == "_") {
node->array_size = 0;
} else if (suffix_node1.GetValue() == "!") {
node->is_optional = true;
} else {
error_handling::HandleInternalError("Undefined suffix (1 element)",
"BuildVisitor.TypeExpression",
std::nullopt);
}
}
}

View file

@ -386,7 +386,7 @@ void ExecuteVisitor::Visit(LoopControlExpression& node) {
void ExecuteVisitor::Visit(ReferenceExpression* node) {
// TODO: check, that there is no references to "Tmp"??
Visit(node->expression.get());
Visitor::Visit(node->expression);
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
@ -748,7 +748,7 @@ void ExecuteVisitor::Visit(TupleName* node) {
std::optional<info::value::TupleValue*> maybe_tuple_value = context_manager_.GetValue<info::value::TupleValue>(value);
if (maybe_tuple_value.has_value()) {
if (!maybe_tuple_value.has_value()) {
error_handling::HandleRuntimeError("Mismatched value types in tuple variable definition", node->base);
}

View file

@ -235,7 +235,7 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& a
// error_handling::HandleNamesError("Can't redefine basic type as abstract type", base_node);
// }
if (FindAbstractType(abstract_type).has_value()) {
if (global_info_.FindAbstractType(abstract_type).has_value()) {
error_handling::HandleNamesError("More then one abstract type with the same name in namespace", base_node);
}
@ -385,16 +385,6 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindLocalTypeId(const
return std::nullopt;
}
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindAbstractTypeId(const std::string& abstract_type) {
auto abstract_type_id_iter = global_info_.name_to_abstract_type_.find(abstract_type);
if (abstract_type_id_iter != global_info_.name_to_abstract_type_.end()) {
return abstract_type_id_iter->second;
}
return std::nullopt;
}
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeclassId(const std::string& typeclass) {
auto typeclass_id_iter = global_info_.name_to_typeclass_.find(typeclass);
@ -578,6 +568,16 @@ std::optional<utils::IdType> GlobalInfo::AddAnnotatedTypeToGraph(interpreter::to
TypeclassGraph::Modifier::Type);
}
std::optional<utils::IdType> GlobalInfo::FindAbstractTypeId(const std::string& abstract_type) {
auto abstract_type_id_iter = name_to_abstract_type_.find(abstract_type);
if (abstract_type_id_iter != name_to_abstract_type_.end()) {
return abstract_type_id_iter->second;
}
return std::nullopt;
}
void GlobalInfo::CollectFunctionInfo(
utils::IdType current_namespace,
utils::ClassInternalsModifier modifier,

View file

@ -134,7 +134,7 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) {
if (maybe_type_namespace.has_value()) {
info::definition::Namespace* type_namespace = maybe_type_namespace.value();
for (ssize_t i = (ssize_t)node->path.size(); i >= 0; --i) {
for (ssize_t i = (ssize_t)node->path.size() - 1; i >= 0; --i) {
info::definition::Namespace* parent_namespace = &global_info_.GetNamespaceInfo(type_namespace->parent_namespace);
auto type_iter = parent_namespace->types.find(type_namespace->type_name);

View file

@ -59,9 +59,17 @@ int main(int argc, char** argv) { // TODO, only test version
// std::cout << "\n---------------------------------- Untyped -------------------------------------\n\n";
// print_visitor.VisitSourceFile(source_file.get());
find_symbols_visitor.VisitSourceFile(source_file.get());
link_symbols_visitor.VisitSourceFile(source_file.get());
type_check_visitor.VisitSourceFile(source_file.get());
try {
find_symbols_visitor.VisitSourceFile(source_file.get());
} catch (...) { error_handling::HandleInternalError("find_symbols_visitor exception", "main", std::nullopt); }
try {
link_symbols_visitor.VisitSourceFile(source_file.get());
} catch (...) { error_handling::HandleInternalError("link_symbols_visitor exception", "main", std::nullopt); }
try {
type_check_visitor.VisitSourceFile(source_file.get());
} catch (...) { error_handling::HandleInternalError("type_check_visitor exception", "main", std::nullopt); }
std::optional<utils::IdType> maybe_main_partition_id = global_info.FindPartition({"main"});
@ -72,13 +80,15 @@ int main(int argc, char** argv) { // TODO, only test version
const info::GlobalInfo::PartitionInfo& main_partition =
global_info.GetPartitionInfo(maybe_main_partition_id.value());
std::cout << "\n---------------------------------- Execution -------------------------------------\n\n";
// std::cout << "\n---------------------------------- Execution -------------------------------------\n\n";
interpreter::ExecuteVisitor execute_visitor(global_info,
type_context_manager,
context_manager);
execute_visitor.ExecutePartition(main_partition.node);
try {
execute_visitor.ExecutePartition(main_partition.node);
} catch (...) { error_handling::HandleInternalError("execute_visitor exception", "main", std::nullopt); }
// std::cout << "\n---------------------------------- Typed -------------------------------------\n\n";
// typed_print_visitor.VisitSourceFile(source_file.get());

View file

@ -398,7 +398,7 @@ void PrintVisitor::Visit(ReferenceExpression* node) {
break;
}
out_ << "] (";
Visit(node->expression.get());
Visitor::Visit(node->expression);
out_ << ')';
}
@ -654,10 +654,14 @@ void PrintVisitor::Visit(VariantType* node) {
}
void PrintVisitor::Visit(TypeExpression* node) {
out_ << "[TypeExpression ";
out_ << "[TypeExpression";
if (node->array_size.has_value()) {
out_ << "[array size: " << node->array_size.value() << ']';
out_ << " [array size: " << node->array_size.value() << ']';
}
if (node->is_optional) {
out_ << " [optional]";
}
out_ << "] (";

View file

@ -58,13 +58,11 @@ void TypeCheckVisitor::Visit(Namespace* node) {
info::definition::AnyType* type_info = maybe_type_info.value();
Visitor::Visit(type_info->node->value);
utils::IdType type = context_manager_.AddValue(
info::type::DefinedType(node->link_type_id_.value(),
current_type_,
type_info->modifier,
context_manager_.GetValueManager()),
ClassInternalsModifierToValueType(node->modifier));
// make parameter local types
VisitDefinedType(type_info, {}, ClassInternalsModifierToValueType(node->modifier));
utils::IdType type = current_type_;
if (node->modifier != utils::ClassInternalsModifier::Static) {
context_manager_.DefineVariable(utils::ClassInternalVarName, type);
@ -248,9 +246,9 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
if (!returned_type_.has_value()) {
returned_type_ = current_type_;
}
if (!context_manager_.EqualValues(returned_type, returned_type_.value())) {
error_handling::DebugPrint(context_manager_.GetAnyValue(returned_type)->ToString());
error_handling::DebugPrint(context_manager_.GetAnyValue(returned_type_.value())->ToString());
// error_handling::DebugPrint(context_manager_.GetAnyValue(returned_type)->ToString() + " : " + context_manager_.GetAnyValue(returned_type_.value())->ToString());
error_handling::HandleTypecheckError("Wrong function return type", node->base);
}
returned_type_ = std::nullopt;
@ -284,7 +282,7 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) {
auto function_iter = type_functions.find(function.first);
if (function_iter == type_functions.end() || !global_info_.GetFunctionInfo(function_iter->second).definition.has_value()) {
error_handling::HandleTypecheckError("Type is not satisfy typeclass requirements: " + function.first + " is not defined", node->base);
error_handling::HandleTypecheckError("Type not define all required functions: " + function.first + " is not defined", node->base);
}
}
@ -437,9 +435,7 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name
}
}
Visitor::Visit(type_info.node->value);
current_type_ = TypeInContext(current_type_, context);
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp);
VisitDefinedType(&type_info, context, utils::ValueType::Tmp);
node->base.type_ = current_type_;
}
@ -698,7 +694,7 @@ void TypeCheckVisitor::Visit(LoopControlExpression&) { // enum
// Operators
void TypeCheckVisitor::Visit(ReferenceExpression* node) {
Visit(node->expression.get());
Visitor::Visit(node->expression);
current_type_ = context_manager_.AddValue(
info::type::ReferenceToType({node->reference},
@ -985,6 +981,8 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
}
}
// TODO: replace with VisitDefinedType ??
AddTypeParameterLocalTypes(&type_info);
Visitor::Visit(type_info.node->value);
std::optional<info::type::VariantType*> maybe_variant_type =
@ -1281,35 +1279,24 @@ void TypeCheckVisitor::Visit(TypeExpression* node) {
std::unordered_map<std::string, utils::IdType> context;
CollectTypeExpressionContext(*node, context);
// TODO: -------- remove, unneeded ------
// auto maybe_internal_type = info::type::ToInternalType(node->type.type);
//
// if (maybe_internal_type.has_value()) { // TODO: ???
// // checks made in link_symbols_visitor
// current_type_ =
// context_manager_.AddValue<info::type::InternalType>(
// maybe_internal_type.value(),
// utils::ValueType::Tmp);
// } else {
std::optional<utils::IdType> maybe_local_abstract_type =
context_manager_.FindLocalType(node->type.type);
if (node->path.empty() && maybe_local_abstract_type.has_value()) {
current_type_ = maybe_local_abstract_type.value();
} else if (node->type.type_id_.has_value()) { // TODO: check that names are different (always true ??)
std::optional<info::definition::AnyType*> maybe_type_info =
global_info_.GetTypeInfo<info::definition::AnyType>(node->type.type_id_.value());
std::optional<utils::IdType> maybe_local_abstract_type =
context_manager_.FindLocalType(node->type.type);
if (node->path.empty() && maybe_local_abstract_type.has_value()) {
current_type_ = maybe_local_abstract_type.value();
} else if (node->type.type_id_.has_value()) { // TODO: check that names are different (always true ??)
std::optional<info::definition::AnyType*> maybe_type_info =
global_info_.GetTypeInfo<info::definition::AnyType>(node->type.type_id_.value());
if (!maybe_type_info.has_value()) {
error_handling::HandleInternalError("No AnyType found (alias types, ... not implemented)",
"TypeCheckVisitor.TypeExpression",
&node->base);
}
VisitDefinedType(maybe_type_info.value(), context);
} else {
error_handling::HandleTypecheckError("Type not found", node->base);
if (!maybe_type_info.has_value()) {
error_handling::HandleInternalError("No AnyType found (alias types, ... not implemented)",
"TypeCheckVisitor.TypeExpression",
&node->base);
}
// }
VisitDefinedType(maybe_type_info.value(), context, utils::ValueType::Tmp);
} else {
error_handling::HandleTypecheckError("Type not found", node->base);
}
if (node->array_size.has_value()) {
current_type_ = context_manager_.AddValue(
@ -1317,15 +1304,23 @@ void TypeCheckVisitor::Visit(TypeExpression* node) {
utils::ValueType::Tmp);
}
if (node->is_optional) {
current_type_ = context_manager_.AddValue(
info::type::OptionalType(current_type_, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
}
node->base.type_ = current_type_;
}
void TypeCheckVisitor::Visit(ExtendedScopedAnyType* node) {
Visitor::Visit(node->type);
current_type_ = context_manager_.AddValue(
info::type::ReferenceToType(node->references, current_type_, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
if (!node->references.empty()) {
current_type_ = context_manager_.AddValue(
info::type::ReferenceToType(node->references, current_type_, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
}
node->base.type_ = current_type_;
}
@ -1433,7 +1428,10 @@ void TypeCheckVisitor::CollectTypeExpressionContext(const TypeExpression& type_e
utils::IdType TypeCheckVisitor::TypeInContext(utils::IdType type,
const std::unordered_map<std::string, utils::IdType>& context) {
info::type::Type type_in_context = *context_manager_.GetAnyValue(type);
type_in_context.InContext(context);
auto maybe_new_type = type_in_context.InContext(context);
if (maybe_new_type.has_value()) {
return maybe_new_type.value();
}
return context_manager_.AddValue(std::move(type_in_context), utils::ValueType::Tmp);
}
@ -1544,7 +1542,7 @@ std::optional<FunctionDeclaration*>
&node->base);
}
VisitDefinedType(maybe_type_info.value(), context);
VisitDefinedType(maybe_type_info.value(), context, utils::ValueType::Tmp);
maybe_function_declaration =
FindDefinedTypeFunctionAndUpdate(node,
maybe_type_info.value(),
@ -1584,7 +1582,7 @@ std::optional<FunctionDeclaration*> TypeCheckVisitor::FindFunctionAndUpdate(Func
&node->base);
}
VisitDefinedType(maybe_type_info.value(), {}); // TODO: context ??
VisitDefinedType(maybe_type_info.value(), {}, utils::ValueType::Tmp); // TODO: context ??
maybe_function_declaration =
FindDefinedTypeFunctionAndUpdate(node,
maybe_type_info.value(),

View file

@ -557,7 +557,7 @@ void TypedPrintVisitor::Visit(ReferenceExpression* node) {
break;
}
out_ << "] (";
Visit(node->expression.get());
Visitor::Visit(node->expression);
out_ << ')';
}
@ -920,9 +920,13 @@ void TypedPrintVisitor::Visit(TypeExpression* node) {
out_ << context_manager_.GetAnyValue(node->base.type_.value())->GetTypeName();
}
out_ << ") ";
out_ << ")";
if (node->array_size.has_value()) {
out_ << "[array size: " << node->array_size.value() << ']';
out_ << " [array size: " << node->array_size.value() << ']';
}
if (node->is_optional) {
out_ << " [optional]";
}
out_ << "] (";

View file

@ -120,13 +120,13 @@ std::optional<utils::IdType> TupleType::GetFieldType(const std::string& name,
return std::nullopt;
}
std::string TupleType::ToString() {
std::string TupleType::ToString() const {
std::string result;
result += "(";
for (auto& field : fields_) {
result += "& ";
result += " & ";
result += type_manager_->GetAnyValue(field.second)->ToString();
}
@ -185,7 +185,7 @@ std::optional<utils::IdType> VariantType::GetFieldType(const std::string& name,
return std::nullopt;
}
std::string VariantType::ToString() {
std::string VariantType::ToString() const {
std::string result;
result += "(";
@ -229,7 +229,7 @@ std::optional<utils::IdType> OptionalType::GetFieldType(const std::string&,
return std::nullopt;
}
std::string OptionalType::ToString() {
std::string OptionalType::ToString() const {
return "Optional " + type_manager_->GetAnyValue(type_)->ToString();
}
@ -263,7 +263,7 @@ std::optional<utils::IdType> ReferenceToType::GetFieldType(const std::string& na
}
std::string ReferenceToType::ToString() {
std::string ReferenceToType::ToString() const {
std::string result;
for (auto& reference : references_) {
@ -337,7 +337,7 @@ std::optional<utils::IdType> FunctionType::GetFieldType(const std::string&,
return std::nullopt;
}
std::string FunctionType::ToString() {
std::string FunctionType::ToString() const {
std::string result;
result += "(";
@ -387,7 +387,7 @@ std::optional<utils::IdType> ArrayType::GetFieldType(const std::string&,
return std::nullopt;
}
std::string ArrayType::ToString() {
std::string ArrayType::ToString() const {
return "Array (" + std::to_string(size_) + ") " + type_manager_->GetAnyValue(elements_type_)->ToString();
}
@ -554,7 +554,7 @@ std::string Type::GetTypeName() const {
return ""; // ??
}
std::string Type::ToString() {
std::string Type::ToString() const {
size_t index = type_.index();
switch (index) {
@ -562,7 +562,7 @@ std::string Type::ToString() {
return std::get<AbstractType>(type_).ToString();
case 1:
return std::get<DefinedType>(type_).ToString();
case 2:
case 2: // ??
return ::info::type::ToString(std::get<InternalType>(type_));
case 3:
return std::get<TupleType>(type_).ToString();

View file

@ -466,7 +466,7 @@ void Visitor::Visit(LoopControlExpression&) {} // enum
// Operators
void Visitor::Visit(ReferenceExpression* node) {
Visit(node->expression.get());
Visit(node->expression);
}
void Visitor::Visit(AccessExpression* node) {

View file

@ -9,13 +9,13 @@ def test_arrays = {
var arr6 <- String._new_array: 10
var arr6_reference = ^arr6
const elem1 = arr1`0
var elem2 = arr1`2
const ref1 = ^arr1`1
var ref2 = ^arr1`3
; arr1`1 = 123
; ~ref1 = arr1`2 // set value
; ref1 = ref2 // set pointer / reference
//
// const elem1 = arr1`0
// var elem2 = arr1`2
// const ref1 = ^arr1`1
// var ref2 = ^arr1`3
// ; arr1`1 = 123
//
// ; ~ref1 = arr1`2 // set value
// ; ref1 = ref2 // set pointer / reference
}

View file

@ -17,7 +17,7 @@ struct (Complex : #Value) =
struct Task =
& name : String
& duration : Float
& duration : Float!
class Employee =
& name : String

View file

@ -0,0 +1,188 @@
basic (Float : #Ord #Div #Str)
basic (Int : #Ord #IDiv #Str)
basic (String : #Ord #Str #CharContainer #Copy)
basic (Char : #Ord #Str #Copy)
basic (Bool : #Ord #Str #Copy)
basic (Unit : #Str #Copy)
//
decl not : Bool -> Bool
def not : x =
(match x with
| true -> false
| false -> true)
decl ( && ) : Bool -> Bool -> Bool
def ( && ) : x y =
match x with
| true -> (
match y with
| true -> true
| false -> false
)
| false -> false
decl ( || ) : Bool -> Bool -> Bool
def ( || ) : x y =
match x with
| true -> true
| false -> (
match y with
| true -> true
| false -> false
)
//
typeclass CharContainer =
& var size : -> Int
& var at : Int -> Char
//
typeclass Move = // TODO
& var ( <- ) : Move -> Unit
typeclass Copy =
& var ( = ) : Copy -> Unit
//
typeclass (Sum : #Copy) =
& var ( += ) : Sum -> Unit
& var ( -= ) : Sum -> Unit
& var ( + ) : Sum -> Sum
& var ( - ) : Sum -> Sum
& zero : -> Sum
namespace var Sum {
def ( + ) : x = {
var ans = self
; ans += x
return ans
}
def ( - ) : x = {
var ans = self
; ans -= x
return ans
}
}
typeclass (Mult : #Sum) =
& var ( *= ) : Mult -> Unit
& var ( * ) : Mult -> Mult
namespace var Mult {
def ( * ) : x = {
var ans = self
; ans *= x
return ans
}
}
typeclass (IDiv : #Mult) =
& var div : IDiv -> IDiv
& var mod : IDiv -> IDiv
namespace var IDiv {
def mod : x = self -. x * self.div: x
}
typeclass (Div : #Mult) =
& var ( /= ) : Div -> Unit
& var ( / ) : Div -> Div
namespace var Div {
def ( / ) : x = {
var ans = self
; ans /= x
return ans
}
}
//
typeclass Eq =
& var ( == ) : Eq -> Bool
& var ( != ) : Eq -> Bool
namespace var Eq {
def ( != ) : x = not: (self == x)
}
//
struct Order =
| EQ
| LT
| GT
typeclass (Ord : #Eq) =
& var compare : Ord -> Order
& var ( < ) : Ord -> Bool
& var ( >= ) : Ord -> Bool
& var ( > ) : Ord -> Bool
& var ( <= ) : Ord -> Bool
decl min ('A : #Ord) : 'A -> 'A -> 'A
def min : x y = if x < y then x else y
decl max ('A : #Ord) : 'A -> 'A -> 'A
def max : x y = if x < y then y else x
namespace var Ord {
def compare : x =
if self == x then $EQ
elif self < x then $LT
else $GT
def ( >= ) : x = not: (self < x)
def ( > ) : x = x < self
def ( <= ) : x = not: (x < self)
}
//
typeclass Show =
& var show : -> String
typeclass Read =
& read : String -> Read
typeclass (Str : #Show #Read)
// typeclass DebugShow = // TODO
// & debug_show : -> String
//
typeclass Default =
& default : -> Default
//
typeclass Bounded =
& min_bound : -> Bounded
& max_bound : -> Bounded
& var is_max_bound : -> Bool
& var is_min_bound : -> Bool
//
typeclass Enum =
& var succ : -> (Optional Enum)
& var pred : -> (Optional Enum)
& to_enum : Int -> Enum
& var from_enum : -> Int
//
namespace IO {
decl print : String -> Unit
decl scan : -> String
decl random : -> Int // TODO
}
//

View file

@ -41,8 +41,8 @@ typeclass CharContainer =
//
typeclass Move =
& var ( <- ) : Move -> Unit // TODO
typeclass Move = // TODO
& var ( <- ) : Move -> Unit
typeclass Copy =
& var ( = ) : Copy -> Unit
@ -149,7 +149,7 @@ typeclass Show =
& var show : -> String
typeclass Read =
& var read : String -> Read
& read : String -> Read
typeclass (Str : #Show #Read)
@ -179,9 +179,11 @@ typeclass Enum =
//
decl print : String -> Unit
decl scan : -> String
decl random : -> Int // TODO
namespace IO {
decl print : String -> Unit
decl scan : -> String
decl random : -> Int // TODO
}
//
@ -199,9 +201,6 @@ decl random : -> Int // TODO
//
decl ret_one : -> Int
def ret_one = 1
decl ( -- ) : Int -> Int -> Int_0
def ( -- ) : begin end = {
var current = begin
@ -211,19 +210,77 @@ def ( -- ) : begin end = {
})
}
decl func : String -> Int -> Int
def func : s i = {
; print: s
var x = s
; print: (i.show:)
return 5
}
// decl func : String -> Int -> Int
// def func : s i = {
// ; print: s
// var x = s
// ; print: (i.show:)
// return 5
// }
//
// exec main {
// for i in 0--19 do func: "a" (i * 2 +. 3)
// ; print: ({
// if true then bring scan: else { ; print: "aaa" }
// bring "nothing"
// ; print: "aaa"
// })
// }
decl scan_int : -> Int
def scan_int = Int.read: (IO.scan:)
decl print_int : Int -> Unit
def print_int : x = IO.print: (x.show:)
decl scan_anything ('A : #Read) : -> 'A
def scan_anything = 'A.read: (IO.scan:)
decl print_anything ('A : #Show) : 'A -> Unit
def print_anything : x = IO.print: (x.show:)
// decl sorted ('A : #Ord #Copy): 'A_0 -> Int -> 'A_0
// def sorted : a sz = {
// var a_copy = a
// if sz == 2 then {
// if a_copy`0 > a_copy`1 then {
// var x = a_copy`0
// a_copy`0 = a_copy`1
// a_copy`1 = x
// }
// return a_copy
// }
//
// var center = sz.div: 2
//
// var a_left = for i in 0--center do a`i
// var a_right = for i in center-sz do a`i
//
// return a_copy
// }
/*
struct Array 'A = & data : 'A_0
namespace Array {
decl of : 'A_0 -> Array
def of: x = $(Array 'A) & data = x
}*/
struct ThreeTuple = & String & String & String
decl scan_three_t : -> ThreeTuple
def scan_three_t = $ThreeTuple & IO.scan: & IO.scan: & IO.scan:
decl scan_three : -> (& String & String & String)
def scan_three = & IO.scan: & IO.scan: & IO.scan:
// var n = scan_anything Int:
// var a = $(Array Int) & data = (for _ in 0--n do scan_int:)
// ; print_anything Int: n
exec main {
for i in 0--19 do func: "a" (i * 2 +. 3)
; print: ({
if true then bring scan: else { ; print: "aaa" }
bring "nothing"
; print: "aaa"
})
var & a & b & c = scan_three_t:
; IO.print: b
var & d & e & f = scan_three:
; IO.print: e
}