Пример #1
0
Файл: flatten.c Проект: oridb/mc
static void
flattencond(Flattenctx *s, Node *n, Node *ltrue, Node *lfalse)
{
	Node **args;
	Node *v, *lnext;

	args = n->expr.args;
	switch (exprop(n)) {
	case Oland:
		lnext = genlbl(n->loc);
		flattencond(s, args[0], lnext, lfalse);
		append(s, lnext);
		flattencond(s, args[1], ltrue, lfalse);
		break;
	case Olor:
		lnext = genlbl(n->loc);
		flattencond(s, args[0], ltrue, lnext);
		append(s, lnext);
		flattencond(s, args[1], ltrue, lfalse);
		break;
	case Olnot:
		flattencond(s, args[0], lfalse, ltrue);
		break;
	default:
		v = rval(s, n);
		cjmp(s, v, ltrue, lfalse);
		break;
	}
}
Пример #2
0
static void simpcond(Simp *s, Node *n, Node *ltrue, Node *lfalse)
{
    Node **args;
    Node *v, *lnext;

    args = n->expr.args;
    switch (exprop(n)) {
        case Oland:
            lnext = genlbl();
            simpcond(s, args[0], lnext, lfalse);
            append(s, lnext);
            simpcond(s, args[1], ltrue, lfalse);
            break;
        case Olor:
            lnext = genlbl();
            simpcond(s, args[0], ltrue, lnext);
            append(s, lnext);
            simpcond(s, args[1], ltrue, lfalse);
            break;
        case Olnot:
            simpcond(s, args[0], lfalse, ltrue);
            break;
        default:
            v = rval(s, n, NULL);
            cjmp(s, v, ltrue, lfalse);
            break;
    }
}
Пример #3
0
/* pat; seq; 
 *      body;;
 *
 * =>
 *      .pseudo = seqinit
 *      jmp :cond
 *      :body
 *           ...body...
 *      :step
 *           ...step...
 *      :cond
 *           ...cond...
 *           cjmp (cond) :match :end
 *      :match
 *           ...match...
 *           cjmp (match) :body :step
 *      :end
 */
static void simpiter(Simp *s, Node *n)
{
    Node *lbody, *lstep, *lcond, *lmatch, *lend;
    Node *idx, *len, *dcl, *seq, *val, *done;
    Node *zero;

    lbody = genlbl();
    lstep = genlbl();
    lcond = genlbl();
    lmatch = genlbl();
    lend = genlbl();

    lappend(&s->loopstep, &s->nloopstep, lstep);
    lappend(&s->loopexit, &s->nloopexit, lend);

    zero = mkintlit(n->line, 0);
    zero->expr.type = tyintptr;

    seq = rval(s, n->iterstmt.seq, NULL);
    idx = gentemp(s, n, tyintptr, &dcl);
    declarelocal(s, dcl);

    /* setup */
    append(s, assign(s, idx, zero));
    jmp(s, lcond);
    simp(s, lbody);
    /* body */
    simp(s, n->iterstmt.body);
    /* step */
    simp(s, lstep);
    simp(s, assign(s, idx, addk(idx, 1)));
    /* condition */
    simp(s, lcond);
    len = seqlen(s, seq, tyintptr);
    done = mkexpr(n->line, Olt, idx, len, NULL);
    cjmp(s, done, lmatch, lend);
    simp(s, lmatch);
    val = load(idxaddr(s, seq, idx));
    umatch(s, n->iterstmt.elt, val, val->expr.type, lbody, lstep);
    simp(s, lend);

    s->nloopstep--;
    s->nloopexit--;
}
Пример #4
0
static void umatch(Simp *s, Node *pat, Node *val, Type *t, Node *iftrue, Node *iffalse)
{
    Node *v, *x, *y;
    Node *deeper, *next;
    Node **patarg;
    Ucon *uc;
    size_t i;
    size_t off;

    assert(pat->type == Nexpr);
    t = tybase(t);
    if (exprop(pat) == Ovar && !decls[pat->expr.did]->decl.isconst) {
        v = assign(s, pat, val);
        append(s, v);
        jmp(s, iftrue);
        return;
    }
    switch (t->type) {
        /* Never supported */
        case Tyvoid: case Tybad: case Tyvalist: case Tyvar:
        case Typaram: case Tyunres: case Tyname: case Ntypes:
        /* Should never show up */
        case Tyslice:
            die("Unsupported type for compare");
            break;
        case Tybool: case Tychar: case Tybyte:
        case Tyint8: case Tyint16: case Tyint32: case Tyint:
        case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint:
        case Tyint64: case Tyuint64: case Tylong:  case Tyulong:
        case Tyfloat32: case Tyfloat64:
        case Typtr: case Tyfunc:
            v = mkexpr(pat->line, Oeq, pat, val, NULL);
            v->expr.type = mktype(pat->line, Tybool);
            cjmp(s, v, iftrue, iffalse);
            break;
        /* We got lucky. The structure of tuple, array, and struct literals
         * is the same, so long as we don't inspect the type, so we can
         * share the code*/
        case Tystruct: case Tytuple: case Tyarray: 
            patarg = pat->expr.args;
            off = 0;
            for (i = 0; i < pat->expr.nargs; i++) {
                off = tyalign(off, size(patarg[i]));
                next = genlbl();
                v = load(addk(addr(s, val, exprtype(patarg[i])), off));
                umatch(s, patarg[i], v, exprtype(patarg[i]), next, iffalse);
                append(s, next);
                off += size(patarg[i]);
            }
            jmp(s, iftrue);
            break;
        case Tyunion:
            uc = finducon(pat);
            if (!uc)
                uc = finducon(val);

            deeper = genlbl();

            x = uconid(s, pat);
            y = uconid(s, val);
            v = mkexpr(pat->line, Oeq, x, y, NULL);
            v->expr.type = tyintptr;
            cjmp(s, v, deeper, iffalse);
            append(s, deeper);
            if (uc->etype) {
                pat = patval(s, pat, uc->etype);
                val = patval(s, val, uc->etype);
                umatch(s, pat, val, uc->etype, iftrue, iffalse);
            }
            break;
    }
}