aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-13 10:38:27 +0200
committerlemon <lsof@mailbox.org>2022-08-13 10:38:27 +0200
commit7d4cb5bb96b061ed8708889b75e4d50757d9b3f2 (patch)
treeb57fdfa2dd7d61b888930d45c5f8f6f873db39ff /src
parent62132ecc8d032ef251d6b54177414a9ba29e8610 (diff)
set template
Diffstat (limited to 'src')
-rw-r--r--src/all.hff16
-rw-r--r--src/parse.cff4
-rw-r--r--src/set.hff46
-rw-r--r--src/util.cff47
4 files changed, 70 insertions, 43 deletions
diff --git a/src/all.hff b/src/all.hff
index f15df13..ff74ab7 100644
--- a/src/all.hff
+++ b/src/all.hff
@@ -85,6 +85,22 @@ struct Tok {
},
}
+struct Type {
+ size usize,
+ align usize,
+ konst bool,
+ id uint,
+ t enum union {
+ void,
+ bool,
+ int struct { sgn bool },
+ flo,
+ ptr *Type,
+ arr struct { child *Type, length i64 },
+ slice *Type,
+ }
+}
+
struct Decl {
}
diff --git a/src/parse.cff b/src/parse.cff
index 9181e70..ef01da5 100644
--- a/src/parse.cff
+++ b/src/parse.cff
@@ -175,7 +175,6 @@ fn readnumber(s *const u8) Option<Tok> {
suffix *const u8 = #null;
for let i = 0; (c = s[i]) != 0; ++i {
- printf("<%c>\n",c);
if i == 0 and c == '0' {
--nused;
}
@@ -205,6 +204,7 @@ fn readnumber(s *const u8) Option<Tok> {
}
let tok = Tok {};
+ assert(suffix == #null,"sufx");
if flt {
tok.t = :flo;
tok.u.flo = accf;
@@ -214,8 +214,6 @@ fn readnumber(s *const u8) Option<Tok> {
tok.u.uint = acc;
return :Some tok;
}
-
- return :None;
}
fn lex(P *Parser) Tok {
diff --git a/src/set.hff b/src/set.hff
new file mode 100644
index 0000000..acff95b
--- /dev/null
+++ b/src/set.hff
@@ -0,0 +1,46 @@
+import "vec.hff";
+import "all.hff";
+
+struct Set<T, Traits> {
+ buf Vec<T>,
+ set **const T,
+ N int,
+ count int,
+
+ fn intern(self *Set, x T) *const T {
+ if self.set == #null {
+ self.set = xcalloc(self.N = 16, sizeof *T);
+ }
+
+ if self.count == self.N / 2 {
+ free(self.set);
+ self.set = xcalloc(self.N *= 2, sizeof *T);
+ vec_each(p, i, self.buf,
+ let i = Traits:hash(p) & (self.N - 1);
+ for ;; {
+ if self.set[i] == #null {
+ self.set[i] = &self.buf.dat[i];
+ break;
+ }
+ i = (i + 1) & (self.N - 1);
+ }
+ )
+ }
+
+ let i0 = Traits:hash(x) & (self.N - 1);
+ let i int = i0;
+ do {
+ if self.set[i] == #null {
+ ++self.count;
+ self.buf->push(Traits:dup(x));
+ return self.set[i] = &self.buf.dat[self.buf.len - 1];
+ } else if Traits:eq(*self.set[i], x) {
+ fprintf(stderr, "found %s\n", x);
+ return self.set[i];
+ }
+ i = (i + 1) & (self.N - 1);
+ } while i != i0;
+ assert(#f, "unreachable");
+ }
+
+}
diff --git a/src/util.cff b/src/util.cff
index d1c9dc5..70c80b4 100644
--- a/src/util.cff
+++ b/src/util.cff
@@ -1,4 +1,4 @@
-import "vec.hff";
+import "set.hff";
import "all.hff";
extern fn xmalloc(n usize) *void {
@@ -79,43 +79,10 @@ extern fn fatal(P *Parser, loc Loc, fmt *const u8, ...) void {
}
extern fn internstr(s *const u8) *const u8 {
- static buf Vec<*const u8> = {};
- static set **const u8 = {};
- static N int = {};
- static count int = {};
-
- if set == #null {
- set = xcalloc(N = 16, sizeof int);
- }
-
- if count == N / 2 {
- free(set);
- set = xcalloc(N *= 2, sizeof int);
- vec_each(s, i, buf,
- let i = fnv1a_s(FNV1A_INI, s) & (N - 1);
- for ;; {
- if set[i] == #null {
- set[i] = s;
- break;
- }
- i = (i + 1) & (N - 1);
- }
- )
- }
-
- let i0 = fnv1a_s(FNV1A_INI, s) & (N - 1);
- let i int = i0;
- do {
- if set[i] == #null {
- ++count;
- buf->push(xstrdup(s));
- set[i] = buf.dat[buf.len - 1];
- return set[i];
- } else if streq(set[i], s) {
- return set[i];
- }
- i = (i + 1) & (N - 1);
- } while i != i0;
- assert(#f, "unreachable");
-
+ static set Set<*const u8, struct {
+ fn hash(s *const u8) u32 { return fnv1a_s(FNV1A_INI, s); }
+ fn eq(a *const u8, b *const u8) bool { return streq(a, b); }
+ fn dup(s *const u8) *const u8 { return as(*const u8)xstrdup(s); }
+ }> = {};
+ return *set->intern(s);
}