From 6c9563e91eb7aa738aa2656d141ce56ef66b50cf Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Sat, 16 May 2020 10:39:05 -0700 Subject: feat: added directory for command line tools --- sys/cmd/cc/cc.c | 93 +++++++++++++++ sys/cmd/cc/cc.h | 328 ++++++++++++++++++++++++++++++++++++++++++++++++++++ sys/cmd/cc/lex.c | 38 ++++++ sys/cmd/cc/rules.mk | 20 ++++ sys/cmd/cc/sym.c | 32 +++++ 5 files changed, 511 insertions(+) create mode 100644 sys/cmd/cc/cc.c create mode 100644 sys/cmd/cc/cc.h create mode 100644 sys/cmd/cc/lex.c create mode 100644 sys/cmd/cc/rules.mk create mode 100644 sys/cmd/cc/sym.c (limited to 'sys/cmd/cc') 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 + +/* 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 +#include + +#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,"") \ + TOK(Aident,"") \ + TOK(Akeywd,"") \ + +#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 + +#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 -- cgit v1.2.1