ref: e92ebbba27581d60d697ce774387fb86a33c55f7
parent: 050c29b20810d6519702f6ee4928c835203caea3
author: Ori Bernstein <[email protected]>
date: Wed Oct 15 09:49:45 EDT 2014
Add support for literal nodes in dtree.
--- a/opt/match.c
+++ b/opt/match.c
@@ -36,9 +36,19 @@
return zalloc(sizeof(Dtree));
}
-static int uconeq(Node *a, Node *b)
+static Dtree *addwild(Dtree *t, Node *var, Node ***cap, size_t *ncap)
{
- return !strcmp(namestr(a), namestr(b));
+ Node *dcl;
+
+ dcl = decls[var->expr.did];
+ /* FIXME: Avoid duplicate constants */
+ if (dcl->decl.isconst)
+ return NULL;
+ if (t->any)
+ return t->any;
+ t->any = mkdtree();
+ lappend(cap, ncap, var);
+ return t->any;
}
static Dtree *addunion(Dtree *t, Node *pat, Node ***cap, size_t *ncap)
@@ -49,11 +59,8 @@
/* if we have the value already... */
sub = NULL;
for (i = 0; i < t->nval; i++) {
- if (!t->val[i])
- fatal(pat, "constructor already matched by earlier variable");
- if (uconeq(t->val[i], pat->expr.args[0])) {
+ if (nameeq(t->val[i], pat->expr.args[0]))
return addpat(t->sub[i], pat->expr.args[1], cap, ncap);
- }
}
sub = mkdtree();
@@ -64,18 +71,20 @@
return sub;
}
-static Dtree *addwild(Dtree *t, Node *var, Node ***cap, size_t *ncap)
+static Dtree *addlit(Dtree *t, Node *pat, Node ***cap, size_t *ncap)
{
- Node *dcl;
+ Dtree *sub;
+ size_t i;
- dcl = decls[var->expr.did];
- if (dcl->decl.isconst)
- return NULL;
- if (t->any)
- return t->any;
- t->any = mkdtree();
- lappend(cap, ncap, var);
- return t->any;
+ for (i = 0; i < t->nval; i++) {
+ if (liteq(t->val[i]->expr.args[0], pat->expr.args[0]))
+ return addpat(t->sub[i], pat->expr.args[1], cap, ncap);
+ }
+
+ sub = mkdtree();
+ lappend(&t->val, &t->nval, pat);
+ lappend(&t->sub, &t->nsub, sub);
+ return sub;
}
static Dtree *addpat(Dtree *t, Node *pat, Node ***cap, size_t *ncap)
@@ -91,10 +100,10 @@
case Oucon:
ret = addunion(t, pat, cap, ncap);
break;
- /*
case Olit:
ret = addlit(t, pat, cap, ncap);
break;
+ /*
case Otup:
ret = addtup(t, pat, cap, ncap);
break;
--- a/parse/node.c
+++ b/parse/node.c
@@ -351,6 +351,33 @@
return NULL;
}
+int liteq(Node *a, Node *b)
+{
+ assert(a->type == Nlit && b->type == Nlit);
+ if (a->lit.littype != b->lit.littype)
+ return 0;
+ if (!tyeq(a->lit.type, b->lit.type))
+ return 0;
+ switch (a->lit.littype) {
+ case Lchr:
+ return a->lit.chrval == b->lit.chrval;
+ case Lbool:
+ return a->lit.boolval == b->lit.boolval;
+ case Lint:
+ return a->lit.intval == b->lit.intval;
+ case Lflt:
+ return a->lit.fltval == b->lit.fltval;
+ case Lstr:
+ return !strcmp(a->lit.strval, b->lit.strval);
+ case Lfunc:
+ return a->lit.fnval == b->lit.fnval;
+ case Llbl:
+ return !strcmp(a->lit.lblval, b->lit.lblval);
+ break;
+ }
+ return 0;
+}
+
/* name hashing */
ulong namehash(void *p)
{
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -393,6 +393,7 @@
int hthas(Htab *ht, void *k);
void **htkeys(Htab *ht, size_t *nkeys);
/* useful key types */
+int liteq(Node *a, Node *b);
ulong strhash(void *key);
int streq(void *a, void *b);
ulong ptrhash(void *key);