type_check_visitor fixes, array access and function call syntax change

This commit is contained in:
ProgramSnail 2023-05-07 09:25:38 +03:00
parent f7080ba856
commit c1dec6a0d1
16 changed files with 426 additions and 311 deletions

View file

@ -124,6 +124,10 @@ private:
Context() = default; Context() = default;
bool DefineVariable(const std::string& name, utils::IdType type_id) { bool DefineVariable(const std::string& name, utils::IdType type_id) {
if (name == "_") { // placeholder // TODO: check in all places
return true;
}
if (variables_.count(name) > 0) { if (variables_.count(name) > 0) {
return false; return false;
} }

Binary file not shown.

View file

@ -985,7 +985,7 @@ void BuildVisitor::Visit(FunctionCallExpression* node) {
size_t child_count = parse_node.NamedChildCount(); size_t child_count = parse_node.NamedChildCount();
if (child_count > excluded_child_count) { // always true (repeat1) if (child_count > excluded_child_count) {
bool parameters_ended = false; bool parameters_ended = false;
node->arguments.resize(child_count - excluded_child_count); node->arguments.resize(child_count - excluded_child_count);

View file

@ -421,7 +421,7 @@ void PrintVisitor::Visit(ReferenceExpression* node) {
void PrintVisitor::Visit(AccessExpression* node) { void PrintVisitor::Visit(AccessExpression* node) {
out_ << "[AccessExpression] ("; out_ << "[AccessExpression] (";
Visit(node->name.get()); Visit(node->name.get());
out_ << ") : ("; out_ << ") ` (";
Visitor::Visit(node->id); Visitor::Visit(node->id);
out_ << ')'; out_ << ')';
} }
@ -447,15 +447,26 @@ void PrintVisitor::Visit(FunctionCallExpression* node) {
out_ << "] ("; out_ << "] (";
bool is_first = true;
for (auto& parameter : node->parameters) { for (auto& parameter : node->parameters) {
if (!is_first) {
out_ << ", ";
}
is_first = false;
Visit(parameter.get()); Visit(parameter.get());
out_ << ", ";
} }
out_ << ") ("; out_ << ") : (";
is_first = true;
for (auto& argument : node->arguments) { for (auto& argument : node->arguments) {
if (!is_first) {
out_ << ", ";
}
is_first = false;
Visitor::Visit(argument); Visitor::Visit(argument);
out_ << ", ";
} }
out_ << ")"; out_ << ")";
} }

View file

@ -524,12 +524,85 @@ void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum
// Operators // Operators
// TODO
void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) { void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
// TODO: Check, that type is not abstract ?? // TODO: Check, that type is not abstract ??
auto maybe_operator_id = namespace_visitor_.FindFunction(std::nullopt, node->operator_name); auto maybe_operator_id = namespace_visitor_.FindFunction(std::nullopt, node->operator_name);
if (maybe_operator_id.has_value()) {
const info::definition::Function& operator_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
if (!operator_info.declaration.has_value()) {
error_handling::HandleTypecheckError("Operator declaration not found", node->base);
}
if (!operator_info.definition.has_value()) { // TODO: builtin, etc.
error_handling::HandleTypecheckError("Operator definition not found", node->base);
}
if (operator_info.argument_count != 3) { // 2 + return type
error_handling::HandleTypecheckError("Operator wrong argument count", node->base);
}
if (operator_info.declaration->parameters.size() > 0) {
error_handling::HandleTypecheckError("Operator with parameters", node->base);
}
Visitor::Visit(*operator_info.declaration.value().argument_types[0]);
utils::IdType left_expression_type = current_type_; // TODO: type in context of deduced types
Visitor::Visit(node->left_expression);
if (!context_manager_.AddTypeRequirement(current_type_, left_expression_type)) {
error_handling::HandleTypecheckError("Operator left expression has wrong type", node->base);
}
Visitor::Visit(*operator_info.declaration.value().argument_types[1]);
utils::IdType right_expression_type = current_type_; // TODO: type in context of deduced types
Visitor::Visit(node->right_expression);
if (!context_manager_.AddTypeRequirement(current_type_, right_expression_type)) {
error_handling::HandleTypecheckError("Operator right expression has wrong type", node->base);
}
Visitor::Visit(*operator_info.declaration.value().argument_types.back());
return;
}
Visitor::Visit(node->left_expression);
auto maybe_left_type = context_manager_.GetType<info::type::DefinedType>(current_type_);
utils::ValueType left_value_type = context_manager_.GetValueType(current_type_);
if (!maybe_left_type.has_value()) {
error_handling::HandleTypecheckError("Operator not found (type is not DefinedType)", node->base);
}
auto maybe_left_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(maybe_left_type.value()->GetTypeId());
std::string left_type_name = maybe_left_type_info.value().type.type;
auto maybe_const_operator_id = namespace_visitor_.FindMethod(std::nullopt,
left_type_name,
node->operator_name,
utils::IsConstModifier::Const);
if (left_value_type != utils::ValueType::Const) {
maybe_operator_id = namespace_visitor_.FindMethod(std::nullopt,
left_type_name,
node->operator_name,
utils::IsConstModifier::Var);
}
if (!maybe_operator_id.has_value() && !maybe_const_operator_id.has_value()) {
error_handling::HandleTypecheckError("Operator not found (method name not found)", node->base);
}
if (maybe_operator_id.has_value() && maybe_const_operator_id.has_value()) {
error_handling::HandleTypecheckError("Ambigious operator (const and var method)", node->base);
}
if (!maybe_operator_id.has_value()) { if (!maybe_operator_id.has_value()) {
error_handling::HandleTypecheckError("Operator not found", node->base); maybe_operator_id = maybe_const_operator_id;
} }
const info::definition::Function& operator_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value()); const info::definition::Function& operator_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
@ -542,7 +615,7 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
error_handling::HandleTypecheckError("Operator definition not found", node->base); error_handling::HandleTypecheckError("Operator definition not found", node->base);
} }
if (operator_info.argument_count != 2) { if (operator_info.argument_count != 2) { // argument + return type
error_handling::HandleTypecheckError("Operator wrong argument count", node->base); error_handling::HandleTypecheckError("Operator wrong argument count", node->base);
} }
@ -550,21 +623,15 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
error_handling::HandleTypecheckError("Operator with parameters", node->base); error_handling::HandleTypecheckError("Operator with parameters", node->base);
} }
Visitor::Visit(*operator_info.declaration.value().argument_types[0]); Visitor::Visit(*operator_info.declaration.value().argument_types[9]);
utils::IdType left_expression_type = current_type_; // TODO: type in context of deduced types
Visitor::Visit(node->left_expression);
if (!context_manager_.AddTypeRequirement(current_type_, left_expression_type)) {
error_handling::HandleTypecheckError("Operator left expression has wrong type", node->base);
}
Visitor::Visit(*operator_info.declaration.value().argument_types[1]);
utils::IdType right_expression_type = current_type_; // TODO: type in context of deduced types utils::IdType right_expression_type = current_type_; // TODO: type in context of deduced types
Visitor::Visit(node->right_expression); Visitor::Visit(node->right_expression);
if (!context_manager_.AddTypeRequirement(current_type_, right_expression_type)) { if (!context_manager_.AddTypeRequirement(current_type_, right_expression_type)) {
error_handling::HandleTypecheckError("Operator right expression has wrong type", node->base); error_handling::HandleTypecheckError("Operator right expression has wrong type", node->base);
} }
Visitor::Visit(*operator_info.declaration.value().argument_types.back());
} }
void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) { void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) {
@ -748,7 +815,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
context_manager_.AddTypeRequirement(current_type_, argument_type); context_manager_.AddTypeRequirement(current_type_, argument_type);
} }
Visitor::Visit(*function_declaration.argument_types.back()); // add return type to info ?? Visitor::Visit(*function_declaration.argument_types.back());
current_type_ = TypeInContext(current_type_, context); current_type_ = TypeInContext(current_type_, context);
} }

View file

@ -1,21 +1,21 @@
decl test_arrays : Unit -> Unit decl test_arrays : Unit -> 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
const ~ref1 = ~arr1:1 const ~ref1 = ~arr1`1
var ~ref2 = ~arr1:3 var ~ref2 = ~arr1`3
; arr1:1 = 123 ; arr1`1 = 123
; ref1 = arr1:2 // set value ; ref1 = arr1`2 // set value
; ~ref1 = ~ref2 // set reference ; ~ref1 = ~ref2 // set reference
} }

View file

@ -1,29 +1,29 @@
decl flow_control_test : Unit -> Unit decl flow_control_test : Unit -> 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 ; ++x
; IO.print y ; IO.print: y
} else { } else {
return {} return {}
} }
while (a > 0) && (!array.is_empty ()) do { while (a > 0) && (!array.is_empty:) do {
; --a ; --a
; array->pop ; array.pop:
} }
while x < 10 do while x < 10 do
x += x + 3 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 {

View file

@ -5,24 +5,24 @@ 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 : (#AccHash 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
@ -32,16 +32,16 @@ alias Hash = (AccHash 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
} }
} }
@ -53,10 +53,10 @@ def is_empty = 0
decl do_something : Unit -> Unit decl do_something : Unit -> 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

View file

@ -1,11 +1,11 @@
decl test_lambdas : Unit -> Unit decl test_lambdas : Unit -> 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
} }

View file

@ -2,18 +2,20 @@
Match Match
================================================================================ ================================================================================
decl fruit_cost : Fruit -> Int
def fruit_cost : fruit = { def fruit_cost : fruit = {
return (match fruit with return (match fruit with
| $Banana -> 11 | $Banana -> 11
| $Apple | $Orange -> 7) | $Apple | $Orange -> 7)
} }
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
} }
@ -22,223 +24,247 @@ def amount_to_string : x is_zero_separated = {
(source_file (source_file
(source_statement (source_statement
(function_definition_statement (partition_statement
(function_definition (namespace_statement
(extended_name (function_declaration
(name_identifier)) (extended_name
(extended_name (name_identifier))
(name_identifier))) (function_type
(superexpression (scoped_any_type
(expression (type_expression
(prefixed_expression (parametrized_type
(block (type_identifier))))
(block_statement (scoped_any_type
(prefixed_expression (type_expression
(return_expression (parametrized_type
(expression (type_identifier)))))))))
(subexpression
(subexpression_token
(scoped_statement
(superexpression
(flow_control
(match
(expression
(subexpression
(subexpression_token
(name_expression
(extended_name
(name_identifier))))))
(match_case
(pattern
(type_constructor_pattern
(type_expression
(type_subexpression
(type_identifier)))))
(expression
(subexpression
(subexpression_token
(literal
(number_literal))))))
(match_case
(pattern
(type_constructor_pattern
(type_expression
(type_subexpression
(type_identifier))))))
(match_case
(pattern
(type_constructor_pattern
(type_expression
(type_subexpression
(type_identifier)))))
(expression
(subexpression
(subexpression_token
(literal
(number_literal))))))))))))))))))))))
(source_statement (source_statement
(function_definition_statement (partition_statement
(function_definition (namespace_statement
(extended_name (function_definition_statement
(name_identifier)) (function_definition
(extended_name (extended_name
(name_identifier)) (name_identifier))
(extended_name (extended_name
(name_identifier))) (name_identifier)))
(superexpression (superexpression
(expression (expression
(prefixed_expression (prefixed_expression
(block (block
(block_statement (block_statement
(variable_definition_statement (prefixed_expression
(any_name (return_expression
(annotated_name (expression
(extended_name (subexpression
(name_identifier)))) (subexpression_token
(superexpression (scoped_statement
(flow_control (superexpression
(match (flow_control
(match
(expression
(subexpression
(subexpression_token
(name_expression
(extended_name
(name_identifier))))))
(match_case
(pattern
(type_constructor_pattern
(type_expression
(parametrized_type
(type_identifier)))))
(expression
(subexpression
(subexpression_token
(literal
(number_literal))))))
(match_case
(pattern
(type_constructor_pattern
(type_expression
(parametrized_type
(type_identifier))))))
(match_case
(pattern
(type_constructor_pattern
(type_expression
(parametrized_type
(type_identifier)))))
(expression
(subexpression
(subexpression_token
(literal
(number_literal))))))))))))))))))))))))
(source_statement
(partition_statement
(namespace_statement
(function_declaration
(extended_name
(name_identifier))
(function_type
(scoped_any_type
(type_expression
(parametrized_type
(type_identifier))))
(scoped_any_type
(type_expression
(parametrized_type
(type_identifier))))
(scoped_any_type
(type_expression
(parametrized_type
(type_identifier)))))))))
(source_statement
(partition_statement
(namespace_statement
(function_definition_statement
(function_definition
(extended_name
(name_identifier))
(extended_name
(name_identifier))
(extended_name
(name_identifier)))
(superexpression
(expression
(prefixed_expression
(block
(block_statement
(variable_definition_statement
(any_name
(annotated_name
(extended_name
(name_identifier))))
(superexpression
(flow_control
(match
(expression
(subexpression
(subexpression_token
(name_expression
(extended_name
(name_identifier))))))
(match_case
(pattern
(literal
(number_literal)))
(expression
(subexpression
(subexpression_token
(name_expression
(extended_name
(name_identifier))))))
(expression
(subexpression
(subexpression_token
(literal
(string_literal))))))
(match_case
(pattern
(literal
(number_literal))))
(match_case
(pattern
(literal
(number_literal))))
(match_case
(pattern
(literal
(number_literal))))
(match_case
(pattern
(literal
(number_literal))))
(match_case
(pattern
(literal
(number_literal)))
(expression
(subexpression
(subexpression_token
(literal
(string_literal))))))
(match_case
(pattern
(extended_name
(name_identifier)))
(expression
(subexpression
(function_call_expression
(subexpression_token
(scoped_statement
(superexpression
(expression
(subexpression
(binary_operator_expression
(subexpression
(subexpression_token
(literal
(number_literal))))
(operator)
(subexpression
(subexpression_token
(literal
(number_literal))))))))))
(extended_name
(name_identifier))
(subexpression_token
(name_expression
(extended_name
(name_identifier)))))))
(expression
(subexpression
(subexpression_token
(literal
(string_literal))))))
(match_case
(pattern
(extended_name
(name_identifier)))
(expression
(subexpression
(function_call_expression
(subexpression_token
(scoped_statement
(superexpression
(expression
(subexpression
(binary_operator_expression
(subexpression
(subexpression_token
(literal
(number_literal))))
(operator)
(subexpression
(subexpression_token
(literal
(number_literal))))))))))
(extended_name
(name_identifier))
(subexpression_token
(name_expression
(extended_name
(name_identifier)))))))
(expression
(subexpression
(subexpression_token
(literal
(string_literal))))))
(match_case
(pattern
(extended_name
(name_identifier)))
(expression
(subexpression
(subexpression_token
(literal
(string_literal)))))))))))
(block_statement
(prefixed_expression
(return_expression
(expression (expression
(subexpression (subexpression
(subexpression_token (subexpression_token
(name_expression (name_expression
(extended_name (extended_name
(name_identifier)))))) (name_identifier))))))))))))))))))
(match_case
(pattern
(pattern_token
(literal
(number_literal))))
(expression
(subexpression
(function_call_expression
(extended_name
(name_identifier))
(function_argument
(subexpression_token
(literal
(unit_literal)))))))
(expression
(subexpression
(subexpression_token
(literal
(string_literal))))))
(match_case
(pattern
(pattern_token
(literal
(number_literal)))))
(match_case
(pattern
(pattern_token
(literal
(number_literal)))))
(match_case
(pattern
(pattern_token
(literal
(number_literal)))))
(match_case
(pattern
(pattern_token
(literal
(number_literal)))))
(match_case
(pattern
(pattern_token
(literal
(number_literal))))
(expression
(subexpression
(subexpression_token
(literal
(string_literal))))))
(match_case
(pattern
(pattern_token
(extended_name
(name_identifier))))
(expression
(subexpression
(function_call_expression
(subexpression_token
(scoped_statement
(superexpression
(expression
(subexpression
(binary_operator_expression
(subexpression
(subexpression_token
(literal
(number_literal))))
(operator)
(subexpression
(subexpression_token
(literal
(number_literal))))))))))
(extended_name
(name_identifier))
(function_argument
(subexpression_token
(name_expression
(extended_name
(name_identifier))))))))
(expression
(subexpression
(subexpression_token
(literal
(string_literal))))))
(match_case
(pattern
(pattern_token
(extended_name
(name_identifier))))
(expression
(subexpression
(function_call_expression
(subexpression_token
(scoped_statement
(superexpression
(expression
(subexpression
(binary_operator_expression
(subexpression
(subexpression_token
(literal
(number_literal))))
(operator)
(subexpression
(subexpression_token
(literal
(number_literal))))))))))
(extended_name
(name_identifier))
(function_argument
(subexpression_token
(name_expression
(extended_name
(name_identifier))))))))
(expression
(subexpression
(subexpression_token
(literal
(string_literal))))))
(match_case
(pattern
(pattern_token
(extended_name
(name_identifier))))
(expression
(subexpression
(subexpression_token
(literal
(string_literal)))))))))))
(block_statement
(prefixed_expression
(return_expression
(expression
(subexpression
(subexpression_token
(name_expression
(extended_name
(name_identifier))))))))))))))))

View file

@ -3,6 +3,6 @@ struct StructWithRef =
decl test_memory : Unit -> Unit decl test_memory : Unit -> 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
} }

View file

@ -1,7 +1,8 @@
decl test_tuples : Unit -> Unit decl test_tuples : Unit -> 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"
} }

View file

@ -1,5 +1,5 @@
decl test_type_casting : Unit -> Unit decl test_type_casting : Unit -> 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:
} }

View file

@ -11,10 +11,10 @@ typeclass E 'A =
& do_something : Unit -> 'A & do_something : Unit -> '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 = 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 = !(a <= b) def ( > ) : a b = !(a <= b)

View file

@ -15,39 +15,45 @@ let T2 = Complex
(source_file (source_file
(source_statement (source_statement
(alias_definition_statement (partition_statement
(type_identifier) (namespace_statement
(type_expression (alias_definition_statement
(type_subexpression (type_identifier)
(type_identifier))))) (type_expression
(parametrized_type
(type_identifier)))))))
(source_statement (source_statement
(abstract_type_definition_statement (partition_statement
(annotated_type (abstract_type_definition_statement
(type_identifier) (annotated_type
(typeclass_expression (type_identifier)
(typeclass_subexpression (parametrized_typeclass
(typeclass_identifier))) (typeclass_identifier))
(typeclass_expression (parametrized_typeclass
(typeclass_subexpression (typeclass_identifier))
(typeclass_identifier))) (parametrized_typeclass
(typeclass_expression
(typeclass_subexpression
(typeclass_identifier)))))) (typeclass_identifier))))))
(source_statement (source_statement
(alias_definition_statement (partition_statement
(type_identifier) (namespace_statement
(type_expression (alias_definition_statement
(type_subexpression (type_identifier)
(type_identifier))))) (type_expression
(parametrized_type
(type_identifier)))))))
(source_statement (source_statement
(alias_definition_statement (partition_statement
(type_identifier) (namespace_statement
(type_expression (alias_definition_statement
(type_subexpression (type_identifier)
(type_identifier))))) (type_expression
(parametrized_type
(type_identifier)))))))
(source_statement (source_statement
(alias_definition_statement (partition_statement
(type_identifier) (namespace_statement
(type_expression (alias_definition_statement
(type_subexpression (type_identifier)
(type_identifier)))))) (type_expression
(parametrized_type
(type_identifier))))))))

View file

@ -1,7 +1,7 @@
decl test_variants : Unit -> Unit decl test_variants : Unit -> 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