bool literals, fixes

This commit is contained in:
ProgramSnail 2023-05-08 20:34:36 +03:00
parent b1aff1935d
commit d31979166e
24 changed files with 179 additions and 46 deletions

View file

@ -1531,6 +1531,13 @@ void BuildVisitor::Visit(UnitLiteral* node) {
SetPosition(node->base, current_node_);
}
void BuildVisitor::Visit(BoolLiteral* node) {
SetPosition(node->base, current_node_);
std::string literal = current_node_.GetValue();
node->value = (literal == "true"); // always "false" in other way
}
void BuildVisitor::Visit(Literal& node) {
auto parse_node = current_node_;
@ -1553,6 +1560,9 @@ void BuildVisitor::Visit(Literal& node) {
} else if (current_node_type == parser::tokens::UnitLiteral) {
node = std::make_unique<UnitLiteral>();
Visit(std::get<std::unique_ptr<UnitLiteral>>(node).get());
} else if (current_node_type == parser::tokens::BoolLiteral) {
node = std::make_unique<BoolLiteral>();
Visit(std::get<std::unique_ptr<BoolLiteral>>(node).get());
} else {
// error
}

View file

@ -73,12 +73,7 @@ void ExecuteVisitor::Visit(TypeclassDefinitionStatement* node) {
}
}
void ExecuteVisitor::Visit(ExecutableStatement* node) {
Visit(&node->name);
Visitor::Visit(node->value);
}
void ExecuteVisitor::Visit(TestStatement* node) {
void ExecuteVisitor::Visit(PartitionStatement* node) {
Visit(&node->name);
Visitor::Visit(node->value);
}
@ -391,5 +386,7 @@ void ExecuteVisitor::Visit(CharLiteral* node) {}
void ExecuteVisitor::Visit(UnitLiteral* node) {}
void ExecuteVisitor::Visit(BoolLiteral* node) {}
} // namespace interpreter

View file

@ -8,7 +8,7 @@ namespace interpreter {
// Namespaces, partitions -----------------
void FindSymbolsVisitor::Visit(Namespace* node) {
namespace_visitor_.AddEnterNamespace(node->type, node->modifier);
namespace_visitor_.AddEnterNamespace(node->type, node->modifier, node->base);
Visitor::Visit(&node->scope);
namespace_visitor_.ExitNamespace();
}

View file

@ -1,7 +1,10 @@
#include <variant>
// for clangd
#include "../include/global_info.hpp"
#include "../include/types.hpp"
#include "../include/error_handling.hpp"
#include <variant>
namespace info {
@ -15,7 +18,12 @@ void GlobalInfo::NamespaceVisitor::AddImport(definition::Import&& import_info,
}
void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
std::optional<utils::IsConstModifier> modifier) {
std::optional<utils::IsConstModifier> modifier,
const interpreter::tokens::BaseNode& base_node) {
if (type::ToInternalType(name).has_value()) {
error_handling::HandleTypecheckError("Can't define basic type namespace", base_node);
}
definition::Namespace* namespace_info = nullptr;
if (modifier.has_value()) {
if (modifier.value() == utils::IsConstModifier::Const) {
@ -122,6 +130,10 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDefinition(const std::str
utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type,
definition::Type&& type_info,
const interpreter::tokens::BaseNode& base_node) {
if (type::ToInternalType(type).has_value()) {
error_handling::HandleTypecheckError("Can't redefine basic type", base_node);
}
size_t id = 0;
auto type_id_iter = namespace_stack_.back()->types.find(type);
@ -181,6 +193,10 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type,
utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& abstract_type,
definition::AbstractType&& abstract_type_info,
const interpreter::tokens::BaseNode& base_node) {
if (type::ToInternalType(abstract_type).has_value()) {
error_handling::HandleTypecheckError("Can't redefine basic type as abstract type", base_node);
}
if (!FindAbstractType(abstract_type).has_value()) {
utils::IdType id = global_info_.abstract_types_.size();
global_info_.name_to_abstract_type_[abstract_type] = id;
@ -197,6 +213,10 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& a
utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& typeclass,
definition::Typeclass&& typeclass_info,
const interpreter::tokens::BaseNode& base_node) {
if (type::ToInternalType(typeclass).has_value()) {
error_handling::HandleTypecheckError("Can't redefine basic type as typeclass", base_node);
}
if (!FindTypeclass(typeclass).has_value()) {
size_t id = global_info_.typeclasses_.size();
global_info_.name_to_typeclass_[typeclass] = id;
@ -211,6 +231,10 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& type
utils::IdType GlobalInfo::NamespaceVisitor::AddConstructor(const std::string& constructor,
definition::Constructor&& constructor_info,
const interpreter::tokens::BaseNode& base_node) {
if (type::ToInternalType(constructor).has_value()) {
error_handling::HandleTypecheckError("Can't redefine basic type as constructor", base_node);
}
auto constructor_id_iter = namespace_stack_.back()->constructors.find(constructor);
if (constructor_id_iter == namespace_stack_.back()->constructors.end()) {

View file

@ -1,7 +1,9 @@
#include <optional>
// for clangd
#include "../include/link_symbols_visitor.hpp"
#include "../include/error_handling.hpp"
#include <optional>
#include "../include/types.hpp"
namespace interpreter {
@ -50,8 +52,20 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
node->type_id_ = namespace_visitor_.FindType(path, node->type.type);
node->constructor_id_ = namespace_visitor_.FindConstructor(path, node->type.type);
// internal type
if (info::type::ToInternalType(node->type.type).has_value()) {
if (!node->path.empty()) {
error_handling::HandleTypecheckError("Internal type is not in namespace", node->base);
}
if (!node->type.parameters.empty()) {
error_handling::HandleTypecheckError("Can't parametrize internal type", node->base);
}
return;
}
// abstract / basic / TODO: local abstract type
if (path.size() == 0 && namespace_visitor_.FindAbstractType(node->type.type).has_value()) { // TODO
// abstract / basic / TODO: local abstract type
return;
}

View file

@ -742,4 +742,8 @@ void PrintVisitor::Visit(UnitLiteral* node) {
out_ << "[Unit ()] ";
}
void PrintVisitor::Visit(BoolLiteral* node) {
out_ << "[Bool " << (node->value ? "true" : "false") << "] ";
}
} // namespace interpreter

View file

@ -765,7 +765,6 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
}
if (node->prefix.has_value()) {
if (std::holds_alternative<std::unique_ptr<SubExpressionToken>>(node->prefix.value())) {
Visitor::Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()));
@ -857,8 +856,8 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
//
if (function_declaration.argument_types.size() + 1 != node->arguments.size()) {
error_handling::HandleTypecheckError("Mismatched argument count in function call expression", node->base);
if (function_declaration.argument_types.size() != node->arguments.size() + 1) {
error_handling::HandleTypecheckError("Mismatched argument count in function call expression", node->base);
}
for (size_t i = 0; i < node->arguments.size(); ++i) {
Visitor::Visit(*function_declaration.argument_types[i]);
@ -1015,7 +1014,7 @@ void TypeCheckVisitor::Visit(ArrayExpression* node) {
}
}
if (node->elements.size() == 0) {
if (node->elements.empty()) {
error_handling::HandleInternalError("Element size is 0", "TypeCheckVisitor.ArrayExpression");
}
@ -1032,7 +1031,7 @@ void TypeCheckVisitor::Visit(PartitionName* node) {} // Handled in partition ( e
void TypeCheckVisitor::Visit(NameExpression* node) {
// TODO: move, etc.
if (node->names.size() == 0) {
if (node->names.empty()) {
error_handling::HandleInternalError("Name expression with zero names", "TypeCheckVisitor.NameExpression");
}
@ -1136,7 +1135,7 @@ void TypeCheckVisitor::Visit(VariantName* node) {
}
for (size_t i = 0; i < node->names.size(); ++i) {
if (maybe_type_value.value()->GetConstructors()[i].GetFields().size() == 0) {
if (maybe_type_value.value()->GetConstructors()[i].GetFields().empty()) {
current_type_ = context_manager_.AddType(
info::type::OptionalType(context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp), context_manager_.GetTypeManager()),
utils::IsConstModifierToValueType(is_const_definition_.value())); // TODO ??
@ -1254,27 +1253,36 @@ void TypeCheckVisitor::Visit(VariantType* node) {
node->base.type_ = current_type_;
}
// TODO: better function design
// TODO handle local abstract types, abstract types, aliases, etc.
void TypeCheckVisitor::Visit(TypeExpression* node) {
std::unordered_map<std::string, utils::IdType> context;
CollectTypeExpressionContext(*node, context);
std::optional<utils::IdType> maybe_local_abstract_type = context_manager_.GetLocalAbstractType(node->type.type);
if (node->path.size() == 0 && maybe_local_abstract_type.has_value()) {
current_type_ = maybe_local_abstract_type.value();
} else if (node->type.type_id_.has_value()) { // TODO: chack that names are different (always true ??)
auto maybe_internal_type = info::type::ToInternalType(node->type.type);
std::optional<info::definition::AnyType*> maybe_type_info =
namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(node->type.type_id_.value());
if (maybe_internal_type.has_value()) {
// checks made in link_symbols_visitor
if (!maybe_type_info.has_value()) { // TODO: add alias, abstract, ... types
error_handling::HandleInternalError("No AnyType found", "TypeCheckVisitor.TypeExpression");
}
Visitor::Visit(*maybe_type_info.value()->value);
current_type_ = TypeInContext(current_type_, context);
current_type_ = context_manager_.AddType<info::type::InternalType>(maybe_internal_type.value(), utils::ValueType::Tmp);
} else {
error_handling::HandleTypecheckError("Type not found", node->base);
std::optional<utils::IdType> maybe_local_abstract_type = context_manager_.GetLocalAbstractType(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: chack that names are different (always true ??)
std::optional<info::definition::AnyType*> maybe_type_info =
namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(node->type.type_id_.value());
if (!maybe_type_info.has_value()) { // TODO: add alias, abstract, ... types
error_handling::HandleInternalError("No AnyType found", "TypeCheckVisitor.TypeExpression");
}
Visitor::Visit(*maybe_type_info.value()->value);
current_type_ = TypeInContext(current_type_, context);
} else {
error_handling::HandleTypecheckError("Type not found", node->base);
}
}
if (node->array_size.has_value()) {
@ -1342,6 +1350,12 @@ void TypeCheckVisitor::Visit(UnitLiteral* node) {
node->base.type_ = current_type_;
}
void TypeCheckVisitor::Visit(BoolLiteral* node) {
current_type_ = context_manager_.AddType(info::type::InternalType::Bool, utils::ValueType::Tmp);
node->base.type_ = current_type_;
}
//
void TypeCheckVisitor::CollectTypeContext(const ParametrizedType& type,

View file

@ -1065,4 +1065,14 @@ void TypedPrintVisitor::Visit(UnitLiteral* node) {
out_ << ") ()] ";
}
void TypedPrintVisitor::Visit(BoolLiteral* node) {
out_ << "[bool : (";
if (node->base.type_.has_value()) {
out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName();
}
out_ << ") " << (node->value ? "true" : "false") << "] ";
}
} // namespace interpreter

View file

@ -285,6 +285,9 @@ void Visitor::Visit(Literal& node) {
case 4:
Visit(std::get<std::unique_ptr<UnitLiteral>>(node).get());
break;
case 5:
Visit(std::get<std::unique_ptr<BoolLiteral>>(node).get());
break;
default:
// error
break;
@ -674,5 +677,7 @@ void Visitor::Visit(CharLiteral* node) {}
void Visitor::Visit(UnitLiteral* node) {}
void Visitor::Visit(BoolLiteral* node) {}
} // namespace interpreter