mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-09 16:38:45 +00:00
changes for new grammar, fixes
This commit is contained in:
parent
91f9affadc
commit
3106a64949
35 changed files with 605 additions and 550 deletions
|
|
@ -65,7 +65,7 @@ struct Constructor {
|
||||||
|
|
||||||
struct FunctionDeclaration {
|
struct FunctionDeclaration {
|
||||||
std::vector<Parameter> parameters;
|
std::vector<Parameter> parameters;
|
||||||
std::vector<interpreter::tokens::AnyType*> argument_types;
|
std::vector<interpreter::tokens::ExtendedScopedAnyType*> argument_types;
|
||||||
interpreter::tokens::FunctionDeclaration* node = nullptr;
|
interpreter::tokens::FunctionDeclaration* node = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -212,13 +212,14 @@ struct FunctionType;
|
||||||
struct TupleType;
|
struct TupleType;
|
||||||
struct VariantType;
|
struct VariantType;
|
||||||
struct TypeExpression;
|
struct TypeExpression;
|
||||||
struct TypeExpression;
|
|
||||||
|
using WrappedTypeExpression = TypeExpression;
|
||||||
|
|
||||||
using Constructor = std::string;
|
using Constructor = std::string;
|
||||||
|
|
||||||
// // ScopedAnyType <-> AnyType
|
// // ScopedAnyType <-> AnyType
|
||||||
using AnyType = std::variant<
|
using AnyType = std::variant<
|
||||||
std::unique_ptr<TypeExpression>,
|
std::unique_ptr<WrappedTypeExpression>,
|
||||||
std::unique_ptr<TupleType>,
|
std::unique_ptr<TupleType>,
|
||||||
std::unique_ptr<VariantType>,
|
std::unique_ptr<VariantType>,
|
||||||
std::unique_ptr<FunctionType>>;
|
std::unique_ptr<FunctionType>>;
|
||||||
|
|
@ -272,6 +273,8 @@ struct Namespace {
|
||||||
TypeIdentifier type;
|
TypeIdentifier type;
|
||||||
NamespaceSources scope;
|
NamespaceSources scope;
|
||||||
|
|
||||||
|
bool is_type_namespace = false; // TODO: use
|
||||||
|
|
||||||
std::optional<utils::IdType> link_type_id_;
|
std::optional<utils::IdType> link_type_id_;
|
||||||
std::optional<utils::IdType> link_typeclass_id_;
|
std::optional<utils::IdType> link_typeclass_id_;
|
||||||
};
|
};
|
||||||
|
|
@ -292,7 +295,7 @@ struct AliasDefinitionStatement {
|
||||||
utils::AliasModifier modifier;
|
utils::AliasModifier modifier;
|
||||||
TypeIdentifier type;
|
TypeIdentifier type;
|
||||||
std::vector<AbstractTypeIdentifier> parameters;
|
std::vector<AbstractTypeIdentifier> parameters;
|
||||||
std::unique_ptr<TypeExpression> value;
|
std::unique_ptr<WrappedTypeExpression> value;
|
||||||
|
|
||||||
utils::IdType type_id_ = 0;
|
utils::IdType type_id_ = 0;
|
||||||
};
|
};
|
||||||
|
|
@ -516,7 +519,7 @@ struct FunctionCallExpression {
|
||||||
BaseNode base;
|
BaseNode base;
|
||||||
|
|
||||||
std::optional<std::variant<std::unique_ptr<SubExpressionToken>,
|
std::optional<std::variant<std::unique_ptr<SubExpressionToken>,
|
||||||
std::unique_ptr<TypeExpression>>> prefix;
|
std::unique_ptr<WrappedTypeExpression>>> prefix;
|
||||||
NameOrOperatorIdentifier name;
|
NameOrOperatorIdentifier name;
|
||||||
std::vector<std::unique_ptr<TypeExpression>> parameters;
|
std::vector<std::unique_ptr<TypeExpression>> parameters;
|
||||||
std::vector<SubExpression> arguments;
|
std::vector<SubExpression> arguments;
|
||||||
|
|
@ -621,21 +624,21 @@ struct AnnotatedName {
|
||||||
struct FunctionType {
|
struct FunctionType {
|
||||||
BaseNode base;
|
BaseNode base;
|
||||||
|
|
||||||
std::vector<ScopedAnyType> types;
|
std::vector<std::unique_ptr<ExtendedScopedAnyType>> types;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TupleType {
|
struct TupleType {
|
||||||
BaseNode base;
|
BaseNode base;
|
||||||
|
|
||||||
std::optional<Constructor> type;
|
std::optional<TypeIdentifier> type;
|
||||||
std::vector<std::pair<std::optional<NameIdentifier>, std::unique_ptr<ExtendedScopedAnyType>>> entities;
|
std::vector<std::pair<std::optional<NameIdentifier>, std::unique_ptr<ExtendedScopedAnyType>>> entities;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VariantType {
|
struct VariantType {
|
||||||
BaseNode base;
|
BaseNode base;
|
||||||
|
|
||||||
std::optional<Constructor> type;
|
std::optional<TypeIdentifier> type;
|
||||||
std::vector<std::variant<Constructor, std::unique_ptr<TupleType>>> constructors;
|
std::vector<std::pair<std::optional<Constructor>, std::optional<std::unique_ptr<TupleType>>>> constructors;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParametrizedType {
|
struct ParametrizedType {
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,7 @@ const std::string FunctionType = "function_type";
|
||||||
const std::string TupleType = "tuple_type";
|
const std::string TupleType = "tuple_type";
|
||||||
const std::string VariantType = "variant_type";
|
const std::string VariantType = "variant_type";
|
||||||
const std::string TypeExpression = "type_expression";
|
const std::string TypeExpression = "type_expression";
|
||||||
|
const std::string WrappedTypeExpression = "wrapped_type_expression";
|
||||||
const std::string Constructor = "constructor";
|
const std::string Constructor = "constructor";
|
||||||
const std::string AnyType = "any_type";
|
const std::string AnyType = "any_type";
|
||||||
const std::string ScopedAnyType = "scoped_any_type";
|
const std::string ScopedAnyType = "scoped_any_type";
|
||||||
|
|
|
||||||
|
|
@ -105,23 +105,23 @@ inline std::optional<InternalType> ToInternalType(const std::string& type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type[0]) {
|
switch (type[0]) {
|
||||||
case 'F':
|
case 'f':
|
||||||
if (type == "Float") { return InternalType::Float; }
|
if (type == "float") { return InternalType::Float; }
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'i':
|
||||||
if (type == "Int") { return InternalType::Int; }
|
if (type == "int") { return InternalType::Int; }
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 's':
|
||||||
if (type == "String") { return InternalType::String; }
|
if (type == "string") { return InternalType::String; }
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'c':
|
||||||
if (type == "Char") { return InternalType::Char; }
|
if (type == "char") { return InternalType::Char; }
|
||||||
break;
|
break;
|
||||||
case 'B':
|
case 'b':
|
||||||
if (type == "Bool") { return InternalType::Bool; }
|
if (type == "bool") { return InternalType::Bool; }
|
||||||
break;
|
break;
|
||||||
case 'U':
|
case 'u':
|
||||||
if (type == "Unit") { return InternalType::Unit; }
|
if (type == "unit") { return InternalType::Unit; }
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -135,22 +135,22 @@ inline std::string ToString(InternalType type) {
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case InternalType::Float:
|
case InternalType::Float:
|
||||||
result = "Float";
|
result = "float";
|
||||||
break;
|
break;
|
||||||
case InternalType::Int:
|
case InternalType::Int:
|
||||||
result = "Int";
|
result = "int";
|
||||||
break;
|
break;
|
||||||
case InternalType::String:
|
case InternalType::String:
|
||||||
result = "String";
|
result = "string";
|
||||||
break;
|
break;
|
||||||
case InternalType::Char:
|
case InternalType::Char:
|
||||||
result = "Char";
|
result = "char";
|
||||||
break;
|
break;
|
||||||
case InternalType::Bool:
|
case InternalType::Bool:
|
||||||
result = "Bool";
|
result = "bool";
|
||||||
break;
|
break;
|
||||||
case InternalType::Unit:
|
case InternalType::Unit:
|
||||||
result = "Unit";
|
result = "unit";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -187,7 +187,7 @@ class VariantType {
|
||||||
public:
|
public:
|
||||||
VariantType() = default;
|
VariantType() = default;
|
||||||
VariantType(const std::optional<std::string>& name,
|
VariantType(const std::optional<std::string>& name,
|
||||||
const std::vector<TupleType>& constructors,
|
const std::vector<std::pair<std::string, std::optional<TupleType>>>& constructors,
|
||||||
std::optional<size_t> current_constructor)
|
std::optional<size_t> current_constructor)
|
||||||
: name_(name), constructors_(constructors), current_constructor_(current_constructor) {}
|
: name_(name), constructors_(constructors), current_constructor_(current_constructor) {}
|
||||||
|
|
||||||
|
|
@ -199,7 +199,7 @@ public:
|
||||||
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
||||||
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
||||||
|
|
||||||
const std::vector<TupleType>& GetConstructors() const {
|
const std::vector<std::pair<std::string, std::optional<TupleType>>>& GetConstructors() const {
|
||||||
return constructors_;
|
return constructors_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,7 +210,7 @@ public:
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
private:
|
private:
|
||||||
std::optional<std::string> name_;
|
std::optional<std::string> name_;
|
||||||
std::vector<TupleType> constructors_;
|
std::vector<std::pair<std::string, std::optional<TupleType>>> constructors_;
|
||||||
std::optional<size_t> current_constructor_;
|
std::optional<size_t> current_constructor_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ ValueType IsConstModifierToValueType(IsConstModifier modifier);
|
||||||
|
|
||||||
ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifier);
|
ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifier);
|
||||||
|
|
||||||
|
std::optional<char> ToEscapeSymbol(char symbol);
|
||||||
|
|
||||||
bool IsBuiltinFunction(const std::string& name);
|
bool IsBuiltinFunction(const std::string& name);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit e4696019cf4ec08e4d2c707297887ed9bc359499
|
Subproject commit 24bcf6e960957daf5662b764480f1d56637b1712
|
||||||
|
|
@ -62,7 +62,9 @@ void BuildVisitor::Visit(Namespace* node) {
|
||||||
node->modifier = utils::ClassInternalsModifier::Static;
|
node->modifier = utils::ClassInternalsModifier::Static;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->type = parse_node.ChildByFieldName("type").GetValue();
|
current_node_ = parse_node.ChildByFieldName("type");
|
||||||
|
node->type = current_node_.GetValue();
|
||||||
|
node->is_type_namespace = (current_node_.PreviousSibling().GetValue() == "\\");
|
||||||
|
|
||||||
current_node_ = parse_node.ChildByFieldName("scope");
|
current_node_ = parse_node.ChildByFieldName("scope");
|
||||||
Visit(&node->scope);
|
Visit(&node->scope);
|
||||||
|
|
@ -130,7 +132,7 @@ void BuildVisitor::Visit(AliasDefinitionStatement* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
current_node_ = parse_node.ChildByFieldName("value");
|
current_node_ = parse_node.ChildByFieldName("value");
|
||||||
node->value = std::make_unique<TypeExpression>();
|
node->value = std::make_unique<WrappedTypeExpression>();
|
||||||
Visit(node->value.get());
|
Visit(node->value.get());
|
||||||
|
|
||||||
current_node_ = parse_node;
|
current_node_ = parse_node;
|
||||||
|
|
@ -961,9 +963,9 @@ void BuildVisitor::Visit(FunctionCallExpression* node) {
|
||||||
node->prefix = std::make_unique<SubExpressionToken>();
|
node->prefix = std::make_unique<SubExpressionToken>();
|
||||||
Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()));
|
Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()));
|
||||||
++excluded_child_count;
|
++excluded_child_count;
|
||||||
} else if (current_node_type == parser::tokens::TypeExpression) {
|
} else if (current_node_type == parser::tokens::WrappedTypeExpression) {
|
||||||
node->prefix = std::make_unique<TypeExpression>();
|
node->prefix = std::make_unique<WrappedTypeExpression>();
|
||||||
Visit(std::get<std::unique_ptr<TypeExpression>>(node->prefix.value()).get());
|
Visit(std::get<std::unique_ptr<WrappedTypeExpression>>(node->prefix.value()).get());
|
||||||
++excluded_child_count;
|
++excluded_child_count;
|
||||||
} else {
|
} else {
|
||||||
// no prefix
|
// no prefix
|
||||||
|
|
@ -1282,7 +1284,8 @@ void BuildVisitor::Visit(FunctionType* node) {
|
||||||
|
|
||||||
for (size_t i = 0; i < types_count; ++i) {
|
for (size_t i = 0; i < types_count; ++i) {
|
||||||
current_node_ = parse_node.NthNamedChild(i);
|
current_node_ = parse_node.NthNamedChild(i);
|
||||||
Visit(node->types[i]);
|
node->types[i] = std::make_unique<ExtendedScopedAnyType>();
|
||||||
|
Visit(node->types[i].get());
|
||||||
}
|
}
|
||||||
|
|
||||||
current_node_ = parse_node;
|
current_node_ = parse_node;
|
||||||
|
|
@ -1340,19 +1343,28 @@ void BuildVisitor::Visit(VariantType* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
node->constructors.resize(child_count - excluded_child_count);
|
if (child_count > excluded_child_count) {
|
||||||
for (size_t i = 0; i < node->constructors.size(); ++i) {
|
node->constructors.reserve(child_count - excluded_child_count);
|
||||||
current_node_ = parse_node.NthNamedChild(i + excluded_child_count);
|
for (size_t i = 0; i < child_count - excluded_child_count; ++i) {
|
||||||
|
current_node_ = parse_node.NthNamedChild(i + excluded_child_count);
|
||||||
|
|
||||||
std::string current_node_type = current_node_.GetType();
|
std::string current_node_type = current_node_.GetType();
|
||||||
|
|
||||||
if (current_node_type == parser::tokens::Constructor) {
|
if (current_node_type == parser::tokens::Constructor) {
|
||||||
node->constructors[i] = current_node_.GetValue();
|
std::string constructor_name = current_node_.GetValue();
|
||||||
} else if (current_node_type == parser::tokens::TupleType) {
|
constructor_name = constructor_name.substr(1, constructor_name.size() - 1);
|
||||||
node->constructors[i] = std::make_unique<TupleType>();
|
node->constructors.push_back({constructor_name, std::nullopt});
|
||||||
Visit(std::get<std::unique_ptr<TupleType>>(node->constructors[i]).get());
|
} else if (current_node_type == parser::tokens::TupleType) {
|
||||||
} else {
|
if (!node->constructors.empty() && !node->constructors.back().second.has_value()) {
|
||||||
// error
|
node->constructors.back().second = std::make_unique<TupleType>();
|
||||||
|
Visit(node->constructors.back().second.value().get());
|
||||||
|
} else {
|
||||||
|
node->constructors.push_back({std::nullopt, std::make_unique<TupleType>()});
|
||||||
|
Visit(node->constructors.back().second.value().get());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1389,11 +1401,11 @@ void BuildVisitor::Visit(TypeExpression* node) {
|
||||||
|
|
||||||
node->is_optional = true;
|
node->is_optional = true;
|
||||||
} else {
|
} else {
|
||||||
if (suffix_node1.GetValue() == "_" && suffix_node2.GetValue() == "!") {
|
if (suffix_node1.GetValue() == "`" && suffix_node2.GetValue() == "?") {
|
||||||
node->array_size = 0;
|
node->array_size = 0;
|
||||||
|
|
||||||
node->is_optional = true;
|
node->is_optional = true;
|
||||||
} else if (suffix_node1.GetValue() == "_") {
|
} else if (suffix_node1.GetValue() == "`") {
|
||||||
current_node_ = suffix_node2;
|
current_node_ = suffix_node2;
|
||||||
|
|
||||||
NumberLiteral literal;
|
NumberLiteral literal;
|
||||||
|
|
@ -1407,9 +1419,9 @@ void BuildVisitor::Visit(TypeExpression* node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (suffix_node1.GetValue() == "_") {
|
if (suffix_node1.GetValue() == "`") {
|
||||||
node->array_size = 0;
|
node->array_size = 0;
|
||||||
} else if (suffix_node1.GetValue() == "!") {
|
} else if (suffix_node1.GetValue() == "?") {
|
||||||
node->is_optional = true;
|
node->is_optional = true;
|
||||||
} else {
|
} else {
|
||||||
error_handling::HandleInternalError("Undefined suffix (1 element)",
|
error_handling::HandleInternalError("Undefined suffix (1 element)",
|
||||||
|
|
@ -1438,9 +1450,9 @@ void BuildVisitor::Visit(AnyType& node) {
|
||||||
|
|
||||||
std::string current_node_type = current_node_.GetType();
|
std::string current_node_type = current_node_.GetType();
|
||||||
|
|
||||||
if (current_node_type == parser::tokens::TypeExpression) {
|
if (current_node_type == parser::tokens::WrappedTypeExpression) {
|
||||||
node = std::make_unique<TypeExpression>();
|
node = std::make_unique<WrappedTypeExpression>();
|
||||||
Visit(std::get<std::unique_ptr<TypeExpression>>(node).get());
|
Visit(std::get<std::unique_ptr<WrappedTypeExpression>>(node).get());
|
||||||
} else if (current_node_type == parser::tokens::TupleType) {
|
} else if (current_node_type == parser::tokens::TupleType) {
|
||||||
node = std::make_unique<TupleType>();
|
node = std::make_unique<TupleType>();
|
||||||
Visit(std::get<std::unique_ptr<TupleType>>(node).get());
|
Visit(std::get<std::unique_ptr<TupleType>>(node).get());
|
||||||
|
|
@ -1550,18 +1562,47 @@ void BuildVisitor::Visit(NumberLiteral* node) {
|
||||||
node->value = std::stoll(current_node_.GetValue());
|
node->value = std::stoll(current_node_.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildVisitor::Visit(StringLiteral* node) { // TODO: special symbols, etc.
|
void BuildVisitor::Visit(StringLiteral* node) { // TODO: other special symbols, etc.
|
||||||
SetPosition(node->base, current_node_);
|
SetPosition(node->base, current_node_);
|
||||||
|
|
||||||
std::string literal = current_node_.GetValue();
|
std::string literal = current_node_.GetValue();
|
||||||
node->value = literal.substr(1, literal.size() - 2);
|
literal = literal.substr(1, literal.size() - 2);
|
||||||
|
node->value.reserve(literal.size());
|
||||||
|
|
||||||
|
bool is_escape_symbol = false;
|
||||||
|
for (size_t i = 0; i < literal.size(); ++i) {
|
||||||
|
if (literal[i] == '\\' && !is_escape_symbol) {
|
||||||
|
is_escape_symbol = true;
|
||||||
|
} else {
|
||||||
|
if (is_escape_symbol) {
|
||||||
|
auto maybe_escape_symbol = utils::ToEscapeSymbol(literal[i]);
|
||||||
|
if (maybe_escape_symbol.has_value()) {
|
||||||
|
node->value += maybe_escape_symbol.value();
|
||||||
|
} else {
|
||||||
|
node->value += literal[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
node->value += literal[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildVisitor::Visit(CharLiteral* node) {
|
void BuildVisitor::Visit(CharLiteral* node) {
|
||||||
SetPosition(node->base, current_node_);
|
SetPosition(node->base, current_node_);
|
||||||
|
|
||||||
std::string literal = current_node_.GetValue();
|
std::string literal = current_node_.GetValue();
|
||||||
node->value = literal.substr(1, literal.size() - 2).back(); // TODO: special symbols, etc.
|
literal = literal.substr(2, literal.size() - 2); // TODO: other special symbols, etc.
|
||||||
|
if (literal[0] == '\\') {
|
||||||
|
auto maybe_escape_symbol = utils::ToEscapeSymbol(literal.back());
|
||||||
|
if (maybe_escape_symbol.has_value()) {
|
||||||
|
node->value = maybe_escape_symbol.value();
|
||||||
|
} else {
|
||||||
|
node->value = literal.back();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
node->value = literal.back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildVisitor::Visit(UnitLiteral* node) {
|
void BuildVisitor::Visit(UnitLiteral* node) {
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
||||||
|
|
||||||
info.argument_types.resize(node->type->types.size());
|
info.argument_types.resize(node->type->types.size());
|
||||||
for (size_t i = 0; i < node->type->types.size(); ++i) {
|
for (size_t i = 0; i < node->type->types.size(); ++i) {
|
||||||
info.argument_types[i] = &node->type->types[i];
|
info.argument_types[i] = node->type->types[i].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
info.node = node;
|
info.node = node;
|
||||||
|
|
|
||||||
|
|
@ -179,35 +179,18 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type,
|
||||||
if (std::holds_alternative<std::unique_ptr<interpreter::tokens::VariantType>>(any_type_info.node->value)) {
|
if (std::holds_alternative<std::unique_ptr<interpreter::tokens::VariantType>>(any_type_info.node->value)) {
|
||||||
interpreter::tokens::VariantType& variant_type_info = *std::get<std::unique_ptr<interpreter::tokens::VariantType>>(any_type_info.node->value);
|
interpreter::tokens::VariantType& variant_type_info = *std::get<std::unique_ptr<interpreter::tokens::VariantType>>(any_type_info.node->value);
|
||||||
for (size_t i = 0; i < variant_type_info.constructors.size(); ++i) {
|
for (size_t i = 0; i < variant_type_info.constructors.size(); ++i) {
|
||||||
std::string constructor_name;
|
|
||||||
definition::Constructor constructor_info;
|
definition::Constructor constructor_info;
|
||||||
|
|
||||||
constructor_info.type_id = id;
|
constructor_info.type_id = id;
|
||||||
constructor_info.order = i;
|
constructor_info.order = i;
|
||||||
|
|
||||||
if (std::holds_alternative<interpreter::tokens::Constructor>(variant_type_info.constructors[i])) {
|
if (variant_type_info.constructors[i].first.has_value()) {
|
||||||
constructor_name = std::get<interpreter::tokens::Constructor>(variant_type_info.constructors[i]);
|
constructor_info.name = variant_type_info.constructors[i].first.value();
|
||||||
} else if (std::holds_alternative<
|
|
||||||
std::unique_ptr<interpreter::tokens::TupleType>>(variant_type_info.constructors[i])) {
|
|
||||||
constructor_info.constructor_tuple_node =
|
|
||||||
std::get<std::unique_ptr<interpreter::tokens::TupleType>>(variant_type_info.constructors[i]).get();
|
|
||||||
|
|
||||||
auto maybe_constructor_name = constructor_info.constructor_tuple_node.value()->type;
|
|
||||||
|
|
||||||
if (maybe_constructor_name.has_value()) {
|
|
||||||
constructor_name = maybe_constructor_name.value();
|
|
||||||
} else {
|
|
||||||
constructor_name = type;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
error_handling::HandleInternalError("Unexprected VariantType constructor node type",
|
constructor_info.name = any_type_info.type.type;
|
||||||
"GlobalInfo.NamespaceVisitor.AddType",
|
|
||||||
&base_node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor_info.name = constructor_name;
|
AddConstructor(constructor_info.name, std::move(constructor_info), base_node);
|
||||||
|
|
||||||
AddConstructor(constructor_name, std::move(constructor_info), base_node);
|
|
||||||
}
|
}
|
||||||
} else if (std::holds_alternative<std::unique_ptr<interpreter::tokens::TupleType>>(any_type_info.node->value)) {
|
} else if (std::holds_alternative<std::unique_ptr<interpreter::tokens::TupleType>>(any_type_info.node->value)) {
|
||||||
definition::Constructor constructor_info;
|
definition::Constructor constructor_info;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,14 @@ void LinkSymbolsVisitor::Visit(Namespace* node) {
|
||||||
maybe_typeclass = namespace_visitor_.FindTypeclassId(node->type);
|
maybe_typeclass = namespace_visitor_.FindTypeclassId(node->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!node->is_type_namespace && (maybe_type.has_value() || maybe_typeclass.has_value())) {
|
||||||
|
error_handling::HandleNamesError("Not type / typeclass namespace has associated type / typeclass", node->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->is_type_namespace && !maybe_type.has_value() && !maybe_typeclass.has_value()) {
|
||||||
|
error_handling::HandleNamesError("Type / typeclass namespace has no associated type / typeclass", node->base);
|
||||||
|
}
|
||||||
|
|
||||||
if (maybe_type.has_value() && maybe_typeclass.has_value()) {
|
if (maybe_type.has_value() && maybe_typeclass.has_value()) {
|
||||||
error_handling::HandleNamesError("Ambigious namespace name (typeclass or type)", node->base);
|
error_handling::HandleNamesError("Ambigious namespace name (typeclass or type)", node->base);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ int main(int argc, char** argv) { // TODO, only test version
|
||||||
info::ContextManager<info::value::Value, info::value::ValueManager> context_manager;
|
info::ContextManager<info::value::Value, info::value::ValueManager> context_manager;
|
||||||
|
|
||||||
interpreter::BuildVisitor build_visitor(parse_tree);
|
interpreter::BuildVisitor build_visitor(parse_tree);
|
||||||
// interpreter::PrintVisitor print_visitor(std::cout);
|
interpreter::PrintVisitor print_visitor(std::cout);
|
||||||
interpreter::FindSymbolsVisitor find_symbols_visitor(global_info);
|
interpreter::FindSymbolsVisitor find_symbols_visitor(global_info);
|
||||||
interpreter::LinkSymbolsVisitor link_symbols_visitor(global_info);
|
interpreter::LinkSymbolsVisitor link_symbols_visitor(global_info);
|
||||||
interpreter::TypeCheckVisitor type_check_visitor(global_info, type_context_manager);
|
interpreter::TypeCheckVisitor type_check_visitor(global_info, type_context_manager);
|
||||||
|
|
@ -56,8 +56,8 @@ int main(int argc, char** argv) { // TODO, only test version
|
||||||
|
|
||||||
build_visitor.VisitSourceFile(source_file.get());
|
build_visitor.VisitSourceFile(source_file.get());
|
||||||
|
|
||||||
// std::cout << "\n---------------------------------- Untyped -------------------------------------\n\n";
|
std::cout << "\n---------------------------------- Untyped -------------------------------------\n\n";
|
||||||
// print_visitor.VisitSourceFile(source_file.get());
|
print_visitor.VisitSourceFile(source_file.get());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
find_symbols_visitor.VisitSourceFile(source_file.get());
|
find_symbols_visitor.VisitSourceFile(source_file.get());
|
||||||
|
|
@ -69,7 +69,7 @@ int main(int argc, char** argv) { // TODO, only test version
|
||||||
|
|
||||||
try {
|
try {
|
||||||
type_check_visitor.VisitSourceFile(source_file.get());
|
type_check_visitor.VisitSourceFile(source_file.get());
|
||||||
} catch (bool) { error_handling::HandleInternalError("type_check_visitor exception", "main", std::nullopt); }
|
} catch (...) { error_handling::HandleInternalError("type_check_visitor exception", "main", std::nullopt); }
|
||||||
|
|
||||||
std::optional<utils::IdType> maybe_main_partition_id = global_info.FindPartition({"main"});
|
std::optional<utils::IdType> maybe_main_partition_id = global_info.FindPartition({"main"});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,7 @@ void PrintVisitor::Visit(MatchCase* node) {
|
||||||
out_ << "[MatchCase | ";
|
out_ << "[MatchCase | ";
|
||||||
Visitor::Visit(node->value);
|
Visitor::Visit(node->value);
|
||||||
if (node->condition.has_value()) {
|
if (node->condition.has_value()) {
|
||||||
out_ << " ? ";
|
out_ << " ?? ";
|
||||||
Visitor::Visit(node->condition.value());
|
Visitor::Visit(node->condition.value());
|
||||||
}
|
}
|
||||||
if (node->statement.has_value()) {
|
if (node->statement.has_value()) {
|
||||||
|
|
@ -428,7 +428,7 @@ void PrintVisitor::Visit(FunctionCallExpression* node) {
|
||||||
} else {
|
} else {
|
||||||
// error
|
// error
|
||||||
}
|
}
|
||||||
out_ << ").";
|
out_ << ")..";
|
||||||
}
|
}
|
||||||
|
|
||||||
Visit(&node->name);
|
Visit(&node->name);
|
||||||
|
|
@ -554,7 +554,7 @@ void PrintVisitor::Visit(PartitionName* node) {
|
||||||
for (size_t i = 0; i < node->path.size(); ++i) {
|
for (size_t i = 0; i < node->path.size(); ++i) {
|
||||||
Visit(&node->path[i]);
|
Visit(&node->path[i]);
|
||||||
if (i + 1 < node->path.size()) {
|
if (i + 1 < node->path.size()) {
|
||||||
out_ << "::";
|
out_ << '.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out_ << ')';
|
out_ << ')';
|
||||||
|
|
@ -565,7 +565,7 @@ void PrintVisitor::Visit(NameExpression* node) {
|
||||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||||
Visit(&node->names[i]);
|
Visit(&node->names[i]);
|
||||||
if (i + 1 < node->names.size()) {
|
if (i + 1 < node->names.size()) {
|
||||||
out_ << "::";
|
out_ << '.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out_ << ')';
|
out_ << ')';
|
||||||
|
|
@ -612,7 +612,7 @@ void PrintVisitor::Visit(FunctionType* node) {
|
||||||
out_ << " -> ";
|
out_ << " -> ";
|
||||||
}
|
}
|
||||||
is_first = false;
|
is_first = false;
|
||||||
Visitor::Visit(type);
|
Visit(type.get());
|
||||||
}
|
}
|
||||||
out_ << ')';
|
out_ << ')';
|
||||||
}
|
}
|
||||||
|
|
@ -641,13 +641,14 @@ void PrintVisitor::Visit(VariantType* node) {
|
||||||
}
|
}
|
||||||
out_ << "] (";
|
out_ << "] (";
|
||||||
for (auto& constructor : node->constructors) {
|
for (auto& constructor : node->constructors) {
|
||||||
out_ << "| ";
|
out_ << "|";
|
||||||
if (std::holds_alternative<Constructor>(constructor)) {
|
if (constructor.first.has_value()) {
|
||||||
Visit(&std::get<Constructor>(constructor));
|
out_ << " ";
|
||||||
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
|
Visit(&constructor.first.value());
|
||||||
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
|
}
|
||||||
} else {
|
if (constructor.second.has_value()) {
|
||||||
// error
|
out_ << " ";
|
||||||
|
Visit(constructor.second.value().get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out_ << ')';
|
out_ << ')';
|
||||||
|
|
@ -667,7 +668,7 @@ void PrintVisitor::Visit(TypeExpression* node) {
|
||||||
out_ << "] (";
|
out_ << "] (";
|
||||||
for (auto& type : node->path) {
|
for (auto& type : node->path) {
|
||||||
Visit(&type);
|
Visit(&type);
|
||||||
out_ << "::";
|
out_ << '.';
|
||||||
}
|
}
|
||||||
Visit(&node->type);
|
Visit(&node->type);
|
||||||
out_ << ')';
|
out_ << ')';
|
||||||
|
|
|
||||||
|
|
@ -224,14 +224,14 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < node->definition->arguments.size(); ++i) {
|
for (size_t i = 0; i < node->definition->arguments.size(); ++i) {
|
||||||
Visitor::Visit(declaration->type->types[i]);
|
Visit(declaration->type->types[i].get());
|
||||||
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Const);
|
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Const);
|
||||||
if (!context_manager_.DefineVariable(node->definition->arguments[i], current_type_)) {
|
if (!context_manager_.DefineVariable(node->definition->arguments[i], current_type_)) {
|
||||||
error_handling::HandleTypecheckError("Can't define function argument variable: name redefinition", node->base);
|
error_handling::HandleTypecheckError("Can't define function argument variable: name redefinition", node->base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Visitor::Visit(declaration->type->types.back());
|
Visit(declaration->type->types.back().get());
|
||||||
utils::IdType returned_type = current_type_;
|
utils::IdType returned_type = current_type_;
|
||||||
|
|
||||||
returned_type_ = std::nullopt;
|
returned_type_ = std::nullopt;
|
||||||
|
|
@ -812,7 +812,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = index_shift; i < node->arguments.size(); ++i) {
|
for (size_t i = index_shift; i < node->arguments.size(); ++i) {
|
||||||
Visitor::Visit(function_declaration->type->types[i - index_shift]);
|
Visit(function_declaration->type->types[i - index_shift].get());
|
||||||
utils::IdType argument_type = TypeInContext(current_type_, context);
|
utils::IdType argument_type = TypeInContext(current_type_, context);
|
||||||
|
|
||||||
Visitor::Visit(node->arguments[i]);
|
Visitor::Visit(node->arguments[i]);
|
||||||
|
|
@ -847,7 +847,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Visitor::Visit(function_declaration->type->types.back());
|
Visit(function_declaration->type->types.back().get());
|
||||||
current_type_ = TypeInContext(current_type_, context);
|
current_type_ = TypeInContext(current_type_, context);
|
||||||
|
|
||||||
context_manager_.ExitContext();
|
context_manager_.ExitContext();
|
||||||
|
|
@ -871,14 +871,14 @@ void TypeCheckVisitor::Visit(TupleExpression* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(VariantExpression* node) {
|
void TypeCheckVisitor::Visit(VariantExpression* node) {
|
||||||
std::vector<info::type::TupleType> constructors;
|
std::vector<std::pair<std::string, std::optional<info::type::TupleType>>> constructors;
|
||||||
|
|
||||||
for (auto& expression : node->expressions) {
|
for (auto& expression : node->expressions) {
|
||||||
Visitor::Visit(expression);
|
Visitor::Visit(expression);
|
||||||
|
|
||||||
// TODO: deal with expression tuple types, etc, ??
|
// TODO: deal with expression tuple types, etc, ??
|
||||||
std::vector<std::pair<std::optional<std::string>, utils::IdType>> constructor_fields {{std::nullopt, current_type_}};
|
std::vector<std::pair<std::optional<std::string>, utils::IdType>> constructor_fields {{std::nullopt, current_type_}};
|
||||||
constructors.push_back(info::type::TupleType(std::nullopt, constructor_fields, context_manager_.GetValueManager()));
|
constructors.push_back({"", info::type::TupleType(std::nullopt, constructor_fields, context_manager_.GetValueManager())});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1170,14 +1170,14 @@ void TypeCheckVisitor::Visit(VariantName* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||||
if (type_value->GetConstructors()[i].GetFields().empty()) {
|
if (!type_value->GetConstructors()[i].second.has_value()) {
|
||||||
current_type_ = context_manager_.AddValue(
|
current_type_ = context_manager_.AddValue(
|
||||||
info::type::OptionalType(
|
info::type::OptionalType(
|
||||||
internal_to_abstract_type_.at(info::type::InternalType::Unit),
|
internal_to_abstract_type_.at(info::type::InternalType::Unit),
|
||||||
context_manager_.GetValueManager()),
|
context_manager_.GetValueManager()),
|
||||||
utils::IsConstModifierToValueType(is_const_definition_.value())); // TODO ??
|
utils::IsConstModifierToValueType(is_const_definition_.value())); // TODO ??
|
||||||
} else {
|
} else {
|
||||||
info::type::TupleType constructor_type_value = type_value->GetConstructors()[i];
|
info::type::TupleType constructor_type_value = type_value->GetConstructors()[i].second.value();
|
||||||
|
|
||||||
utils::IdType constructor_type =
|
utils::IdType constructor_type =
|
||||||
context_manager_.AddValue(std::move(constructor_type_value),
|
context_manager_.AddValue(std::move(constructor_type_value),
|
||||||
|
|
@ -1227,7 +1227,7 @@ void TypeCheckVisitor::Visit(FunctionType* node) {
|
||||||
std::vector<utils::IdType> argument_types(node->types.size());
|
std::vector<utils::IdType> argument_types(node->types.size());
|
||||||
|
|
||||||
for (auto& argument_type : node->types) {
|
for (auto& argument_type : node->types) {
|
||||||
Visitor::Visit(argument_type);
|
Visit(argument_type.get());
|
||||||
argument_types.push_back(current_type_);
|
argument_types.push_back(current_type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1262,24 +1262,25 @@ void TypeCheckVisitor::Visit(TupleType* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(VariantType* node) {
|
void TypeCheckVisitor::Visit(VariantType* node) {
|
||||||
std::vector<info::type::TupleType> constructors;
|
std::vector<std::pair<std::string, std::optional<info::type::TupleType>>> constructors;
|
||||||
|
|
||||||
constructors.reserve(node->constructors.size());
|
constructors.reserve(node->constructors.size());
|
||||||
for (auto& constructor : node->constructors) {
|
for (auto& constructor : node->constructors) {
|
||||||
if (std::holds_alternative<Constructor>(constructor)) {
|
if (!constructor.first.has_value() && !node->type.has_value()) {
|
||||||
std::vector<std::pair<std::optional<std::string>, utils::IdType>> constructor_fields;
|
error_handling::HandleTypecheckError("Constructor type not recognized", node->base);
|
||||||
constructors.push_back(info::type::TupleType(std::get<Constructor>(constructor), constructor_fields, context_manager_.GetValueManager()));
|
} // TODO: decide
|
||||||
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
|
|
||||||
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
|
constructors.push_back({constructor.first.has_value() ? constructor.first.value() : node->type.value(), std::nullopt}); // TODO: real constructor name, instead of variant name (names in namespaces, etc)
|
||||||
|
|
||||||
|
if (constructor.second.has_value()) {
|
||||||
|
Visit(constructor.second.value().get());
|
||||||
std::optional<info::type::TupleType*> maybe_constructor = context_manager_.GetValue<info::type::TupleType>(current_type_);
|
std::optional<info::type::TupleType*> maybe_constructor = context_manager_.GetValue<info::type::TupleType>(current_type_);
|
||||||
if (!maybe_constructor.has_value()) {
|
if (!maybe_constructor.has_value()) {
|
||||||
error_handling::HandleInternalError("Entity of VariantType is not TupleType",
|
error_handling::HandleInternalError("Entity of VariantType is not TupleType",
|
||||||
"TypeCheckVisitor.VariantType",
|
"TypeCheckVisitor.VariantType",
|
||||||
&node->base);
|
&node->base);
|
||||||
}
|
}
|
||||||
constructors.push_back(*maybe_constructor.value());
|
constructors.back().second = *maybe_constructor.value();
|
||||||
} else {
|
|
||||||
// error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -599,7 +599,7 @@ void TypedPrintVisitor::Visit(FunctionCallExpression* node) {
|
||||||
} else {
|
} else {
|
||||||
// error
|
// error
|
||||||
}
|
}
|
||||||
out_ << ").";
|
out_ << ")..";
|
||||||
}
|
}
|
||||||
|
|
||||||
Visit(&node->name);
|
Visit(&node->name);
|
||||||
|
|
@ -772,7 +772,7 @@ void TypedPrintVisitor::Visit(PartitionName* node) {
|
||||||
for (size_t i = 0; i < node->path.size(); ++i) {
|
for (size_t i = 0; i < node->path.size(); ++i) {
|
||||||
Visit(&node->path[i]);
|
Visit(&node->path[i]);
|
||||||
if (i + 1 < node->path.size()) {
|
if (i + 1 < node->path.size()) {
|
||||||
out_ << "::";
|
out_ << '.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out_ << ')';
|
out_ << ')';
|
||||||
|
|
@ -789,7 +789,7 @@ void TypedPrintVisitor::Visit(NameExpression* node) {
|
||||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||||
Visit(&node->names[i]);
|
Visit(&node->names[i]);
|
||||||
if (i + 1 < node->names.size()) {
|
if (i + 1 < node->names.size()) {
|
||||||
out_ << "::";
|
out_ << '.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out_ << ')';
|
out_ << ')';
|
||||||
|
|
@ -860,7 +860,7 @@ void TypedPrintVisitor::Visit(FunctionType* node) {
|
||||||
out_ << " -> ";
|
out_ << " -> ";
|
||||||
}
|
}
|
||||||
is_first = false;
|
is_first = false;
|
||||||
Visitor::Visit(type);
|
Visit(type.get());
|
||||||
}
|
}
|
||||||
out_ << ')';
|
out_ << ')';
|
||||||
}
|
}
|
||||||
|
|
@ -902,12 +902,13 @@ void TypedPrintVisitor::Visit(VariantType* node) {
|
||||||
out_ << "] (";
|
out_ << "] (";
|
||||||
for (auto& constructor : node->constructors) {
|
for (auto& constructor : node->constructors) {
|
||||||
out_ << "| ";
|
out_ << "| ";
|
||||||
if (std::holds_alternative<Constructor>(constructor)) {
|
if (constructor.first.has_value()) {
|
||||||
Visit(&std::get<Constructor>(constructor));
|
out_ << " ";
|
||||||
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
|
Visit(&constructor.first.value());
|
||||||
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
|
}
|
||||||
} else {
|
if (constructor.second.has_value()) {
|
||||||
// error
|
out_ << " ";
|
||||||
|
Visit(constructor.second.value().get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out_ << ')';
|
out_ << ')';
|
||||||
|
|
@ -932,7 +933,7 @@ void TypedPrintVisitor::Visit(TypeExpression* node) {
|
||||||
out_ << "] (";
|
out_ << "] (";
|
||||||
for (auto& type : node->path) {
|
for (auto& type : node->path) {
|
||||||
Visit(&type);
|
Visit(&type);
|
||||||
out_ << "::";
|
out_ << '.';
|
||||||
}
|
}
|
||||||
Visit(&node->type);
|
Visit(&node->type);
|
||||||
out_ << ')';
|
out_ << ')';
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,9 @@ std::string TupleType::ToString() const {
|
||||||
|
|
||||||
std::optional<utils::IdType> VariantType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
|
std::optional<utils::IdType> VariantType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
|
||||||
for (size_t i = 0; i < constructors_.size(); ++i) {
|
for (size_t i = 0; i < constructors_.size(); ++i) {
|
||||||
constructors_[i].InContext(context);
|
if (constructors_[i].second.has_value()) {
|
||||||
|
constructors_[i].second.value().InContext(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
@ -156,9 +158,20 @@ bool VariantType::Same(const VariantType& type) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < constructors_.size(); ++i) {
|
for (size_t i = 0; i < constructors_.size(); ++i) {
|
||||||
if (!constructors_[i].Same(constructors_[i])) {
|
|
||||||
|
if (constructors_[i].first != type.constructors_[i].first) { // TODO: decide
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (constructors_[i].second.has_value() != type.constructors_[i].second.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (constructors_[i].second.has_value()) {
|
||||||
|
if (!constructors_[i].second.value().Same(type.constructors_[i].second.value())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -184,8 +197,8 @@ bool VariantType::operator>(const VariantType& type) const {
|
||||||
|
|
||||||
std::optional<utils::IdType> VariantType::GetFieldType(const std::string& name,
|
std::optional<utils::IdType> VariantType::GetFieldType(const std::string& name,
|
||||||
const std::unordered_set<utils::IdType>& type_namespaces) const {
|
const std::unordered_set<utils::IdType>& type_namespaces) const {
|
||||||
if (current_constructor_.has_value()) {
|
if (current_constructor_.has_value() && constructors_.at(current_constructor_.value()).second.has_value()) {
|
||||||
return constructors_.at(current_constructor_.value()).GetFieldType(name, type_namespaces);
|
return constructors_[current_constructor_.value()].second.value().GetFieldType(name, type_namespaces);
|
||||||
}
|
}
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
@ -197,7 +210,10 @@ std::string VariantType::ToString() const {
|
||||||
|
|
||||||
for (auto& constructor : constructors_) {
|
for (auto& constructor : constructors_) {
|
||||||
result += "& ";
|
result += "& ";
|
||||||
result += constructor.ToString();
|
result += constructor.first;
|
||||||
|
if (constructor.second.has_value()) {
|
||||||
|
result += " " + constructor.second.value().ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result += ")";
|
result += ")";
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,29 @@ ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifier) {
|
||||||
exit(1); // unreachable
|
exit(1); // unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<char> ToEscapeSymbol(char symbol) {
|
||||||
|
switch (symbol) {
|
||||||
|
case 'a':
|
||||||
|
return '\a';
|
||||||
|
case 'b':
|
||||||
|
return '\b';
|
||||||
|
case 'e':
|
||||||
|
return '\e';
|
||||||
|
case 'f':
|
||||||
|
return '\f';
|
||||||
|
case 'n':
|
||||||
|
return '\n';
|
||||||
|
case 'r':
|
||||||
|
return '\r';
|
||||||
|
case 't':
|
||||||
|
return '\t';
|
||||||
|
case 'v':
|
||||||
|
return '\v';
|
||||||
|
default:
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool IsBuiltinFunction(const std::string& name) { // optimize ??
|
bool IsBuiltinFunction(const std::string& name) { // optimize ??
|
||||||
std::unordered_set<std::string> builtin_functions;
|
std::unordered_set<std::string> builtin_functions;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -583,7 +583,7 @@ void Visitor::Visit(AnnotatedName* node) {
|
||||||
|
|
||||||
void Visitor::Visit(FunctionType* node) {
|
void Visitor::Visit(FunctionType* node) {
|
||||||
for (auto& type : node->types) {
|
for (auto& type : node->types) {
|
||||||
Visit(type);
|
Visit(type.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -604,12 +604,11 @@ void Visitor::Visit(VariantType* node) {
|
||||||
Visit(&node->type.value());
|
Visit(&node->type.value());
|
||||||
}
|
}
|
||||||
for (auto& constructor : node->constructors) {
|
for (auto& constructor : node->constructors) {
|
||||||
if (std::holds_alternative<Constructor>(constructor)) {
|
if (constructor.first.has_value()) {
|
||||||
Visit(&std::get<Constructor>(constructor));
|
Visit(&constructor.first.value());
|
||||||
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
|
}
|
||||||
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
|
if (constructor.second.has_value()) {
|
||||||
} else {
|
Visit(constructor.second.value().get());
|
||||||
// error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
decl test_arrays : -> Unit
|
decl test-arrays : -> \unit
|
||||||
def test_arrays = {
|
def test-arrays = {
|
||||||
var arr1 = ,1 ,2 ,3
|
var arr1 = ,1 ,2 ,3
|
||||||
const arr2 = Int._array: 32
|
const arr2 = \int..array: 32
|
||||||
var arr3 = String._array: 11
|
var arr3 = \string..array: 11
|
||||||
const arr4 = 'a'--'z'
|
const arr4 = ''a--''z
|
||||||
const n = 100
|
const n = 100
|
||||||
var arr5 <- Int._new_array: 10
|
var arr5 <- \int..new-array: 10
|
||||||
|
|
||||||
var arr6 <- String._new_array: 10
|
var arr6 <- \string..new-array: 10
|
||||||
var arr6_reference = ^arr6
|
var arr6-reference = ^arr6
|
||||||
|
|
||||||
const elem1 = arr1`0
|
const elem1 = arr1`0
|
||||||
var elem2 = arr1`2
|
var elem2 = arr1`2
|
||||||
|
|
|
||||||
|
|
@ -1,59 +1,59 @@
|
||||||
struct Fruit =
|
struct \fruit =
|
||||||
| Apple
|
| $apple
|
||||||
| Orange
|
| $orange
|
||||||
| Banana
|
| $banana
|
||||||
|
|
||||||
struct Optional 'A =
|
struct \optional 'a =
|
||||||
| Some & 'A
|
| $some & 'a
|
||||||
| None
|
| $none
|
||||||
|
|
||||||
struct (Result : #Move) 'A 'B =
|
struct \result[#move] 'a 'b =
|
||||||
| & 'A
|
| & 'a
|
||||||
| Error & 'B
|
| $error & 'b
|
||||||
|
|
||||||
struct (Complex : #Value) =
|
struct \complex[#value] =
|
||||||
& Float
|
& \float
|
||||||
& Float
|
& \float
|
||||||
|
|
||||||
struct Task =
|
struct \task =
|
||||||
& name : String
|
& name : \string
|
||||||
& duration : Float!
|
& duration : \float?
|
||||||
|
|
||||||
class Employee =
|
class \employee =
|
||||||
& name : String
|
& name : \string
|
||||||
& role :
|
& role :
|
||||||
( | Director
|
( | $director
|
||||||
& importance : Float
|
& importance : \float
|
||||||
& share : Float
|
& share : \float
|
||||||
| Manager
|
| $manager
|
||||||
& productivity :
|
& productivity :
|
||||||
( Productivity
|
( \productivity
|
||||||
| .Low
|
| $.low
|
||||||
| .Average
|
| $.average
|
||||||
| .High
|
| $.high
|
||||||
& duration : Float
|
& duration : \float
|
||||||
& sleep_on_work :
|
& sleep-on-work :
|
||||||
(SleepOnWork
|
( \sleep-on-work
|
||||||
| ..Yes
|
| $..yes
|
||||||
| ..No
|
| $..no
|
||||||
))
|
))
|
||||||
& salary : Int
|
& salary : \int
|
||||||
| Programmer
|
| $programmer
|
||||||
& skills : Float
|
& skills : \float
|
||||||
& current_task : (Optional Task)
|
& current-task : \optional[task]
|
||||||
& salary : Int)
|
& salary : \int)
|
||||||
|
|
||||||
|
|
||||||
class Bag =
|
class \bag =
|
||||||
&
|
&
|
||||||
( | Apple
|
( | $apple
|
||||||
| Orange
|
| $orange
|
||||||
| Banana)
|
| $banana)
|
||||||
& bag_type :
|
& bag-type :
|
||||||
( | Small
|
( | $small
|
||||||
| Medium
|
| $medium
|
||||||
& weight_kg : Int
|
& weight-kg : \int
|
||||||
& weight_g : Int
|
& weight-g : \int
|
||||||
& weight_g : Int
|
& weight-mg : \int
|
||||||
| Big)
|
| $big)
|
||||||
& other_things : (Array Something)
|
& other-things : \array[something]
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,18 @@
|
||||||
namespace Employee {
|
namespace \employee {
|
||||||
decl gen_employee : Unit -> Employee
|
decl gen-employee : \unit -> \employee
|
||||||
def gen_employee = {
|
def gen-employee = {
|
||||||
var x = $@Complex & 11.3 & 15.87 // construct on heap
|
var x = $@complex & 11.3 & 15.87 // construct on heap
|
||||||
return
|
return
|
||||||
$Employee // construct on stack
|
$employee // construct on stack
|
||||||
& name = "John"
|
& name = "John"
|
||||||
& role =
|
& role =
|
||||||
($Manager
|
($manager
|
||||||
& "John"
|
& "John"
|
||||||
& productivity =
|
& productivity =
|
||||||
($Productivity::High
|
($productivity.high
|
||||||
& duration = 10.3
|
& duration = 10.3
|
||||||
& sleep_on_work = ($Productivity::SleepOnWork::No))
|
& sleep-on-work = ($productivity.sleep-on-work.no))
|
||||||
& salary = 123)
|
& salary = 123)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
class Employee =
|
|
||||||
& name : String
|
|
||||||
& role :
|
|
||||||
( | Director
|
|
||||||
& importance : Float
|
|
||||||
& share : Float
|
|
||||||
| Manager
|
|
||||||
& productivity :
|
|
||||||
( Productivity
|
|
||||||
| .Low
|
|
||||||
| .Average
|
|
||||||
| .High
|
|
||||||
& duration : Float
|
|
||||||
& sleep_on_work :
|
|
||||||
(SleepOnWork
|
|
||||||
| ..Yes
|
|
||||||
| ..No
|
|
||||||
))
|
|
||||||
& salary : Int
|
|
||||||
| Programmer
|
|
||||||
& skills : Float
|
|
||||||
& current_task : Optional Task
|
|
||||||
& salary : Int)
|
|
||||||
*/
|
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,28 @@
|
||||||
decl flow_control_test : -> Unit
|
decl flow-control-test : -> \unit
|
||||||
def flow_control_test = {
|
def flow-control-test = {
|
||||||
if (a < b ||. a == b) && (b < c) then IO.print: x
|
if (a < b ||. a == b) && (b < c) then \io..print: x
|
||||||
elif x < 0 then {
|
elif x < 0 then {
|
||||||
; x += 1
|
; x += 1
|
||||||
; IO.print: y
|
; \io..print: y
|
||||||
} else {
|
} else {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (a > 0) && not: (array.is_empty:) do {
|
while (a > 0) && not: (array..is-empty:) do {
|
||||||
; a -= 1
|
; a -= 1
|
||||||
; array.pop:
|
; array..pop:
|
||||||
}
|
}
|
||||||
|
|
||||||
while x < 10 do x +=. x + 3
|
while x < 10 do x +=. x + 3
|
||||||
|
|
||||||
for i in 0--y do {
|
for i in 0--y do {
|
||||||
; IO.print: i
|
; \io..print: i
|
||||||
}
|
}
|
||||||
|
|
||||||
for & i & j in (& 0--y & 0--k) do { // ??
|
for & i & j in (& 0--y & 0--k) do { // ??
|
||||||
; IO.print: 1
|
; \io..print: 1
|
||||||
; IO.print: 2
|
; \io..print: 2
|
||||||
; IO.print: 128
|
; \io..print: 128
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,62 @@
|
||||||
decl sum ('A : #Add) : 'A -> 'A -> 'A
|
decl sum 'a[#add] : 'a -> 'a -> 'a
|
||||||
def sum : a b = a + b
|
def sum : a b = a + b
|
||||||
|
|
||||||
decl fib : Int -> Int
|
decl fib : \int -> \int
|
||||||
def fib : n =
|
def fib : n =
|
||||||
match n with
|
match n with
|
||||||
| 0 | 1 -> 1
|
| 0 | 1 -> 1
|
||||||
| n ? n > 1 -> fib: (n - 1) + fib: n
|
| n ?? n > 1 -> fib: (n - 1) + fib: n
|
||||||
| _ -> error: "n must be positive"
|
| _ -> error: "n must be positive"
|
||||||
|
|
||||||
decl fact : Int -> Int
|
decl fact : \int -> \int
|
||||||
def fact : n =
|
def fact : n =
|
||||||
match n with
|
match n with
|
||||||
| 0 -> 1
|
| 0 -> 1
|
||||||
| n ? n > 0 -> n * fact: (n - 1)
|
| n ?? n > 0 -> n * fact: (n - 1)
|
||||||
| _ -> error: "n must be positive"
|
| _ -> error: "n must be positive"
|
||||||
|
|
||||||
decl find_prefix_hashes ('H : (#AccHash Char)) : String -> (Array 'H)
|
decl find-prefix-hashes 'h[#acc-hash[char]] : \string -> \array['h]
|
||||||
def find_prefix_hashes : str = {
|
def find-prefix-hashes : str = {
|
||||||
var hashes = (Array 'H).new: (str.size: + 1)
|
var hashes = \array['h]..new: (str..size: + 1)
|
||||||
|
|
||||||
; hashes`0 = 'H.of: str`0
|
; hashes`0 = 'h..of: str`0
|
||||||
for i in 1--hashes.size: do {
|
for i in 1--hashes..size: do {
|
||||||
; hashes`i = hashes`(i - 1)
|
; hashes`i = hashes`(i - 1)
|
||||||
; hashes`i.append: str`i
|
; hashes`i..append: str`i
|
||||||
}
|
}
|
||||||
|
|
||||||
return hashes
|
return hashes
|
||||||
}
|
}
|
||||||
|
|
||||||
alias Hash = (AccHash Char)
|
alias \hash = \acc-hash[char]
|
||||||
|
|
||||||
decl find_substring : String -> String -> (Array Index)
|
decl find-substring : \string -> \string -> \array[index]
|
||||||
def find_substring : str substr = {
|
def find-substring : str substr = {
|
||||||
var result = (Array Index).empty:
|
var result = \array[index]..empty:
|
||||||
|
|
||||||
const str_hashes = find_prefix_hashes Hash: str
|
const str-hashes = find-prefix-hashes:[hash] str
|
||||||
const substr_hash = Hash.of: substr
|
const substr-hash = \hash..of: substr
|
||||||
|
|
||||||
for i in 0--(str_hashes.size: - substr.size:) do {
|
for i in 0--(str-hashes..size: - substr..size:) do {
|
||||||
const part_hash = Hash.diff: str_hashes`(i + substr.size:) str_hashes`i
|
const part-hash = hash..diff: str-hashes`(i + substr..size:) str-hashes`i
|
||||||
|
|
||||||
if part_hash == substr_hash then {
|
if part-hash == substr-hash then {
|
||||||
; result.push: i
|
; result..push: i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
decl is_empty : -> Bool
|
decl is-empty : -> \bool
|
||||||
def is_empty = 0
|
def is-empty = 0
|
||||||
|
|
||||||
decl do_something : -> Unit
|
decl do-something : -> \unit
|
||||||
def do_something =
|
def do-something =
|
||||||
IO.print: "Hello World!"
|
\io..print: "Hello World!"
|
||||||
|
|
||||||
decl mul : Int -> Int -> Int
|
decl mul : \int -> \int -> \int
|
||||||
def mul : x y = x * y
|
def mul : x y = x * y
|
||||||
|
|
||||||
decl mul_10 : Int -> Int
|
decl mul-10 : \int -> \int
|
||||||
def mul_10 = mul: 10
|
def mul-10 = mul: 10
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
import "module"
|
import "module"
|
||||||
import "module" : func
|
import "module" : func
|
||||||
import "module" :
|
import "module" :
|
||||||
Type1
|
\type1
|
||||||
func1
|
func1
|
||||||
func2
|
func2
|
||||||
func3
|
func3
|
||||||
func4
|
func4
|
||||||
|
|
||||||
use ModuleNamespace = import "module"
|
use module-namespace = import "module"
|
||||||
|
|
||||||
use PartOfModuleNamespace =
|
use part-of-module-namespace =
|
||||||
import "module" :
|
import "module" :
|
||||||
func1
|
func1
|
||||||
func2
|
func2
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
decl test_lambdas : -> Unit
|
decl test-lambdas : -> \unit
|
||||||
def test_lambdas = {
|
def test-lambdas = {
|
||||||
const lambda1 = \x -> x * x
|
const lambda1 = \\x -> x * x
|
||||||
const lambda2 = \x -> x.hash:
|
const lambda2 = \\x -> x..hash:
|
||||||
const lambda3 = \x y -> x + y
|
const lambda3 = \\x y -> x + y
|
||||||
|
|
||||||
const lambda4 = \x -> {
|
const lambda4 = \\x -> {
|
||||||
; IO.print: x
|
; \io..print: x
|
||||||
const y = x + x
|
const y = x + x
|
||||||
return y
|
return y
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
decl fruit_cost : Fruit -> Int
|
decl fruit-cost : \fruit -> \int
|
||||||
def fruit_cost : fruit = {
|
def fruit-cost : fruit = {
|
||||||
var fruit_copy = fruit
|
var fruit-copy = fruit
|
||||||
return (match <- fruit_copy with // consuming match
|
return (match <- fruit-copy with // consuming match
|
||||||
| $Banana -> 11
|
| $banana -> 11
|
||||||
| $Apple | $Orange -> 7)
|
| $apple | $orange -> 7)
|
||||||
}
|
}
|
||||||
|
|
||||||
decl amount_to_string : Int -> Bool -> String
|
decl amount-to-string : \int -> \bool -> \string
|
||||||
def amount_to_string : x is_zero_separated = {
|
def amount-to-string : x is-zero-separated = {
|
||||||
const ans = match x with
|
const ans = match x with
|
||||||
| 0 ? is_zero_separated -> "Zero"
|
| 0 ?? is-zero-separated -> "Zero"
|
||||||
| 0 | 1 | 2 | 3 | 4 -> "Few"
|
| 0 | 1 | 2 | 3 | 4 -> "Few"
|
||||||
| x ? (5--9).contains: x -> "Several"
|
| x ?? (5--9)..contains: x -> "Several"
|
||||||
| x ? (10--19).contains: x -> "Pack"
|
| x ?? (10--19)..contains: x -> "Pack"
|
||||||
| _ -> "Lots"
|
| _ -> "Lots"
|
||||||
return ans
|
return ans
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
struct StructWithRef =
|
struct \struct-with-ref =
|
||||||
& @Int_0
|
& @\int`0
|
||||||
|
|
||||||
decl test_memory : -> Unit
|
decl test-memory : -> \unit
|
||||||
def test_memory = {
|
def test-memory = {
|
||||||
const unique_ref1 <- Int._new: 5
|
const unique-ref1 <- \int..new: 5
|
||||||
var unique_ref2 <- Array.of: 1 2 3
|
var unique-ref2 <- \array..of: 1 2 3
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,19 @@
|
||||||
namespace Namespace {
|
namespace some-namespace {
|
||||||
decl something : -> Unit
|
decl something : -> \unit
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Array {
|
namespace \array {
|
||||||
decl something : -> Unit
|
decl something : -> \unit
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Array {
|
namespace \array {
|
||||||
decl something : -> Unit
|
decl something : -> \unit
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace var Array {
|
namespace var \array {
|
||||||
decl something : -> Unit
|
decl something : -> \unit
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace const Array {
|
namespace const \array {
|
||||||
decl something : -> Unit
|
decl something : -> \unit
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
test All::Dev::Syntax::testing {
|
test all.dev.syntax.testing {
|
||||||
const a = 31
|
const a = 31
|
||||||
; do_something: a
|
; do-something: a
|
||||||
}
|
}
|
||||||
|
|
||||||
exec App::exe {
|
exec app.exe {
|
||||||
const b = true
|
const b = true
|
||||||
const c = false
|
const c = false
|
||||||
; do_something_different: b b c
|
; do-something-different: b b c
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,19 @@
|
||||||
basic (Float : #Ord #Div #Str)
|
basic \float[#ord #div #str]
|
||||||
basic (Int : #Ord #IDiv #Str)
|
basic \int[#ord #idiv #str]
|
||||||
basic (String : #Ord #Str #CharContainer #Copy)
|
basic \string[#ord #str #char-container #copy]
|
||||||
basic (Char : #Ord #Str #Copy)
|
basic \char[#ord #str #copy]
|
||||||
basic (Bool : #Ord #Str #Copy)
|
basic \bool[#ord #str #copy]
|
||||||
basic (Unit : #Str #Copy)
|
basic \unit[#str #copy]
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
decl not : Bool -> Bool
|
decl not : \bool -> \bool
|
||||||
def not : x =
|
def not : x =
|
||||||
(match x with
|
(match x with
|
||||||
| true -> false
|
| true -> false
|
||||||
| false -> true)
|
| false -> true)
|
||||||
|
|
||||||
decl ( && ) : Bool -> Bool -> Bool
|
decl ( && ) : \bool -> \bool -> \bool
|
||||||
def ( && ) : x y =
|
def ( && ) : x y =
|
||||||
match x with
|
match x with
|
||||||
| true -> (
|
| true -> (
|
||||||
|
|
@ -23,7 +23,7 @@ def ( && ) : x y =
|
||||||
)
|
)
|
||||||
| false -> false
|
| false -> false
|
||||||
|
|
||||||
decl ( || ) : Bool -> Bool -> Bool
|
decl ( || ) : \bool -> \bool -> \bool
|
||||||
def ( || ) : x y =
|
def ( || ) : x y =
|
||||||
match x with
|
match x with
|
||||||
| true -> true
|
| true -> true
|
||||||
|
|
@ -35,28 +35,28 @@ def ( || ) : x y =
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass CharContainer =
|
typeclass \char-container =
|
||||||
& var size : -> Int
|
& var size : -> \int
|
||||||
& var at : Int -> Char
|
& var at : \int -> \char
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass Move = // TODO
|
typeclass \move = // TODO
|
||||||
& var ( <- ) : Move -> Unit
|
& var ( <- ) : \move -> \unit
|
||||||
|
|
||||||
typeclass Copy =
|
typeclass \copy =
|
||||||
& var ( = ) : Copy -> Unit
|
& var ( = ) : \copy -> \unit
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass (Sum : #Copy) =
|
typeclass \sum[#copy] =
|
||||||
& var ( += ) : Sum -> Unit
|
& var ( += ) : \sum -> \unit
|
||||||
& var ( -= ) : Sum -> Unit
|
& var ( -= ) : \sum -> \unit
|
||||||
& var ( + ) : Sum -> Sum
|
& var ( + ) : \sum -> \sum
|
||||||
& var ( - ) : Sum -> Sum
|
& var ( - ) : \sum -> \sum
|
||||||
& zero : -> Sum
|
& zero : -> \sum
|
||||||
|
|
||||||
namespace var Sum {
|
namespace var \sum {
|
||||||
def ( + ) : x = {
|
def ( + ) : x = {
|
||||||
var ans = self
|
var ans = self
|
||||||
; ans += x
|
; ans += x
|
||||||
|
|
@ -70,11 +70,11 @@ namespace var Sum {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typeclass (Mult : #Sum) =
|
typeclass \mult[#sum] =
|
||||||
& var ( *= ) : Mult -> Unit
|
& var ( *= ) : \mult -> \unit
|
||||||
& var ( * ) : Mult -> Mult
|
& var ( * ) : \mult -> \mult
|
||||||
|
|
||||||
namespace var Mult {
|
namespace var \mult {
|
||||||
def ( * ) : x = {
|
def ( * ) : x = {
|
||||||
var ans = self
|
var ans = self
|
||||||
; ans *= x
|
; ans *= x
|
||||||
|
|
@ -82,19 +82,19 @@ namespace var Mult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typeclass (IDiv : #Mult) =
|
typeclass \idiv[#mult] =
|
||||||
& var div : IDiv -> IDiv
|
& var div : \idiv -> \idiv
|
||||||
& var mod : IDiv -> IDiv
|
& var mod : \idiv -> \idiv
|
||||||
|
|
||||||
namespace var IDiv {
|
namespace var \idiv {
|
||||||
def mod : x = self -. x * self.div: x
|
def mod : x = self -. x * self..div: x
|
||||||
}
|
}
|
||||||
|
|
||||||
typeclass (Div : #Mult) =
|
typeclass \div[#mult] =
|
||||||
& var ( /= ) : Div -> Unit
|
& var ( /= ) : \div -> \unit
|
||||||
& var ( / ) : Div -> Div
|
& var ( / ) : \div -> \div
|
||||||
|
|
||||||
namespace var Div {
|
namespace var \div {
|
||||||
def ( / ) : x = {
|
def ( / ) : x = {
|
||||||
var ans = self
|
var ans = self
|
||||||
; ans /= x
|
; ans /= x
|
||||||
|
|
@ -104,39 +104,39 @@ namespace var Div {
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass Eq =
|
typeclass \eq =
|
||||||
& var ( == ) : Eq -> Bool
|
& var ( == ) : \eq -> \bool
|
||||||
& var ( != ) : Eq -> Bool
|
& var ( != ) : \eq -> \bool
|
||||||
|
|
||||||
namespace var Eq {
|
namespace var \eq {
|
||||||
def ( != ) : x = not: (self == x)
|
def ( != ) : x = not: (self == x)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
struct Order =
|
struct \order =
|
||||||
| EQ
|
| $eq
|
||||||
| LT
|
| $lt
|
||||||
| GT
|
| $gt
|
||||||
|
|
||||||
typeclass (Ord : #Eq) =
|
typeclass \ord[#eq] =
|
||||||
& var compare : Ord -> Order
|
& var compare : \ord -> \order
|
||||||
& var ( < ) : Ord -> Bool
|
& var ( < ) : \ord -> \bool
|
||||||
& var ( >= ) : Ord -> Bool
|
& var ( >= ) : \ord -> \bool
|
||||||
& var ( > ) : Ord -> Bool
|
& var ( > ) : \ord -> \bool
|
||||||
& var ( <= ) : Ord -> Bool
|
& var ( <= ) : \ord -> \bool
|
||||||
|
|
||||||
decl min ('A : #Ord) : 'A -> 'A -> 'A
|
decl min 'a[#ord] : 'a -> 'a -> 'a
|
||||||
def min : x y = if x < y then x else y
|
def min : x y = if x < y then x else y
|
||||||
|
|
||||||
decl max ('A : #Ord) : 'A -> 'A -> 'A
|
decl max 'a[#ord] : 'a -> 'a -> 'a
|
||||||
def max : x y = if x < y then y else x
|
def max : x y = if x < y then y else x
|
||||||
|
|
||||||
namespace var Ord {
|
namespace var \ord {
|
||||||
def compare : x =
|
def compare : x =
|
||||||
if self == x then $EQ
|
if self == x then $eq
|
||||||
elif self < x then $LT
|
elif self < x then $lt
|
||||||
else $GT
|
else $gt
|
||||||
|
|
||||||
def ( >= ) : x = not: (self < x)
|
def ( >= ) : x = not: (self < x)
|
||||||
def ( > ) : x = x < self
|
def ( > ) : x = x < self
|
||||||
|
|
@ -145,44 +145,45 @@ namespace var Ord {
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass Show =
|
typeclass \show =
|
||||||
& var show : -> String
|
& var show : -> \string
|
||||||
|
|
||||||
typeclass Read =
|
typeclass \read =
|
||||||
& read : String -> Read
|
& read : \string -> \read
|
||||||
|
|
||||||
typeclass (Str : #Show #Read)
|
typeclass \str[#show #read]
|
||||||
|
|
||||||
// typeclass DebugShow = // TODO
|
// typeclass debug-show = // TODO
|
||||||
// & debug_show : -> String
|
// & debugdshow : -> \string
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass Default =
|
typeclass \default =
|
||||||
& default : -> Default
|
& default : -> \default
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass Bounded =
|
typeclass \bounded =
|
||||||
& min_bound : -> Bounded
|
& min-bound : -> \bounded
|
||||||
& max_bound : -> Bounded
|
& max-bound : -> \bounded
|
||||||
& var is_max_bound : -> Bool
|
& var is-max-bound : -> \bool
|
||||||
& var is_min_bound : -> Bool
|
& var is-min-bound : -> \bool
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass Enum =
|
typeclass \enum =
|
||||||
& var succ : -> (Optional Enum)
|
& var succ : -> \optional[enum]
|
||||||
& var pred : -> (Optional Enum)
|
& var pred : -> \optional[enum]
|
||||||
& to_enum : Int -> Enum
|
& to-enum : \int -> \enum
|
||||||
& var from_enum : -> Int
|
& var from-enum : -> \int
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
namespace IO {
|
namespace io {
|
||||||
decl print : String -> Unit
|
decl print : \string -> \unit
|
||||||
decl scan : -> String
|
decl scan : -> \string
|
||||||
decl random : -> Int // TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decl random : -> \int // TODO
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,19 @@
|
||||||
basic (Float : #Ord #Div #Str)
|
basic \float[#ord #div #str]
|
||||||
basic (Int : #Ord #IDiv #Str)
|
basic \int[#ord #idiv #str]
|
||||||
basic (String : #Ord #Str #CharContainer #Copy)
|
basic \string[#ord #str #char-container #copy]
|
||||||
basic (Char : #Ord #Str #Copy)
|
basic \char[#ord #str #copy]
|
||||||
basic (Bool : #Ord #Str #Copy)
|
basic \bool[#ord #str #copy]
|
||||||
basic (Unit : #Str #Copy)
|
basic \unit[#str #copy]
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
decl not : Bool -> Bool
|
decl not : \bool -> \bool
|
||||||
def not : x =
|
def not : x =
|
||||||
(match x with
|
(match x with
|
||||||
| true -> false
|
| true -> false
|
||||||
| false -> true)
|
| false -> true)
|
||||||
|
|
||||||
decl ( && ) : Bool -> Bool -> Bool
|
decl ( && ) : \bool -> \bool -> \bool
|
||||||
def ( && ) : x y =
|
def ( && ) : x y =
|
||||||
match x with
|
match x with
|
||||||
| true -> (
|
| true -> (
|
||||||
|
|
@ -23,7 +23,7 @@ def ( && ) : x y =
|
||||||
)
|
)
|
||||||
| false -> false
|
| false -> false
|
||||||
|
|
||||||
decl ( || ) : Bool -> Bool -> Bool
|
decl ( || ) : \bool -> \bool -> \bool
|
||||||
def ( || ) : x y =
|
def ( || ) : x y =
|
||||||
match x with
|
match x with
|
||||||
| true -> true
|
| true -> true
|
||||||
|
|
@ -35,28 +35,28 @@ def ( || ) : x y =
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass CharContainer =
|
typeclass \char-container =
|
||||||
& var size : -> Int
|
& var size : -> \int
|
||||||
& var at : Int -> Char
|
& var at : \int -> \char
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass Move = // TODO
|
typeclass \move = // TODO
|
||||||
& var ( <- ) : Move -> Unit
|
& var ( <- ) : \move -> \unit
|
||||||
|
|
||||||
typeclass Copy =
|
typeclass \copy =
|
||||||
& var ( = ) : Copy -> Unit
|
& var ( = ) : \copy -> \unit
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass (Sum : #Copy) =
|
typeclass \sum[#copy] =
|
||||||
& var ( += ) : Sum -> Unit
|
& var ( += ) : \sum -> \unit
|
||||||
& var ( -= ) : Sum -> Unit
|
& var ( -= ) : \sum -> \unit
|
||||||
& var ( + ) : Sum -> Sum
|
& var ( + ) : \sum -> \sum
|
||||||
& var ( - ) : Sum -> Sum
|
& var ( - ) : \sum -> \sum
|
||||||
& zero : -> Sum
|
& zero : -> \sum
|
||||||
|
|
||||||
namespace var Sum {
|
namespace var \sum {
|
||||||
def ( + ) : x = {
|
def ( + ) : x = {
|
||||||
var ans = self
|
var ans = self
|
||||||
; ans += x
|
; ans += x
|
||||||
|
|
@ -70,11 +70,11 @@ namespace var Sum {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typeclass (Mult : #Sum) =
|
typeclass \mult[#sum] =
|
||||||
& var ( *= ) : Mult -> Unit
|
& var ( *= ) : \mult -> \unit
|
||||||
& var ( * ) : Mult -> Mult
|
& var ( * ) : \mult -> \mult
|
||||||
|
|
||||||
namespace var Mult {
|
namespace var \mult {
|
||||||
def ( * ) : x = {
|
def ( * ) : x = {
|
||||||
var ans = self
|
var ans = self
|
||||||
; ans *= x
|
; ans *= x
|
||||||
|
|
@ -82,19 +82,19 @@ namespace var Mult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typeclass (IDiv : #Mult) =
|
typeclass \idiv[#mult] =
|
||||||
& var div : IDiv -> IDiv
|
& var div : \idiv -> \idiv
|
||||||
& var mod : IDiv -> IDiv
|
& var mod : \idiv -> \idiv
|
||||||
|
|
||||||
namespace var IDiv {
|
namespace var \idiv {
|
||||||
def mod : x = self -. x * self.div: x
|
def mod : x = self -. x * self..div: x
|
||||||
}
|
}
|
||||||
|
|
||||||
typeclass (Div : #Mult) =
|
typeclass \div[#mult] =
|
||||||
& var ( /= ) : Div -> Unit
|
& var ( /= ) : \div -> \unit
|
||||||
& var ( / ) : Div -> Div
|
& var ( / ) : \div -> \div
|
||||||
|
|
||||||
namespace var Div {
|
namespace var \div {
|
||||||
def ( / ) : x = {
|
def ( / ) : x = {
|
||||||
var ans = self
|
var ans = self
|
||||||
; ans /= x
|
; ans /= x
|
||||||
|
|
@ -104,39 +104,39 @@ namespace var Div {
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass Eq =
|
typeclass \eq =
|
||||||
& var ( == ) : Eq -> Bool
|
& var ( == ) : \eq -> \bool
|
||||||
& var ( != ) : Eq -> Bool
|
& var ( != ) : \eq -> \bool
|
||||||
|
|
||||||
namespace var Eq {
|
namespace var \eq {
|
||||||
def ( != ) : x = not: (self == x)
|
def ( != ) : x = not: (self == x)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
struct Order =
|
struct \order =
|
||||||
| EQ
|
| $eq
|
||||||
| LT
|
| $lt
|
||||||
| GT
|
| $gt
|
||||||
|
|
||||||
typeclass (Ord : #Eq) =
|
typeclass \ord[#eq] =
|
||||||
& var compare : Ord -> Order
|
& var compare : \ord -> \order
|
||||||
& var ( < ) : Ord -> Bool
|
& var ( < ) : \ord -> \bool
|
||||||
& var ( >= ) : Ord -> Bool
|
& var ( >= ) : \ord -> \bool
|
||||||
& var ( > ) : Ord -> Bool
|
& var ( > ) : \ord -> \bool
|
||||||
& var ( <= ) : Ord -> Bool
|
& var ( <= ) : \ord -> \bool
|
||||||
|
|
||||||
decl min ('A : #Ord) : 'A -> 'A -> 'A
|
decl min 'a[#ord] : 'a -> 'a -> 'a
|
||||||
def min : x y = if x < y then x else y
|
def min : x y = if x < y then x else y
|
||||||
|
|
||||||
decl max ('A : #Ord) : 'A -> 'A -> 'A
|
decl max 'a[#ord] : 'a -> 'a -> 'a
|
||||||
def max : x y = if x < y then y else x
|
def max : x y = if x < y then y else x
|
||||||
|
|
||||||
namespace var Ord {
|
namespace var \ord {
|
||||||
def compare : x =
|
def compare : x =
|
||||||
if self == x then $EQ
|
if self == x then $eq
|
||||||
elif self < x then $LT
|
elif self < x then $lt
|
||||||
else $GT
|
else $gt
|
||||||
|
|
||||||
def ( >= ) : x = not: (self < x)
|
def ( >= ) : x = not: (self < x)
|
||||||
def ( > ) : x = x < self
|
def ( > ) : x = x < self
|
||||||
|
|
@ -145,63 +145,64 @@ namespace var Ord {
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass Show =
|
typeclass \show =
|
||||||
& var show : -> String
|
& var show : -> \string
|
||||||
|
|
||||||
typeclass Read =
|
typeclass \read =
|
||||||
& read : String -> Read
|
& read : \string -> \read
|
||||||
|
|
||||||
typeclass (Str : #Show #Read)
|
typeclass \str[#show #read]
|
||||||
|
|
||||||
// typeclass DebugShow = // TODO
|
// typeclass debug-show = // TODO
|
||||||
// & debug_show : -> String
|
// & debugdshow : -> \string
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass Default =
|
typeclass \default =
|
||||||
& default : -> Default
|
& default : -> \default
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass Bounded =
|
typeclass \bounded =
|
||||||
& min_bound : -> Bounded
|
& min-bound : -> \bounded
|
||||||
& max_bound : -> Bounded
|
& max-bound : -> \bounded
|
||||||
& var is_max_bound : -> Bool
|
& var is-max-bound : -> \bool
|
||||||
& var is_min_bound : -> Bool
|
& var is-min-bound : -> \bool
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
typeclass Enum =
|
typeclass \enum =
|
||||||
& var succ : -> (Optional Enum)
|
& var succ : -> \optional[enum]
|
||||||
& var pred : -> (Optional Enum)
|
& var pred : -> \optional[enum]
|
||||||
& to_enum : Int -> Enum
|
& to-enum : \int -> \enum
|
||||||
& var from_enum : -> Int
|
& var from-enum : -> \int
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
namespace IO {
|
namespace io {
|
||||||
decl print : String -> Unit
|
decl print : \string -> \unit
|
||||||
decl scan : -> String
|
decl scan : -> \string
|
||||||
decl random : -> Int // TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
decl random : -> \int // TODO
|
||||||
|
|
||||||
// // bad
|
|
||||||
// typeclass Functor 'A =
|
|
||||||
// & fmap 'B ('F : (#Functor 'B)) : ('A -> 'B) -> Functor -> 'F
|
|
||||||
|
|
||||||
// typeclass (Iterator : #Eq) =
|
|
||||||
// & next : -> Unit
|
|
||||||
// & prev : -> Unit
|
|
||||||
//
|
|
||||||
// typeclass Iterable ('Iter : #Iterable) =
|
|
||||||
// & begin : -> 'Iter
|
|
||||||
// & end : -> 'Iter
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
decl ( -- ) : Int -> Int -> Int_0
|
// // // bad
|
||||||
|
// // typeclass \functor 'a =
|
||||||
|
// // & fmap 'b ('f[#functor['b]]) : ('a -> 'b) -> \functor -> 'f
|
||||||
|
//
|
||||||
|
// // typeclass \iterator[#eq] =
|
||||||
|
// // & next : -> \unit
|
||||||
|
// // & prev : -> \unit
|
||||||
|
//
|
||||||
|
// // typeclass \iterable 'iter[#iterable] =
|
||||||
|
// // & begin : -> 'iter
|
||||||
|
// // & end : -> 'iter
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
decl ( -- ) : \int -> \int -> \int`0
|
||||||
def ( -- ) : begin end = {
|
def ( -- ) : begin end = {
|
||||||
var current = begin
|
var current = begin
|
||||||
return (while current < end do {
|
return (while current < end do {
|
||||||
|
|
@ -210,11 +211,11 @@ def ( -- ) : begin end = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// decl func : String -> Int -> Int
|
// decl func : \string -> \int -> \int
|
||||||
// def func : s i = {
|
// def func : s i = {
|
||||||
// ; print: s
|
// ; print: s
|
||||||
// var x = s
|
// var x = s
|
||||||
// ; print: (i.show:)
|
// ; print: (i..show:)
|
||||||
// return 5
|
// return 5
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
|
@ -227,60 +228,60 @@ def ( -- ) : begin end = {
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
decl scan_int : -> Int
|
decl scan-int : -> \int
|
||||||
def scan_int = Int.read: (IO.scan:)
|
def scan-int = \int..read: (\io..scan:)
|
||||||
|
|
||||||
decl print_int : Int -> Unit
|
decl print-int : \int -> \unit
|
||||||
def print_int : x = IO.print: (x.show:)
|
def print-int : x = \io..print: (x..show:)
|
||||||
|
|
||||||
decl scan_anything ('A : #Read) : -> 'A
|
decl scan-anything 'a[#read] : -> 'a
|
||||||
def scan_anything = 'A.read: (IO.scan:)
|
def scan-anything = 'a..read: (\io..scan:)
|
||||||
|
|
||||||
decl print_anything ('A : #Show) : 'A -> Unit
|
decl print-anything 'a[#show] : 'a -> \unit
|
||||||
def print_anything : x = IO.print: (x.show:)
|
def print-anything : x = \io..print: (x..show:)
|
||||||
|
|
||||||
// decl sorted ('A : #Ord #Copy): 'A_0 -> Int -> 'A_0
|
// decl sorted 'a[#ord #copy]: 'a`0 -> \int -> 'a`0
|
||||||
// def sorted : a sz = {
|
// def sorted : a sz = {
|
||||||
// var a_copy = a
|
// var a-copy = a
|
||||||
// if sz == 2 then {
|
// if sz == 2 then {
|
||||||
// if a_copy`0 > a_copy`1 then {
|
// if a-copy`0 > a-copy`1 then {
|
||||||
// var x = a_copy`0
|
// var x = a-copy`0
|
||||||
// a_copy`0 = a_copy`1
|
// a-copy`0 = a-copy`1
|
||||||
// a_copy`1 = x
|
// a-copy`1 = x
|
||||||
// }
|
// }
|
||||||
// return a_copy
|
// return a-copy
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// var center = sz.div: 2
|
// var center = sz..div: 2
|
||||||
//
|
//
|
||||||
// var a_left = for i in 0--center do a`i
|
// var a-left = for i in 0--center do a`i
|
||||||
// var a_right = for i in center-sz do a`i
|
// var a-right = for i in center-sz do a`i
|
||||||
//
|
//
|
||||||
// return a_copy
|
// return a-copy
|
||||||
// }
|
// }
|
||||||
|
|
||||||
struct Array 'A = & 'A // 'A_0
|
// struct \array 'a = & 'a // 'a`0
|
||||||
|
|
||||||
// namespace Array {
|
// namespace \array {
|
||||||
// decl of : 'A_0 -> (Array 'A)
|
// decl of : 'a`0 -> \array['a]
|
||||||
// def of : x = $(Array 'A) & data = x
|
// def of : x = $array['a] & data = x
|
||||||
// }
|
// }
|
||||||
|
|
||||||
struct ThreeTuple = & String & String & String
|
struct \three-tuple = & \string & \string & \string
|
||||||
|
|
||||||
decl scan_three_t : -> ThreeTuple
|
decl scan-three-t : -> \three-tuple
|
||||||
def scan_three_t = $ThreeTuple & IO.scan: & IO.scan: & IO.scan:
|
def scan-three-t = $three-tuple & \io..scan: & \io..scan: & \io..scan:
|
||||||
|
|
||||||
decl scan_three : -> (& String & String & String)
|
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 = scan_anything Int:
|
var n = scan-anything:[int]
|
||||||
var x = $(Array Int) & 0 // (for _ in 0--n do scan_int:)
|
var x = (for _ in 0--n do scan-int:) // $array[int] & 0
|
||||||
; print_anything Int: n
|
; print-anything:[int] n
|
||||||
|
|
||||||
var & a & b & c = scan_three_t:
|
var & a & b & c = scan-three-t:
|
||||||
; IO.print: b
|
; \io..print: b
|
||||||
var & d & e & f = scan_three:
|
var & d & e & f = scan-three:
|
||||||
; IO.print: e
|
; \io..print: e
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
decl test_tuples : -> Unit
|
decl test-tuples : -> \unit
|
||||||
def test_tuples = {
|
def test-tuples = {
|
||||||
var tuple1 = & "a" & 2 & "hello"
|
var tuple1 = & ''a & 2 & "hello"
|
||||||
const & t1 & t2 & t3 = f: x
|
const & t1 & t2 & t3 = f: x
|
||||||
|
|
||||||
; tuple1`0 = "b"
|
; tuple1`0 = ''b
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
decl test_type_casting : -> Unit
|
decl test-type-casting : -> \unit
|
||||||
def test_type_casting = {
|
def test-type-casting = {
|
||||||
var x = y.as Int:
|
var x = y..as:[int]
|
||||||
var k = (f: y x).as Float:
|
var k = (f: y x)..as:[float]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,29 @@
|
||||||
typeclass Default =
|
typeclass \default =
|
||||||
& default : -> Copy
|
& default : -> \default
|
||||||
|
|
||||||
typeclass (Ord : #Eq) =
|
typeclass \ord[#eq] =
|
||||||
& var is_less_then : Ord -> Bool
|
& var is-less-then : \ord -> \bool
|
||||||
|
|
||||||
typeclass (D : #A #B #C) 'A 'B =
|
typeclass \d[#a #b #c] 'a 'b =
|
||||||
& var do_something : -> (& 'A & 'B)
|
& var do-something : -> (& 'a & 'b)
|
||||||
|
|
||||||
typeclass E 'A =
|
typeclass \e 'a =
|
||||||
& var do_something : -> 'A
|
& var do-something : -> 'a
|
||||||
|
|
||||||
decl ( == ) ('A : #Ord) : 'A -> 'A -> Bool
|
decl ( == ) 'a[#ord] : 'a -> 'a -> \bool
|
||||||
def ( == ) : a b = a.is_equal_to: b
|
def ( == ) : a b = a..is-equal-to: b
|
||||||
|
|
||||||
decl ( != ) ('A : #Ord) : 'A -> 'A -> Bool
|
decl ( != ) 'a[#ord] : 'a -> 'a -> \bool
|
||||||
def ( != ) : a b = not: (a == b)
|
def ( != ) : a b = not: (a == b)
|
||||||
|
|
||||||
decl ( < ) ('A : #Ord) : 'A -> 'A -> Bool
|
decl ( < ) 'a[#ord] : 'a -> 'a -> \bool
|
||||||
def ( < ) : a b = a.is_less_then: b
|
def ( < ) : a b = a..is-less-then: b
|
||||||
|
|
||||||
decl ( > ) ('A : #Ord) : 'A -> 'A -> Bool
|
decl ( > ) 'a[#ord] : 'a -> 'a -> \bool
|
||||||
def ( > ) : a b = not: (a <= b)
|
def ( > ) : a b = not: (a <= b)
|
||||||
|
|
||||||
decl ( <= ) ('A : #Ord) : 'A -> 'A -> Bool
|
decl ( <= ) 'a[#ord] : 'a -> 'a -> \bool
|
||||||
def ( <= ) : a b = a < b ||. a == b
|
def ( <= ) : a b = a < b ||. a == b
|
||||||
|
|
||||||
decl ( >= ) ('A : #Ord) : 'A -> 'A -> Bool
|
decl ( >= ) 'a[#ord] : 'a -> 'a -> \bool
|
||||||
def ( >= ) : a b = not: (a < b)
|
def ( >= ) : a b = not: (a < b)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
alias T1 = Int
|
alias \t1 = \int
|
||||||
|
|
||||||
abstract (T2 : #A #B #C)
|
abstract \t2[#a #b #c]
|
||||||
|
|
||||||
// Used to pre-compile module for some types
|
// Used to pre-compile module for some types
|
||||||
let T2 = Int
|
let \t2 = \int
|
||||||
let T2 = Float
|
let \t2 = \float
|
||||||
let T2 = Complex
|
let \t2 = \complex
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
decl test_variants : -> Unit
|
decl test-variants : -> \unit
|
||||||
def test_variants = {
|
def test-variants = {
|
||||||
var variant1 = | 'a' | 2 | "hello"
|
var variant1 = | ''a | 2 | "hello"
|
||||||
var | val | err = f: x
|
var | val | err = f: x
|
||||||
|
|
||||||
; val -?> "something" // open variant as value in expr
|
; val -?> "something" // open variant as value in expr
|
||||||
|
|
@ -8,7 +8,7 @@ def test_variants = {
|
||||||
; val -!> "nothing" // open variant as None in expr
|
; val -!> "nothing" // open variant as None in expr
|
||||||
|
|
||||||
match variant1 with
|
match variant1 with
|
||||||
| 'a' -> "something"
|
| ''a -> "something"
|
||||||
| 2 -> "nothing"
|
| 2 -> "nothing"
|
||||||
| "hello" -> "nothing"
|
| "hello" -> "nothing"
|
||||||
| 11 -> "nothing"
|
| 11 -> "nothing"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue