ref: e9b59bee4efb648e323dfb6269209b59c575806f
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, int startid); 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, 0); 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; }