aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cffc.hff (renamed from src/all.hff)62
-rw-r--r--src/common.hff45
-rw-r--r--src/env.cff3
-rw-r--r--src/fmt.cff25
-rw-r--r--src/main.cff5
-rw-r--r--src/map.hff5
-rw-r--r--src/mem.hff3
-rw-r--r--src/parse.cff23
-rw-r--r--src/set.hff36
-rw-r--r--src/targ.cff3
-rw-r--r--src/targ.hff12
-rw-r--r--src/type.cff3
-rw-r--r--src/type.hff15
-rw-r--r--src/util.cff5
-rw-r--r--src/util.hff12
-rw-r--r--src/vec.hff9
16 files changed, 168 insertions, 98 deletions
diff --git a/src/all.hff b/src/cffc.hff
index 4ae3e26..dcb91f7 100644
--- a/src/all.hff
+++ b/src/cffc.hff
@@ -1,34 +1,7 @@
-import "mem.hff";
import "libc.hff";
+import "mem.hff";
import "option.hff";
-/// Macros
-
-defmacro assert {
-(ex, s, ...args) [
- (do
- if not (ex) {
- fprintf(stderr, "%s:%d: assertion failed: ", #FILE, #LINE);
- fprintf(stderr, s, args);
- fprintf(stderr, "\n");
- abort();
- }
- )
-]
-}
-
-defmacro foreach(x, i, a, ...body) [
- {
- let $a = a;
- for let i = 0; i < $a.#len; ++i {
- let x = $a[i];
- { body }
- }
- }
-]
-
-defmacro streq(a,b) [ (strcmp(a,b) == 0) ]
-
/// Types
struct Type;
@@ -138,25 +111,15 @@ struct Targ {
extern fn parser_init(*Parser, path *const u8) void;
extern fn parse(*Parser) [#]Decl;
-// util.cff
-extern fn xmalloc(n usize) *void;
-extern fn xcalloc(n usize, m usize) *void;
-extern fn xrealloc(p *void, n usize) *void;
-extern fn xstrdup(str *const u8) *u8;
-def FNV1A_INI u32 = 0x811c9dc5;
-extern fn fnv1a(h u32, [#]const u8) u32;
-extern fn fnv1a_s(h u32, *const u8) u32;
-extern fn fnv1a_i(h u32, i64) u32;
-extern fn addfilepath(*const u8) int;
-extern fn fatal(*Parser, Loc, fmt *const u8, ...) void;
-extern fn internstr(*const u8) *const u8;
-
// fmt.cff
extern fn vpfmt(proc *fn(u8, *void) void, parg *void, fmt *const u8, va_list) void;
extern fn pfmt(proc *fn(u8, *void) void, parg *void, fmt *const u8, ...) void;
extern fn vefmt(fmt *const u8, ap va_list) void;
extern fn efmt(fmt *const u8, ...) void;
+// .. util.cff ..
+extern fn fatal(*Parser, Loc, fmt *const u8, ...) void;
+
// type.cff
// env.cff
@@ -166,20 +129,3 @@ extern fn envput(*Env, *const Decl) *Decl;
// targ.cff
extern static g_targ *const Targ;
extern fn targ_ini(name *const u8) bool;
-
-// Inline functions
-fn bswap32(x u32) u32 {
- return (x >> 24)
- | ((x >> 8) & 0x00FF00)
- | ((x << 8) & 0xFF0000)
- | (x << 24);
-}
-
-fn bswap64(x u64) u64 {
- return (as(u64)bswap32(x) << 32)
- | (bswap32(x >> 32));
-}
-
-fn spanz(x *const u8) [#]const u8 {
- return x[0::strlen(x)];
-}
diff --git a/src/common.hff b/src/common.hff
new file mode 100644
index 0000000..aac733e
--- /dev/null
+++ b/src/common.hff
@@ -0,0 +1,45 @@
+import "libc.hff";
+
+/// Macros
+
+defmacro assert {
+(ex, s, ...args) [
+ (do
+ if not (ex) {
+ fprintf(stderr, "%s:%d: assertion failed: ", #FILE, #LINE);
+ fprintf(stderr, s, args);
+ fprintf(stderr, "\n");
+ abort();
+ }
+ )
+]
+}
+
+defmacro foreach(x, i, a, ...body) [
+ {
+ let $a = a;
+ for let i = 0; i < $a.#len; ++i {
+ let x = $a[i];
+ { body }
+ }
+ }
+]
+
+defmacro streq(a,b) [ (strcmp(a,b) == 0) ]
+
+// Inline functions
+fn bswap32(x u32) u32 {
+ return (x >> 24)
+ | ((x >> 8) & 0x00FF00)
+ | ((x << 8) & 0xFF0000)
+ | (x << 24);
+}
+
+fn bswap64(x u64) u64 {
+ return (as(u64)bswap32(x) << 32)
+ | (bswap32(x >> 32));
+}
+
+fn spanz(x *const u8) [#]const u8 {
+ return x[0::strlen(x)];
+}
diff --git a/src/env.cff b/src/env.cff
index 8878238..d1eab07 100644
--- a/src/env.cff
+++ b/src/env.cff
@@ -1,5 +1,6 @@
+import "cffc.hff";
import "map.hff";
-import "all.hff";
+import "util.hff";
struct StringKeyTraits {
fn hash(s *const u8) u32 { return fnv1a_s(FNV1A_INI, s); }
diff --git a/src/fmt.cff b/src/fmt.cff
index 8212593..90fcd47 100644
--- a/src/fmt.cff
+++ b/src/fmt.cff
@@ -1,4 +1,5 @@
-import "all.hff";
+import "cffc.hff";
+import "common.hff";
extern fn vpfmt(proc *fn(u8, *void) void, parg *void, fmt *const u8, ap va_list) void {
defmacro p(x) [ proc(x, parg) ]
@@ -10,14 +11,22 @@ extern fn vpfmt(proc *fn(u8, *void) void, parg *void, fmt *const u8, ap va_list)
defmacro pch(ch) [ {
extern fn isprint(int) int;
- let $ch = ch;
- if isprint($ch) != 0 {
+ let $ch u8 = ch;
+ switch {
+ case $ch == '\'';
+ ps("\\'");
+ case $ch == '\"';
+ ps("\\\"");
+ case $ch == '\\';
+ ps("\\\\");
+ case isprint($ch) != 0;
p($ch);
- } else {
- p('\\');
- p('0' + ($ch % 8));
- p('0' + (($ch / 8) % 8));
- p('0' + (($ch / 8 / 8) % 8));
+ case $ch == '\n';
+ ps("\\n");
+ case else;
+ ps("\\x");
+ p("0123456789ABCDEF"[($ch >> 4) & 15]);
+ p("0123456789ABCDEF"[$ch & 15]);
}
} ]
diff --git a/src/main.cff b/src/main.cff
index 596a411..7cc90a0 100644
--- a/src/main.cff
+++ b/src/main.cff
@@ -1,6 +1,5 @@
-import "all.hff";
-import "libc.hff";
-import "vec.hff";
+import "cffc.hff";
+import "common.hff";
extern fn main(argc int, argv **u8) int {
assert(argc > 1, "args?");
diff --git a/src/map.hff b/src/map.hff
index 87d0506..d7883dd 100644
--- a/src/map.hff
+++ b/src/map.hff
@@ -1,4 +1,5 @@
-import "all.hff";
+import "common.hff";
+import "util.hff";
// KTraits:
// :hash(K) u32
@@ -32,6 +33,8 @@ struct Map<K, V, KTraits> {
}
fn _reallockvb(self *Map) void {
+ // keys, vals, bitmap are in a contiguous memory allocation,
+ // XXX ^ alignment
let p = xcalloc((self.N * (sizeof K + sizeof V)) + (self.N / 8), 1);
self.keys = p;
self.vals = as(*V)(self.keys + self.N);
diff --git a/src/mem.hff b/src/mem.hff
index a86bee3..805c3ce 100644
--- a/src/mem.hff
+++ b/src/mem.hff
@@ -1,8 +1,7 @@
import "libc.hff";
-import "all.hff";
-def ARENA_SIZE = 16 * 1024;
defmacro ALIGNUP(x,a) [ (((x) + ((a) - 1)) & -(a)) ]
+def ARENA_SIZE = 16 * 1024;
extern fn xmalloc(n usize) *void;
extern fn xcalloc(n usize, m usize) *void;
extern fn xrealloc(p *void, n usize) *void;
diff --git a/src/parse.cff b/src/parse.cff
index 0843ccf..25a2617 100644
--- a/src/parse.cff
+++ b/src/parse.cff
@@ -1,5 +1,7 @@
+import "mem.hff";
+import "util.hff";
import "vec.hff";
-import "all.hff";
+import "cffc.hff";
///////////
// Lexer //
@@ -164,6 +166,15 @@ fn str2keyword(s *const u8) int {
return -1;
}
+fn xdigit2num(c u8) int {
+ switch {
+ case isdigit(c); return c - '0';
+ case c >= 'a' and c <= 'f'; return (c - 'a') + 10;
+ case c >= 'A' and c <= 'F'; return (c - 'A') + 10;
+ }
+ return -1;
+}
+
fn readnumber(s *const u8) Option<Tok> {
let c u8 #?,
acc = 0u64,
@@ -198,8 +209,7 @@ fn readnumber(s *const u8) Option<Tok> {
accf = accf + ((c - '0') * fmul);
fmul *= 0.1;
} else {
- c = tolower(c);
- acc = (acc * base) + (c <= '9' ? c - '0' : (c - 'a') + 10);
+ acc = (acc * base) + xdigit2num(c);
}
}
@@ -323,6 +333,13 @@ fn lex(P *Parser) Tok {
case 'r'; str->push('\r'); case 't'; str->push('\t');
case 'v'; str->push('\v'); case 'f'; str->push('\f');
case '0'; str->push('\0');
+ case 'x';
+ let x0 = xdigit2num(chr(P)),
+ x1 = xdigit2num(chr(P));
+ if x0 < 0 or x1 < 0 {
+ fatal(P, P.tokloc, "not a hex byte escape sequence");
+ }
+ str->push((x0 << 4) | x1);
case else
fatal(P, P.tokloc, "unknown escape sequence '\\%c'", c);
}
diff --git a/src/set.hff b/src/set.hff
index 6ab44ea..82c213f 100644
--- a/src/set.hff
+++ b/src/set.hff
@@ -1,5 +1,4 @@
import "vec.hff";
-import "all.hff";
#{
Traits:hash(K) u32
@@ -12,6 +11,12 @@ struct Set<T, Traits> {
N int,
count int,
+
+ fn _nexthash(h *u32) u32 {
+ // return *h = (*h * 1664525) + 1013904223u; // double hashing
+ return ++*h; // linear probing
+ }
+
fn intern(self *Set, x T) *const T {
if self.set == #null {
self.set = xcalloc(self.N = 16, sizeof int);
@@ -21,20 +26,22 @@ struct Set<T, Traits> {
free(self.set);
self.set = xcalloc(self.N *= 2, sizeof int);
vec_each(p, i, self.buf,
- let j = Traits:hash(p) & (self.N - 1);
+ let h = Traits:hash(p);
+ let j = h & (self.N - 1);
for ;; {
if self.set[j] == 0 {
self.set[j] = i + 1;
break;
}
- j = (j + 1) & (self.N - 1);
+ j = _nexthash(&h) & (self.N - 1);
}
)
}
- let i0 u32 = Traits:hash(x) & (self.N - 1);
- let i int = i0;
- do {
+ let h u32 = Traits:hash(x);
+ let i = h & (self.N - 1) & (self.N - 1);
+ let n = 0;
+ for ;; {
if self.set[i] == 0 {
++self.count;
self.buf->push(Traits:dup(x));
@@ -46,23 +53,22 @@ struct Set<T, Traits> {
return x2;
}
}
- i = (i + 1) & (self.N - 1);
- } while i != i0;
- assert(#f, "unreachable");
+ ++n;
+ i = _nexthash(&h) & (self.N - 1);
+ }
}
fn contains(self *Set, x T) bool {
- let i0 u32 = Traits:hash(x) & (self.N - 1);
- let i int = i0;
- do {
+ let h u32 = Traits:hash(x);
+ let i = h & (self.N - 1);
+ for ;; {
if self.set[i] == 0 {
return #f;
} else if Traits:eq(self.buf.dat[self.set[i] - 1], x) {
return #t;
}
- i = (i + 1) & (self.N - 1);
- } while i != i0;
- assert(#f, "unreachable");
+ i = _nexthash(&h) & (self.N - 1);
+ }
}
fn put(self *Set, x T) void {
diff --git a/src/targ.cff b/src/targ.cff
index 6490dff..59078a0 100644
--- a/src/targ.cff
+++ b/src/targ.cff
@@ -1,4 +1,5 @@
-import "all.hff";
+import "cffc.hff";
+import "common.hff";
static const targs []const Targ = {
{
diff --git a/src/targ.hff b/src/targ.hff
new file mode 100644
index 0000000..9df8ee5
--- /dev/null
+++ b/src/targ.hff
@@ -0,0 +1,12 @@
+struct Targ {
+ name *const u8,
+ ptrsize u8,
+ intsize u8,
+ longsize u8, longalign u8,
+ llongsize u8, llongalign u8,
+ sizesize u8,
+ f64align u8,
+ valistsize u8, valistalign u8,
+ charsigned bool,
+ shortenum bool,
+}
diff --git a/src/type.cff b/src/type.cff
index a6987b7..a3c7021 100644
--- a/src/type.cff
+++ b/src/type.cff
@@ -1,4 +1,5 @@
-import "all.hff";
+import "cffc.hff";
+import "util.hff";
fn hashtype(ty *const Type) u32 {
let h = FNV1A_INI;
diff --git a/src/type.hff b/src/type.hff
new file mode 100644
index 0000000..ce04063
--- /dev/null
+++ b/src/type.hff
@@ -0,0 +1,15 @@
+struct Type {
+ size usize,
+ align usize,
+ konst bool,
+ id uint,
+ u enum union {
+ Void,
+ Bool,
+ Int struct { sgn bool },
+ Flo,
+ Ptr *Type,
+ Arr struct { child *Type, length i64 },
+ Slice *Type,
+ }
+}
diff --git a/src/util.cff b/src/util.cff
index 18305b2..1b81ab4 100644
--- a/src/util.cff
+++ b/src/util.cff
@@ -1,5 +1,8 @@
+import "util.hff";
+import "cffc.hff";
import "set.hff";
-import "all.hff";
+import "mem.hff";
+import "common.hff";
extern fn xmalloc(n usize) *void {
let p = malloc(n);
diff --git a/src/util.hff b/src/util.hff
new file mode 100644
index 0000000..5eb9c88
--- /dev/null
+++ b/src/util.hff
@@ -0,0 +1,12 @@
+// util.cff
+extern fn xmalloc(n usize) *void;
+extern fn xcalloc(n usize, m usize) *void;
+extern fn xrealloc(p *void, n usize) *void;
+extern fn xstrdup(str *const u8) *u8;
+def FNV1A_INI u32 = 0x811c9dc5;
+extern fn fnv1a(h u32, [#]const u8) u32;
+extern fn fnv1a_s(h u32, *const u8) u32;
+extern fn fnv1a_i(h u32, i64) u32;
+extern fn addfilepath(*const u8) int;
+// extern fn fatal(*Parser, Loc, fmt *const u8, ...) void;
+extern fn internstr(*const u8) *const u8;
diff --git a/src/vec.hff b/src/vec.hff
index 35a9331..7f012aa 100644
--- a/src/vec.hff
+++ b/src/vec.hff
@@ -1,6 +1,7 @@
-import "all.hff";
+import "common.hff";
+import "mem.hff";
+import "util.hff";
-extern fn malloc(n usize) *void;
struct Vec<T> {
dat *T,
len uint,
@@ -10,10 +11,10 @@ struct Vec<T> {
if vec.len >= vec.cap {
vec.cap = (vec.len + 1) > 8 ? (vec.len + 1) * 2 : 8;
if vec.dat == #null {
- vec.dat = malloc(vec.cap * sizeof T);
+ vec.dat = xmalloc(vec.cap * sizeof T);
assert(vec.dat != #null, "malloc");
} else {
- vec.dat = realloc(vec.dat, vec.cap * sizeof T);
+ vec.dat = xrealloc(vec.dat, vec.cap * sizeof T);
assert(vec.dat != #null, "realloc");
}
}