mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
245 lines
7.3 KiB
Swift
245 lines
7.3 KiB
Swift
// RUN: %swift %s -verify
|
|
|
|
import swift
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Tests and samples.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Comment.
|
|
|
|
// Various function types.
|
|
var func1 : () -> (); // No input, no output.
|
|
var func1a : void -> void; // same as func1
|
|
var func2 : (:int) -> int;
|
|
var func3 : () -> () -> (); // Takes nothing, returns a fn.
|
|
var func3a : () -> (:() -> ()); // same as func3
|
|
var func4 : (fn : () -> ()) -> (); // Takes a fn, returns nothing.
|
|
var func5 : (fn : (:int,:int) -> ()) -> (); // Takes a fn, returns nothing.
|
|
var func6 : (fn : (:int,:int) -> int) -> (); // Takes a fn, returns nothing.
|
|
var func7 : () -> (:int,:int,:int); // Takes nothing, returns tuple.
|
|
|
|
// Top-Level expressions. These are 'main' content.
|
|
func1();
|
|
4+7;
|
|
|
|
var bind_test1 : () -> () = func1;
|
|
var bind_test2 : int = 4 func1; // expected-error {{expression resolves to an unevaluated function}}
|
|
|
|
func basictest() {
|
|
// Simple integer variables.
|
|
var x : int
|
|
var x2 = 4 // Simple Type inference.
|
|
var x3 = 4+x*(4+x2)/97 // Basic Expressions.
|
|
|
|
// Declaring a variable void, aka (), is fine too.
|
|
var v : void
|
|
|
|
var x4 : bool = true
|
|
var x5 : bool = // expected-note {{while converting 'var' initializer to declared type}}
|
|
4 // expected-error {{invalid conversion from type 'integer_literal_type' to 'bool'}}
|
|
|
|
//var x6 : float = 4+5;
|
|
|
|
// FIXME: This should be rejected: the 5 is not bound.
|
|
var x7 = 4 5
|
|
|
|
|
|
// Various tuple types.
|
|
var tuple1 : ();
|
|
var tuple2 : (:int);
|
|
var tuple3 : (:int, :int, : ());
|
|
var tuple2a : (a : int);
|
|
var tuple3a : (a : int, b : int, c : ());
|
|
|
|
var tuple4 = (1, 2); // Tuple literal.
|
|
var tuple5 = (1, 2, 3, 4); // Tuple literal.
|
|
var tuple6 = (1 2 3 4); // Grouping paren around sequence, w/dead exprs.
|
|
|
|
|
|
// Brace expressions.
|
|
var brace1 = ( 4 5 );
|
|
var brace2 = ( 4 5+7 );
|
|
// FIXME: func() syntax.
|
|
// var brace3 = {
|
|
// var brace2 = 42; // variable shadowing.
|
|
// brace2+7
|
|
// };
|
|
|
|
// Function calls.
|
|
var call1 = func1()
|
|
var call2 = func2(1);
|
|
var call3 = func2 1; // Grouping parens aren't needed.
|
|
var call4 = func3()();
|
|
|
|
// Cannot call an integer.
|
|
bind_test2(); // expected-error {{tuple expression isn't bound to identifier}}
|
|
}
|
|
|
|
// Infix operators and attribute lists.
|
|
var [infix=2] fooinfix : (: int, :int) -> ();
|
|
var [] infixtest : () = 4 % 2 + 27 fooinfix 123;
|
|
|
|
// Expressions can be auto-closurified, so that they can be evaluated separately
|
|
// from their definition.
|
|
var closure1 : () -> int = 4; // Function producing 4 whenever it is called.
|
|
var closure2 : (:int,:int) -> int = 4; // Has some (dead) arguments.
|
|
var closure3 : (:int,:int)->int->(:int,:int) = (4, 2); // multi-level closing.
|
|
var closure4 : (:int,:int) -> int = $0 + $1;
|
|
|
|
|
|
// The func keyword gives a nice simplification for function definitions.
|
|
func funcdecl1(a : int, y : int) {}
|
|
func funcdecl2() {
|
|
// return
|
|
funcdecl1(4, 2)
|
|
}
|
|
func funcdecl3() -> int {
|
|
//return
|
|
12
|
|
}
|
|
func funcdecl4(a : (:int->int), b : int)
|
|
func signal(sig : int, f : (:int)->void) -> (:int)->void;
|
|
|
|
func funcdecl5(a : int, y : int) {
|
|
// Pass in a closure containing the call to funcdecl3.
|
|
funcdecl4(funcdecl3(), 12);
|
|
func4(funcdecl2());
|
|
func5(funcdecl2()); // Closure with two implicit arguments
|
|
func5($0 + $1 ()) // Closure with two named anonymous arguments
|
|
func6((4 $0) + $1); // Closure with sequence expr inferred type
|
|
func6(($0 4) + $0); // First $0 should get int type because of second.
|
|
|
|
var testfunc : (:(), :int) -> int;
|
|
testfunc // expected-note {{while converting function argument to expected type}}
|
|
($0+1); // expected-error {{invalid conversion from type 'int' to '(: (), : int)'}}
|
|
|
|
funcdecl5(1, 2); // recursion.
|
|
|
|
// Element access from a tuple.
|
|
var a : (:int, f : int, : int);
|
|
var b = a.$1+a.f;
|
|
|
|
// Tuple expressions with named elements.
|
|
var i : (y : int, x : int) = (.x = 42, .y = 11);
|
|
funcdecl1(.y = 123, .a = 444);
|
|
}
|
|
|
|
// Doing fun things with named arguments. Basic stuff first.
|
|
func funcdecl6(a : int, b : int) -> int { a+b }
|
|
|
|
// Can dive into tuples, 'b' is a reference to the whole tuple, c and d are
|
|
// fields in it. Cannot dive into functions or through aliases.
|
|
func funcdecl7(a : int, b : (c : int, d : int)) -> int {
|
|
a + b.$0 + b.c + c + d
|
|
}
|
|
|
|
// Error recovery.
|
|
func testfunc2 (: (:(), :int) -> int) -> int;
|
|
func errorRecovery() {
|
|
testfunc2 // expected-note {{while converting function argument to expected type}}
|
|
($0 // expected-error {{invalid conversion from type '()' to 'int'}}
|
|
+1); // expected-note {{while converting left side of binary operator to expected type}}
|
|
|
|
oneof oneof1 { bar, baz } // expected-note {{type declared here}}
|
|
var a : int = // expected-note {{while converting 'var' initializer to declared type}}
|
|
:hello; // expected-error {{type 'int' has no member named 'hello'}}
|
|
var b : oneof1 = :bar; // ok
|
|
var c : oneof1 = // expected-note {{while converting 'var' initializer to declared type}}
|
|
:xyz; // expected-error {{type 'oneof1' has no member named 'xyz'}}
|
|
var d : (:int,:int,:int) = // expected-note {{while converting 'var' initializer to declared type}}
|
|
(1,2); // expected-error {{no value to initialize tuple element #2}}
|
|
var e : (:int,:int) = // expected-note {{while converting 'var' initializer to declared type}}
|
|
(1, 2, 3); // expected-error {{element #2 of tuple value not used when converting}}
|
|
|
|
var f : (:int,:int) = // expected-note {{while converting 'var' initializer to declared type}}
|
|
(1, 2, .f = 3); // expected-error {{tuple element 'f' (#2) of tuple value not used when converting}}
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: Result can be named as well, but is writeonly. Need to model lvalues
|
|
// and support the '=' operator.
|
|
|
|
// Type aliases.
|
|
typealias int_pair : (:int,:int);
|
|
typealias int_triple : (:int,:int, :int);
|
|
typealias pair_Stuff : (:int_pair, :int_triple);
|
|
var ta_test : pair_Stuff = ((4,2), (1,2,3));
|
|
|
|
|
|
|
|
var test : int->int->int = $0;
|
|
func test2 (a : int) -> (b : int) -> (c : int) {
|
|
// FIXME: return $0
|
|
}
|
|
|
|
|
|
func test3(arg1 : int, arg2 : int) -> int {
|
|
// return
|
|
4
|
|
}
|
|
|
|
func test4 () -> (arg1 : int, arg2 : int) -> int {
|
|
// FIXME: return test3
|
|
}
|
|
|
|
func test5() {
|
|
var a : (:int, :int);
|
|
var // expected-note {{while converting 'var' initializer to declared type}}
|
|
b : (: int->int, :int) = a; // expected-error {{element #0 of tuple value has type 'int', but expected type 'int -> int'}}
|
|
|
|
|
|
var c : (a : int, b : int);
|
|
var d : (b : int, a : int) = c; // Ok, reshuffle tuple.
|
|
}
|
|
|
|
|
|
// Functions can obviously take and return values.
|
|
func w3(a : int) -> int { a }
|
|
func w4( : int) -> int { 4 }
|
|
|
|
|
|
|
|
func b1() {}
|
|
|
|
func foo1(a : int, b: int) -> int;
|
|
func foo2(a : int) -> (b: int) -> int;
|
|
func foo3(a : int = 2, b : int = 3);
|
|
|
|
|
|
func test_lambda() {
|
|
// A simple lambda.
|
|
var a = lambda(val : int) { print(val+1) }
|
|
|
|
// A recursive lambda.
|
|
var fib = lambda(n : int) {
|
|
if (n < 2) {} // return n;
|
|
//return
|
|
fib(n-1)+fib(n-2)
|
|
}
|
|
}
|
|
|
|
|
|
// More realistic examples.
|
|
|
|
func fib(n : int) -> int {
|
|
if (n < 2)
|
|
{} //return 1; // Need Return!
|
|
|
|
// return
|
|
fib(n-2) + fib(n-1)
|
|
}
|
|
|
|
//func fib2(n : int) -> int {
|
|
// if (n < 2)
|
|
// return n
|
|
//
|
|
// return fib(n-2) + fib(n-1)
|
|
//}
|
|
|
|
|
|
|
|
|