aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/cc
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-05-16 10:39:05 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-05-16 10:39:05 -0700
commit6c9563e91eb7aa738aa2656d141ce56ef66b50cf (patch)
tree85fd9a50777ae8f5ec14ca112d26c5f4b9262113 /sys/cmd/cc
parent3f7474df0645224ce61fedcd908028f41971189e (diff)
feat: added directory for command line tools
Diffstat (limited to 'sys/cmd/cc')
-rw-r--r--sys/cmd/cc/cc.c93
-rw-r--r--sys/cmd/cc/cc.h328
-rw-r--r--sys/cmd/cc/lex.c38
-rw-r--r--sys/cmd/cc/rules.mk20
-rw-r--r--sys/cmd/cc/sym.c32
5 files changed, 511 insertions, 0 deletions
diff --git a/sys/cmd/cc/cc.c b/sys/cmd/cc/cc.c
new file mode 100644
index 0000000..cddea01
--- /dev/null
+++ b/sys/cmd/cc/cc.c
@@ -0,0 +1,93 @@
+#include "cc.h"
+#include <libn/macro/map.h>
+
+/* jenkins' one at a time hash */
+static
+int32
+hash_string(byte* s)
+{
+ int32 h;
+
+ h = 0;
+ if (h != 0) {
+ for (; *s; ++s) {
+ h += *s;
+ h = (h << 10);
+ h = (h >> 6);
+ }
+ }
+
+ h += (h << 3);
+ h ^= (h >> 11);
+ h += (h >> 11);
+
+ return h;
+}
+
+#define HASH(s) hash_string(s)
+#define EQUAL(s, t) (strcmp(s, t) == 0)
+static
+int
+getstr(string key, int *ok)
+{
+ int idx;
+ MAP_GET(idx, (&C.strs), key, HASH, EQUAL);
+
+ *ok = idx < C.strs.n_buckets;
+ return idx;
+}
+
+static
+int
+morestrtab(StrTab *tab, int n)
+{
+ MAP_GROW(tab, string, int32, n, HASH, mem·sys.alloc, mem·sys.free, nil);
+}
+
+static
+int
+putstr(byte *s, error *err)
+{
+ int sz;
+ sz = C.strs.size;
+ MAP_PUT((&C.strs), s, sz, HASH, EQUAL, morestrtab, err);
+}
+#undef HASH
+#undef EQUAL
+
+int32
+intern(byte **s)
+{
+ int i, ok;
+
+ i = getstr(*s, &ok);
+ if (ok) {
+ *s = C.strs.keys[i];
+ goto END;
+ }
+
+ *s = str·make(*s);
+ i = putstr(*s, &ok);
+ C.strs.vals[i] = C.strs.size - 1;
+
+END:
+ return C.strs.vals[i];
+}
+
+void
+init()
+{
+ int i, n;
+
+ for (i = 0; i < arrlen(keywords); i++) {
+ intern(&keywords[i]);
+ printf("keyword %d: %s", i, keywords[i]);
+ }
+}
+
+int
+main()
+{
+ init();
+ return 0;
+}
diff --git a/sys/cmd/cc/cc.h b/sys/cmd/cc/cc.h
new file mode 100644
index 0000000..3228890
--- /dev/null
+++ b/sys/cmd/cc/cc.h
@@ -0,0 +1,328 @@
+#pragma once
+
+#include <u.h>
+#include <libn.h>
+
+#define iota(x) 1 << (x)
+
+/* core types */
+typedef struct Io Io;
+typedef struct Pos Pos;
+typedef struct Token Token;
+
+typedef struct Sym Sym;
+typedef struct Type Type;
+
+typedef struct Spec Spec;
+typedef struct Decl Decl;
+typedef struct Stmt Stmt;
+typedef struct Expr Expr;
+
+/* maps */
+typedef struct SymTab SymTab;
+typedef struct StrTab StrTab;
+
+// -----------------------------------------------------------------------
+// lexing: byte stream -> tokens
+// pre-processor built in
+
+struct Pos
+{
+ int col;
+ int line;
+ string path;
+};
+
+#define DIRECTIVES \
+ DIRECTIVE(Dpragma,"pragma") \
+ DIRECTIVE(Dinclude,"include") \
+ DIRECTIVE(Dif,"if") \
+ DIRECTIVE(Ddefine,"define") \
+ DIRECTIVE(Difdef,"ifdef") \
+ DIRECTIVE(Difndef,"ifndef")
+
+#define DIRECTIVE(a, b) a,
+enum { DIRECTIVES };
+#undef DIRECTIVE
+
+#define DIRECTIVE(a, b) b,
+static byte *directives[] = { DIRECTIVES };
+#undef DIRECTIVE
+
+#define KEYWORDS \
+ KEYWORD(Kauto,"auto") \
+ KEYWORD(Kregister,"register") \
+ KEYWORD(Kstatic,"static") \
+ KEYWORD(Kextern,"extern") \
+ KEYWORD(Ktypedef,"typedef") \
+ KEYWORD(Kconst,"const") \
+ KEYWORD(Kvolatile,"volatile") \
+ KEYWORD(Krestrict,"restrict") \
+ KEYWORD(Kinline,"inline") \
+ KEYWORD(Kvoid,"void") \
+ KEYWORD(Kchar,"char") \
+ KEYWORD(Kint,"int") \
+ KEYWORD(Kfloat,"float") \
+ KEYWORD(Kdouble,"double") \
+ KEYWORD(Ksigned,"signed") \
+ KEYWORD(Kunsigned,"unsigned") \
+ KEYWORD(Kshort,"short") \
+ KEYWORD(Klong,"long") \
+ KEYWORD(Kvlong,"vlong") \
+ KEYWORD(Kstruct,"struct") \
+ KEYWORD(Kunion,"union") \
+ KEYWORD(Kenum,"enum") \
+ KEYWORD(Kfor,"for") \
+ KEYWORD(Kdo,"do") \
+ KEYWORD(Kwhile,"while") \
+ KEYWORD(Kcontinue,"continue") \
+ KEYWORD(Kif,"if") \
+ KEYWORD(Kelse,"else") \
+ KEYWORD(Kswitch,"switch") \
+ KEYWORD(Kcase,"case") \
+ KEYWORD(Kdefault,"default") \
+ KEYWORD(Kbreak,"break") \
+ KEYWORD(Kgoto,"goto") \
+ KEYWORD(Kreturn,"return") \
+ KEYWORD(Ksizeof,"sizeof") \
+ KEYWORD(Kalignof,"alignof")
+
+#define KEYWORD(a, b) a,
+enum { KEYWORDS };
+#undef KEYWORD
+
+#define KEYWORD(a, b) b,
+static byte *keywords[] = { KEYWORDS };
+#undef KEYWORD
+
+#undef KEYWORDS
+
+#define TOKENS \
+ TOK(Anil,"nil") \
+ TOK(Aeof,"eof") \
+ TOK(Aeq, "==") \
+ TOK(Aneq, "!=") \
+ TOK(Anot, "!") \
+ TOK(Aneg, "~") \
+ TOK(Axor, "^") \
+ TOK(Aor, "|") \
+ TOK(Aand, "&") \
+ TOK(Aoror, "||") \
+ TOK(Aandand, "&&") \
+ TOK(Aadd,"+") \
+ TOK(Asub,"-") \
+ TOK(Astar,"*") \
+ TOK(Adiv,"/") \
+ TOK(Amod,"%") \
+ TOK(Agt,">") \
+ TOK(Alt,"<") \
+ TOK(Agteq,">=") \
+ TOK(Alteq,"<=") \
+ TOK(Alsft,"<<") \
+ TOK(Arsft,">>") \
+ TOK(Ainc,"++") \
+ TOK(Adec,"--") \
+ TOK(Aasn,"=") \
+ TOK(Aorasn,"|=") \
+ TOK(Axorasn,"^=") \
+ TOK(Aandasn,"&=") \
+ TOK(Aaddasn,"+=") \
+ TOK(Asubasn,"-=") \
+ TOK(Amulasn,"*=") \
+ TOK(Adivasn,"/=") \
+ TOK(Amodasn,"%=") \
+ TOK(Alsftasn,"<<=") \
+ TOK(Arsftasn,">>=") \
+ TOK(Acomma,",") \
+ TOK(Acolon,":") \
+ TOK(Asemi,";") \
+ TOK(Alparen,"(") \
+ TOK(Arparen,")") \
+ TOK(Albrace,"{") \
+ TOK(Arbrace,"}") \
+ TOK(Albrkt,"[") \
+ TOK(Arbrkt,"]") \
+ TOK(Adot,".") \
+ TOK(Aarrow,"->") \
+ TOK(Aqmark,"?") \
+ TOK(Aellip,"...") \
+ TOK(Alit,"<literal>") \
+ TOK(Aident,"<identifier>") \
+ TOK(Akeywd,"<keyword>") \
+
+#define TOK(a, b) a,
+enum
+{
+ TOKENS
+};
+#undef TOK
+
+#define TOK(a, b) b,
+static byte *tokens[] = { TOKENS };
+#undef TOK
+#undef TOKENS
+
+/* TODO: store literals in a big val */
+struct Token
+{
+ uint32 kind;
+ struct Pos pos;
+ union {
+ string str;
+ double f;
+ vlong i;
+ };
+};
+
+enum
+{
+ Svar,
+ Sfunc,
+ Smacro,
+};
+
+struct Sym
+{
+ uint32 kind;
+ string name;
+};
+
+struct Lexer
+{
+ Token tok;
+ Io *io;
+ SymTab *sym;
+ byte buf[1024];
+};
+
+// -----------------------------------------------------------------------
+// parsing & type resolution
+// tokens -> ast
+
+/* statements */
+enum
+{
+ Sbad,
+ Slabel,
+ Sblock,
+ Sexpr,
+ Sselect,
+ Sloop,
+ Sjump,
+};
+
+struct Stmt
+{
+ union
+ {
+
+ };
+};
+
+/* expressions */
+enum
+{
+ Xbad,
+ Xparen,
+ Xident,
+ Xlit,
+ Xassign,
+ Xcomma,
+ Xternary,
+ Xbinary,
+ Xprefix,
+ Xunary,
+ Xpostfix,
+ Xcast,
+};
+
+struct Expr
+{
+ union
+ {
+
+ };
+};
+
+/* declarations */
+
+// specifiers
+enum
+{
+ Mauto = iota(0), // Corresponds to auto int
+ Mtype = iota(1),
+ Mstatic = iota(2),
+ Mreg = iota(3),
+
+ Qconst = iota(4),
+ Qrestr = iota(5),
+ Qvoltl = iota(6),
+ Finlne = iota(7),
+
+ Tlong = iota(8),
+ Tvlong = iota(9),
+ Tsign = iota(10),
+ Tunsign = iota(11),
+
+ Tvoid = iota(12),
+ Tchar = iota(13),
+ Tshort = iota(14),
+ Tfloat = iota(15),
+ Tdouble = iota(16),
+ Tcmplx = iota(17),
+ Timag = iota(18),
+
+ Taggr = iota(19),
+ Tenum = iota(20),
+ Tname = iota(21),
+};
+
+enum
+{
+ Dnil,
+ Dbad,
+ Dfunc,
+ Dvar,
+};
+
+struct Decl
+{
+ Pos pos;
+ uint kind;
+};
+
+// -----------------------------------------------------------------------
+// compiler
+
+struct Io
+{
+ io·Buffer b;
+ string path;
+ uint32 flag;
+ struct Io *link;
+};
+
+struct StrTab
+{
+ int32 n_buckets, size, n_occupied, upper_bound;
+ int32 *flags;
+ string *keys;
+ int32 *vals;
+};
+
+static struct
+{
+ mem·Arena *heap;
+ StrTab strs;
+
+ string *include;
+ Io *io;
+ Io iostk[100];
+} C;
+
+void init();
+
+int32 intern(byte **str);
+string internview(byte* beg, byte *end);
+
+#undef iota
diff --git a/sys/cmd/cc/lex.c b/sys/cmd/cc/lex.c
new file mode 100644
index 0000000..af3bbf3
--- /dev/null
+++ b/sys/cmd/cc/lex.c
@@ -0,0 +1,38 @@
+#include "cc.h"
+
+static
+void
+errorat(Pos x, byte *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ printf("error %d:", x.line);
+ vprintf(fmt, args);
+ va_end(args);
+}
+
+static
+byte
+getbyte(struct Lexer *lex)
+{
+ return bufio·getbyte(&lex->buf);
+}
+
+static
+error
+ungetbyte(struct Lexer *lex, byte b)
+{
+ return bufio·ungetbyte(&lex->buf, b);
+}
+
+void
+lex(struct Lexer *lex)
+{
+ int b;
+
+ b = getbyte(lex);
+TOP:
+ switch (b) {
+
+ }
+}
diff --git a/sys/cmd/cc/rules.mk b/sys/cmd/cc/rules.mk
new file mode 100644
index 0000000..fe30305
--- /dev/null
+++ b/sys/cmd/cc/rules.mk
@@ -0,0 +1,20 @@
+include share/push.mk
+# Iterate through subdirectory tree
+
+# Local sources
+SRCS_$(d) := \
+ $(d)/lex.c \
+ $(d)/sym.c \
+ $(d)/cc.c
+
+LIBS_$(d) :=
+BINS_$(d) := $(d)/cc
+TSTS_$(d) :=
+
+include share/paths.mk
+
+# Local rules
+$(BINS_$(d)): $(OBJS_$(d)) $(OBJ_DIR)/libn/libn.a
+ $(COMPLINK)
+
+include share/pop.mk
diff --git a/sys/cmd/cc/sym.c b/sys/cmd/cc/sym.c
new file mode 100644
index 0000000..ef40bce
--- /dev/null
+++ b/sys/cmd/cc/sym.c
@@ -0,0 +1,32 @@
+#include "cc.h"
+
+#include <libn/macro/map.h>
+
+#define PTR_HASH(p) (uintptr)(p)
+#define PTR_EQUAL(p1, p2) ((uintptr)(p1) == (uintptr)(p2))
+
+#if 0
+struct SymTab
+{
+ MAP_STRUCT_BODY(string, Sym*);
+};
+
+Sym*
+getsym(SymTab *tab, string key)
+{
+ MAP_GET(tab, key, PTR_HASH, PTR_EQUAL, nil);
+}
+
+static
+int
+moresymtab(SymTab *tab, int n)
+{
+ MAP_GROW(tab, string, Sym*, n, PTR_HASH);
+}
+
+int
+putsym(SymTab *tab, Sym *sym, error *err)
+{
+ MAP_PUT(tab, sym->name, sym, PTR_HASH, PTR_EQUAL, moresymtab, err);
+}
+#endif