boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

01-kitchen-sink.c (9782B)


      1 /* tests/cc-e2e/01-kitchen-sink.c — single-TU integration test.
      2  *
      3  * Single-file end-to-end exercise of the codegen surface that the
      4  * parser drives today. Each numbered test computes a value; main
      5  * checks each against an expected literal and exits with the test
      6  * number (1..N) on first mismatch, 0 on full pass.
      7  *
      8  * Designed to stress *interactions* between features (e.g., struct
      9  * members through fn-ptr-returned pointer, variadic + recursion +
     10  * pointer arith, etc.) that the per-feature cc-cg fixtures don't.
     11  */
     12 
     13 typedef char *va_list;
     14 
     15 /* -------- Globals: scalar, bss, array, string, struct, designated, fn-ptr table -- */
     16 
     17 int g_scalar = 42;
     18 int g_zero;                                /* bss */
     19 int g_arr[3] = { 10, 20, 30 };
     20 char g_msg[] = "hello";
     21 struct Point { int x; int y; };
     22 struct Point g_pt  = { 100, 200 };          /* positional */
     23 struct Point g_pt2 = { .y = 5, .x = 7 };    /* designated */
     24 
     25 typedef int (*op2_t)(int, int);
     26 int op_add(int a, int b) { return a + b; }
     27 int op_mul(int a, int b) { return a * b; }
     28 op2_t g_ops[2] = { op_add, op_mul };
     29 
     30 enum Color { RED, GREEN = 5, BLUE };
     31 
     32 /* -------- Tests ----------------------------------------------------------- */
     33 
     34 int test_arith(void) {
     35     int a = 5;
     36     int b = 3;
     37     int r = 0;
     38     r = r + (a + b);                /* 8  */
     39     r = r + (a - b);                /* 2  */
     40     r = r + (a * b);                /* 15 */
     41     r = r + (10 / 3);               /* 3  */
     42     r = r + (10 % 3);               /* 1  */
     43     r = r + (1 << 4);               /* 16 */
     44     r = r + (64 >> 2);              /* 16 */
     45     r = r + (12 & 10);              /* 8  */
     46     r = r + (12 | 10);              /* 14 */
     47     r = r + (12 ^ 10);              /* 6  */
     48     r = r + !0;                     /* 1  */
     49     r = r + ~0;                     /* -1 */
     50     r = r + (-1);                   /* -1 */
     51     return r;                       /* 88 */
     52 }
     53 
     54 int test_compound(void) {
     55     int x = 10;
     56     x += 5;                         /* 15 */
     57     x -= 3;                         /* 12 */
     58     x *= 2;                         /* 24 */
     59     x /= 4;                         /* 6  */
     60     x %= 4;                         /* 2  */
     61     x <<= 3;                        /* 16 */
     62     x >>= 1;                        /* 8  */
     63     x &= 12;                        /* 8  */
     64     x |= 1;                         /* 9  */
     65     x ^= 6;                         /* 15 */
     66     return x;
     67 }
     68 
     69 int test_inc_dec(void) {
     70     int x = 5;
     71     int a = x++;                    /* a=5, x=6 */
     72     int b = ++x;                    /* b=7, x=7 */
     73     int c = x--;                    /* c=7, x=6 */
     74     int d = --x;                    /* d=5, x=5 */
     75     return a + b + c + d + x;       /* 5+7+7+5+5 = 29 */
     76 }
     77 
     78 int test_logical(void) {
     79     int r = 0;
     80     if (1 && 1) r = r + 1;
     81     if (0 && 1) r = r + 100;
     82     if (1 || 0) r = r + 2;
     83     if (0 || 0) r = r + 100;
     84     int side = 0;
     85     if (1 || (side = 100)) r = r + 4;       /* short-circuit; side stays 0 */
     86     if (0 && (side = 100)) r = r + 100;
     87     return r + side;                        /* 1+2+4+0 = 7 */
     88 }
     89 
     90 int test_ternary(void) {
     91     int x = 5;
     92     int y = (x > 3) ? 10  : 20;     /* 10  */
     93     int z = (x < 3) ? 100 : 200;    /* 200 */
     94     return y + z;                   /* 210 */
     95 }
     96 
     97 int test_compare(void) {
     98     int r = 0;
     99     if (5 == 5) r = r + 1;
    100     if (5 != 6) r = r + 2;
    101     if (5 <  6) r = r + 4;
    102     if (6 >  5) r = r + 8;
    103     if (5 <= 5) r = r + 16;
    104     if (5 >= 5) r = r + 32;
    105     return r;                       /* 63 */
    106 }
    107 
    108 int test_pointer(void) {
    109     int x = 7;
    110     int *p = &x;
    111     *p = *p + 3;                    /* x = 10 */
    112     int **pp = &p;
    113     int v = **pp;                   /* 10 */
    114     return *p + v;                  /* 20 */
    115 }
    116 
    117 int test_array(void) {
    118     int a[5] = { 1, 2, 3, 4, 5 };
    119     int sum = 0;
    120     int i;
    121     for (i = 0; i < 5; i = i + 1) sum = sum + a[i];
    122     return sum;                     /* 15 */
    123 }
    124 
    125 int test_array_2d(void) {
    126     int m[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
    127     int sum = 0;
    128     int i; int j;
    129     for (i = 0; i < 2; i = i + 1)
    130         for (j = 0; j < 3; j = j + 1)
    131             sum = sum + m[i][j];
    132     return sum;                     /* 21 */
    133 }
    134 
    135 int test_struct(void) {
    136     struct Point local = { 3, 4 };
    137     return local.x + local.y;       /* 7 */
    138 }
    139 
    140 int f_struct_arg(struct Point *p) { return p->x + p->y; }
    141 
    142 int test_struct_ptr(void) {
    143     return f_struct_arg(&g_pt) + g_pt2.x + g_pt2.y;     /* 300 + 7 + 5 = 312 */
    144 }
    145 
    146 int f_basic(int a, int b) { return a + b; }
    147 
    148 int test_call(void) {
    149     int x = f_basic(3, 4);          /* 7  */
    150     int y = f_basic(10, -2);        /* 8  */
    151     return x + y;                   /* 15 */
    152 }
    153 
    154 int factorial(int n) {
    155     if (n <= 1) return 1;
    156     return n * factorial(n - 1);
    157 }
    158 
    159 int test_recursion(void) { return factorial(5); }       /* 120 */
    160 
    161 int f_variadic(int n, ...) {
    162     va_list ap;
    163     int total;
    164     int i;
    165     __builtin_va_start(ap, n);
    166     total = 0;
    167     i = 0;
    168     while (i < n) {
    169         total = total + __builtin_va_arg(ap, int);
    170         i = i + 1;
    171     }
    172     __builtin_va_end(ap);
    173     return total;
    174 }
    175 
    176 int test_variadic(void) { return f_variadic(4, 1, 2, 3, 4); }   /* 10 */
    177 
    178 int test_fn_ptr(void) {
    179     op2_t add = g_ops[0];
    180     op2_t mul = g_ops[1];
    181     return add(3, 4) + mul(5, 6);   /* 7 + 30 = 37 */
    182 }
    183 
    184 /* Interaction: fn-ptr param + struct-ptr param + member access via -> */
    185 int apply2(op2_t f, struct Point *p) { return f(p->x, p->y); }
    186 
    187 int test_apply(void) {
    188     return apply2(op_add, &g_pt) + apply2(op_mul, &g_pt2);  /* 300 + 35 = 335 */
    189 }
    190 
    191 /* Interaction: pointer arith + deref + recursion + global-array decay */
    192 int sum_arr(int *p, int n) {
    193     if (n == 0) return 0;
    194     return *p + sum_arr(p + 1, n - 1);
    195 }
    196 
    197 int test_ptr_recursion(void) { return sum_arr(g_arr, 3); }      /* 60 */
    198 
    199 int counter(void) {
    200     static int n = 0;
    201     n = n + 1;
    202     return n;
    203 }
    204 
    205 int test_static(void) {
    206     int a = counter();              /* 1 */
    207     int b = counter();              /* 2 */
    208     int c = counter();              /* 3 */
    209     return a + b + c;               /* 6 */
    210 }
    211 
    212 int test_switch(void) {
    213     int r = 0;
    214     int i;
    215     for (i = 0; i < 4; i = i + 1) {
    216         switch (i) {
    217             case 0: r = r + 1; break;
    218             case 1: r = r + 2; break;
    219             case 2:
    220             case 3: r = r + 10; break;
    221             default: r = r + 100; break;
    222         }
    223     }
    224     return r;                       /* 1 + 2 + 10 + 10 = 23 */
    225 }
    226 
    227 int test_goto(void) {
    228     int n = 0;
    229 loop:
    230     n = n + 1;
    231     if (n < 5) goto loop;
    232     return n;                       /* 5 */
    233 }
    234 
    235 int test_loops(void) {
    236     int x = 0;
    237     do { x = x + 1; } while (x < 3);            /* x = 3 */
    238     int y = 0;
    239     while (y < 10) {
    240         y = y + 1;
    241         if (y == 5) continue;
    242         x = x + 1;
    243     }                                           /* x = 3 + 9 = 12 */
    244     return x;                                   /* 12 */
    245 }
    246 
    247 int test_strings(void) {
    248     char *s = "world";
    249     int sum = 0;
    250     while (*s) {
    251         sum = sum + *s;
    252         s = s + 1;
    253     }
    254     return sum;                     /* w+o+r+l+d = 119+111+114+108+100 = 552 */
    255 }
    256 
    257 int test_globals(void) {
    258     g_zero = g_zero + 1;            /* now 1 */
    259     return g_scalar + g_zero + g_arr[1] + g_msg[0];     /* 42+1+20+'h'(104) = 167 */
    260 }
    261 
    262 int test_sizeof(void) {
    263     return sizeof(int) + sizeof(char) + sizeof(struct Point) + sizeof(g_arr);
    264     /* 4 + 1 + 8 + 12 = 25 */
    265 }
    266 
    267 int test_enum(void) {
    268     return RED + GREEN + BLUE;      /* 0 + 5 + 6 = 11 */
    269 }
    270 
    271 void f_void(int *out, int v) { *out = v; }
    272 
    273 int test_void_call(void) {
    274     int x = 0;
    275     f_void(&x, 42);
    276     return x;                       /* 42 */
    277 }
    278 
    279 int test_cast(void) {
    280     int a = 300;
    281     int b = (int)(char)a;           /* (char)300 = 44 (sign-extends back to int) */
    282     int c = (int)(short)a;          /* (short)300 = 300 (fits in 16 bits) */
    283     return b + c;                   /* 344 */
    284 }
    285 
    286 int test_void_ptr(void) {
    287     int x = 99;
    288     void *p = &x;
    289     int *q = (int *)p;
    290     return *q;                      /* 99 */
    291 }
    292 
    293 int test_comma(void) {
    294     int a = 0; int b = 0;
    295     int x = (a = 5, b = 10, a + b); /* 15 */
    296     return x;
    297 }
    298 
    299 int test_addr_array(void) {
    300     int (*p)[3] = &g_arr;
    301     return (*p)[0] + (*p)[1] + (*p)[2];     /* 60 */
    302 }
    303 
    304 /* -------- main ------------------------------------------------------------ */
    305 
    306 int main(int argc, char **argv) {
    307     if (test_arith()         != 88)  return 1;
    308     if (test_compound()      != 15)  return 2;
    309     if (test_inc_dec()       != 29)  return 3;
    310     if (test_logical()       != 7)   return 4;
    311     if (test_ternary()       != 210) return 5;
    312     if (test_compare()       != 63)  return 6;
    313     if (test_pointer()       != 20)  return 7;
    314     if (test_array()         != 15)  return 8;
    315     if (test_array_2d()      != 21)  return 9;
    316     if (test_struct()        != 7)   return 10;
    317     if (test_struct_ptr()    != 312) return 11;
    318     if (test_call()          != 15)  return 12;
    319     if (test_recursion()     != 120) return 13;
    320     if (test_variadic()      != 10)  return 14;
    321     if (test_fn_ptr()        != 37)  return 15;
    322     if (test_apply()         != 335) return 16;
    323     if (test_ptr_recursion() != 60)  return 17;
    324     if (test_static()        != 6)   return 18;
    325     if (test_switch()        != 23)  return 19;
    326     if (test_goto()          != 5)   return 20;
    327     if (test_loops()         != 12)  return 21;
    328     if (test_strings()       != 552) return 22;
    329     if (test_globals()       != 167) return 23;
    330     if (test_sizeof()        != 25)  return 24;
    331     if (test_enum()          != 11)  return 25;
    332     if (test_void_call()     != 42)  return 26;
    333     if (test_cast()          != 344) return 27;
    334     if (test_void_ptr()      != 99)  return 28;
    335     if (test_comma()         != 15)  return 29;
    336     if (test_addr_array()    != 60)  return 30;
    337     return 0;
    338 }