History

use qp tries for symbol lookup; disable imaginary part of numbers for now

Sigrid Solveig Haflínudóttir committed 5 years agomaster

Commit f2102991 parent 77e90d86 files · +208 −11Browse files

Unified · Split

6 files
  1. aa.c +8 −6
  2. aa.h +7 −1
  3. aa_math.c +4 −4
  4. mkfile +3 −0
  5. qp.c +180 −0
  6. qp.h +6 −0
aa.c+8−6
@@ -2,6 +2,7 @@ · 1 unmodified line
22 #include <libc.h>
33 #include <bio.h>
44 #include "aa.h"
5+#include "qp.h"
56
67 #define CAR(x) ( (x)->car.o )
78 #define CDR(x) ( (x)->cdr.o )
@@ -257,7 +258,7 @@ aa_mark(aaContext *ctx, aaObject *obj) · 249 unmodified lines
257258 aaObject *car;
258259
259260 begin:
260− if((TAG(obj) & GCMARKBIT) != 0 || ISNULL(obj))
261+ if(ISNULL(obj) || (TAG(obj) & GCMARKBIT) != 0)
261262 return;
262263 car = CAR(obj); /* store car before modifying it with GCMARKBIT */
263264 TAG(obj) |= GCMARKBIT;
@@ -290,6 +291,7 @@ collectgarbage(aaContext *ctx) · 26 unmodified lines
290291 /* mark */
291292 for(i = 0; i < ctx->gcstack_idx; i++)
292293 aa_mark(ctx, ctx->gcstack[i]);
294+
293295 aa_mark(ctx, ctx->symlist);
294296
295297 /* sweep and unmark */
@@ -442,13 +444,12 @@ aaObject * · 146 unmodified lines
442444 aa_symbol_find(aaContext *ctx, const char *name)
443445 {
444446 aaObject *obj;
447+ char *pk;
445448
446− for(obj = ctx->symlist; !ISNULL(obj); obj = CDR(obj)){
447− if(streq(CAR(CDR(CAR(obj))), name))
448− return CAR(obj);
449− }
449+ obj = nil;
450+ qpget(ctx->symtrie, name, 0, &pk, &obj);
450451
451− return nil;
452+ return obj;
452453 }
453454
454455 aaObject *
@@ -465,6 +466,7 @@ aa_symbol(aaContext *ctx, const char *name) · 10 unmodified lines
465466 SETTYPE(obj, AA_TSYMBOL);
466467 CDR(obj) = aa_cons(ctx, aa_string(ctx, name), nil); /* nil not &Null, because it's unbound */
467468 ctx->symlist = aa_cons(ctx, obj, ctx->symlist);
469+ ctx->symtrie = qpset(ctx->symtrie, strdup(name), 0, obj);
468470
469471 return obj;
470472 }
aa.h+7−1
@@ -1,5 +1,8 @@
11 #define GCSTACKSIZE 256
22
3+typedef union Trie Trie;
4+#pragma incomplete Trie
5+
36 typedef struct aaContext aaContext;
47 typedef struct aaHandlers aaHandlers;
58 typedef struct aaNumber aaNumber;
@@ -13,8 +16,10 @@ typedef char (*aaReadFn)(aaContext *ctx, void *udata); · 7 unmodified lines
1316
1417 struct aaNumber {
1518 double r;
16− double i;
19+ //double i;
1720 };
21+//#define aNumber(r,i) (aaNumber){r, i}
22+#define aNumber(r,i) (aaNumber){r}
1823
1924 union aaValue {
2025 Biobuf *port;
@@ -44,6 +49,7 @@ struct aaContext { · 23 unmodified lines
4449 aaObject *calllist;
4550 aaObject *freelist;
4651 aaObject *symlist;
52+ Trie *symtrie;
4753 aaObject *t;
4854 Rune nextrune;
4955
aa_math.c+4−4
@@ -9,7 +9,7 @@ · 8 unmodified lines
99 cf_##func(aaContext *ctx, aaObject *arg) \
1010 { \
1111 aaNumber x = aa_tonumber(ctx, aa_nextarg(ctx, &arg, 0)); \
12− return aa_number(ctx, (aaNumber){func(x.r), 0.0}); \
12+ return aa_number(ctx, aNumber(func(x.r), 0.0)); \
1313 }
1414
1515 #define CFUNC2(func) \
@@ -18,7 +18,7 @@ · 2 unmodified lines
1818 { \
1919 aaNumber x = aa_tonumber(ctx, aa_nextarg(ctx, &arg, 0)); \
2020 aaNumber y = aa_tonumber(ctx, aa_nextarg(ctx, &arg, 0)); \
21− return aa_number(ctx, (aaNumber){func(x.r, y.r), 0.0}); \
21+ return aa_number(ctx, aNumber(func(x.r, y.r), 0.0)); \
2222 }
2323
2424 #define FUNCS \
@@ -46,8 +46,8 @@ cf_atan2(aaContext *ctx, aaObject *arg) · 21 unmodified lines
4646 {
4747 aaNumber x = aa_tonumber(ctx, aa_nextarg(ctx, &arg, 0));
4848 aaObject *yo = aa_nextarg(ctx, &arg, 1);
49− aaNumber y = yo != nil ? aa_tonumber(ctx, yo) : (aaNumber){1.0, 0.0};
50− return aa_number(ctx, (aaNumber){atan2(x.r, y.r), 0.0});
49+ aaNumber y = yo != nil ? aa_tonumber(ctx, yo) : aNumber(1.0, 0.0);
50+ return aa_number(ctx, aNumber(atan2(x.r, y.r), 0.0));
5151 }
5252
5353 static aaObject *
mkfile+3−0
@@ -6,10 +6,13 @@ CFLAGS=$CFLAGS -p · 5 unmodified lines
66
77 HFILES=\
88 aa.h\
9+ aa_math.h\
10+ qp.h\
911
1012 OFILES=\
1113 aa.$O\
1214 aa_math.$O\
15+ qp.$O\
1316 repl.$O\
1417
1518 default:V: all
qp.c+180−0
@@ -0,0 +1,180 @@
1+#include <u.h>
2+#include <libc.h>
3+#include "qp.h"
4+
5+typedef u16int Tbitmap;
6+typedef struct Tbranch Tbranch;
7+typedef struct Tleaf Tleaf;
8+
9+struct Tleaf {
10+ char *k;
11+ void *v;
12+};
13+
14+struct Tbranch {
15+ Trie *twigs;
16+ u64int x;
17+};
18+
19+union Trie {
20+ Tleaf leaf;
21+ Tbranch branch;
22+};
23+
24+#define x_flags(x) ((x)>>62)
25+#define x_index(x) ((x)>>16 & ((1ULL<<46)-1ULL))
26+#define x_bitmap(x) ((x) & 0xffff)
27+
28+#define isbranch(t) (x_flags((t)->branch.x) != 0)
29+#define hastwig(t, b) (x_bitmap((t)->branch.x) & (b))
30+#define twigoff(t, b) popcount(x_bitmap((t)->branch.x) & ((b)-1))
31+#define twig(t, i) (&(t)->branch.twigs[(i)])
32+#define twigoffmax(off, max, t, b) do{ off = twigoff(t, b); max = popcount(x_bitmap((t)->branch.x)); }while(0)
33+#define nibbit(k, f) (1 << (((k) & (((f)-2) ^ 0x0f) & 0xff) >> ((2-(f))<<2)))
34+#define twigbit(t, k, len) \
35+ (x_index((t)->branch.x) >= (len) ? \
36+ 1 : \
37+ nibbit((u8int)(k)[x_index((t)->branch.x)], x_flags((t)->branch.x)))
38+
39+/*
40+// need some speed? just say no.
41+#define POPCNT BYTE $0xf3; BYTE $0x0f; BYTE $0xb8
42+
43+TEXT popcount(SB),$0
44+ MOVL b+0(FP), AX
45+ POPCNT
46+ RET
47+*/
48+static u16int
49+popcount(u16int b)
50+{
51+ b -= b>>1 & 0x5555;
52+ b = (b & 0x3333) + ((b>>2) & 0x3333);
53+ b = (b + (b>>4)) & 0x0f0f;
54+ b = (b + (b>>8)) & 0x00ff;
55+ return b;
56+}
57+
58+int
59+qpget(Trie *t, char *k, int len, char **pk, void **pv)
60+{
61+ Tbitmap b;
62+
63+ assert(k != nil && pk != nil && pv != nil);
64+
65+ if(len < 1)
66+ len = strlen(k);
67+ if(t == nil)
68+ return -1;
69+ for(; isbranch(t); t = twig(t, twigoff(t, b))){
70+ b = twigbit(t, k, len);
71+ if(!hastwig(t, b))
72+ return -1;
73+ }
74+ if(strncmp(k, t->leaf.k, len) != 0)
75+ return -1;
76+ *pk = t->leaf.k;
77+ *pv = t->leaf.v;
78+
79+ return 0;
80+}
81+
82+int
83+qpnext(Trie *t, char **pk, int *plen, void **pv)
84+{
85+ Tbitmap b;
86+ uint s, m;
87+
88+ assert(pk != nil && plen != nil && pv != nil);
89+
90+ if(isbranch(t)){
91+ b = twigbit(t, *pk, *plen);
92+ twigoffmax(s, m, t, b);
93+ for(; s < m; s++){
94+ if(qpnext(twig(t, s), pk, plen, pv) == 0)
95+ return 0;
96+ }
97+ return -1;
98+ }
99+
100+ if(*pk == nil){
101+ *pk = t->leaf.k;
102+ *plen = strlen(*pk);
103+ *pv = t->leaf.v;
104+ return 0;
105+ }
106+
107+ return -1;
108+}
109+
110+Trie *
111+qpset(Trie *t, char *k, int len, void *v)
112+{
113+ Trie *t0, t1, t2;
114+ uint i, s, m;
115+ u8int f;
116+ Tbitmap b, b1, b2;
117+ u8int k2;
118+
119+ assert(k != nil && v != nil);
120+ if(len < 1)
121+ len = strlen(k);
122+ assert(len > 0);
123+
124+ if(t == nil){
125+ t = malloc(sizeof(*t));
126+ assert(t != nil);
127+ t->leaf.k = k;
128+ t->leaf.v = v;
129+ return t;
130+ }
131+
132+ t0 = t;
133+ for(; isbranch(t); t = twig(t, i)){
134+ b = twigbit(t, k, len);
135+ i = hastwig(t, b) ? twigoff(t, b) : 0;
136+ }
137+ for(i = 0; i <= len && k[i] == t->leaf.k[i]; i++);
138+ if(i == len+1){
139+ t->leaf.v = v;
140+ return t0;
141+ }
142+
143+ k2 = (u8int)t->leaf.k[i];
144+ f = (((u8int)k[i] ^ k2) & 0xf0) ? 1 : 2;
145+ b1 = nibbit(k[i], f);
146+ t1.leaf.k = k;
147+ t1.leaf.v = v;
148+ for(t = t0; isbranch(t); t = twig(t, twigoff(t, b))){
149+ if(i == x_index(t->branch.x)){
150+ if(f == x_flags(t->branch.x))
151+ goto growbranch;
152+ if(f < x_flags(t->branch.x))
153+ break;
154+ }else if(i < x_index(t->branch.x)){
155+ break;
156+ }
157+ b = twigbit(t, k, len);
158+ assert(hastwig(t, b));
159+ }
160+
161+ t2 = *t;
162+ b2 = nibbit(k2, f);
163+ t->branch.twigs = malloc(sizeof(*t)*2);
164+ assert(t->branch.twigs != nil);
165+ t->branch.x = (uvlong)f<<62 | (uvlong)i<<16 | b1 | b2;
166+ *twig(t, twigoff(t, b1)) = t1;
167+ *twig(t, twigoff(t, b2)) = t2;
168+
169+ return t0;
170+
171+growbranch:
172+ assert(!hastwig(t, b1));
173+ twigoffmax(s, m, t, b1);
174+ t->branch.twigs = realloc(t->branch.twigs, sizeof(*t)*(m+1));
175+ memmove(t->branch.twigs+s+1, t->branch.twigs+s, sizeof(*t)*(m-s));
176+ memmove(t->branch.twigs+s, &t1, sizeof(t1));
177+ t->branch.x |= b1;
178+
179+ return t0;
180+}
qp.h+6−0
@@ -0,0 +1,6 @@
1+typedef union Trie Trie;
2+#pragma incomplete Trie
3+
4+int qpget(Trie *t, char *k, int len, char **pk, void **pv);
5+int qpnext(Trie *t, char **pk, int *plen, void **pv);
6+Trie *qpset(Trie *t, char *k, int len, void *v);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t