Example #1
0
SemVal *p_catCode(SemVal *lval, SemVal *rval)
{
    register unsigned l;
    register unsigned r;

    r = rval->codelen;                      /* sizeof rval code */
    l = lval->codelen;                      /* sizeof lval code */

    lval->code = rss_realloc(lval->code,       /* room for new code */
                          (l + r) * sizeof(int8_t));

                                            /* catenate the code */
    memcpy(lval->code + l, rval->code, r * sizeof(int8_t));
    lval->codelen += r;                     /* new size */

    patchadd(l, &lval->truelist, &lval->truelen,
                rval->truelist, rval->truelen);

    patchadd(l, &lval->falselist, &lval->falselen,
                rval->falselist, rval->falselen);

    patchadd(l, &lval->continuelist, &lval->continuelen,
                 rval->continuelist,  rval->continuelen);

    lval->type |= rval->type;               /* type of combined code */
                                            /* (is ok with same types) */

    p_discard(rval);                          /* free memory used by SemVal */

    return (lval);                          /* return new frame */
}
Example #2
0
SemVal *p_ternary(SemVal *cond, SemVal *ifTrue, SemVal *ifFalse)
{
    if ((ifTrue->type & ifFalse->type & e_typeMask) == 0)
    {
        util_semantic(gp_typeConflict, "?:");
        p_clearOperands(ifTrue, ifFalse);
        
        return cond;
    }

    if (test_type(cond, e_const))      /* constant: true or false  */
    {
        p_discard(cond);
        if (cond->evalue)
        {
            p_discard(ifFalse);
            p_expr2stack(ifTrue);
            return ifTrue;
        }

        p_discard(ifTrue);
        p_expr2stack(ifFalse);
        return ifFalse;
    }


    p_expr2stack(ifTrue);                   /* convert the expressions to code */
    p_expr2stack(ifFalse);

    p_generateCode(cond, op_jmp_false, j_falselist); /* jmp around the ifTrue code */
    p_patchupTrue(cond, 1);          /* destination for the ifTrue code */

    p_catCode(cond, ifTrue);           /* cond = cond + ifTrue */
    p_generateCode(cond, op_jmp, j_truelist);   /* jmp around the ifFalse code */

    p_patchupFalse(cond, 1);         /* destination of the false alternative */
    p_catCode(cond, ifFalse);         /* cond = cond + ifTrue + jmp + ifFalse */

    p_patchupTrue(cond, 1);          /* jump from ifTrue to the end of expr. */

    return cond;                     /* ?: return */
}
Example #3
0
                                            /* opstr is '=', or "/=", etc. */
SemVal *p_assignment(SemVal *lval, SemVal *rval, char *opstr)
{
    SemVal *tmp;
    unsigned type;
    unsigned value;

    if (!test_type(lval, e_var))
    {
        util_semantic(gp_lvalueNeeded, opstr);
        p_discard(rval);
        return lval;
    }

    p_trySIconvert(lval, rval);

    p_expr2stack(rval);                             /* convert rval to code */

                                            /* same types */
    if (lval->type & rval->type & (e_int | e_str | e_list))
    {
        type = lval->type;                  /* save type/idx for return */
        value = lval->evalue;

        p_generateCode(lval, op_copy_var, lval->evalue);
        tmp = p_catCode(rval, lval);          /* catenate p_assignment code */

        tmp->evalue = value;                /* set lvalue type and idx */
        tmp->type = type;

        return tmp;
    }

    util_semantic(gp_typeConflict, opstr);
    p_discard(rval);

    return lval;
}
Example #4
0
SemVal *p_catStmnts(SemVal *lval, SemVal *rval)
{
    p_patchupFalse(lval, 1);

    msg("lval length: %u, rval length: %u", lval->codelen, rval->codelen);

    if (gp_nestLevel == 0)
    {
        util_out(gp_bin, lval->code, lval->codelen);
        p_discard(lval);
        return rval;
    }

    return p_catCode(lval, rval);
}
Example #5
0
SemVal *p_indexOp(SemVal *larg, SemVal *rarg)
{
    register int ok;
    ExprType type = f_element;
    SemVal *tmp;


    p_expr2stack(larg);                             /* arg to stack */
    p_expr2stack(rarg);                             /* arg to stack */

    /* This follows the code of `p_twoArgs.c' to compute a list/string    */
    /* element                                                          */

                                            /* first arg must be int */
    if (!test_type(larg, e_int))            /* first expression is no int */
    {
        tmp = larg;                         /* then swap    */
        larg = rarg;
        rarg = tmp;
    }

    if ( (ok = test_type(larg, e_int)) )    /* right arg must be int    */
    {                               /* second arg == list: ok */
        if (!(ok = test_type(rarg, e_list)))
        {                           /* second arg == string: ok */
            ok = test_type(rarg, e_str);
            type = f_str_el;        /* string element requested */
        }
    }

    if (ok)
    {
        p_catCode(rarg, larg);                /* make one code vector */
        p_callRss(rarg, type);
    }
    else
    {
        util_semantic(gp_typeConflict, gp_funstring[type]);
        p_discard(larg);
    }
    return (rarg);
}
Example #6
0
SemVal *p_twoArgs(ExprType type, SemVal *larg, SemVal *rarg)
{
    register int ok;

    msg("start");

    p_expr2stack(larg);                             /* arg to stack */
    p_expr2stack(rarg);                             /* arg to stack */

    switch ((FunNr)type)
    {
        case f_fgets:
            ok = test_type(larg, e_str) && test_type(rarg, e_list);
        break;

        case f_element:                     /* f_element */
                                            /* first arg must be int */
            if ( (ok = test_type(larg, e_int)) )
            {                               /* second arg == list: ok */
                if (!(ok = test_type(rarg, e_list)))
                {                           /* second arg == string: ok */
                    ok = test_type(rarg, e_str);
                    type = f_str_el;        /* string element requested */
                }
            }
        break;

        case f_resize:
            ok = test_type(larg, e_str) && test_type(rarg, e_int);
        break;

        case f_listfind:
            ok = test_type(larg, e_list) && test_type(rarg, e_str);
        break;

        case f_listunion:
            ok = test_type(larg, e_list) && test_type(rarg, e_str | e_list);
        break;

        default:
            /*
                case f_strchr:
                case f_strtok:
                case f_c_ext:
                case f_c_base:
                case f_c_path:
                case f_strfind:
            */
            ok = larg->type & rarg->type & e_str;
    }

    msg("types test %d, funstring: %x", ok, type);

    if (ok)
    {
        p_catCode(rarg, larg);                /* make one code vector */
        p_callRss(rarg, type);
    }
    else
    {
        util_semantic(gp_typeConflict, gp_funstring[type]);
        p_discard(larg);
        rarg = p_stackFrame(e_null);
    }
    msg("leaving");
    return rarg;
}