ref: 2533822d0fb51d2aedf941bac59d492acc1036a1
dir: /mi/match_test.c/
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "util.h"
#include "parse.h"
#include "mi.h"
#define V1
/**
* TODO
* Recursively check the types of the pattern and the subject tree.
*
*/
File file;
char debugopt[128];
typedef struct Dtree Dtree;
extern Dtree *gendtree(Node *m, Node *val, Node **lbl, size_t nlbl);
extern void dtreedump(FILE *fd, Dtree *dt);
static char *
errorf(char *fmt, ...)
{
va_list ap;
char *p;
size_t n;
p = malloc(2048);
if (p == NULL)
return "(NULL)";
va_start(ap, fmt);
n = vsnprintf(p, 2048, fmt, ap);
va_end(ap);
if (n > 0) {
p = realloc(p, n+1);
} else {
free(p);
p = "(NULL)";
}
return p;
}
static Type *
installucons(Type *t)
{
Type *b;
size_t i;
if (!t)
return NULL;
b = tybase(t);
switch (b->type) {
case Tystruct:
for (i = 0; i < b->nmemb; i++)
installucons(b->sdecls[i]->decl.type);
break;
case Tyunion:
for (i = 0; i < b->nmemb; i++) {
if (!b->udecls[i]->utype)
b->udecls[i]->utype = b;
b->udecls[i]->id = i;
}
break;
default:
break;
}
return t;
}
static Node *
mkdummymatch(Node *p)
{
Node *b;
b = mkblock(Zloc, mkstab(0));
b->block.stmts = NULL;
b->block.nstmts = 0;
return mkmatch(Zloc, p, b);
}
static Node *
ty(Node *n, Type *t)
{
switch (n->type) {
case Nlit:
n->lit.type = t;
break;
case Nexpr:
n->expr.type = t;
default:
;
}
return n;
}
static char *
exprequal(Node *a, Node *b, int depth)
{
size_t i;
char *err;
if (a == NULL && b == NULL)
return NULL;
if (a == NULL || b == NULL)
return "either one is null";
if (false && a->nid != b->nid)
return errorf("nid is not matched. (%d) want %d, got %d", depth, a->nid, b->nid);
if (a->type != b->type)
return errorf("ntype is not matched. (%d) want %s, got %s", depth, nodestr[a->type], nodestr[b->type]);
switch (a->type) {
case Nexpr:
if (exprop(a) != exprop(b))
return errorf("op is not matched. (%d) want %s, got %s", depth, opstr[exprop(a)], opstr[exprop(b)]);
if (a->expr.nargs != b->expr.nargs) {
fprintf(stderr, "op:%s\n", opstr[exprop(a)]);
return errorf("nargs is not matched. (%d) want %d, got %d", depth, a->expr.nargs, b->expr.nargs);
}
for (i = 0; i < a->expr.nargs; i++) {
err = exprequal(a->expr.args[i], b->expr.args[i], depth+1);
if (err != NULL)
return err;
}
break;
case Nlit:
switch (a->lit.littype) {
case Lint:
if (a->lit.intval != b->lit.intval)
return errorf("lit.intval is not matched. (%d) want %d, got %d", depth, a->lit.intval, b->lit.intval);
break;
default:
return errorf("unexpected littype: %s", nodestr[a->type]);
}
break;
case Nname:
break;
default:
return errorf("unexpected ntype: %s", nodestr[a->type]);
}
return NULL;
}
static char *
dtequal(Dtree *a, Dtree *b, int depth)
{
size_t i;
char *err;
if (a == NULL && b == NULL)
return NULL;
if (a == NULL || b == NULL)
return "either one is null";
if (a->id != b->id)
return errorf("id is not matched. (depth:%d) want %d, got %d", depth, a->id, b->id);
if (a->nconstructors != b->nconstructors)
return errorf("nconstructors is not matched. (depth:%d id:%d) want %ld, got %ld", depth, a->id, a->nconstructors, b->nconstructors);
if (a->accept != b->accept)
return errorf("accept is not matched. (depth:%d id:%d) want %ld, got %ld", depth, a->id, a->accept, b->accept);
if (a->emitted != b->emitted)
return errorf("emitted is not matched. (depth:%d id:%d) want %ld, got %ld", depth, a->id, a->emitted, b->emitted);
err = exprequal(a->load, b->load, 0);
if (err != NULL) {
fprintf(stderr, "WANT:\n");
dumpn(a->load, stderr);
fprintf(stderr, "GOT:\n");
dumpn(b->load, stderr);
return errorf("load is not matched. (depth:%d id:%d) want %p, got %p, %s", depth, a->id, a->load, b->load, err);
}
if (a->nnext != b->nnext)
return errorf("nnext is not matched. (depth:%d id:%d) want %d, got %d", depth, a->id, a->nnext, b->nnext);
for (i = 0; i < a->npat; i++) {
err = exprequal(a->pat[i], b->pat[i], 0);
if (err != NULL) {
fprintf(stderr, "WANT:\n");
dumpn(a->pat[i], stderr);
fprintf(stderr, "GOT:\n");
dumpn(b->pat[i], stderr);
return errorf("pat is not matched. (depth:%d id:%d) want %p, got %p, %s", depth, a->id, a->pat[i], b->pat[i], err);
}
}
for (i = 0; i < a->nnext; i++) {
err = dtequal(a->next[i], b->next[i], depth+1);
if (err != NULL)
return errorf("next[%d] is not matched. (depth:%d id:%d) want %p, got %p, %s", i, depth, a->id, a->next[i], b->next[i], err);
}
err = dtequal(a->any, b->any, depth+1);
if (err != NULL)
return errorf("any is not matched. (depth:%d id:%d) want %p, got %p, %s", depth, a->id, a->any, b->any, err);
return NULL;
}
static char *
test_match(int idx, Node *val, Node **pat, Dtree *want)
{
Dtree *dt;
Node *m, *v, *r, **lbl, **matches;
size_t i, nlbl, npat, nmatches;
char *err;
matches = NULL;
nmatches = 0;
for (npat = 0; pat[npat] != NULL; npat++) {
lappend(&matches, &nmatches, mkdummymatch(pat[npat]));
}
m = mkmatchstmt(Zloc, val, matches, nmatches);
r = val;
v = gentemp(r->loc, r->expr.type, NULL);
if (getenv("D")) {
fprintf(stderr, "[%.3d]>\n", idx);
dumpn(m, stdout);
}
if (1) {
lbl = NULL;
nlbl = 0;
for (i = 0; i < nmatches; i++) {
lappend(&lbl, &nlbl, genlbl(pat[i]->match.block->loc));
}
dt = gendtree(m, v, lbl, nlbl);
if (getenv("d")) {
fprintf(stderr, "dtree >>\n");
dtreedump(stderr, dt);
}
err = dtequal(want, dt, 0);
if (err)
return err;
}
if (getenv("G")) {
Node **matches = NULL;
size_t nmatches = 0;
genmatch(m, v, &matches, &nmatches);
fprintf(stdout, "===========\n");
for (i = 0; i < nmatches; i++) {
dumpn(matches[i], stdout);
}
}
return NULL;
}
typedef struct Test {
char *name;
char *desc;
Node *val;
Node **pats;
Dtree *dt;
} Test;
inline static Node *
setnode(Node **dst, Node *src)
{
*dst = src;
return *dst;
}
inline static Node *
getnode(Node *n)
{
return n;
}
int
main(int argc, char **argv)
{
size_t i;
char *err;
Node *t, *p_, *p0, *p1, *p2;
#define P(x) getnode(p##x)
#define InitP0(p) setnode(&p0, p)
#define InitP1(p) setnode(&p1, p)
#define InitP2(p) setnode(&p2, p)
#define InitP_(p) setnode(&p_, p)
#define InitT(v) setnode(&t, v)
#define T getnode(t)
Type *_int32 = mktype(Zloc, Tyint32);
Type *_int64 = mktype(Zloc, Tyint64);
Type *_int32t1 = mktytuple(Zloc, (Type*[]){_int32}, 1);
Type *_int32t2 = mktytuple(Zloc, (Type*[]){_int32, _int32}, 2);
Type *_int32t3 = mktytuple(Zloc, (Type*[]){_int32, _int32, _int32}, 3);
Type *_int32s1 = mktystruct(Zloc, (Node*[]){mkdecl(Zloc, mkname(Zloc, "foo"), _int32)}, 1);
Type *_enum1 = installucons(mktyunion(Zloc, (Ucon*[]){mkucon(Zloc, mkname(Zloc, "Foo"), NULL, NULL)}, 1));
Type *_enum2 = installucons(mktyunion(Zloc,
(Ucon*[]){
mkucon(Zloc, mkname(Zloc, "Foo"), NULL, NULL),
mkucon(Zloc, mkname(Zloc, "Bar"), NULL, NULL)},
2));
Type *_enum3 = installucons(mktyunion(Zloc,
(Ucon*[]){
mkucon(Zloc, mkname(Zloc, "Foo"), NULL, NULL),
mkucon(Zloc, mkname(Zloc, "Bar"), NULL, NULL),
mkucon(Zloc, mkname(Zloc, "Baz"), NULL, NULL)},
3));
Type *_int32u1 = mktyunion(Zloc, (Ucon*[]){
mkucon(Zloc, mkname(Zloc, "Foo"), NULL, _int32t1),
}, 1);
Type *_int32a1 = mktyslice(Zloc, _int32);
Type *_bug001u = installucons(mktyunion(Zloc, (Ucon*[]){
mkucon(Zloc, mkname(Zloc, "Foo"), NULL, _int32t1),
mkucon(Zloc, mkname(Zloc, "Bar"), NULL, NULL)
}, 2));
Type *_bug001s = mktystruct(Zloc, (Node*[]){
mkdecl(Zloc, mkname(Zloc, "s1_slice"), _int32a1),
mkdecl(Zloc, mkname(Zloc, "s1_int32"), _int32),
}, 2);
Type *_bug002s = mktystruct(Zloc, (Node*[]){
mkdecl(Zloc, mkname(Zloc, "s2_ufoo"), _bug001u),
mkdecl(Zloc, mkname(Zloc, "s2_sbar"), _bug001s),
mkdecl(Zloc, mkname(Zloc, "s2_int32"), _int32),
}, 3);
Dtree *dt11 = &(Dtree){
.id = 11,
.any = NULL,
};
Dtree *dt8 = &(Dtree){
.id = 8,
.any =dt11,
};
dt11->any = dt8;
Test tests[] = {
{
.name = "int32 matched by 1 wildcard",
.val = InitT(gentemp(Zloc, _int32, NULL)),
.pats = (Node*[]){
ty(mkexpr(Zloc, Ogap, NULL), _int32),
NULL,
},
.dt = &(Dtree){
.id = 0,
.accept = 1,
},
},
{
.name = "int32 matched by 1 capture variable",
.val = InitT(gentemp(Zloc, _int32, NULL)),
.pats = (Node*[]){
InitP0(ty(mkexpr(Zloc, Ovar, mkname(Zloc, "foovar"), NULL), _int32)),
NULL,
},
.dt = &(Dtree){
.id = 0,
.accept = 1,
},
},
{
.name = "int32 matched by 1 literals",
.val = InitT(gentemp(Zloc, _int32, NULL)),
.pats = (Node*[]){
InitP0(ty(mkexpr(Zloc, Olit, mkint(Zloc, 123), NULL), _int32)),
InitP_(ty(mkexpr(Zloc, Ogap, NULL), _int32)),
NULL,
},
.dt = &(Dtree){
.id = 2,
.load = gentemp(Zloc, _int32, NULL),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
[0] = p0,
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 0,
.accept = 1,
},
},
.any = &(Dtree){
.id = 1,
.accept = 1,
},
},
},
{
.name = "int32 matched by 2 literals",
.val = InitT(gentemp(Zloc, _int32, NULL)),
.pats = (Node*[]){
InitP0(ty(mkexpr(Zloc, Olit, mkint(Zloc, 123), NULL), _int32)),
InitP1(ty(mkexpr(Zloc, Olit, mkint(Zloc, 456), NULL), _int32)),
InitP_(ty(mkexpr(Zloc, Ogap, NULL), _int32)),
NULL,
},
.dt = &(Dtree){
.id = 3,
.load = gentemp(Zloc, _int32, NULL),
.nconstructors = 4294967296,
.npat = 2,
.nnext = 2,
.pat = (Node*[]){
[0] = P(0),
[1] = P(1),
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 0,
.accept = 1,
},
[1] = &(Dtree){
.id = 1,
.accept = 1,
},
},
.any = &(Dtree){
.id = 2,
.accept = 1,
},
},
},
{
.name = "1-tuple, matched by wildcard only",
.val = InitT(gentemp(Zloc, _int32t1, NULL)),
.pats = (Node*[]){
ty(mkexpr(Zloc, Otup, ty(mkexpr(Zloc, Ogap, NULL), _int32), NULL), _int32t1),
NULL,
},
.dt = &(Dtree){
.id = 0,
.accept = 1,
.nnext = 0,
.npat = 0,
.any = NULL,
},
},
{
.name = "1-tuple",
.val = InitT(gentemp(Zloc, _int32t1, NULL)),
.pats = (Node *[]){
InitP0(ty(mkexpr(Zloc, Otup, ty(mkexpr(Zloc, Olit, mkint(Zloc, 123), NULL), _int32), NULL), _int32t1)),
InitP1(ty(mkexpr(Zloc, Ogap, NULL), _int32t1)),
NULL,
},
.dt = &(Dtree){
.id = 2,
.load = ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 0), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(0)->expr.args[0],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 0,
.accept = 1,
},
},
.any = &(Dtree){
.id = 1,
.accept = 1
},
},
},
{
.name = "2-tuple",
.val = InitT(gentemp(Zloc, _int32t2, NULL)),
.pats = (Node *[]){
/**
* | (123, 456):
*/
InitP0(ty(mkexpr(Zloc, Otup,
ty(mkexpr(Zloc, Olit, mkint(Zloc, 123), NULL), _int32),
ty(mkexpr(Zloc, Olit, mkint(Zloc, 456), NULL), _int32),
NULL), _int32t2)),
/**
* | (_, _):
*/
InitP1(ty(mkexpr(Zloc, Ogap, NULL), _int32t2)),
NULL,
},
.dt = &(Dtree){
.id = 3,
.load = ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 0), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(0)->expr.args[0],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 2,
.load =ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 1), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(0)->expr.args[1],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 0,
.accept = 1,
},
},
.any = &(Dtree){
.id = 1,
.accept = 1,
},
},
},
.any = &(Dtree){
.id = 1,
.accept = 1,
}
},
},
{
.name = "3-tuple",
.val = InitT(gentemp(Zloc, _int32t3, NULL)),
.pats = (Node *[]){
/**
* | (123, 456):
*/
InitP0(ty(mkexpr(Zloc, Otup,
ty(mkexpr(Zloc, Olit, mkint(Zloc, 123), NULL), _int32),
ty(mkexpr(Zloc, Olit, mkint(Zloc, 456), NULL), _int32),
ty(mkexpr(Zloc, Olit, mkint(Zloc, 789), NULL), _int32),
NULL), _int32t3)),
/**
* | (_, _):
*/
InitP1(ty(mkexpr(Zloc, Ogap, NULL), _int32t3)),
NULL,
},
.dt = &(Dtree){
.id = 4,
.load = ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 0), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(0)->expr.args[0],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 3,
.load = ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 1), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(0)->expr.args[1],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 2,
.load = ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 2), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(0)->expr.args[2],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 0,
.accept = 1,
}
},
.any = &(Dtree){
.id = 1,
.accept = 1,
},
},
},
.any = &(Dtree){
.id = 1,
.accept = 1,
},
},
},
.any = &(Dtree){
.id = 1,
.accept =1,
},
},
},
{
.name = "3-tuple-3-pat",
.val = InitT(gentemp(Zloc, _int32t3, NULL)),
.pats = (Node *[]){
/**
* | (123, 456):
*/
InitP0(ty(mkexpr(Zloc, Otup,
ty(mkexpr(Zloc, Olit, mkint(Zloc, 101), NULL), _int32),
ty(mkexpr(Zloc, Olit, mkint(Zloc, 102), NULL), _int32),
ty(mkexpr(Zloc, Olit, mkint(Zloc, 103), NULL), _int32),
NULL), _int32t3)),
InitP1(ty(mkexpr(Zloc, Otup,
ty(mkexpr(Zloc, Olit, mkint(Zloc, 201), NULL), _int32),
ty(mkexpr(Zloc, Olit, mkint(Zloc, 202), NULL), _int32),
ty(mkexpr(Zloc, Olit, mkint(Zloc, 203), NULL), _int32),
NULL), _int32t3)),
InitP2(ty(mkexpr(Zloc, Otup,
ty(mkexpr(Zloc, Olit, mkint(Zloc, 301), NULL), _int32),
ty(mkexpr(Zloc, Olit, mkint(Zloc, 302), NULL), _int32),
ty(mkexpr(Zloc, Olit, mkint(Zloc, 303), NULL), _int32),
NULL), _int32t3)),
/**
* | (_, _):
*/
InitP_(ty(mkexpr(Zloc, Ogap, NULL), _int32t3)),
NULL,
},
.dt = &(Dtree){
.id = 10,
.load = ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 0), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 3,
.npat = 3,
.pat = (Node*[]){
P(0)->expr.args[0],
P(1)->expr.args[0],
P(2)->expr.args[0],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 5,
.load = ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 1), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(0)->expr.args[1],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 4,
.load = ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 2), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(0)->expr.args[2],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 0,
.accept = 1,
},
},
.any = &(Dtree){
.id = 3,
.accept = 1,
},
},
},
.any = &(Dtree){
.id = 3,
.accept = 1,
},
},
[1] = &(Dtree){
.id = 7,
.load = ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 1), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(1)->expr.args[1],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 6,
.load = ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 2), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(1)->expr.args[2],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 1,
.accept = 1,
},
},
.any = &(Dtree){
.id = 3,
.accept = 1,
},
},
},
.any = &(Dtree){
.id = 3,
.accept = 1,
},
},
[2] = &(Dtree){
.id = 9,
.load = ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 1), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(2)->expr.args[1],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 8,
.load = ty(mkexpr(Zloc, Otupget, T, mkintlit(Zloc, 2), NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(2)->expr.args[2],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 2,
.accept = 1,
},
},
.any = &(Dtree){
.id = 3,
.accept = 1,
},
},
},
.any = &(Dtree){
.id = 3,
.accept = 1,
},
},
},
.any = &(Dtree){
.id = 3,
.accept = 1,
},
},
},
{
.name = "1-int32-struct",
.val = InitT(gentemp(Zloc, _int32s1, NULL)),
.pats = (Node*[]){
InitP0(ty(mkexprl(Zloc, Ostruct, (Node*[]){mkidxinit(Zloc, mkname(Zloc, "foo"), mkintlit(Zloc, 123))}, 1), _int32s1)),
InitP_(ty(mkexpr(Zloc, Ogap, NULL), _int32s1)),
NULL,
},
.dt = &(Dtree){
.id = 2,
.load = ty(mkexpr(Zloc, Omemb, T, tybase(exprtype(P(0)))->sdecls[0]->decl.name, NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(0)->expr.args[0],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 0,
.accept = 1,
},
},
.any = &(Dtree){
.id = 1,
.accept = 1,
},
},
},
{
.name = "1-enum, matched by wildcard only",
.val = InitT(gentemp(Zloc, _enum1, NULL)),
.pats = (Node*[]){
InitP_( ty(mkexpr(Zloc, Ogap, NULL), _enum1)),
NULL,
},
.dt = &(Dtree){
.id = 0,
.accept = 1,
},
},
{
.name = "1-enum, matched by a valid constructor",
.val = InitT(gentemp(Zloc, _enum1, NULL)),
.pats = (Node*[]){
InitP0(ty(mkexpr(Zloc, Oucon, mkname(Zloc, "Foo"), NULL), _enum1)),
InitP_(ty(mkexpr(Zloc, Ogap, NULL), _enum1)),
NULL,
},
.dt = &(Dtree){
.id = 2,
.nconstructors = 1,
.load = ty(mkexpr(Zloc, Outag, T, NULL), _int32),
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
/*
* the matcher will convert the Oucon expr to an Nlit for the Dtree
*/
ty(mkintlit(Zloc, finducon(_enum1, P(0)->expr.args[0])->id), _int32),
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 0,
.accept = 1,
},
},
.any = &(Dtree){
.id = 1,
.accept = 1,
},
},
},
/**
* match v : _enum2
* | `Foo
* | `Bar
* ;;
*
*/
{
.name = "2-enum, matched by 2 valid constructors",
.val = InitT(gentemp(Zloc, _enum2, NULL)),
.pats = (Node*[]) {
InitP0(ty(mkexpr(Zloc, Oucon, mkname(Zloc, "Foo"), NULL), _enum2)),
InitP1(ty(mkexpr(Zloc, Oucon, mkname(Zloc, "Bar"), NULL), _enum2)),
NULL,
},
.dt = &(Dtree){
.id = 2,
.load = ty(mkexpr(Zloc, Outag, T, NULL), _int32),
.nconstructors = 2,
.nnext = 2,
.npat = 2,
.pat = (Node*[]){
ty(mkintlit(Zloc, finducon(_enum2, P(0)->expr.args[0])->id), _int32),
ty(mkintlit(Zloc, finducon(_enum2, P(1)->expr.args[0])->id), _int32),
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 0,
.accept = 1,
},
[1] = &(Dtree){
.id = 1,
.accept = 1,
},
},
.any = NULL,
},
},
{
.name = "3-enum, matched by 3 valid constructors",
.val = InitT(gentemp(Zloc, _enum3, NULL)),
.pats = (Node*[]) {
InitP0(ty(mkexpr(Zloc, Oucon, mkname(Zloc, "Foo"), NULL), _enum3)),
InitP1(ty(mkexpr(Zloc, Oucon, mkname(Zloc, "Bar"), NULL), _enum3)),
InitP2(ty(mkexpr(Zloc, Oucon, mkname(Zloc, "Baz"), NULL), _enum3)),
NULL,
},
.dt = &(Dtree){
.id = 3,
.load = ty(mkexpr(Zloc, Outag, T, NULL), _int32),
.nconstructors = 3,
.nnext = 3,
.npat = 3,
.pat = (Node*[]){
ty(mkintlit(Zloc, finducon(_enum3, P(0)->expr.args[0])->id), _int32),
ty(mkintlit(Zloc, finducon(_enum3, P(1)->expr.args[0])->id), _int32),
ty(mkintlit(Zloc, finducon(_enum3, P(2)->expr.args[0])->id), _int32),
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 0,
.accept = 1,
},
[1] = &(Dtree){
.id = 1,
.accept = 1,
},
[2] = &(Dtree){
.id = 2,
.accept = 1,
},
},
.any = NULL,
},
},
{
.name = "1-int32-array, matched by an element",
.val = InitT(gentemp(Zloc, _int32a1, NULL)),
.pats = (Node*[]) {
InitP0(ty(mkexpr(Zloc, Oarr,
/**
* {.[0] = 123}
*/
mkidxinit(Zloc, mkintlit(Zloc, 0), mkintlit(Zloc, 123)),
NULL),
_int32s1)),
InitP_(ty(mkexpr(Zloc, Ogap, NULL), _int32a1)),
NULL,
},
.dt = &(Dtree){
.id = 2,
.nconstructors = 4294967296,
.load = ty(mkexpr(Zloc, Oidx, T, ty(mkintlit(Zloc, 0), _int64), NULL), _int32),
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(0)->expr.args[0],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 0,
.accept = 1,
},
},
.any = &(Dtree){
.id = 1,
.accept = 1,
},
},
},
/**
* | `Foo (int32)
*/
{
.name = "1-union of 1-tuple, matched by wildcard only",
.val = InitT(gentemp(Zloc, _int32u1, NULL)),
.pats = (Node*[]){
InitP_(ty(mkexpr(Zloc, Ogap, NULL), _int32u1)),
NULL,
},
.dt = &(Dtree){
.id = 0,
.accept = 1,
},
},
{
.name = "1-union of 1-tuple",
.val = InitT(gentemp(Zloc, _int32u1, NULL)),
.pats = (Node*[]){
/**
* `Foo (123)
*/
InitP0(ty(mkexpr(Zloc, Oucon, mkname(Zloc, "Foo"),
ty(mkexpr(Zloc, Otup, ty(mkexpr(Zloc, Olit, mkint(Zloc, 123), NULL), _int32), NULL), _int32t1), NULL), _int32u1)),
InitP_(ty(mkexpr(Zloc, Ogap, NULL), _int32u1)),
NULL,
},
.dt = &(Dtree){
.id = 3,
.load = ty(mkexpr(Zloc, Outag, T, NULL), _int32),
.nconstructors = 1,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
/*
* the matcher will convert the Oucon expr to an Nlit for the Dtree
*/
ty(mkintlit(Zloc, finducon(_enum1, P(0)->expr.args[0])->id), _int32),
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 2,
.load = ty(mkexpr(Zloc, Otupget,
ty(mkexpr(Zloc, Oudata, T, NULL), _int32t1),
mkintlit(Zloc, 0),
NULL), _int32),
.nconstructors = 4294967296,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(0)->expr.args[1]->expr.args[0],
},
.next = (Dtree*[]){
&(Dtree){
.id = 0,
.accept = 1,
},
},
.any = &(Dtree){
.id = 1,
.accept = 1,
},
},
},
.any = &(Dtree){
.id = 1,
.accept = 1,
},
},
},
{
.name = "bug1",
.val = InitT(gentemp(Zloc, _bug002s, NULL)),
.pats = (Node*[]){
InitP0(ty(mkexprl(Zloc, Ostruct, (Node*[]){
mkidxinit(Zloc, mkname(Zloc, "s2_ufoo"),
ty(mkexpr(Zloc, Oucon, mkname(Zloc, "Foo"),
mkintlit(Zloc, 123), NULL), _int32u1)
)}, 1), _bug002s)),
InitP_(ty(mkexpr(Zloc, Ogap, NULL), _bug002s)),
NULL,
},
.dt = &(Dtree){
.id = 3,
.load = ty(mkexpr(Zloc, Outag,
ty(mkexpr(Zloc, Omemb, T, tybase(exprtype(P(0)))->sdecls[0]->decl.name, NULL), _bug001u),
NULL), _int32),
.nconstructors = 2,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
ty(mkintlit(Zloc, finducon(_bug001u, P(0)->expr.args[0]->expr.args[0])->id), _int32),
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 2,
.load = ty(mkexpr(Zloc, Oudata, ty(mkexpr(Zloc, Omemb, T, tybase(exprtype(P(0)))->sdecls[0]->decl.name, NULL), _int32), NULL), _int32t1),
.nconstructors = 1,
.nnext = 1,
.npat = 1,
.pat = (Node*[]){
P(0)->expr.args[0]->expr.args[1],
},
.next = (Dtree*[]){
[0] = &(Dtree){
.id = 0,
.accept = 1,
},
},
.any = &(Dtree){
.id = 1,
.accept = 1,
}
},
},
.any = &(Dtree){
.id = 1,
.accept = 1,
},
},
},
};
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
Test *t = &tests[i];
char *name = t->name;
char *filter = getenv("N");
if (filter && !strstr(name, filter))
continue;
initfile(&file, errorf("(test-%d-%s)", i, name));
fprintf(stderr, "[%03lu]------ %s ##\n", i, name);
err = test_match(i, t->val, t->pats, t->dt);
if (err) {
fprintf(stderr, "FAILED id: %ld name: %s\n", i, name);
fprintf(stderr, "%s\r\n", err);
break;
}
}
return 0;
}