boot2

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

001-kitchen-sink.c (9942B)


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