mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-26 16:58:45 +00:00
const -> let
This commit is contained in:
parent
3ae6ed079d
commit
189306df26
33 changed files with 406 additions and 285 deletions
|
|
@ -315,6 +315,8 @@ void BuildVisitor::Visit(PartitionStatement* node) {
|
|||
node->modifier = utils::PartitionModifier::Exec;
|
||||
} else if (partition_modifier == "test") {
|
||||
node->modifier = utils::PartitionModifier::Test;
|
||||
} else if (partition_modifier == "example") {
|
||||
node->modifier = utils::PartitionModifier::Example;
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
|
|
@ -826,6 +828,15 @@ void BuildVisitor::Visit(Expression& node) {
|
|||
} else if (current_node_type == parser::tokens::SubExpression) {
|
||||
node = std::make_unique<SubExpression>();
|
||||
Visit(*std::get<std::unique_ptr<SubExpression>>(node));
|
||||
} else if (current_node_type == parser::tokens::AndExpression) {
|
||||
node = std::make_unique<AndExpression>();
|
||||
Visit(std::get<std::unique_ptr<AndExpression>>(node).get());
|
||||
} else if (current_node_type == parser::tokens::OrExpression) {
|
||||
node = std::make_unique<OrExpression>();
|
||||
Visit(std::get<std::unique_ptr<OrExpression>>(node).get());
|
||||
} else if (current_node_type == parser::tokens::ArrayExpression) {
|
||||
node = std::make_unique<ArrayExpression>();
|
||||
Visit(std::get<std::unique_ptr<ArrayExpression>>(node).get());
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
|
|
@ -849,9 +860,6 @@ void BuildVisitor::Visit(SuperExpression& node) {
|
|||
} else if (current_node_type == parser::tokens::VariantExpression) {
|
||||
node = std::make_unique<VariantExpression>();
|
||||
Visit(std::get<std::unique_ptr<VariantExpression>>(node).get());
|
||||
} else if (current_node_type == parser::tokens::ArrayExpression) {
|
||||
node = std::make_unique<ArrayExpression>();
|
||||
Visit(std::get<std::unique_ptr<ArrayExpression>>(node).get());
|
||||
} else if (current_node_type == parser::tokens::Expression) {
|
||||
node = std::make_unique<Expression>();
|
||||
Visit(*std::get<std::unique_ptr<Expression>>(node));
|
||||
|
|
@ -884,7 +892,7 @@ void BuildVisitor::VisitBinaryOperatorExpression(FunctionCallExpression* node) {
|
|||
node->arguments.resize(2);
|
||||
|
||||
current_node_ = parse_node.ChildByFieldName("left_expression");
|
||||
Visit(node->arguments[0]);
|
||||
Visit(node->arguments[0].second);
|
||||
|
||||
node->name = parse_node.ChildByFieldName("operator_name").GetValue();
|
||||
|
||||
|
|
@ -896,15 +904,16 @@ void BuildVisitor::VisitBinaryOperatorExpression(FunctionCallExpression* node) {
|
|||
}
|
||||
|
||||
current_node_ = parse_node.ChildByFieldName("right_expression");
|
||||
Visit(node->arguments[1]);
|
||||
Visit(node->arguments[1].second);
|
||||
|
||||
// ??
|
||||
for (size_t i = 0; i < node->arguments.size(); ++i) {
|
||||
if (std::holds_alternative<std::unique_ptr<FunctionCallExpression>>(node->arguments[i])) {
|
||||
FunctionCallExpression* argument_node = std::get<std::unique_ptr<FunctionCallExpression>>(node->arguments[i]).get();
|
||||
if (std::holds_alternative<std::unique_ptr<FunctionCallExpression>>(node->arguments[i].second)) {
|
||||
FunctionCallExpression* argument_node = std::get<std::unique_ptr<FunctionCallExpression>>(node->arguments[i].second).get();
|
||||
if (argument_node->is_binary_operator_expression
|
||||
&& argument_node->precedence.has_value()
|
||||
&& argument_node->precedence.value() == node->precedence.value()) {
|
||||
&& argument_node->precedence.value() == node->precedence.value()
|
||||
&& node->name != argument_node->name) { // same operators can be chained
|
||||
error_handling::HandleParsingError("Operators can't be chained (left argument)", node->base.start_position, node->base.end_position);
|
||||
}
|
||||
}
|
||||
|
|
@ -986,6 +995,7 @@ void BuildVisitor::Visit(FunctionCallExpression* node) {
|
|||
|
||||
if (child_count > excluded_child_count) {
|
||||
bool parameters_ended = false;
|
||||
bool last_child_is_annotation = false;
|
||||
|
||||
for (size_t i = 0; i + excluded_child_count < child_count; ++i) {
|
||||
current_node_ = parse_node.NthNamedChild(i + excluded_child_count);
|
||||
|
|
@ -998,10 +1008,26 @@ void BuildVisitor::Visit(FunctionCallExpression* node) {
|
|||
node->parameters.push_back(std::make_unique<TypeExpression>());
|
||||
Visit(node->parameters.back().get());
|
||||
} else {
|
||||
node->arguments.push_back(std::make_unique<SubExpressionToken>());
|
||||
Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->arguments.back()));
|
||||
if (!current_node_.PreviousSibling().IsNull() && current_node_.PreviousSibling().GetValue() == "::") { // annotation
|
||||
node->arguments.push_back({current_node_.GetValue(), SubExpression()});
|
||||
last_child_is_annotation = true;
|
||||
} else if (last_child_is_annotation) { // argument after annotation
|
||||
node->arguments.back().second = std::make_unique<SubExpressionToken>();
|
||||
Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->arguments.back().second));
|
||||
last_child_is_annotation = false;
|
||||
} else { // argument without annotation
|
||||
node->arguments.push_back({std::nullopt, std::make_unique<SubExpressionToken>()});
|
||||
Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->arguments.back().second));
|
||||
last_child_is_annotation = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last_child_is_annotation) {
|
||||
error_handling::HandleInternalError("Last child is annotation",
|
||||
"BuildVisitor.FunctionCallExpression",
|
||||
&node->base);
|
||||
}
|
||||
}
|
||||
|
||||
current_node_ = parse_node;
|
||||
|
|
@ -1137,6 +1163,40 @@ void BuildVisitor::Visit(LambdaFunction* node) {
|
|||
current_node_ = parse_node;
|
||||
}
|
||||
|
||||
void BuildVisitor::Visit(AndExpression* node) {
|
||||
SetPosition(node->base, current_node_);
|
||||
|
||||
auto parse_node = current_node_;
|
||||
|
||||
size_t expressions_count = parse_node.NamedChildCount();
|
||||
|
||||
node->expressions.resize(expressions_count);
|
||||
|
||||
for (size_t i = 0; i < expressions_count; ++i) {
|
||||
current_node_ = parse_node.NthNamedChild(i);
|
||||
Visit(node->expressions[i]);
|
||||
}
|
||||
|
||||
current_node_ = parse_node;
|
||||
}
|
||||
|
||||
void BuildVisitor::Visit(OrExpression* node) {
|
||||
SetPosition(node->base, current_node_);
|
||||
|
||||
auto parse_node = current_node_;
|
||||
|
||||
size_t expressions_count = parse_node.NamedChildCount();
|
||||
|
||||
node->expressions.resize(expressions_count);
|
||||
|
||||
for (size_t i = 0; i < expressions_count; ++i) {
|
||||
current_node_ = parse_node.NthNamedChild(i);
|
||||
Visit(node->expressions[i]);
|
||||
}
|
||||
|
||||
current_node_ = parse_node;
|
||||
}
|
||||
|
||||
void BuildVisitor::Visit(ArrayExpression* node) {
|
||||
SetPosition(node->base, current_node_);
|
||||
|
||||
|
|
@ -1296,12 +1356,31 @@ void BuildVisitor::Visit(FunctionType* node) {
|
|||
|
||||
size_t types_count = parse_node.NamedChildCount();
|
||||
|
||||
node->types.resize(types_count);
|
||||
node->types.reserve(types_count);
|
||||
|
||||
bool last_child_is_annotation = false;
|
||||
|
||||
for (size_t i = 0; i < types_count; ++i) {
|
||||
current_node_ = parse_node.NthNamedChild(i);
|
||||
node->types[i] = std::make_unique<ExtendedScopedAnyType>();
|
||||
Visit(node->types[i].get());
|
||||
|
||||
if (!current_node_.PreviousSibling().IsNull() && current_node_.PreviousSibling().GetValue() == "::") { // annotation
|
||||
node->types.push_back({current_node_.GetValue(), nullptr});
|
||||
last_child_is_annotation = true;
|
||||
} else if (last_child_is_annotation) { // argument after annotation
|
||||
node->types.back().second = std::make_unique<ExtendedScopedAnyType>();
|
||||
Visit(node->types.back().second.get());
|
||||
last_child_is_annotation = false;
|
||||
} else { // argument without annotation
|
||||
node->types.push_back({std::nullopt, std::make_unique<ExtendedScopedAnyType>()});
|
||||
Visit(node->types.back().second.get());
|
||||
last_child_is_annotation = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (last_child_is_annotation) {
|
||||
error_handling::HandleInternalError("Last child is annotation",
|
||||
"BuildVisitor.FunctionType",
|
||||
&node->base);
|
||||
}
|
||||
|
||||
current_node_ = parse_node;
|
||||
|
|
|
|||
|
|
@ -477,7 +477,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
|
|||
}
|
||||
} else {
|
||||
if (node->is_method_of_first_argument_) {
|
||||
Visitor::Visit(node->arguments[0]);
|
||||
Visitor::Visit(node->arguments[0].second);
|
||||
|
||||
if (context_manager_.GetValueType(current_value_) == utils::ValueType::Tmp) {
|
||||
// temporary value can't be modified inside
|
||||
|
|
@ -598,7 +598,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
|
|||
|
||||
// handle arguments
|
||||
for (size_t i = index_shift; i < node->arguments.size(); ++i) {
|
||||
Visitor::Visit(node->arguments[i]);
|
||||
Visitor::Visit(node->arguments[i].second);
|
||||
|
||||
// function arguments can't be changed inside function
|
||||
current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const);
|
||||
|
|
@ -711,6 +711,38 @@ void ExecuteVisitor::Visit(LambdaFunction* node) {
|
|||
&node->base);
|
||||
}
|
||||
|
||||
void ExecuteVisitor::Visit(AndExpression* node) {
|
||||
bool result = true;
|
||||
|
||||
for (auto& expression : node->expressions) {
|
||||
Visitor::Visit(expression);
|
||||
if (!*ExtractInternalValue<bool>(current_value_, node->base)) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(result),
|
||||
utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
void ExecuteVisitor::Visit(OrExpression* node) {
|
||||
bool result = false;
|
||||
|
||||
for (auto& expression : node->expressions) {
|
||||
Visitor::Visit(expression);
|
||||
if (*ExtractInternalValue<bool>(current_value_, node->base)) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(result),
|
||||
utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
void ExecuteVisitor::Visit(ArrayExpression* node) {
|
||||
std::vector<utils::IdType> elements;
|
||||
|
||||
|
|
@ -1014,7 +1046,7 @@ void ExecuteVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) {
|
|||
|
||||
bool ExecuteVisitor::HandleBuiltinFunctionCall(FunctionCallExpression* node) {
|
||||
if (node->name == "print") {
|
||||
Visitor::Visit(node->arguments[0]);
|
||||
Visitor::Visit(node->arguments[0].second);
|
||||
info::builtin::Print(*ExtractInternalValue<std::string>(current_value_, node->base));
|
||||
|
||||
current_value_ = context_manager_.AddValue(info::value::InternalValue(info::value::Unit()),
|
||||
|
|
@ -1025,6 +1057,13 @@ bool ExecuteVisitor::HandleBuiltinFunctionCall(FunctionCallExpression* node) {
|
|||
} else if (node->name == "random") { // TODO: different types, better random, seed, etc.
|
||||
current_value_ = context_manager_.AddValue(info::value::InternalValue(rand()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (node->name == "error") {
|
||||
Visitor::Visit(node->arguments[0].second);
|
||||
info::builtin::Error(*ExtractInternalValue<std::string>(current_value_, node->base));
|
||||
|
||||
error_handling::HandleInternalError("Error function finished",
|
||||
"ExecuteVisitor.HandleBuiltinFunctionCall",
|
||||
&node->base);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1046,7 +1085,7 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
|
|||
}
|
||||
|
||||
for (auto& argument : node->arguments) {
|
||||
Visitor::Visit(argument);
|
||||
Visitor::Visit(argument.second);
|
||||
arguments.push_back(ExtractValue<info::value::InternalValue>(current_value_, node->base));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
|||
|
||||
info.argument_types.resize(node->type->types.size());
|
||||
for (size_t i = 0; i < node->type->types.size(); ++i) {
|
||||
info.argument_types[i] = node->type->types[i].get();
|
||||
info.argument_types[i] = node->type->types[i].second.get();
|
||||
}
|
||||
|
||||
info.node = node;
|
||||
|
|
@ -179,6 +179,7 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
|||
}
|
||||
|
||||
void FindSymbolsVisitor::Visit(PartitionStatement* node) {
|
||||
// TODO: difference between partitions ??
|
||||
node->executable_id_ = namespace_visitor_.AddPartition(node->name.path, node, node->base);
|
||||
|
||||
Visitor::Visit(node->value); // to visit all tree
|
||||
|
|
|
|||
|
|
@ -193,6 +193,9 @@ void PrintVisitor::Visit(PartitionStatement* node) {
|
|||
case utils::PartitionModifier::Test:
|
||||
out_ << "test ";
|
||||
break;
|
||||
case utils::PartitionModifier::Example:
|
||||
out_ << "example ";
|
||||
break;
|
||||
}
|
||||
Visit(&node->name);
|
||||
out_ << "] = (";
|
||||
|
|
@ -460,7 +463,13 @@ void PrintVisitor::Visit(FunctionCallExpression* node) {
|
|||
}
|
||||
is_first = false;
|
||||
|
||||
Visitor::Visit(argument);
|
||||
if (argument.first.has_value()) {
|
||||
out_ << "::";
|
||||
Visit(&argument.first.value());
|
||||
out_ << ' ';
|
||||
}
|
||||
|
||||
Visitor::Visit(argument.second);
|
||||
}
|
||||
out_ << ")";
|
||||
}
|
||||
|
|
@ -544,6 +553,24 @@ void PrintVisitor::Visit(LambdaFunction* node) {
|
|||
out_ << ")\n";
|
||||
}
|
||||
|
||||
void PrintVisitor::Visit(AndExpression* node) {
|
||||
out_ << "[AndExpression] (";
|
||||
for (auto& expression : node->expressions) {
|
||||
out_ << "&&";
|
||||
Visitor::Visit(expression);
|
||||
}
|
||||
out_ << ")";
|
||||
}
|
||||
|
||||
void PrintVisitor::Visit(OrExpression* node) {
|
||||
out_ << "[OrExpression] (";
|
||||
for (auto& expression : node->expressions) {
|
||||
out_ << "||";
|
||||
Visitor::Visit(expression);
|
||||
}
|
||||
out_ << ")";
|
||||
}
|
||||
|
||||
void PrintVisitor::Visit(ArrayExpression* node) {
|
||||
out_ << "[ArrayExpression] ( ,";
|
||||
for (auto& element : node->elements) {
|
||||
|
|
@ -619,7 +646,14 @@ void PrintVisitor::Visit(FunctionType* node) {
|
|||
out_ << " -> ";
|
||||
}
|
||||
is_first = false;
|
||||
Visit(type.get());
|
||||
|
||||
if (type.first.has_value()) {
|
||||
out_ << "::";
|
||||
Visit(&type.first.value());
|
||||
out_ << ' ';
|
||||
}
|
||||
|
||||
Visit(type.second.get());
|
||||
}
|
||||
out_ << ')';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,14 +239,14 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < node->definition->arguments.size(); ++i) {
|
||||
Visit(declaration->type->types[i].get());
|
||||
Visit(declaration->type->types[i].second.get());
|
||||
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Const);
|
||||
if (!context_manager_.DefineVariable(node->definition->arguments[i], current_type_)) {
|
||||
error_handling::HandleTypecheckError("Can't define function argument variable: name redefinition", node->base);
|
||||
}
|
||||
}
|
||||
|
||||
Visit(declaration->type->types.back().get());
|
||||
Visit(declaration->type->types.back().second.get());
|
||||
utils::IdType returned_type = current_type_;
|
||||
|
||||
returned_type_ = std::nullopt;
|
||||
|
|
@ -828,10 +828,18 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
|||
}
|
||||
|
||||
for (size_t i = index_shift; i < node->arguments.size(); ++i) {
|
||||
Visit(function_declaration->type->types[i - index_shift].get());
|
||||
Visit(function_declaration->type->types[i - index_shift].second.get());
|
||||
utils::IdType argument_type = TypeInContext(current_type_, context);
|
||||
|
||||
Visitor::Visit(node->arguments[i]);
|
||||
if (node->arguments[i].first.has_value()) {
|
||||
if (!function_declaration->type->types[i - index_shift].first.has_value()) {
|
||||
error_handling::HandleTypecheckError("Declared argument has no annotation (argument " + std::to_string(i - index_shift + 1) + ")", node->base);
|
||||
} else if (node->arguments[i].first.value() != function_declaration->type->types[i - index_shift].first.value()) {
|
||||
error_handling::HandleTypecheckError("Wrong argument annotation (argument " + std::to_string(i - index_shift + 1) + ")", node->base);
|
||||
}
|
||||
}
|
||||
|
||||
Visitor::Visit(node->arguments[i].second);
|
||||
if (!context_manager_.AddValueRequirement(current_type_, argument_type)) {
|
||||
error_handling::HandleTypecheckError("Wrong argument type (argument " + std::to_string(i - index_shift + 1) + ")", node->base);
|
||||
}
|
||||
|
|
@ -863,7 +871,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
|||
}
|
||||
}
|
||||
|
||||
Visit(function_declaration->type->types.back().get());
|
||||
Visit(function_declaration->type->types.back().second.get());
|
||||
current_type_ = TypeInContext(current_type_, context);
|
||||
|
||||
context_manager_.ExitContext();
|
||||
|
|
@ -1052,6 +1060,32 @@ void TypeCheckVisitor::Visit(LambdaFunction* node) {
|
|||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(AndExpression* node) {
|
||||
for (auto& expression : node->expressions) {
|
||||
Visitor::Visit(expression);
|
||||
if (!context_manager_.EqualValues(internal_to_abstract_type_.at(info::type::InternalType::Bool), current_type_)) {
|
||||
error_handling::HandleTypecheckError("And expression element is not bool expression", node->base);
|
||||
}
|
||||
}
|
||||
|
||||
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Bool);
|
||||
|
||||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(OrExpression* node) {
|
||||
for (auto& expression : node->expressions) {
|
||||
Visitor::Visit(expression);
|
||||
if (!context_manager_.EqualValues(internal_to_abstract_type_.at(info::type::InternalType::Bool), current_type_)) {
|
||||
error_handling::HandleTypecheckError("Or expression element is not bool expression", node->base);
|
||||
}
|
||||
}
|
||||
|
||||
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Bool);
|
||||
|
||||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(ArrayExpression* node) {
|
||||
utils::IdType elements_type = 0;
|
||||
|
||||
|
|
@ -1282,7 +1316,7 @@ void TypeCheckVisitor::Visit(FunctionType* node) {
|
|||
std::vector<utils::IdType> argument_types(node->types.size());
|
||||
|
||||
for (auto& argument_type : node->types) {
|
||||
Visit(argument_type.get());
|
||||
Visit(argument_type.second.get());
|
||||
argument_types.push_back(current_type_);
|
||||
}
|
||||
|
||||
|
|
@ -1677,8 +1711,8 @@ std::optional<FunctionDeclaration*> TypeCheckVisitor::FindFunctionAndUpdate(Func
|
|||
}
|
||||
}
|
||||
|
||||
if (!maybe_function_declaration.has_value() && node->is_binary_operator_expression && node->arguments.size() > 0) {
|
||||
Visitor::Visit(node->arguments[0]);
|
||||
if (!maybe_function_declaration.has_value() && node->is_binary_operator_expression && node->arguments.size() > 0 && !node->arguments[0].first.has_value()) { // ... , no annotation
|
||||
Visitor::Visit(node->arguments[0].second);
|
||||
maybe_function_declaration = FindExpressionMethodAndUpdate(node, current_type_);
|
||||
if (maybe_function_declaration.has_value()) {
|
||||
node->is_method_of_first_argument_ = true;
|
||||
|
|
|
|||
|
|
@ -260,6 +260,9 @@ void TypedPrintVisitor::Visit(PartitionStatement* node) {
|
|||
case utils::PartitionModifier::Test:
|
||||
out_ << "test ";
|
||||
break;
|
||||
case utils::PartitionModifier::Example:
|
||||
out_ << "example ";
|
||||
break;
|
||||
}
|
||||
Visit(&node->name);
|
||||
out_ << "] = (";
|
||||
|
|
@ -631,7 +634,13 @@ void TypedPrintVisitor::Visit(FunctionCallExpression* node) {
|
|||
}
|
||||
is_first = false;
|
||||
|
||||
Visitor::Visit(argument);
|
||||
if (argument.first.has_value()) {
|
||||
out_ << "::";
|
||||
Visit(&argument.first.value());
|
||||
out_ << ' ';
|
||||
}
|
||||
|
||||
Visitor::Visit(argument.second);
|
||||
}
|
||||
out_ << ")";
|
||||
}
|
||||
|
|
@ -750,6 +759,36 @@ void TypedPrintVisitor::Visit(LambdaFunction* node) {
|
|||
out_ << ")\n";
|
||||
}
|
||||
|
||||
void TypedPrintVisitor::Visit(AndExpression* node) {
|
||||
out_ << "[AndExpression : ";
|
||||
|
||||
if (node->base.type_.has_value()) {
|
||||
out_ << context_manager_.GetAnyValue(node->base.type_.value())->GetTypeName();
|
||||
}
|
||||
|
||||
out_ << "] (";
|
||||
for (auto& expression : node->expressions) {
|
||||
out_ << "&&";
|
||||
Visitor::Visit(expression);
|
||||
}
|
||||
out_ << ")";
|
||||
}
|
||||
|
||||
void TypedPrintVisitor::Visit(OrExpression* node) {
|
||||
out_ << "[OrExpression : ";
|
||||
|
||||
if (node->base.type_.has_value()) {
|
||||
out_ << context_manager_.GetAnyValue(node->base.type_.value())->GetTypeName();
|
||||
}
|
||||
|
||||
out_ << "] (";
|
||||
for (auto& expression : node->expressions) {
|
||||
out_ << "||";
|
||||
Visitor::Visit(expression);
|
||||
}
|
||||
out_ << ")";
|
||||
}
|
||||
|
||||
void TypedPrintVisitor::Visit(ArrayExpression* node) {
|
||||
out_ << "[ArrayExpression : ";
|
||||
|
||||
|
|
@ -873,7 +912,14 @@ void TypedPrintVisitor::Visit(FunctionType* node) {
|
|||
out_ << " -> ";
|
||||
}
|
||||
is_first = false;
|
||||
Visit(type.get());
|
||||
|
||||
if (type.first.has_value()) {
|
||||
out_ << "::";
|
||||
Visit(&type.first.value());
|
||||
out_ << ' ';
|
||||
}
|
||||
|
||||
Visit(type.second.get());
|
||||
}
|
||||
out_ << ')';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ std::optional<char> ToEscapeSymbol(char symbol) {
|
|||
return '\t';
|
||||
case 'v':
|
||||
return '\v';
|
||||
case 's':
|
||||
return ' ';
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
@ -82,6 +84,7 @@ bool IsBuiltinFunction(const std::string& name) { // optimize ??
|
|||
builtin_functions.insert("one");
|
||||
builtin_functions.insert("show");
|
||||
builtin_functions.insert("read");
|
||||
builtin_functions.insert("error");
|
||||
// builtin_functions.insert("debug_show"); // TODO
|
||||
|
||||
return builtin_functions.count(name) != 0;
|
||||
|
|
|
|||
|
|
@ -188,6 +188,15 @@ void Visitor::Visit(Expression& node) {
|
|||
case 3:
|
||||
Visit(*std::get<std::unique_ptr<SubExpression>>(node));
|
||||
break;
|
||||
case 4:
|
||||
Visit(std::get<std::unique_ptr<AndExpression>>(node).get());
|
||||
break;
|
||||
case 5:
|
||||
Visit(std::get<std::unique_ptr<OrExpression>>(node).get());
|
||||
break;
|
||||
case 6:
|
||||
Visit(std::get<std::unique_ptr<ArrayExpression>>(node).get());
|
||||
break;
|
||||
default:
|
||||
// error
|
||||
break;
|
||||
|
|
@ -206,9 +215,6 @@ void Visitor::Visit(SuperExpression& node) {
|
|||
Visit(std::get<std::unique_ptr<VariantExpression>>(node).get());
|
||||
break;
|
||||
case 3:
|
||||
Visit(std::get<std::unique_ptr<ArrayExpression>>(node).get());
|
||||
break;
|
||||
case 4:
|
||||
Visit(*std::get<std::unique_ptr<Expression>>(node));
|
||||
break;
|
||||
default:
|
||||
|
|
@ -500,7 +506,10 @@ void Visitor::Visit(FunctionCallExpression* node) {
|
|||
}
|
||||
|
||||
for (auto& argument : node->arguments) {
|
||||
Visit(argument);
|
||||
if (argument.first.has_value()) {
|
||||
Visit(&argument.first.value());
|
||||
}
|
||||
Visit(argument.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -544,6 +553,18 @@ void Visitor::Visit(LambdaFunction* node) {
|
|||
Visit(node->expression);
|
||||
}
|
||||
|
||||
void Visitor::Visit(AndExpression* node) {
|
||||
for (auto& expression : node->expressions) {
|
||||
Visit(expression);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(OrExpression* node) {
|
||||
for (auto& expression : node->expressions) {
|
||||
Visit(expression);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(ArrayExpression* node) {
|
||||
for (auto& element : node->elements) {
|
||||
Visit(element);
|
||||
|
|
@ -590,7 +611,10 @@ void Visitor::Visit(Name* node) {
|
|||
|
||||
void Visitor::Visit(FunctionType* node) {
|
||||
for (auto& type : node->types) {
|
||||
Visit(type.get());
|
||||
if (type.first.has_value()) {
|
||||
Visit(&type.first.value());
|
||||
}
|
||||
Visit(type.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue