harec

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

00-constants.ha (6892B)


      1 use rt;
      2 
      3 type my_enum = enum u8 {
      4 	FOO,
      5 };
      6 
      7 fn assignment() void = {
      8 	let i = 0i8;
      9 	let u = 0u64;
     10 	let f = 0.0f64;
     11 	let r = 'a';
     12 	let e = my_enum::FOO;
     13 
     14 	// There are five cases that need to be tested for tagged unions:
     15 	// - The default type for the constant is a member of the union
     16 	// - A single non-default type the constant could assume is a member of
     17 	//   the union
     18 	// - The default type for the constant along with at least one other
     19 	//   type the constant could assume are both members of the union
     20 	// - At least two types the constant could assume are members of the
     21 	//   union, and the default type isn't a member of the union
     22 	// - None of the types the constant could assume are members of the
     23 	//   union
     24 	// All but the fourth and fifth case are valid, and the invalid cases
     25 	// should error out gracefully.
     26 	let itu1: (int | void) = void;
     27 	let itu2: (u64 | void) = void;
     28 	let itu3: (int | u64 | void) = void;
     29 	let ftu1: (f64 | void) = void;
     30 	let ftu2: (f32 | void) = void;
     31 	let ftu3: (f32 | f64 | void) = void;
     32 	let rtu1: (rune | void) = void;
     33 	let rtu2: (u64 | void) = void;
     34 	let rtu3: (rune | u64 | void) = void;
     35 
     36 	i = 127;
     37 	assert(rt::compile("export fn main() void = { let i = 0i8; i = 128; };") != 0);
     38 	u = 18446744073709551615;
     39 	assert(rt::compile("export fn main() void = { let u = 0u32; u = 4294967296; };") != 0);
     40 	assert(rt::compile("export fn main() void = { let f = 0.0f64; f = 0; };") != 0);
     41 	assert(rt::compile("export fn main() void = { let r = 'a'; r = 0; };") != 0);
     42 	e = 0;
     43 	assert(rt::compile("type my_enum = enum u8 { FOO }; export fn main() void = { let e: my_enum = my_enum::FOO; e = 256; };") != 0);
     44 	assert(rt::compile("export fn main() void = { let p: nullable *void = null; p = 0; };") != 0);
     45 	assert(rt::compile("export fn main() void = { let b = false; b = 0; };") != 0);
     46 	assert(rt::compile("export fn main() void = { let n = null; n = 0; };") != 0);
     47 	assert(rt::compile("export fn main() void = { let s: struct { i: int } = struct { i: int = 0 }; s = 0; };") != 0);
     48 	assert(rt::compile("export fn main() void = { let t = (0, 1); t = 0; };") != 0);
     49 	assert(rt::compile("export fn main() void = { let a = [0, 1]; a = 0; };") != 0);
     50 	assert(rt::compile("export fn main() void = { let s = \"\"; s = 0; };") != 0);
     51 	itu1 = 0;
     52 	itu2 = 0;
     53 	itu3 = 0;
     54 	assert(rt::compile("export fn main() void = { let itu4: (u32 | u64 | void) = void; itu4 = 0; };") != 0);
     55 	assert(rt::compile("export fn main() void = { let itu5: (str | void) = void; itu5 = 0; };") != 0);
     56 
     57 	assert(rt::compile("export fn main() void = { let i = 0i8; i = 0.0; };") != 0);
     58 	assert(rt::compile("export fn main() void = { let u = 0u8; u = 0.0; };") != 0);
     59 	f = 0.0;
     60 	assert(rt::compile("export fn main() void = { let r = 'a'; r = 0.0; };") != 0);
     61 	assert(rt::compile("type my_enum = enum u8 { FOO }; export fn main() void = { let e: my_enum = my_enum::FOO; e = 0.0; };") != 0);
     62 	assert(rt::compile("export fn main() void = { let p: nullable *void = null; p = 0.0; };") != 0);
     63 	assert(rt::compile("export fn main() void = { let b = false; b = 0.0; };") != 0);
     64 	assert(rt::compile("export fn main() void = { let n = null; n = 0.0; };") != 0);
     65 	assert(rt::compile("export fn main() void = { let s: struct { i: int } = struct { i: int = 0 }; s = 0.0; };") != 0);
     66 	assert(rt::compile("export fn main() void = { let t = (0, 1); t = 0.0; };") != 0);
     67 	assert(rt::compile("export fn main() void = { let a = [0, 1]; a = 0.0; };") != 0);
     68 	assert(rt::compile("export fn main() void = { let s = ""; s = 0.0; };") != 0);
     69 	ftu1 = 0.0;
     70 	ftu2 = 0.0;
     71 	ftu3 = 0.0;
     72 	assert(rt::compile("type my_f32 = f32; export fn main() void = { let ftu4: (f32 | my_f32 | void) = void; ftu4 = 0.0; };") != 0);
     73 	assert(rt::compile("export fn main() void = { let ftu5: (str | void) = void; ftu5 = 0.0; };") != 0);
     74 
     75 	i = 'a';
     76 	u = 'a';
     77 	assert(rt::compile("export fn main() void = { let f = 0.0f64; f = 'a'; };") != 0);
     78 	r = 'a';
     79 	e = 'a';
     80 	assert(rt::compile("export fn main() void = { let p: nullable *void = null; p = 'a'; };") != 0);
     81 	assert(rt::compile("export fn main() void = { let b = false; b = 'a'; };") != 0);
     82 	assert(rt::compile("export fn main() void = { let n = null; n = 'a'; };") != 0);
     83 	assert(rt::compile("export fn main() void = { let s: struct { i: int } = struct { i: int = 0 }; s = 'a'; };") != 0);
     84 	assert(rt::compile("export fn main() void = { let t = (0, 1); t = 'a'; };") != 0);
     85 	assert(rt::compile("export fn main() void = { let a = [0, 1]; a = 'a'; };") != 0);
     86 	assert(rt::compile("export fn main() void = { let s = ""; s = 'a'; };") != 0);
     87 	rtu1 = 'a';
     88 	rtu2 = 'a';
     89 	rtu3 = 'a';
     90 	assert(rt::compile("export fn main() void = { let rtu4: (u32 | u64 | void) = void; rtu4 = 'a'; };") != 0);
     91 	assert(rt::compile("export fn main() void = { let rtu5: (str | void) = void; rtu5 = 'a'; };") != 0);
     92 };
     93 
     94 fn aggregates() void = {
     95 	// Pointers
     96 
     97 	// Kinda hacky way to verify that something has the expected type
     98 	// The variables are necessary in order to avoid type hints, which would
     99 	// avoid verifying that constants are lowered when entering aggregate
    100 	// types
    101 	let maxiptr = if (true) alloc(2147483647) else void;
    102 	free(maxiptr as *int);
    103 	let miniptr = if (true) alloc(-2147483648) else void;
    104 	free(miniptr as *int);
    105 	let smalli64ptr = if (true) alloc(2147483648) else void;
    106 	free(smalli64ptr as *i64);
    107 	let negi64ptr = if (true) alloc(-2147483649) else void;
    108 	free(negi64ptr as *i64);
    109 	let maxi64ptr = if (true) alloc(9223372036854775807) else void;
    110 	free(maxi64ptr as *i64);
    111 	// -9223372036854775808 can't be made to work without lots of hacks
    112 	let mini64ptr = if (true) alloc(-9223372036854775807) else void;
    113 	free(mini64ptr as *i64);
    114 	let fptr = if (true) alloc(0.0) else void;
    115 	free(fptr as *f64);
    116 	let rptr = if (true) alloc('a') else void;
    117 	free(rptr as *rune);
    118 
    119 	// Tuples
    120 
    121 	// The edge cases of the iconst lowering algorithm were already tested
    122 	// above, and tuple items can't affect each other, so this suffices
    123 	let tuple = if (true) (2147483647, 0.0, 'a') else void;
    124 	tuple as (int, f64, rune);
    125 
    126 	// Arrays
    127 	let iarr = if (true) [0, 1, 2] else void;
    128 	iarr as [3]int;
    129 	let uarr = if (true) [0u8, 1, 2] else void;
    130 	uarr as [3]u8;
    131 	let u2arr = if (true) [0, 1u8, 2] else void;
    132 	u2arr as [3]u8;
    133 };
    134 
    135 export fn main() void = {
    136 	let i1 = 13, i2 = 13i, i3 = 13i8, i4 = 13i16, i5 = 13i32, i6 = 13i64;
    137 	let u1 = 13u, u2 = 13z, u3 = 13u8, u4 = 13u16, u5 = 13u32, u6 = 13u64;
    138 	let n1 = -13, n2 = -13u;
    139 	let b1 = true, b2 = false;
    140 	let p1: nullable *int = null;
    141 	let r1 = 'x', r2 = '\x0A', r3 = '\u1234', r4 = '\0', r5 = '\a',
    142 		r6 = '\b', r7 = '\f', r8 = '\n', r9 = '\r', r10 = '\t',
    143 		r11 = '\v', r12 = '\\', r13 = '\'', r14 = '\"',
    144 		r15 = '\U12345678';
    145 	let f1 = 1.0, f2 = 1f32, f3 = 1.0e2, f4 = 1.0f64;
    146 	let f5 = 1.23e+45, f6 = 9.87e-65, f7 = 1e-7, f8 = 5.0e-324;
    147 
    148 	// The interaction between constants and result type reduction is tested
    149 	// in 30-reduction.c
    150 	assignment();
    151 	aggregates();
    152 };