backend

Unnamed repository; edit this file 'description' to name the repository.
git clone https://git.deepztream.com/backend
Log | Files | Refs

backend.c (4690B)


      1 #include <stdbool.h>
      2 
      3 #define DLIB_IMPLEMENTATION
      4 #include "dlib.h"
      5 
      6 typedef struct Ir_program Ir_program;
      7 typedef bool (*Compile_fn)(Ir_program, string_builder *);
      8 
      9 typedef struct {
     10   const char *name;
     11   Compile_fn compile;
     12 } Backend;
     13 
     14 enum Ir_type {
     15   TYPE_VOID,
     16   TYPE_I8,
     17   TYPE_U8,
     18   TYPE_I16,
     19   TYPE_U16,
     20   TYPE_I32,
     21   TYPE_U32,
     22   TYPE_I64,
     23   TYPE_U64,
     24   TYPE_PTR,
     25   TYPE_F32,
     26   TYPE_F64,
     27 };
     28 
     29 enum Ir_kind {
     30   IR_LOAD,
     31   IR_STORE,
     32   IR_ASSIGN,
     33   IR_BINOP,
     34   IR_CALL,
     35   IR_RETURN,
     36   IR_LABEL,
     37   IR_JUMP,
     38   IR_JUMP_IF_NOT,
     39 };
     40 
     41 enum Ir_arg_kind {
     42   ARG_NONE,
     43   ARG_INT_LITERAL,
     44   /*ARG_FLOAT_LITERAL,*/
     45   ARG_CSTRING_LITERAL,
     46   ARG_TEMP_STORAGE,
     47   ARG_ADDRESS,
     48 };
     49 
     50 enum Ir_binop {
     51   OP_ADD,
     52   OP_SUB,
     53   OP_MUL,
     54   OP_DIV,
     55   OP_LT,
     56   OP_GT,
     57   OP_EQ,
     58   OP_LEQ,
     59   OP_GEQ,
     60 };
     61 
     62 typedef struct {
     63   enum Ir_arg_kind type;
     64   union {
     65     int64_t i64;
     66     /* double f64; */
     67     ssize_t temp_id;
     68     void *addr;
     69     char *cstr;
     70   };
     71 } Ir_arg;
     72 
     73 typedef struct {
     74   Ir_arg *items;
     75   size_t count;
     76   size_t capacity;
     77 } Ir_arg_list;
     78 
     79 typedef struct {
     80   enum Ir_kind type;
     81   Ir_arg result;
     82   union {
     83     struct {
     84       enum Ir_binop op;
     85       Ir_arg left;
     86       Ir_arg right;
     87     } binop;
     88     struct {
     89       Ir_arg loc;
     90     } load;
     91     struct {
     92       Ir_arg loc;
     93       Ir_arg data;
     94     } store;
     95     Ir_arg assign;
     96     string_view label;
     97     struct {
     98       Ir_arg cond;
     99       string_view label;
    100     } jump;
    101     Ir_arg ret;
    102     struct {
    103       Ir_arg indirect;
    104       string_view name;
    105       Ir_arg_list args;
    106     } call;
    107   };
    108 } Ir;
    109 
    110 typedef struct {
    111   Ir  *items;
    112   size_t count;
    113   size_t capacity;
    114 } Ir_list;
    115 
    116 typedef struct {
    117   enum Ir_type *items;
    118   size_t count;
    119   size_t capacity;
    120 } Ir_type_list;
    121 
    122 typedef struct {
    123   enum Ir_type type;
    124   union {
    125     int8_t i8;
    126     uint8_t u8;
    127     int16_t i16;
    128     uint16_t u16;
    129     int32_t i32;
    130     uint32_t u32;
    131     int64_t i64;
    132     uint64_t u64;
    133     /* double f64;
    134     float f32; */
    135     string_view str;
    136     char *cstr;
    137   };
    138 } Ir_data;
    139 
    140 typedef struct {
    141   string_view name;
    142   Ir_data default_value;
    143 } Ir_static_data;
    144 
    145 typedef struct {
    146   Ir_static_data *items;
    147   size_t count;
    148   size_t capacity;
    149 } Ir_static_data_list;
    150 
    151 typedef struct {
    152   string_view name;
    153   enum Ir_type return_type;
    154   Ir_type_list argument_types;
    155   Ir_list body;
    156 } Ir_function;
    157 
    158 typedef struct {
    159   Ir_function *items;
    160   size_t count;
    161   size_t capacity;
    162 } Ir_function_list;
    163 
    164 struct Ir_program {
    165   Ir_function_list functions;
    166   Ir_static_data_list data;
    167 };
    168 
    169 bool ir_compile(Ir_program, string_builder *);
    170 
    171 Backend ir_backend = {
    172   "IR Dump",
    173   ir_compile,
    174 };
    175 
    176 int
    177 main(int argc, char **argv)
    178 {
    179   (void) argc;
    180   (void) argv;
    181   string_builder sb = {0};
    182   Ir_list ir_list = {0};
    183   da_append(&ir_list, ((Ir) { .type = IR_LABEL, .label = {.data = "start", .count = 5}}));
    184   da_append(&ir_list, ((Ir) { .type = IR_ASSIGN, .result = { .type = ARG_TEMP_STORAGE, .temp_id = 0}, .assign = {.type = ARG_INT_LITERAL, .i64 = 0}}));
    185   da_append(&ir_list, ((Ir) { .type = IR_LABEL, .label = {.data = "loop", .count = 4}}));
    186   da_append(&ir_list, ((Ir) { .type = IR_BINOP, .result = { .type = ARG_TEMP_STORAGE, .temp_id = 1}, .binop = {.op = OP_LT, .left = {.type = ARG_TEMP_STORAGE, .temp_id = 0}, .right = {.type = ARG_INT_LITERAL, .i64 = 10}}}));
    187   da_append(&ir_list, ((Ir) { .type = IR_JUMP_IF_NOT, .jump = {.cond = {.type = ARG_TEMP_STORAGE, .temp_id = 1}, .label = {.data = "loop_end", .count = 8}}}));
    188   da_append(&ir_list, ((Ir) { .type = IR_CALL, .result = {.type = ARG_TEMP_STORAGE, .temp_id = 2}, .call = { .name = {.data = "printf", .count = 6}, .args = {0}}}));
    189   da_append(&ir_list.items[ir_list.count - 1].call.args, ((Ir_arg) {.type = ARG_CSTRING_LITERAL, .cstr = "%i\\n"}));
    190   da_append(&ir_list.items[ir_list.count - 1].call.args, ((Ir_arg) {.type = ARG_TEMP_STORAGE, .temp_id = 0}));
    191   da_append(&ir_list, ((Ir) { .type = IR_BINOP, .result = { .type = ARG_TEMP_STORAGE, .temp_id = 0}, .binop = {.op = OP_ADD, .left = {.type = ARG_TEMP_STORAGE, .temp_id = 0}, .right = {.type = ARG_INT_LITERAL, .i64 = 1}}}));
    192   da_append(&ir_list, ((Ir) { .type = IR_JUMP, .jump = {.label = {.data = "loop", .count = 4}}}));
    193   da_append(&ir_list, ((Ir) { .type = IR_LABEL, .label = {.data = "loop_end", .count = 8}}));
    194   da_append(&ir_list, ((Ir) { .type = IR_RETURN, .ret = {.type = ARG_INT_LITERAL, .i64 = 69}}));
    195   Ir_program prog = {0};
    196   da_append(&prog.functions, ((Ir_function) {.name = {.data = "main", .count = 4}, .return_type = TYPE_I32, .body = ir_list}));
    197   da_append(&prog.functions.items[0].argument_types, TYPE_I32);
    198   da_append(&prog.functions.items[0].argument_types, TYPE_PTR);
    199 
    200   if (!ir_backend.compile(prog, &sb)) {
    201     return 1;
    202   }
    203   sb_write(1, sb);
    204   return 0;
    205 }
    206 
    207 #include "ir_backend.c"