aboutsummaryrefslogtreecommitdiff
path: root/bootstrap/all.h
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-03 20:24:47 +0200
committerlemon <lsof@mailbox.org>2022-08-03 20:24:47 +0200
commit1625c50f0c0e4b1c7ba01a5df5713efaf6dce606 (patch)
treebc5f24811413749b776964c1bbdec13a46dd9768 /bootstrap/all.h
initial
Diffstat (limited to 'bootstrap/all.h')
-rw-r--r--bootstrap/all.h415
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 *);