aboutsummaryrefslogtreecommitdiffhomepage
path: root/c/c.h
blob: 45ce5096c5406eaefb832c75f506e637f26c67ca (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "../common.h"
#include "../type.h"

/*************/
/* EXPR TREE */
/*************/

enum exprkind {
   EXXX, ENUMLIT, ESTRLIT, ESYM, EVAARG, EINIT, EGETF, ECALL, ECOND,
   /* unary */
   EPLUS, ENEG, ECOMPL, ELOGNOT, EDEREF, EADDROF, ECAST,
   EPREINC, EPOSTINC, EPREDEC, EPOSTDEC,
   /* binary */
   EADD, ESUB, EMUL, EDIV, EREM, EBAND, EBIOR, EXOR, ESHL, ESHR,
   ELOGAND, ELOGIOR,
   EEQU, ENEQ, ELTH, EGTH, ELTE, EGTE,
   ESET, ESETADD, ESETSUB, ESETMUL, ESETDIV, ESETREM, ESETAND, ESETIOR, ESETXOR, ESETSHL, ESETSHR,
   ESEQ,
};
#define isunop(t) in_range(t, EPLUS, EPOSTDEC)
#define isbinop(t) in_range(t, EADD, ESEQ)
#define isassign(t) in_range(t, ESET, ESETSHR)
#define assigntobinop(t) ((t) - ESETADD + EADD)

struct expr {
   uchar t;
   uchar qual;
   union type ty;
   struct span span;
   union {
     struct {
        struct expr *sub; /* child(ren) */
        union {
           struct exgetfld {
              ushort off;
              uchar bitsiz, bitoff;
           } fld; /* EGETF */
           ushort narg; /* ECALL */
        };
     };
     uvlong u; vlong i; double f; /* ENUMLIT */
     struct {
        union {
           uchar *p;
           ushort *w16;
           uint *w32;
        };
        uint n;
     } s; /* ESTRLIT */
     struct decl *sym; /* ESYM */
     struct init *init; /* EINIT */
   };
};

struct init {
   struct bitset zero[BSSIZE(64)]; /* bytes to zero out up to 64 */
   struct initval {
      struct initval *next;
      uint off;
      uchar bitoff, bitsiz;
      struct expr ex;
   } *vals, **tail;
};

/** C compiler state **/
struct comp {
   struct lexer *lx;
   struct env *env;
   struct arena *fnarena, *exarena;
   struct span fnblkspan;
   uint loopdepth, switchdepth;
   struct block *breakto, *loopcont;
   struct switchstmt *switchstmt;
   struct label *labels;
};

enum storageclass {
   SCNONE,
   SCTYPEDEF = 1<<0,
   SCEXTERN = 1<<1,
   SCSTATIC = 1<<2,
   SCTHREADLOCAL = 1<<3,
   SCAUTO = 1<<4,
   SCREGISTER = 1<<5,
};

struct decl {
   union type ty;
   uchar scls;
   uchar qual : 2,
         noret : 1,
         inlin : 1,
         isenum : 1,
         isdef : 1,
         isbuiltin : 1;
   struct span span;
   internstr name;
   union {
      internstr sym;
      struct { ushort align; int id; };
      vlong value;
      const struct builtin *builtin;
   };
};

extern union type cvalistty;
struct function;
struct decl *envadddecl(struct env *env, const struct decl *d);
bool assigncheck(union type t, const struct expr *src);
union ref expraddr(struct function *, const struct expr *);
union ref compileexpr(struct function *, const struct expr *, bool discard);

/** builtin.c **/
struct builtin {
   bool (*sema)(struct comp *, struct expr *);
   union ref (*comp)(struct function *, struct expr *, bool discard);
};
void putbuiltins(struct env *);
union ref builtin_va_arg_comp(struct function *, const struct expr *, bool discard);

/** eval.c **/
enum evalmode {
   EVNONE,
   EVINTCONST,
   EVARITH,
   EVSTATICINI,
   EVFOLD,
};

bool eval(struct expr *, enum evalmode);

/* vim:set ts=3 sw=3 expandtab: */