nostrdb

an unfairly fast embedded nostr database backed by lmdb
git clone git://jb55.com/nostrdb
Log | Files | Refs | Submodules | README | LICENSE

codegen_c.h (10127B)


      1 #ifndef CODEGEN_C_H
      2 #define CODEGEN_C_H
      3 
      4 #include <assert.h>
      5 #include <stdarg.h>
      6 
      7 #include "symbols.h"
      8 #include "parser.h"
      9 #include "codegen.h"
     10 
     11 /* -DFLATCC_PORTABLE may help if inttypes.h is missing. */
     12 #ifndef PRId64
     13 #include <inttypes.h>
     14 #endif
     15 
     16 #define __FLATCC_ERROR_TYPE "INTERNAL_ERROR_UNEXPECTED_TYPE"
     17 
     18 #ifndef gen_panic
     19 #define gen_panic(context, msg) fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg), assert(0), exit(-1)
     20 #endif
     21 
     22 
     23 static inline void token_name(fb_token_t *t, int *n, const char **s) {
     24     *n = (int)t->len;
     25     *s = t->text;
     26 }
     27 
     28 typedef char fb_symbol_text_t[FLATCC_NAME_BUFSIZ];
     29 typedef struct fb_scoped_name fb_scoped_name_t;
     30 
     31 /* Should be zeroed because scope is cached across updates. */
     32 struct fb_scoped_name {
     33     fb_symbol_text_t text;
     34     fb_scope_t *scope;
     35     int scope_len, len, total_len;
     36 };
     37 
     38 #define fb_clear(x) (memset(&(x), 0, sizeof(x)))
     39 
     40 /* Returns length or -1 if length exceeds namespace max. */
     41 int __flatcc_fb_copy_scope(fb_scope_t *scope, char *buf);
     42 #define fb_copy_scope __flatcc_fb_copy_scope
     43 
     44 void __flatcc_fb_scoped_symbol_name(fb_scope_t *scope, fb_symbol_t *sym, fb_scoped_name_t *sn);
     45 #define fb_scoped_symbol_name __flatcc_fb_scoped_symbol_name
     46 
     47 static inline void fb_compound_name(fb_compound_type_t *ct, fb_scoped_name_t *sn)
     48 {
     49     fb_scoped_symbol_name(ct->scope, &ct->symbol, sn);
     50 }
     51 
     52 static inline void symbol_name(fb_symbol_t *sym, int *n, const char **s) {
     53     token_name(sym->ident, n, s);
     54 }
     55 
     56 static inline const char *scalar_type_ns(fb_scalar_type_t scalar_type, const char *ns)
     57 {
     58     return scalar_type == fb_bool ? ns : "";
     59 }
     60 
     61 static inline const char *scalar_type_prefix(fb_scalar_type_t scalar_type)
     62 {
     63     const char *tname;
     64     switch (scalar_type) {
     65     case fb_ulong:
     66         tname = "uint64";
     67         break;
     68     case fb_uint:
     69         tname = "uint32";
     70         break;
     71     case fb_ushort:
     72         tname = "uint16";
     73         break;
     74     case fb_char:
     75         tname = "char";
     76         break;
     77     case fb_ubyte:
     78         tname = "uint8";
     79         break;
     80     case fb_bool:
     81         tname = "bool";
     82         break;
     83     case fb_long:
     84         tname = "int64";
     85         break;
     86     case fb_int:
     87         tname = "int32";
     88         break;
     89     case fb_short:
     90         tname = "int16";
     91         break;
     92     case fb_byte:
     93         tname = "int8";
     94         break;
     95     case fb_float:
     96         tname = "float";
     97         break;
     98     case fb_double:
     99         tname = "double";
    100         break;
    101     default:
    102         gen_panic(0, "internal error: unexpected type during code generation");
    103         tname = __FLATCC_ERROR_TYPE;
    104         break;
    105     }
    106     return tname;
    107 }
    108 
    109 static inline const char *scalar_type_name(fb_scalar_type_t scalar_type)
    110 {
    111     const char *tname;
    112     switch (scalar_type) {
    113     case fb_ulong:
    114         tname = "uint64_t";
    115         break;
    116     case fb_uint:
    117         tname = "uint32_t";
    118         break;
    119     case fb_ushort:
    120         tname = "uint16_t";
    121         break;
    122     case fb_char:
    123         tname = "char";
    124         break;
    125     case fb_ubyte:
    126         tname = "uint8_t";
    127         break;
    128     case fb_bool:
    129         tname = "bool_t";
    130         break;
    131     case fb_long:
    132         tname = "int64_t";
    133         break;
    134     case fb_int:
    135         tname = "int32_t";
    136         break;
    137     case fb_short:
    138         tname = "int16_t";
    139         break;
    140     case fb_byte:
    141         tname = "int8_t";
    142         break;
    143     case fb_float:
    144         tname = "float";
    145         break;
    146     case fb_double:
    147         tname = "double";
    148         break;
    149     default:
    150         gen_panic(0, "internal error: unexpected type during code generation");
    151         tname = __FLATCC_ERROR_TYPE;
    152         break;
    153     }
    154     return tname;
    155 }
    156 
    157 static inline const char *scalar_vector_type_name(fb_scalar_type_t scalar_type)
    158 {
    159     const char *tname;
    160     switch (scalar_type) {
    161     case fb_ulong:
    162         tname = "uint64_vec_t";
    163         break;
    164     case fb_uint:
    165         tname = "uint32_vec_t";
    166         break;
    167     case fb_ushort:
    168         tname = "uint16_vec_t";
    169         break;
    170     case fb_char:
    171         tname = "char_vec_t";
    172         break;
    173     case fb_ubyte:
    174         tname = "uint8_vec_t";
    175         break;
    176     case fb_bool:
    177         tname = "uint8_vec_t";
    178         break;
    179     case fb_long:
    180         tname = "int64_vec_t";
    181         break;
    182     case fb_int:
    183         tname = "int32_vec_t";
    184         break;
    185     case fb_short:
    186         tname = "int16_vec_t";
    187         break;
    188     case fb_byte:
    189         tname = "int8_vec_t";
    190         break;
    191     case fb_float:
    192         tname = "float_vec_t";
    193         break;
    194     case fb_double:
    195         tname = "double_vec_t";
    196         break;
    197     default:
    198         gen_panic(0, "internal error: unexpected type during code generation");
    199         tname = __FLATCC_ERROR_TYPE;
    200         break;
    201     }
    202     return tname;
    203 }
    204 
    205 /* Only for integers. */
    206 static inline const char *scalar_cast(fb_scalar_type_t scalar_type)
    207 {
    208     const char *cast;
    209     switch (scalar_type) {
    210     case fb_ulong:
    211         cast = "UINT64_C";
    212         break;
    213     case fb_uint:
    214         cast = "UINT32_C";
    215         break;
    216     case fb_ushort:
    217         cast = "UINT16_C";
    218         break;
    219     case fb_char:
    220         cast = "char";
    221         break;
    222     case fb_ubyte:
    223         cast = "UINT8_C";
    224         break;
    225     case fb_bool:
    226         cast = "UINT8_C";
    227         break;
    228     case fb_long:
    229         cast = "INT64_C";
    230         break;
    231     case fb_int:
    232         cast = "INT32_C";
    233         break;
    234     case fb_short:
    235         cast = "INT16_C";
    236         break;
    237     case fb_byte:
    238         cast = "INT8_C";
    239         break;
    240     default:
    241         gen_panic(0, "internal error: unexpected type during code generation");
    242         cast = "";
    243         break;
    244     }
    245     return cast;
    246 }
    247 
    248 typedef char fb_literal_t[100];
    249 
    250 static inline size_t print_literal(fb_scalar_type_t scalar_type, const fb_value_t *value, fb_literal_t literal)
    251 {
    252     const char *cast;
    253 
    254     switch (value->type) {
    255     case vt_uint:
    256         cast = scalar_cast(scalar_type);
    257         return (size_t)sprintf(literal, "%s(%"PRIu64")", cast, (uint64_t)value->u);
    258         break;
    259     case vt_int:
    260         cast = scalar_cast(scalar_type);
    261         return (size_t)sprintf(literal, "%s(%"PRId64")", cast, (int64_t)value->i);
    262         break;
    263     case vt_bool:
    264         cast = scalar_cast(scalar_type);
    265         return (size_t)sprintf(literal, "%s(%u)", cast, (unsigned)value->b);
    266         break;
    267     case vt_float:
    268         /*
    269          * .9g ensures sufficient precision in 32-bit floats and
    270          * .17g ensures sufficient precision for 64-bit floats (double).
    271          * The '#' forces a decimal point that would not be printed
    272          * for integers which would result in the wrong type in C
    273          * source.
    274          */
    275         if (scalar_type == fb_float) {
    276             return (size_t)sprintf(literal, "%#.9gf", (float)value->f);
    277         } else {
    278             return (size_t)sprintf(literal, "%#.17g", (double)value->f);
    279         }
    280         break;
    281     default:
    282         gen_panic(0, "internal error: unexpected type during code generation");
    283         *literal = 0;
    284         return 0;
    285     }
    286 }
    287 
    288 static inline const char *scalar_suffix(fb_scalar_type_t scalar_type)
    289 {
    290     const char *suffix;
    291     switch (scalar_type) {
    292     case fb_ulong:
    293         suffix = "ULL";
    294         break;
    295     case fb_uint:
    296         suffix = "UL";
    297         break;
    298     case fb_ushort:
    299         suffix = "U";
    300         break;
    301     case fb_char:
    302         suffix = "";
    303         break;
    304     case fb_ubyte:
    305         suffix = "U";
    306         break;
    307     case fb_bool:
    308         suffix = "U";
    309         break;
    310     case fb_long:
    311         suffix = "LL";
    312         break;
    313     case fb_int:
    314         suffix = "L";
    315         break;
    316     case fb_short:
    317         suffix = "";
    318         break;
    319     case fb_byte:
    320         suffix = "";
    321         break;
    322     case fb_double:
    323         suffix = "";
    324         break;
    325     case fb_float:
    326         suffix = "F";
    327         break;
    328     default:
    329         gen_panic(0, "internal error: unexpected type during code generation");
    330         suffix = "";
    331         break;
    332     }
    333     return suffix;
    334 }
    335 
    336 /* See also: https://github.com/philsquared/Catch/issues/376 */
    337 static inline int gen_prologue(fb_output_t *out)
    338 {
    339     if (out->opts->cgen_pragmas) {
    340         fprintf(out->fp, "#include \"flatcc/flatcc_prologue.h\"\n");
    341     }
    342     return 0;
    343 }
    344 
    345 static inline int gen_epilogue(fb_output_t *out)
    346 {
    347     if (out->opts->cgen_pragmas) {
    348         fprintf(out->fp, "#include \"flatcc/flatcc_epilogue.h\"\n");
    349     }
    350     return 0;
    351 }
    352 
    353 /* This assumes the output context is named out which it is by convention. */
    354 #define indent() (out->indent++)
    355 #define unindent() { assert(out->indent); out->indent--; }
    356 #define margin() { out->tmp_indent = out->indent; out->indent = 0; }
    357 #define unmargin() { out->indent = out->tmp_indent; }
    358 
    359 /* Redefine names to avoid polluting library namespace. */
    360 
    361 int __flatcc_fb_init_output_c(fb_output_t *out, fb_options_t *opts);
    362 #define fb_init_output_c __flatcc_fb_init_output_c
    363 
    364 int __flatcc_fb_open_output_file(fb_output_t *out, const char *name, size_t len, const char *ext);
    365 #define fb_open_output_file __flatcc_fb_open_output_file
    366 
    367 void __flatcc_fb_close_output_file(fb_output_t *out);
    368 #define fb_close_output_file __flatcc_fb_close_output_file
    369 
    370 void __flatcc_fb_gen_c_includes(fb_output_t *out, const char *ext, const char *extup);
    371 #define fb_gen_c_includes __flatcc_fb_gen_c_includes
    372 
    373 int __flatcc_fb_gen_common_c_header(fb_output_t *out);
    374 #define fb_gen_common_c_header __flatcc_fb_gen_common_c_header
    375 
    376 int __flatcc_fb_gen_common_c_builder_header(fb_output_t *out);
    377 #define fb_gen_common_c_builder_header __flatcc_fb_gen_common_c_builder_header
    378 
    379 int __flatcc_fb_gen_c_reader(fb_output_t *out);
    380 #define fb_gen_c_reader __flatcc_fb_gen_c_reader
    381 
    382 int __flatcc_fb_gen_c_builder(fb_output_t *out);
    383 #define fb_gen_c_builder __flatcc_fb_gen_c_builder
    384 
    385 int __flatcc_fb_gen_c_verifier(fb_output_t *out);
    386 #define fb_gen_c_verifier __flatcc_fb_gen_c_verifier
    387 
    388 int __flatcc_fb_gen_c_sorter(fb_output_t *out);
    389 #define fb_gen_c_sorter __flatcc_fb_gen_c_sorter
    390 
    391 int __flatcc_fb_gen_c_json_parser(fb_output_t *out);
    392 #define fb_gen_c_json_parser __flatcc_fb_gen_c_json_parser
    393 
    394 int __flatcc_fb_gen_c_json_printer(fb_output_t *out);
    395 #define fb_gen_c_json_printer __flatcc_fb_gen_c_json_printer
    396 
    397 #endif /* CODEGEN_C_H */