part of type deduction done, debugging in proces

This commit is contained in:
ProgramSnail 2023-07-07 22:53:14 +03:00
parent a208e2f42d
commit 3815f8259b
6 changed files with 212 additions and 59 deletions

View file

@ -34,7 +34,8 @@ public:
bool Require(const AbstractType& type) const; bool Require(const AbstractType& type) const;
bool DeduceContext(const AbstractType& actual_type, bool DeduceContext(const AbstractType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const; std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const;
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;
@ -74,7 +75,8 @@ public:
bool Require(const DefinedType& type) const; bool Require(const DefinedType& type) const;
bool DeduceContext(const DefinedType& actual_type, bool DeduceContext(const DefinedType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const; std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const;
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;
@ -179,7 +181,8 @@ public:
bool Require(const TupleType& type) const; bool Require(const TupleType& type) const;
bool DeduceContext(const TupleType& actual_type, bool DeduceContext(const TupleType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const; std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const;
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;
@ -208,7 +211,8 @@ public:
bool Require(const VariantType& type) const; bool Require(const VariantType& type) const;
bool DeduceContext(const VariantType& actual_type, bool DeduceContext(const VariantType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const; std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const;
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;
@ -240,7 +244,8 @@ public:
bool Require(const OptionalType& type) const; bool Require(const OptionalType& type) const;
bool DeduceContext(const OptionalType& actual_type, bool DeduceContext(const OptionalType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const; std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const;
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;
@ -273,7 +278,8 @@ public:
bool Require(const ReferenceToType& type) const; bool Require(const ReferenceToType& type) const;
bool DeduceContext(const ReferenceToType& actual_type, bool DeduceContext(const ReferenceToType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const; std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const;
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;
@ -300,7 +306,8 @@ public:
bool Require(const FunctionType& type) const; bool Require(const FunctionType& type) const;
bool DeduceContext(const FunctionType& actual_type, bool DeduceContext(const FunctionType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const; std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const;
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;
@ -325,7 +332,8 @@ public:
bool Require(const ArrayType& type) const; bool Require(const ArrayType& type) const;
bool DeduceContext(const ArrayType& actual_type, bool DeduceContext(const ArrayType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const; std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const;
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;
@ -351,7 +359,8 @@ public:
bool Require(const Type& type) const; // TODO: check abstract type requirements for not abstract types bool Require(const Type& type) const; // TODO: check abstract type requirements for not abstract types
bool DeduceContext(const Type& actual_type, bool DeduceContext(const Type& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const; std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const;
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;

View file

@ -1088,6 +1088,15 @@ bool ExecuteVisitor::HandleBuiltinFunctionCall(FunctionCallExpression* node) {
error_handling::HandleInternalError("Error function finished", error_handling::HandleInternalError("Error function finished",
"ExecuteVisitor.HandleBuiltinFunctionCall", "ExecuteVisitor.HandleBuiltinFunctionCall",
&node->base); &node->base);
} else if (node->name == "some") { // TODO: manage value type ??
Visitor::Visit(node->arguments[0].second);
current_value_ = context_manager_.AddValue(info::value::OptionalValue(current_value_,
context_manager_.GetValueManager()),
utils::ValueType::Tmp);
} else if (node->name == "none") { // TODO: manage value type ??
current_value_ = context_manager_.AddValue(info::value::OptionalValue(std::nullopt,
context_manager_.GetValueManager()),
utils::ValueType::Tmp);
} else { } else {
return false; return false;
} }

View file

@ -764,6 +764,10 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
&node->base); &node->base);
} }
if (node->name == "some") {
error_handling::DebugPrint("0");
}
// try to find function declaration // try to find function declaration
if (node->prefix.has_value()) { if (node->prefix.has_value()) {
if (std::holds_alternative<std::unique_ptr<SubExpressionToken>>(node->prefix.value())) { if (std::holds_alternative<std::unique_ptr<SubExpressionToken>>(node->prefix.value())) {
@ -784,6 +788,10 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
maybe_function_declaration = FindFunctionAndUpdate(node); maybe_function_declaration = FindFunctionAndUpdate(node);
} }
if (node->name == "some") {
error_handling::DebugPrint("1");
}
// function declaration check // function declaration check
if (!maybe_function_declaration.has_value()) { if (!maybe_function_declaration.has_value()) {
error_handling::HandleTypecheckError("No function declaration found for function in call expression", node->base); error_handling::HandleTypecheckError("No function declaration found for function in call expression", node->base);
@ -794,11 +802,10 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
// check & collect parmeters // check & collect parmeters
if (function_declaration->parameters.size() != node->parameters.size()) { if (function_declaration->parameters.size() != node->parameters.size()) {
// if (node->parameters.size() != 0) { if (node->parameters.size() != 0) {
error_handling::HandleTypecheckError("Mismatched parameter count in function call expression", node->base); error_handling::HandleTypecheckError("Mismatched parameter count in function call expression", node->base);
// } }
// deduce_parameters = true; deduce_parameters = true;
// TODO: paramters deduction
} }
for (size_t i = 0; i < node->parameters.size(); ++i) { for (size_t i = 0; i < node->parameters.size(); ++i) {
Visit(node->parameters[i].get()); Visit(node->parameters[i].get());
@ -819,6 +826,12 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
function_declaration->parameters[i]->graph_id_, function_declaration->parameters[i]->graph_id_,
typeclass_graph_), typeclass_graph_),
utils::ValueType::Tmp)); utils::ValueType::Tmp));
// TODO: type requirements check needed ??
}
if (node->name == "some") {
error_handling::DebugPrint("2");
} }
size_t index_shift = (node->is_method_of_first_argument_ ? 1 : 0); size_t index_shift = (node->is_method_of_first_argument_ ? 1 : 0);
@ -830,6 +843,15 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
bool all_arguments = function_declaration->type->types.size() <= node->arguments.size() + 1 - index_shift; bool all_arguments = function_declaration->type->types.size() <= node->arguments.size() + 1 - index_shift;
std::unordered_map<std::string, std::optional<utils::IdType>> deduced_context;
for (auto& parameter : function_declaration->parameters) {
deduced_context[parameter->type] = std::nullopt;
}
if (node->name == "some") {
error_handling::DebugPrint("3");
}
{ {
size_t i = index_shift; // function call argument id size_t i = index_shift; // function call argument id
size_t j = 0; // actual argument id size_t j = 0; // actual argument id
@ -851,6 +873,10 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
} }
} }
if (node->name == "some") {
error_handling::DebugPrint("4");
}
Visit(function_declaration->type->types[j].second.get()); Visit(function_declaration->type->types[j].second.get());
utils::IdType argument_type = TypeInContext(current_type_, context); utils::IdType argument_type = TypeInContext(current_type_, context);
@ -862,9 +888,50 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
} }
} }
if (node->name == "some") {
error_handling::DebugPrint("5");
}
Visitor::Visit(node->arguments[i].second); Visitor::Visit(node->arguments[i].second);
if (!context_manager_.AddValueRequirement(current_type_, argument_type)) {
error_handling::HandleTypecheckError("Wrong argument type (argument " + std::to_string(j + 1) + ")", node->base); if (node->name == "some") {
error_handling::DebugPrint("6");
}
if (deduce_parameters) {
std::unordered_map<std::string, std::optional<utils::IdType>> local_deduced_context;
for (auto& parameter : function_declaration->parameters) {
local_deduced_context[parameter->type] = std::nullopt;
}
// TODO: do this in context manager ??
if (!context_manager_.GetAnyValue(current_type_)->DeduceContext(*context_manager_.GetAnyValue(argument_type), local_deduced_context, *context_manager_.GetValueManager())) {
error_handling::HandleTypecheckError("Can't deduce parameters (argument " + std::to_string(j + 1) + ")", node->base);
}
for (auto& local_deduced_type : local_deduced_context) {
auto deduced_type = deduced_context[local_deduced_type.first];
if (!deduced_type.has_value()) {
deduced_context[local_deduced_type.first] = local_deduced_type.second;
continue;
}
if (local_deduced_type.second.has_value() &&
!context_manager_.EqualValues(local_deduced_type.second.value(), deduced_type.value())) {
error_handling::HandleTypecheckError("Different types deduced for one parameter in function call expression", node->base);
}
}
} else {
if (!context_manager_.AddValueRequirement(current_type_, argument_type)) {
error_handling::HandleTypecheckError("Wrong argument type (argument " + std::to_string(j + 1) + ")", node->base);
}
}
if (node->name == "some") {
error_handling::DebugPrint("7");
} }
++i; ++i;
@ -887,6 +954,43 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
} }
} }
if (node->name == "some") {
error_handling::DebugPrint("8");
}
if (deduce_parameters) {
for (size_t i = 0; i < function_declaration->parameters.size(); ++i) {
auto deduced_type = deduced_context[function_declaration->parameters[i]->type];
if (!deduced_type.has_value()) {
error_handling::HandleTypecheckError("Can't deduce parameters in function call", node->base);
}
current_type_ = deduced_type.value();
if (context.count(function_declaration->parameters[i]->type) != 0) {
error_handling::HandleInternalError("Local abstract types with same name in one context",
"TypeCheckVisitor.FunctionCallExpresssion",
&node->base);
}
context[function_declaration->parameters[i]->type] = current_type_;
context_manager_.DefineLocalType(
function_declaration->parameters[i]->type,
context_manager_.AddValue(
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
function_declaration->parameters[i]->graph_id_,
typeclass_graph_),
utils::ValueType::Tmp));
// TODO: check, that parameter type valid ??
}
}
if (node->name == "some") {
error_handling::DebugPrint("9");
}
if (!utils::IsBuiltinFunction(node->name)) { if (!utils::IsBuiltinFunction(node->name)) {
if (node->function_id_.has_value()) { if (node->function_id_.has_value()) {
if (!global_info_.GetFunctionInfo(node->function_id_.value()).definition.has_value()) { if (!global_info_.GetFunctionInfo(node->function_id_.value()).definition.has_value()) {
@ -913,12 +1017,20 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
} }
} }
if (node->name == "some") {
error_handling::DebugPrint("10");
}
Visit(function_declaration->type->types.back().second.get()); Visit(function_declaration->type->types.back().second.get());
current_type_ = TypeInContext(current_type_, context); current_type_ = TypeInContext(current_type_, context);
context_manager_.ExitContext(); context_manager_.ExitContext();
node->base.type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp); node->base.type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp);
if (node->name == "some") {
error_handling::DebugPrint("11");
}
} }
void TypeCheckVisitor::Visit(TupleExpression* node) { void TypeCheckVisitor::Visit(TupleExpression* node) {

View file

@ -23,7 +23,8 @@ bool AbstractType::Require(const AbstractType& type) const { // TODO: cache Depe
} }
bool AbstractType::DeduceContext(const AbstractType& actual_type, bool AbstractType::DeduceContext(const AbstractType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const { std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const {
return typeclass_graph_.GetDependenciesSet(graph_id_).count(actual_type.graph_id_) != 0 || graph_id_ == actual_type.graph_id_; return typeclass_graph_.GetDependenciesSet(graph_id_).count(actual_type.graph_id_) != 0 || graph_id_ == actual_type.graph_id_;
} }
@ -55,9 +56,10 @@ bool DefinedType::Require(const DefinedType& type) const {
} }
bool DefinedType::DeduceContext(const DefinedType& actual_type, bool DefinedType::DeduceContext(const DefinedType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const { std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const {
return type_id_ == actual_type.type_id_ return type_id_ == actual_type.type_id_
&& type_manager_->GetAnyValue(type_)->DeduceContext(*type_manager_->GetAnyValue(actual_type.type_), context); && type_manager_->GetAnyValue(type_)->DeduceContext(*type_manager_->GetAnyValue(actual_type.type_), context, type_manager);
} }
std::optional<utils::IdType> DefinedType::GetFieldType(const std::string& name, std::optional<utils::IdType> DefinedType::GetFieldType(const std::string& name,
@ -115,13 +117,14 @@ bool TupleType::Require(const TupleType& type) const {
} }
bool TupleType::DeduceContext(const TupleType& actual_type, bool TupleType::DeduceContext(const TupleType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const { std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const {
if (fields_.size() != actual_type.fields_.size()) { if (fields_.size() != actual_type.fields_.size()) {
return false; return false;
} }
for (size_t i = 0; i < fields_.size(); ++i) { for (size_t i = 0; i < fields_.size(); ++i) {
if (!type_manager_->GetAnyValue(fields_[i].second)->DeduceContext(*type_manager_->GetAnyValue(actual_type.fields_[i].second), context)) { if (!type_manager_->GetAnyValue(fields_[i].second)->DeduceContext(*type_manager_->GetAnyValue(actual_type.fields_[i].second), context, type_manager)) {
return false; return false;
} }
} }
@ -215,7 +218,8 @@ bool VariantType::Require(const VariantType& type) const {
} }
bool VariantType::DeduceContext(const VariantType& actual_type, bool VariantType::DeduceContext(const VariantType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const { std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const {
if (constructors_.size() != actual_type.constructors_.size()) { if (constructors_.size() != actual_type.constructors_.size()) {
return false; return false;
} }
@ -230,7 +234,7 @@ bool VariantType::DeduceContext(const VariantType& actual_type,
} }
if (constructors_[i].second.has_value()) { if (constructors_[i].second.has_value()) {
if (!constructors_[i].second.value().DeduceContext(actual_type.constructors_[i].second.value(), context)) { if (!constructors_[i].second.value().DeduceContext(actual_type.constructors_[i].second.value(), context, type_manager)) {
return false; return false;
} }
} }
@ -286,8 +290,9 @@ bool OptionalType::Require(const OptionalType& type) const {
} }
bool OptionalType::DeduceContext(const OptionalType& actual_type, bool OptionalType::DeduceContext(const OptionalType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const { std::unordered_map<std::string, std::optional<utils::IdType>>& context,
return type_manager_->GetAnyValue(type_)->DeduceContext(*type_manager_->GetAnyValue(actual_type.type_), context); TypeManager& type_manager) const {
return type_manager_->GetAnyValue(type_)->DeduceContext(*type_manager_->GetAnyValue(actual_type.type_), context, type_manager);
} }
std::optional<utils::IdType> OptionalType::GetFieldType(const std::string&, std::optional<utils::IdType> OptionalType::GetFieldType(const std::string&,
@ -320,8 +325,9 @@ bool ReferenceToType::Require(const ReferenceToType& type) const {
} }
bool ReferenceToType::DeduceContext(const ReferenceToType& actual_type, bool ReferenceToType::DeduceContext(const ReferenceToType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const { std::unordered_map<std::string, std::optional<utils::IdType>>& context,
return references_ == actual_type.references_ && type_manager_->GetAnyValue(type_)->DeduceContext(*type_manager_->GetAnyValue(actual_type.type_), context); TypeManager& type_manager) const {
return references_ == actual_type.references_ && type_manager_->GetAnyValue(type_)->DeduceContext(*type_manager_->GetAnyValue(actual_type.type_), context, type_manager);
} }
std::optional<utils::IdType> ReferenceToType::GetFieldType(const std::string& name, std::optional<utils::IdType> ReferenceToType::GetFieldType(const std::string& name,
@ -396,13 +402,14 @@ bool FunctionType::Require(const FunctionType& type) const {
} }
bool FunctionType::DeduceContext(const FunctionType& actual_type, bool FunctionType::DeduceContext(const FunctionType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const { std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const {
if (argument_types_.size() != actual_type.argument_types_.size()) { if (argument_types_.size() != actual_type.argument_types_.size()) {
return false; return false;
} }
for (size_t i = 0; i < argument_types_.size(); ++i) { for (size_t i = 0; i < argument_types_.size(); ++i) {
if (!type_manager_->GetAnyValue(argument_types_[i])->DeduceContext(*type_manager_->GetAnyValue(actual_type.argument_types_[i]), context)) { if (!type_manager_->GetAnyValue(argument_types_[i])->DeduceContext(*type_manager_->GetAnyValue(actual_type.argument_types_[i]), context, type_manager)) {
return false; return false;
} }
} }
@ -457,8 +464,9 @@ bool ArrayType::Require(const ArrayType& type) const {
} }
bool ArrayType::DeduceContext(const ArrayType& actual_type, bool ArrayType::DeduceContext(const ArrayType& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const { std::unordered_map<std::string, std::optional<utils::IdType>>& context,
return size_ == actual_type.size_ && type_manager_->GetAnyValue(elements_type_)->DeduceContext(*type_manager_->GetAnyValue(actual_type.elements_type_), context); TypeManager& type_manager) const {
return size_ == actual_type.size_ && type_manager_->GetAnyValue(elements_type_)->DeduceContext(*type_manager_->GetAnyValue(actual_type.elements_type_), context, type_manager);
} }
std::optional<utils::IdType> ArrayType::GetFieldType(const std::string&, std::optional<utils::IdType> ArrayType::GetFieldType(const std::string&,
@ -570,15 +578,16 @@ bool Type::Require(const Type& type) const { // TODO: check abstract type requir
// TODO: check abstract type requirements for not abstract types // TODO: check abstract type requirements for not abstract types
bool Type::DeduceContext(const Type& actual_type, bool Type::DeduceContext(const Type& actual_type,
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const { std::unordered_map<std::string, std::optional<utils::IdType>>& context,
TypeManager& type_manager) const {
size_t this_index = type_.index(); size_t this_index = type_.index();
size_t type_index = actual_type.type_.index(); size_t type_index = actual_type.type_.index();
if (this_index == 0) { if (this_index == 0) {
std::string type_name = std::get<AbstractType>(type_).GetName(); std::string type_name = std::get<AbstractType>(type_).GetName();
if (context.count(type_name) != 0) { // is abstract type if (context.count(type_name) != 0) { // is abstract type
// context[type_name] = // TODO: actual_type.id_; ?? context[type_name] = type_manager.AddAnyValue(Type(actual_type), utils::ValueType::Tmp);
// TODO: fixes // TODO: choose value type ?? (or should be set later ??)
} }
} }
@ -588,30 +597,38 @@ bool Type::DeduceContext(const Type& actual_type,
switch (this_index) { switch (this_index) {
case 0: case 0:
return std::get<AbstractType>(type_).DeduceContext(std::get<AbstractType>(actual_type.type_), return std::get<AbstractType>(type_).DeduceContext(std::get<AbstractType>(actual_type.type_),
context); context,
type_manager);
case 1: case 1:
return std::get<DefinedType>(type_).DeduceContext(std::get<DefinedType>(actual_type.type_), return std::get<DefinedType>(type_).DeduceContext(std::get<DefinedType>(actual_type.type_),
context); context,
type_manager);
case 2: case 2:
return std::get<InternalType>(type_) == std::get<InternalType>(actual_type.type_); return std::get<InternalType>(type_) == std::get<InternalType>(actual_type.type_);
case 3: case 3:
return std::get<TupleType>(type_).DeduceContext(std::get<TupleType>(actual_type.type_), return std::get<TupleType>(type_).DeduceContext(std::get<TupleType>(actual_type.type_),
context); context,
type_manager);
case 4: case 4:
return std::get<VariantType>(type_).DeduceContext(std::get<VariantType>(actual_type.type_), return std::get<VariantType>(type_).DeduceContext(std::get<VariantType>(actual_type.type_),
context); context,
type_manager);
case 5: case 5:
return std::get<ReferenceToType>(type_).DeduceContext(std::get<ReferenceToType>(actual_type.type_), return std::get<ReferenceToType>(type_).DeduceContext(std::get<ReferenceToType>(actual_type.type_),
context); context,
type_manager);
case 6: case 6:
return std::get<FunctionType>(type_).DeduceContext(std::get<FunctionType>(actual_type.type_), return std::get<FunctionType>(type_).DeduceContext(std::get<FunctionType>(actual_type.type_),
context); context,
type_manager);
case 7: case 7:
return std::get<ArrayType>(type_).DeduceContext(std::get<ArrayType>(actual_type.type_), return std::get<ArrayType>(type_).DeduceContext(std::get<ArrayType>(actual_type.type_),
context); context,
type_manager);
case 8: case 8:
return std::get<OptionalType>(type_).DeduceContext(std::get<OptionalType>(actual_type.type_), return std::get<OptionalType>(type_).DeduceContext(std::get<OptionalType>(actual_type.type_),
context); context,
type_manager);
default: default:
// error // error
break; break;

View file

@ -85,6 +85,8 @@ bool IsBuiltinFunction(const std::string& name) { // optimize ??
builtin_functions.insert("show"); builtin_functions.insert("show");
builtin_functions.insert("read"); builtin_functions.insert("read");
builtin_functions.insert("error"); builtin_functions.insert("error");
builtin_functions.insert("some");
builtin_functions.insert("none");
// builtin_functions.insert("debug_show"); // TODO // builtin_functions.insert("debug_show"); // TODO
return builtin_functions.count(name) != 0; return builtin_functions.count(name) != 0;

View file

@ -16,6 +16,10 @@ decl random : -> \int // TODO
decl error : \string -> \unit decl error : \string -> \unit
decl some 'a : 'a -> 'a?
decl none 'a : 'a -> 'a?
// //
decl not : \bool -> \bool decl not : \bool -> \bool
@ -264,24 +268,24 @@ decl scan-three : -> (& \string & \string & \string)
def scan-three = & \io..scan: & \io..scan: & \io..scan: def scan-three = & \io..scan: & \io..scan: & \io..scan:
exec main { exec main {
var n = \int..read: (\io..scan:) // var n = \int..read: (\io..scan:)
//
// if n <= 0 then error: "n can't be less then 1"
//
// // var x = (for _ in 0--n do scan-int:)
// var x = \array[int]..of: (for _ in 0--n do scan-int:)
//
//
// var k? = if n < 2 then n * 2 +. 3 in
// , print-anything:[string] "n < 2"
// , print-anything:[int] k
//
// ; print-anything:[int] n
if n <= 0 then error: "n can't be less then 1" ; print-int-with-comment: ::i 123 (some: "comment")
// var x = (for _ in 0--n do scan-int:) // var & a & b & c = scan-three-t:
var x = \array[int]..of: (for _ in 0--n do scan-int:) // ; \io..print: b
// var & d & e & f = scan-three:
// ; \io..print: e
var k? = if n < 2 then n * 2 +. 3 in
, print-anything:[string] "n < 2"
, print-anything:[int] k
; print-anything:[int] n
; print-int-with-comment: ::i 123
var & a & b & c = scan-three-t:
; \io..print: b
var & d & e & f = scan-three:
; \io..print: e
} }