harec

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

11-globals.ha (3664B)


      1 use rt;
      2 
      3 let x: int = 42, y: int = 69;
      4 
      5 fn write() void = {
      6 	assert(x == 42 && y == 69);
      7 	x = 1337;
      8 	assert(x == 1337);
      9 };
     10 
     11 let ar: [3]int = [1, 2, 3];
     12 let sl: []int = [1, 2, 3];
     13 let st: str = "Hello!";
     14 
     15 type coords = struct { x: int, y: int };
     16 let su: coords = coords { y = 10, x = 20};
     17 let su_autofill: coords = coords { y = 10, x = 20, ... };
     18 let au: coords = coords { ... };
     19 
     20 type coords3 = struct { coords: coords, z: int };
     21 let a3: coords3 = coords3 { ... };
     22 
     23 type embedded = struct { a: uint, b: u8 };
     24 
     25 type with_embedded = struct { embedded, c: int };
     26 let em: with_embedded = with_embedded { a = 3, b = 4, c = 18 };
     27 let em_autofill: with_embedded = with_embedded { ... };
     28 
     29 type with_embedded2 = struct { c: int, embedded };
     30 let em2: with_embedded2 = with_embedded2 { a = 3, b = 4, c = 18 };
     31 let em2_autofill: with_embedded2 = with_embedded2 { ... };
     32 
     33 type aenum = enum u64 {
     34 	BIG_VALUE = 0x1234567887654321,
     35 };
     36 const big_value: aenum = aenum::BIG_VALUE;
     37 
     38 const float: f32 = 1234.5678;
     39 const double: f64 = 1234.5678;
     40 
     41 fn storage() void = {
     42 	assert(len(ar) == 3);
     43 	assert(ar[0] == 1 && ar[1] == 2 && ar[2] == 3);
     44 	assert(len(sl) == 3);
     45 	assert(sl[0] == 1 && sl[1] == 2 && sl[2] == 3);
     46 	assert(len(st) == 6);
     47 	assert(su.x == 20 && su.y == 10);
     48 	assert(su_autofill.x == 20 && su_autofill.y == 10);
     49 	assert(au.x == 0 && au.y == 0);
     50 	assert(a3.coords.x == 0 && a3.coords.y == 0 && a3.z == 0);
     51 	assert(em.a == 3 && em.b == 4 && em.c == 18);
     52 	assert(em_autofill.a == 0 && em_autofill.b == 0 && em_autofill.c == 0);
     53 	assert(em2.a == 3 && em2.b == 4 && em2.c == 18);
     54 	assert(em2_autofill.a == 0 && em2_autofill.b == 0 && em2_autofill.c == 0);
     55 	assert(big_value == 0x1234567887654321: aenum);
     56 	assert(float == 1234.5678);
     57 	assert(double == 1234.5678);
     58 };
     59 
     60 fn invariants() void = {
     61 	assert(rt::compile("fn test() int; let x: int = test();") != 0);
     62 	assert(rt::compile("const a: u8 = 2; const b: u8 = a + 5;") != 0);
     63 };
     64 
     65 fn counter() int = {
     66 	static let x = 0;
     67 	x += 1;
     68 	return x;
     69 };
     70 
     71 fn static_binding() void = {
     72 	assert(counter() == 1);
     73 	assert(counter() == 2);
     74 	assert(counter() == 3);
     75 };
     76 
     77 const val: u32 = 42;
     78 const tup: (u8, str) = (2, "asdf");
     79 const ptr: *u32 = &val;
     80 const ptr_tup: *(u8, str) = &tup;
     81 // TODO const ptr_memb: *str = &tup.1;
     82 
     83 fn pointers() void = {
     84 	assert(ptr == &val && *ptr == val);
     85 };
     86 
     87 type foo = (int | uint);
     88 
     89 let subtype: foo = 10u;
     90 
     91 let arr_of_tagged_of_tuple: [3]((int, int)|void) = [(1, 2), (3, 4), (5, 6)];
     92 
     93 fn tagged() void = {
     94 	assert((arr_of_tagged_of_tuple[0] as (int, int)).0 == 1);
     95 	assert((arr_of_tagged_of_tuple[0] as (int, int)).1 == 2);
     96 	assert((arr_of_tagged_of_tuple[1] as (int, int)).0 == 3);
     97 	assert((arr_of_tagged_of_tuple[1] as (int, int)).1 == 4);
     98 	assert((arr_of_tagged_of_tuple[2] as (int, int)).0 == 5);
     99 	assert((arr_of_tagged_of_tuple[2] as (int, int)).1 == 6);
    100 	assert(subtype is uint);
    101 	// TODO: subset-compat
    102 };
    103 
    104 // Real-world sample
    105 
    106 type basic = enum {
    107 	FN,
    108 	FOR,
    109 	IF,
    110 	IN,
    111 	NOT,
    112 	SWITCH,
    113 	WHILE,
    114 };
    115 
    116 const keywords: [_](str, basic) = [
    117 	("fn", basic::FN),
    118 	("for", basic::FOR),
    119 	("if", basic::IF),
    120 	("in", basic::IN),
    121 	("not", basic::NOT),
    122 	("switch", basic::SWITCH),
    123 	("while", basic::WHILE),
    124 ];
    125 
    126 fn tuplearray() void = {
    127 	assert(keywords[0].0 == "fn");
    128 	assert(keywords[1].0 == "for");
    129 	assert(keywords[2].0 == "if");
    130 	assert(keywords[3].0 == "in");
    131 	assert(keywords[4].0 == "not");
    132 	assert(keywords[5].0 == "switch");
    133 	assert(keywords[6].0 == "while");
    134 };
    135 
    136 export fn main() void = {
    137 	// TODO: Expand this test:
    138 	// - Declare & validate globals of more types
    139 	// - Globals which are pointers to other globals
    140 	write();
    141 	storage();
    142 	invariants();
    143 	static_binding();
    144 	pointers();
    145 	tagged();
    146 	tuplearray();
    147 };