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
2#include <libc.h>2#include <libc.h>
3#include <bio.h>3#include <bio.h>
4#include "aa.h"4#include "aa.h"
5#include "qp.h"
5 6
6#define CAR(x) ( (x)->car.o )7#define CAR(x) ( (x)->car.o )
7#define CDR(x) ( (x)->cdr.o )8#define CDR(x) ( (x)->cdr.o )
@@ -257,7 +258,7 @@ aa_mark(aaContext *ctx, aaObject *obj) · 249 unmodified lines
257 aaObject *car;258 aaObject *car;
258 259
259begin:260begin:
260 if((TAG(obj) & GCMARKBIT) != 0 || ISNULL(obj))261 if(ISNULL(obj) || (TAG(obj) & GCMARKBIT) != 0)
261 return;262 return;
262 car = CAR(obj); /* store car before modifying it with GCMARKBIT */263 car = CAR(obj); /* store car before modifying it with GCMARKBIT */
263 TAG(obj) |= GCMARKBIT;264 TAG(obj) |= GCMARKBIT;
@@ -290,6 +291,7 @@ collectgarbage(aaContext *ctx) · 26 unmodified lines
290 /* mark */291 /* mark */
291 for(i = 0; i < ctx->gcstack_idx; i++)292 for(i = 0; i < ctx->gcstack_idx; i++)
292 aa_mark(ctx, ctx->gcstack[i]);293 aa_mark(ctx, ctx->gcstack[i]);
294
293 aa_mark(ctx, ctx->symlist);295 aa_mark(ctx, ctx->symlist);
294 296
295 /* sweep and unmark */297 /* sweep and unmark */
@@ -442,13 +444,12 @@ aaObject * · 146 unmodified lines
442aa_symbol_find(aaContext *ctx, const char *name)444aa_symbol_find(aaContext *ctx, const char *name)
443{445{
444 aaObject *obj;446 aaObject *obj;
447 char *pk;
445 448
446 for(obj = ctx->symlist; !ISNULL(obj); obj = CDR(obj)){449 obj = nil;
447 if(streq(CAR(CDR(CAR(obj))), name))450 qpget(ctx->symtrie, name, 0, &pk, &obj);
448 return CAR(obj);
449 }
450 451
451 return nil;452 return obj;
452}453}
453 454
454aaObject *455aaObject *
@@ -465,6 +466,7 @@ aa_symbol(aaContext *ctx, const char *name) · 10 unmodified lines
465 SETTYPE(obj, AA_TSYMBOL);466 SETTYPE(obj, AA_TSYMBOL);
466 CDR(obj) = aa_cons(ctx, aa_string(ctx, name), nil); /* nil not &Null, because it's unbound */467 CDR(obj) = aa_cons(ctx, aa_string(ctx, name), nil); /* nil not &Null, because it's unbound */
467 ctx->symlist = aa_cons(ctx, obj, ctx->symlist);468 ctx->symlist = aa_cons(ctx, obj, ctx->symlist);
469 ctx->symtrie = qpset(ctx->symtrie, strdup(name), 0, obj);
468 470
469 return obj;471 return obj;
470}472}
aa.h+7−1
@@ -1,5 +1,8 @@
1#define GCSTACKSIZE 2561#define GCSTACKSIZE 256
2 2
3typedef union Trie Trie;
4#pragma incomplete Trie
5
3typedef struct aaContext aaContext;6typedef struct aaContext aaContext;
4typedef struct aaHandlers aaHandlers;7typedef struct aaHandlers aaHandlers;
5typedef struct aaNumber aaNumber;8typedef struct aaNumber aaNumber;
@@ -13,8 +16,10 @@ typedef char (*aaReadFn)(aaContext *ctx, void *udata); · 7 unmodified lines
13 16
14struct aaNumber {17struct aaNumber {
15 double r;18 double r;
16 double i;19 //double i;
17};20};
21//#define aNumber(r,i) (aaNumber){r, i}
22#define aNumber(r,i) (aaNumber){r}
18 23
19union aaValue {24union aaValue {
20 Biobuf *port;25 Biobuf *port;
@@ -44,6 +49,7 @@ struct aaContext { · 23 unmodified lines
44 aaObject *calllist;49 aaObject *calllist;
45 aaObject *freelist;50 aaObject *freelist;
46 aaObject *symlist;51 aaObject *symlist;
52 Trie *symtrie;
47 aaObject *t;53 aaObject *t;
48 Rune nextrune;54 Rune nextrune;
49 55
aa_math.c+4−4
@@ -9,7 +9,7 @@ · 8 unmodified lines
9 cf_##func(aaContext *ctx, aaObject *arg) \9 cf_##func(aaContext *ctx, aaObject *arg) \
10 { \10 { \
11 aaNumber x = aa_tonumber(ctx, aa_nextarg(ctx, &arg, 0)); \11 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)); \
13 }13 }
14 14
15#define CFUNC2(func) \15#define CFUNC2(func) \
@@ -18,7 +18,7 @@ · 2 unmodified lines
18 { \18 { \
19 aaNumber x = aa_tonumber(ctx, aa_nextarg(ctx, &arg, 0)); \19 aaNumber x = aa_tonumber(ctx, aa_nextarg(ctx, &arg, 0)); \
20 aaNumber y = aa_tonumber(ctx, aa_nextarg(ctx, &arg, 0)); \20 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)); \
22 }22 }
23 23
24#define FUNCS \24#define FUNCS \
@@ -46,8 +46,8 @@ cf_atan2(aaContext *ctx, aaObject *arg) · 21 unmodified lines
46{46{
47 aaNumber x = aa_tonumber(ctx, aa_nextarg(ctx, &arg, 0));47 aaNumber x = aa_tonumber(ctx, aa_nextarg(ctx, &arg, 0));
48 aaObject *yo = aa_nextarg(ctx, &arg, 1);48 aaObject *yo = aa_nextarg(ctx, &arg, 1);
49 aaNumber y = yo != nil ? aa_tonumber(ctx, yo) : (aaNumber){1.0, 0.0};49 aaNumber y = yo != nil ? aa_tonumber(ctx, yo) : aNumber(1.0, 0.0);
50 return aa_number(ctx, (aaNumber){atan2(x.r, y.r), 0.0});50 return aa_number(ctx, aNumber(atan2(x.r, y.r), 0.0));
51}51}
52 52
53static aaObject *53static aaObject *
mkfile+3−0
@@ -6,10 +6,13 @@ CFLAGS=$CFLAGS -p · 5 unmodified lines
6 6
7HFILES=\7HFILES=\
8 aa.h\8 aa.h\
9 aa_math.h\
10 qp.h\
9 11
10OFILES=\12OFILES=\
11 aa.$O\13 aa.$O\
12 aa_math.$O\14 aa_math.$O\
15 qp.$O\
13 repl.$O\16 repl.$O\
14 17
15default:V: all18default:V: all
qp.c+180−0
@@ -0,0 +1,180 @@
1#include <u.h>
2#include <libc.h>
3#include "qp.h"
4
5typedef u16int Tbitmap;
6typedef struct Tbranch Tbranch;
7typedef struct Tleaf Tleaf;
8
9struct Tleaf {
10 char *k;
11 void *v;
12};
13
14struct Tbranch {
15 Trie *twigs;
16 u64int x;
17};
18
19union 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
43TEXT popcount(SB),$0
44 MOVL b+0(FP), AX
45 POPCNT
46 RET
47*/
48static u16int
49popcount(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
58int
59qpget(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
82int
83qpnext(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
110Trie *
111qpset(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
171growbranch:
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 @@
1typedef union Trie Trie;
2#pragma incomplete Trie
3
4int qpget(Trie *t, char *k, int len, char **pk, void **pv);
5int qpnext(Trie *t, char **pk, int *plen, void **pv);
6Trie *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