diff --git a/src/compiler.pr b/src/compiler.pr index a8373e42..2662eb96 100644 --- a/src/compiler.pr +++ b/src/compiler.pr @@ -8913,6 +8913,12 @@ def do_create_type(tpe: &typechecking::Type, svalue: &scope::Value, module: &too for var i in 0..vector::length(tpe.return_t) { create_type(tpe.return_t[i], module, cache) } + case typechecking::TypeKind::TUPLE: + value.values[0] = { kind = ValueKind::INT, tpe = builtins::int_, i = 17 } !Value + //TODO Tuples + for var i in 0..vector::length(tpe.return_t) { + create_type(tpe.return_t[i], module, cache) + } case typechecking::TypeKind::ENUM: value.values[0] = { kind = ValueKind::INT, tpe = builtins::int_, i = 10 } !Value let enum_values = allocate_ref(Value, 2) diff --git a/src/parser.pr b/src/parser.pr index 67a9f7ac..71980b1e 100644 --- a/src/parser.pr +++ b/src/parser.pr @@ -1763,10 +1763,11 @@ def expect_array_or_tuple(parse_state: &ParseState) -> &Node { } var tpe = expect_type(parse_state) - tok = peek(parse_state) if may_be_tuple { skip_newline(parse_state) + tok = peek(parse_state) + if tok.tpe == lexer::TokenType::COMMA { let variants = vector::make(type &Node) @@ -1779,6 +1780,8 @@ def expect_array_or_tuple(parse_state: &ParseState) -> &Node { tok = peek(parse_state) } + variants.push(tpe) + tok = expect(parse_state, lexer::TokenType::C_SQUARE, "Expected ']'") node = make_node(NodeKind::TUPLE_T, line, column, parse_state) diff --git a/src/runtime.pr b/src/runtime.pr index daac6bb7..5b77eaec 100644 --- a/src/runtime.pr +++ b/src/runtime.pr @@ -45,6 +45,7 @@ export type TypeKind = enum { WEAK_REF TYPE VARIANT + TUPLE } export type Function = struct { diff --git a/src/typechecking.pr b/src/typechecking.pr index a2f15773..1482f9b2 100644 --- a/src/typechecking.pr +++ b/src/typechecking.pr @@ -1801,11 +1801,20 @@ def replace_parameter(tpe: &Type, types: &SMap(&Type)) -> &Type { if tpe._tpe { tpe._tpe = replace_parameter(tpe._tpe, types) } - } else if tpe.kind == TypeKind::FUNCTION or tpe.kind == TypeKind::CLOSURE or tpe.kind == TypeKind::TUPLE { + } else if tpe.kind == TypeKind::FUNCTION or tpe.kind == TypeKind::CLOSURE { for var i in 0..vector::length(tpe.parameter_t) { - let np = tpe.parameter_t[i] + let np = tpe.parameter_t.get(i) np._tpe = replace_parameter(np.tpe, types) } + for var i in 0..vector::length(tpe.return_t) { + let rett = tpe.return_t[i] + tpe.return_t[i] = replace_parameter(rett, types) + } + } else if tpe.kind == tpe.kind == TypeKind::TUPLE { + for var i in 0..vector::length(tpe.return_t) { + let rett = tpe.return_t[i] + tpe.return_t[i] = replace_parameter(rett, types) + } } else if tpe.kind != TypeKind::TYPE_DEF and tpe.name { let ntpe = types.get_or_default(tpe.name, null) if ntpe { return ntpe } @@ -2930,7 +2939,7 @@ export def do_type_lookup(node: &parser::Node, state: &State, current_type: &Typ for var i in 0..node.value.body.length { var n = node.value.body[i] var cur: &Type = null - if current_type { cur = current_type.field_types[i].tpe } + if current_type { cur = current_type.return_t[i] } let e = type_lookup(n, state, cur, lookup_default, cache) return_t.push(e) @@ -4017,7 +4026,7 @@ export def walk_Def(node: &parser::Node, state: &State, polymorph: bool = false) let c_return_t = vector::make(type &Type) let parameter_t = vector::make(NamedParameter) - let return_t = vector::make(type &Type) + var return_t = vector::make(type &Type) let types = allocate_ref(StructMember, 2) types[0] = { tpe = pointer(make_function_type_n(name, parameter_t, return_t)), name = "function" } !StructMember @@ -4077,6 +4086,14 @@ export def walk_Def(node: &parser::Node, state: &State, polymorph: bool = false) } arr[state.function_stack.length - 1] = parser::identifier_to_str(name) + // Unpack tuple + if node.tpe.return_t and node.tpe.return_t.length == 1 { + let tuple = node.tpe.return_t[0] + if tuple and tuple.kind == TypeKind::TUPLE { + return_t = tuple.return_t + } + } + tpe = make_function_type_n(make_identifier(arr), parameter_t, return_t, state.module) tpe.type_name += "." + state.lambda_counter state.lambda_counter += 1 @@ -4085,7 +4102,17 @@ export def walk_Def(node: &parser::Node, state: &State, polymorph: bool = false) tpe.node = node } else { if not node.tpe { return } - tpe = make_function_type_n(name, node.tpe.parameter_t, node.tpe.return_t, state.module, extern, test = test) + + // Unpack tuple + var return_t = node.tpe.return_t + if node.tpe.return_t and node.tpe.return_t.length == 1 { + let tuple = node.tpe.return_t[0] + if tuple and tuple.kind == TypeKind::TUPLE { + return_t = tuple.return_t + } + } + + tpe = make_function_type_n(name, node.tpe.parameter_t, return_t, state.module, extern, test = test) tpe.node = node check_is_valid_function(name, node.tpe.parameter_t, state) }