kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

rpn_lang.c (4084B)


      1 #include <kit/frontend.h>
      2 
      3 #include <stddef.h>
      4 #include <stdint.h>
      5 
      6 typedef struct RpnFrontend {
      7   KitCompiler* c;
      8 } RpnFrontend;
      9 
     10 static KitFrontendState* rpn_new(KitCompiler* c) {
     11   KitHeap* h = kit_compiler_context(c)->heap;
     12   RpnFrontend* fe = (RpnFrontend*)h->alloc(h, sizeof(*fe), _Alignof(RpnFrontend));
     13   if (!fe) return NULL;
     14   fe->c = c;
     15   return (KitFrontendState*)fe;
     16 }
     17 
     18 static void rpn_free(KitFrontendState* st) {
     19   RpnFrontend* fe = (RpnFrontend*)st;
     20   KitHeap* h;
     21   if (!fe) return;
     22   h = kit_compiler_context(fe->c)->heap;
     23   h->free(h, fe, sizeof(*fe));
     24 }
     25 
     26 static void rpn_skip_ws(const char** p, const char* end) {
     27   while (*p < end && (**p == ' ' || **p == '\t' || **p == '\r' || **p == '\n'))
     28     ++(*p);
     29 }
     30 
     31 static int rpn_read_int(const char** p, const char* end, int64_t* out) {
     32   int neg = 0;
     33   int any = 0;
     34   int64_t v = 0;
     35   if (*p < end && **p == '-') {
     36     neg = 1;
     37     ++(*p);
     38   }
     39   while (*p < end && **p >= '0' && **p <= '9') {
     40     any = 1;
     41     v = v * 10 + (int64_t)(**p - '0');
     42     ++(*p);
     43   }
     44   if (!any) return 0;
     45   *out = neg ? -v : v;
     46   return 1;
     47 }
     48 
     49 static KitStatus rpn_compile_cg(KitFrontendState* st,
     50                                 const KitFrontendCompileOptions* opts,
     51                                 const KitSourceInput* input, KitCg* cg) {
     52   RpnFrontend* fe = (RpnFrontend*)st;
     53   const char* p = input->bytes.s;
     54   const char* end = p + input->bytes.len;
     55   KitCgTypeId i32_ty = kit_cg_type_builtin(fe->c, KIT_CG_BUILTIN_I32);
     56   KitCgTypeId func_ty;
     57   KitCgFuncResult result;
     58   KitCgFuncSig sig;
     59   KitCgDecl decl;
     60   KitCgSym main_sym;
     61   int depth = 0;
     62   (void)opts;
     63 
     64   result.type = i32_ty;
     65   result.attrs.flags = 0;
     66   result.attrs.align = 0;
     67   result.attrs.dereferenceable_size = 0;
     68   sig.result = result;
     69   sig.params = NULL;
     70   sig.nparams = 0;
     71   sig.call_conv = KIT_CG_CC_TARGET_C;
     72   sig.abi_variadic = false;
     73   func_ty = kit_cg_type_func(fe->c, sig);
     74 
     75   decl = (KitCgDecl){0};
     76   decl.kind = KIT_CG_DECL_FUNC;
     77   decl.linkage_name =
     78       kit_cg_c_linkage_name(fe->c, kit_sym_intern(fe->c, KIT_SLICE_LIT("main")));
     79   decl.display_name = kit_sym_intern(fe->c, KIT_SLICE_LIT("main"));
     80   decl.type = func_ty;
     81   decl.sym.bind = KIT_SB_GLOBAL;
     82   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
     83   decl.sym.flags = 0;
     84   decl.as.func.flags = 0;
     85   decl.as.func.inline_policy = KIT_CG_INLINE_DEFAULT;
     86 
     87   main_sym = kit_cg_decl(cg, decl);
     88   if (main_sym == KIT_CG_SYM_NONE) return KIT_ERR;
     89   kit_cg_func_begin(cg, main_sym);
     90   while (p < end) {
     91     int64_t v;
     92     rpn_skip_ws(&p, end);
     93     if (p >= end) break;
     94     if ((*p >= '0' && *p <= '9') ||
     95         (*p == '-' && p + 1 < end && p[1] >= '0' && p[1] <= '9')) {
     96       if (!rpn_read_int(&p, end, &v)) return KIT_MALFORMED;
     97       kit_cg_push_int(cg, (uint64_t)(int32_t)v, i32_ty);
     98       ++depth;
     99       continue;
    100     }
    101     if (*p == '+' || *p == '-' || *p == '*') {
    102       char op = *p++;
    103       if (depth < 2) return KIT_MALFORMED;
    104       if (op == '+')
    105         kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    106       else if (op == '-')
    107         kit_cg_int_binop(cg, KIT_CG_INT_SUB, 0);
    108       else
    109         kit_cg_int_binop(cg, KIT_CG_INT_MUL, 0);
    110       --depth;
    111       continue;
    112     }
    113     return KIT_MALFORMED;
    114   }
    115   if (depth != 1) return KIT_MALFORMED;
    116   kit_cg_ret(cg);
    117   kit_cg_func_end(cg);
    118   return KIT_OK;
    119 }
    120 
    121 static const KitSlice rpn_exts[] = {KIT_SLICE_LIT("rpn")};
    122 static const KitSlice rpn_names[] = {KIT_SLICE_LIT("rpn")};
    123 
    124 const KitFrontendVTable kit_rpn_frontend_vtable = {
    125     .new_frontend = rpn_new,
    126     .compile_cg = rpn_compile_cg,
    127     .compile_obj = NULL,
    128     .free_frontend = rpn_free,
    129     .extensions = rpn_exts,
    130     .nextensions = (uint32_t)(sizeof rpn_exts / sizeof rpn_exts[0]),
    131     .extension_kinds = NULL,
    132     .names = rpn_names,
    133     .nnames = (uint32_t)(sizeof rpn_names / sizeof rpn_names[0]),
    134     .commit = NULL,
    135     .abort = NULL,
    136     .caps = {false, KIT_FRONTEND_LTO_CG, false},
    137     .parse_options = NULL,
    138     .free_options = NULL,
    139 };
    140 
    141 KitStatus kit_rpn_register_frontends(KitFrontendRegistry* registry) {
    142   return kit_frontend_registry_add(registry, &kit_rpn_frontend_vtable, NULL);
    143 }