harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

05-implicit-casts.ha (2883B)


      1 use rt;
      2 
      3 type subtype = struct {
      4 	foo: int,
      5 };
      6 
      7 type super1 = struct {
      8 	foo: subtype,
      9 	bar: int,
     10 };
     11 
     12 type super2 = struct {
     13 	subtype,
     14 	bar: int,
     15 };
     16 
     17 type super3 = struct {
     18 	struct { foo: int },
     19 	bar: int,
     20 };
     21 
     22 fn rules() void = {
     23 	// Fixed precision ints
     24 	let _i64: i64 = 0i64;
     25 	_i64 = 42i8;
     26 	_i64 = 42i16;
     27 	_i64 = 42i32;
     28 	_i64 = 42i;
     29 	let _i32: i32 = 0i32;
     30 	_i32 = 42i8;
     31 	_i32 = 42i16;
     32 	let _i16: i16 = 0i16;
     33 	_i16 = 42i8;
     34 	let _u64: u64 = 0u64;
     35 	_u64 = 42u8;
     36 	_u64 = 42u16;
     37 	_u64 = 42u32;
     38 	_u64 = 42u;
     39 	let _u32: u32 = 0u32;
     40 	_u32 = 42u8;
     41 	_u32 = 42u16;
     42 	let _u16: u16 = 0u16;
     43 	_u16 = 42u8;
     44 
     45 	// Implementation-defined precision
     46 	if (size(int) == 8) {
     47 		assert(rt::compile("fn test() void = { let i: int = 42i64; };") == 0);
     48 	};
     49 	let i: int = 42i;
     50 	i = 42i32;
     51 	i = 42i16;
     52 	i = 42i8;
     53 
     54 	if (size(uint) == 8) {
     55 		assert(rt::compile("fn test() void = { let u: uint = 42u64; };") == 0);
     56 	};
     57 	let u: uint = 42u;
     58 	u = 42u32;
     59 	u = 42u16;
     60 	u = 42u8;
     61 
     62 	// Precision loss (should fail)
     63 	assert(rt::compile("fn test() void = { let _i8: i8 = 42i16; };") != 0);
     64 	assert(rt::compile("fn test() void = { let _i8: i8 = 42i32; };") != 0);
     65 	assert(rt::compile("fn test() void = { let _i8: i8 = 42i64; };") != 0);
     66 	assert(rt::compile("fn test() void = { let _i8: i8 = 42i; };") != 0);
     67 	assert(rt::compile("fn test() void = { let _i16: i16 = 42i32; };") != 0);
     68 	assert(rt::compile("fn test() void = { let _i16: i16 = 42i64; };") != 0);
     69 	assert(rt::compile("fn test() void = { let _i32: i32 = 42i64; };") != 0);
     70 	assert(rt::compile("fn test() void = { let _u8: u8 = 42u16; };") != 0);
     71 	assert(rt::compile("fn test() void = { let _u8: u8 = 42u32; };") != 0);
     72 	assert(rt::compile("fn test() void = { let _u8: u8 = 42u64; };") != 0);
     73 	assert(rt::compile("fn test() void = { let _u8: u8 = 42u; };") != 0);
     74 	assert(rt::compile("fn test() void = { let _u16: u16 = 42u32; };") != 0);
     75 	assert(rt::compile("fn test() void = { let _u16: u16 = 42u64; };") != 0);
     76 	assert(rt::compile("fn test() void = { let _u32: u32 = 42u64; };") != 0);
     77 
     78 	// Pointer conversions
     79 	let cchr: *const char = "hello world";
     80 	let nptr: nullable *int = null;
     81 	nptr = &i;
     82 	let vptr: nullable *void = nptr;
     83 
     84 	// Struct subtyping
     85 	let sptr: *subtype = &super1 { ... };
     86 	let sptr: *subtype = &super2 { ... };
     87 	let sptr: *struct { foo: int } = &super3 { ... };
     88 
     89 	// Invalid pointer conversions
     90 	assert(rt::compile(
     91 		"fn test() void = { let x: nullable *int = null; let y: *int = x; };"
     92 	) != 0);
     93 	assert(rt::compile(
     94 		"fn test() void = { let x: int = 10; let y: *int = &x; let y: *uint = x; };"
     95 	) != 0);
     96 
     97 	// Non-const from const (copy)
     98 	const j = 10;
     99 	let k = j;
    100 };
    101 
    102 fn rvalue() i64 = {
    103 	return 1234;
    104 };
    105 
    106 fn callme(in: i64) void = {
    107 	assert(in == 1234i64);
    108 };
    109 
    110 fn calls() void = {
    111 	callme(1234);
    112 };
    113 
    114 export fn main() void = {
    115 	rules();
    116 	assert(rvalue() == 1234i64);
    117 	calls();
    118 	// TODO: Expand this:
    119 	// - Floats
    120 	// - Arrays <-> slices
    121 };