diff options
| author | 2022-08-03 20:24:47 +0200 | |
|---|---|---|
| committer | 2022-08-03 20:24:47 +0200 | |
| commit | 1625c50f0c0e4b1c7ba01a5df5713efaf6dce606 (patch) | |
| tree | bc5f24811413749b776964c1bbdec13a46dd9768 /bootstrap/all.h | |
initial
Diffstat (limited to 'bootstrap/all.h')
| -rw-r--r-- | bootstrap/all.h | 415 |
1 files changed, 415 insertions, 0 deletions
diff --git a/bootstrap/all.h b/bootstrap/all.h new file mode 100644 index 0000000..7f26372 --- /dev/null +++ b/bootstrap/all.h @@ -0,0 +1,415 @@ +#pragma once + +#include "vec.h" +#include <assert.h> +#include <limits.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/***********/ +/** Types **/ +/***********/ + +typedef uint8_t u8; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int64_t i64; +#define bool _Bool +#define noreturn _Noreturn +#define slice_t(T) struct { T *d; unsigned n; } + +struct span { + short fileid; + int idx, col, line; +}; + +/* must be alpha sorted */ +#define LIST_KEYWORDS(_) \ + _(and) \ + _(break) \ + _(case) \ + _(const) \ + _(defmacro) \ + _(do) \ + _(else) \ + _(extern) \ + _(fn) \ + _(for) \ + _(if) \ + _(let) \ + _(not) \ + _(or) \ + _(return) \ + _(switch) \ + _(typedef) \ + _(typeof) \ + _(while) \ + +enum toktype { +#define KWTK(kw) TKkw_##kw, + LIST_KEYWORDS(KWTK) +#undef KWTK + TKintlit, + TKflolit, + TKboolit, + TKstrlit, + TKchrlit, + TKnullit, + TKident, + TKgensym, + TKeof, + NUM_LEXTOKENS +}; +#define NUM_KEYWORDS TKintlit + +struct tok { + int t; + struct span span; + union { + struct { + const struct type *ty; + u64 i; + } ilit; + struct { + const struct type *ty; + double f; + } flit; + bool boolit; + struct { + const char *str; + int strlen; + }; + }; +}; + +struct toktree { + slice_t(struct tok); +}; + +struct expanarg { + const char *name; + struct toktree toks; +}; + +struct parser { + FILE *fp; + const char *curfile; + struct span tokspan; + struct span curspan; + bool eof; + int peekchr; + bool have_peektok; + struct tok peektok; + struct env *primenv; + struct env *tlenv; + struct env *curenv; + struct fn *curfn; + struct expan { + struct expan *prev; + slice_t(struct expanarg) args; + struct toktree toks; + const char *name; + struct span spp,span; + int idx; + } *curexpan; // macro expansions + int expanno; +}; + +enum typetype { + TYvoid, + TYbool, + TYint, + TYfloat, + TYptr, + TYarr, + TYslice, + TYfn, +}; + +struct type { + enum typetype t; + size_t size, align; + bool konst; + union { + bool int_signed; + struct { + const struct type *child; + i64 length; + }; + struct { + slice_t(const struct type *) params; + const struct type *retty; + bool variadic; + } fn; + }; + // cgen.c (mutated later, not hashed or involved in equality) + const char *_cname; +}; + +struct fnparam { + const struct type *ty; + const char *name; +}; + +struct fn { + const char *name, *asmname; + slice_t(struct fnparam) params; + const struct type *selfty; + const struct type *retty; + bool variadic; + int id; + struct stmt *body; +}; + +struct macrocase { + bool variadic; + slice_t(const char *) params; + struct toktree body; +}; + +struct macro { + const char *name; + slice_t(struct macrocase) cs; +}; + +enum decltype { + Dtype, + Dfn, + Dvar, + Dmacro, +}; + +struct decl { + enum decltype t; + const char *name; + char **_cname; + bool externp; + struct span span; + union { + const struct type *ty; + struct fn fn; + struct { + const struct type *ty; + struct expr *ini; + int fnid; + } var; + struct macro macro; + }; +}; + +struct env { + struct env *parent; + struct decls { + struct decls *next; + struct decl decl; + } *decls; +}; + +enum exprtype { + Eintlit, + Eflolit, + Estrlit, + Eboolit, + Enullit, + Ename, + Eprefix, Epostfix, // (unops) + Ebinop, + Econd, + Ecall, + Eindex, +}; + +struct expr { + enum exprtype t; + struct span span; + const struct type *ty; + union { + u64 i; // also for bool lit + double f; + struct { + const char *d; + u64 n; + } strlit; + const struct decl *ref; + struct { + int op; // operator token + struct expr *child; + } unop; + struct { + int op; // operator token + struct expr *lhs, *rhs; + } binop; + struct { + struct expr *test, *t, *f; + } cond; + struct { + struct expr *callee; + slice_t(struct expr) args; + } call; + struct { + struct expr *lhs, *rhs; + } index; + }; +}; + +enum stmttype { + Sblock, + Sexpr, + Sdecl, + Sifelse, + Swhile, + Sfor, + Siswitch, + Sreturn, +}; + +struct blockstmt { + struct env env; + slice_t(struct stmt) stmts; +}; + +struct iswitchcase { + slice_t(struct expr) es; + struct blockstmt t; +}; + +struct stmt { + enum stmttype t; + union { + struct blockstmt block; + struct expr expr; + struct decl decl; + struct { + struct expr test; + struct blockstmt t; + struct stmt *f; + } ifelse; + struct { + struct stmt *ini; + struct expr test; + struct expr *next; + struct blockstmt body; + } loop; + struct { + struct expr test; + slice_t(struct iswitchcase) cs; + struct blockstmt *f; + } iswitch; + struct expr *retex; + }; +}; + +struct transunit { + slice_t(struct decl) decls; +}; + +/************/ +/** Target **/ +/************/ + +#define alignof __alignof__ + +static const struct targ { + size_t ptrsize, + shortsize, + intsize, + longsize, + llongsize, + sizesize, + f32align, + f64align; + bool charsigned; +} g_targ = { + .ptrsize = sizeof(void *), + .shortsize = sizeof(short), + .intsize = sizeof(int), + .longsize = sizeof(long), + .llongsize = sizeof(long long), + .sizesize = sizeof(size_t), + .f32align = alignof(float), + .f64align = alignof(double), + .charsigned = CHAR_MIN < 0, +}; + +/*********************************/ +/** Macros and inline functions **/ +/*********************************/ + +#define ARRAY_LENGTH(a) (sizeof a / sizeof *a) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define WITH_TMPCHANGE(T,var,new) \ + for (T __old = (var), *__dummy = ((var) = (new), NULL); \ + !__dummy; \ + __dummy++, (var) = __old) + +static inline u32 +bswap32(u32 x) { + return (x >> 24) + | (x >> 8 & 0xFF00) + | (x << 8 & 0xFF0000) + | (x << 24 & 0xFF000000u); +} + +static inline u64 +bswap64(u64 x) { + return ((u64)bswap32(x) << 32) | bswap32(x >> 32) ; +} + +#define vec_slice_cpy(slice, v) \ + ((slice)->d = vec_compact(v), \ + (slice)->n = (v)->length) + +#define jkhashv(h, v) jkhash(h, (void *)&(v), sizeof((v))) + +///////////////////////////////// + +/** util.c **/ +u32 jkhash(u32 hash, const u8 *data, size_t length); +int addfilepath(const char *); +const char *fileid2path(int); +void *xmalloc(size_t); +void *xcalloc(size_t, size_t); +void *xrealloc(void *, size_t); +char *xstrdup(const char *); +char *xasprintf(const char *fmt, ...); +void noreturn fatal(struct parser *, struct span, const char *fmt, ...); + +/** parse.c **/ +extern const char *keyword2str[]; +void parse(struct transunit *, struct parser *); +void initparser(struct parser *, const char *fname); + +/** types.c **/ +extern const struct type + *ty_void, *ty_bool, *ty_f32, *ty_f64, + *ty_i8, *ty_u8, *ty_i16, *ty_u16, + *ty_i32, *ty_u32, *ty_i64, *ty_u64, + *ty_int, *ty_uint, *ty_isize, *ty_usize, + *ty_iptrint, *ty_uptrint, *ty_c_int, *ty_c_uint, + *ty_c_char, *ty_c_schar, *ty_c_uchar, *ty_c_short, + *ty_c_ushort, *ty_c_long, *ty_c_ulong, *ty_c_llong, + *ty_c_ullong; +void inittypes(void); +const struct type *interntype(struct type); +bool typeeql(const struct type *lhs, const struct type *rhs); +bool completetype(const struct type *); +void putprimtypes(struct env *); +void visittypes(void (*visitor)(const struct type *, void *), void *arg); + +/** env.c **/ +struct decl *envfind(const struct env *, const char *name); +bool envput(struct env *, const struct decl *decl); +struct env *mkenv(const struct env *parent); + +/** dump.c **/ +void dumptransunit(const struct transunit *); +const char *tokt2str(int); +const char *tok2str(struct tok); +void pritoktree(struct toktree); + +/** cgen.c **/ +void cgen(FILE *, const struct transunit *); |