Exemple #1
0
SemVal *p_execute(SemVal *arr)
{
    register size_t count;
    SemVal
        tmp,
        *argp,                              /* pointer to args */
        e;

    count = arr->type;                      /* get argument count */

    if (count < 6)                          /* to few arguments */
    {
        util_semantic(gp_illegalArgCount, "execute");
        return (arr);                       /* dummy  args return */
    }

    argp = codestruc(arr, 0);               /* point to first arg */
    e = *(argp + 2);                        /* cmd head info at e */

    p_callRss(&e, f_cmd_head);                /* code for cmd_head at e */

    p_callRss(argp + 3, f_arg_head);          /* code for arg_head */
    p_catCode(&e, argp + 3);                  /* code appended to e*/

    p_callRss(&argp[count - 2], f_arg_tail);  /* code for arg_tail */
    p_catCode(&e, &argp[count - 2]);          /* code appended to e*/

    p_callRss(&argp[count - 1], f_cmd_tail);  /* code for cmd_tail */
    p_catCode(&e, &argp[count - 1]);          /* code appended to e*/

                                            /* keep variable # of args */
    memmove(argp + 2, argp + 4, (count - 2) * sizeof(SemVal));
    arr->type -= 4;                         /* remove 4 arguments */

    p_catCode(&e, p_specials(f_exec, arr));     /* catenate call-code */

    free(gp_stringbuf);                        /* make sure empty string */
    gp_stringbuf = rss_strdup("");              /* is pushed */

    tmp = *p_stackFrame(e_str | e_const);     /* empty string argument */

    p_expr2stack(&tmp);
    p_catCode(&e, &tmp);                      /* empty string on the stack */

    p_generateCode(&e, op_call_rss, f_cmd_tail);   /* used with cmd_tail..cmd_head */
    p_generateCode(&e, op_call_rss, f_arg_tail);
    p_generateCode(&e, op_call_rss, f_arg_head);

    p_callRss(&e, f_cmd_head);

    *arr = e;
    return arr;
}
Exemple #2
0
void p_bool2int(SemVal *e)
{
    if (!test_type(e, e_bool))              /* no batchpatching needed */
        return;

    p_patchupTrue(e, 1);
    e->truelen = 0;

    p_generateCode(e, op_push_1_jmp_end);          /* truelist target */

    p_patchupFalse(e, 1);
    e->falselen = 0;

    p_generateCode(e, op_push_0);                  /* falselist target */

    set_type(e, e_int | e_stack);            /* set int code type */
}
Exemple #3
0
SemVal *p_callFunction(int funIdx, SemVal *e)
{
    msg("calling function 0x%x", funIdx);

    register unsigned nParams;

/*
    fprintf(stderr,
        "type: %d\n"
        "truelen: %d\n"
        "falselen: %d\n"
        "codelen: %d\n"
        "evalue: %d\n"
        "truelist: %p\n"
        "falselist: %p\n"
        "code: %p\n",
        e->type,
        e->truelen,
        e->falselen,
        e->codelen,
        e->evalue,
        e->truelist,
        e->falselist,
        e->code);
*/            

    if (funIdx == -1)                   /* function name not found ? */
        return e;                       /* nothing to do here        */

    nParams = symtab_fun_nParams(funIdx);    /* then check correct # of args */

    if ((unsigned)e->type == nParams)
        p_checkArgumentTypes(nParams, funIdx, (SemVal *)e->code);
    else
        util_semantic("Function '%s()' requires %u arguments",
                    symtab_funName(funIdx), nParams);

    p_catArgs(e);                             /* convert args to code */

                                            /* call function and clean stack */
    p_generateCode(e, op_call, symtab_funAddress(funIdx));
    p_generateCode(e, op_asp,  nParams);
    set_type(e, symtab_funType(funIdx));

    return e;                               /* return called function code */
}
Exemple #4
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 */
}
Exemple #5
0
void p_makeFrame()
{
    if (symtab_nLocals())
    {
        SemVal e = *p_stackFrame(0);         /* initialize empty frame */

        p_pushDead();
        gp_dead[gp_dead_sp] = 0;
        p_generateCode(&e, op_frame);        /* generate frame instruction */
        p_popDead();

        util_out(gp_bin, e.code, e.codelen); /* write to gp_bin */

        msg("write code frame of %u bytes", e.codelen);

        free(e.code);
    }
}
Exemple #6
0
SemVal *p_negate(SemVal *e)                  /* expression so far */
{
    if (p_testOperand(e, op_umin))            /* test types ok */
    {
        util_semantic(gp_illegalType, gp_opstring[op_umin]);
        return (e);
    }

    if (e->type & e_const)                  /* immediate value */
        e->evalue = -(int)e->evalue;
    else
    {
        p_expr2stack(e);                            /* convert to code */
        p_generateCode(e, op_umin);                /* generate instruction */
    }

    return (e);
}
Exemple #7
0
SemVal *p_not(SemVal *e)                   /* expression so far */
{
    if (p_testOperand(e, op_bnot))            /* test types ok */
    {
        util_semantic(gp_illegalType, gp_opstring[op_bnot]);
        return e;
    }

    if ((e->type & (unsigned)~e_typeMask) == e_const)   /* immediate value */
        e->evalue = ~e->evalue;
    else
    {
        p_expr2stack(e);                            /* convert to code */
        p_generateCode(e, op_bnot);                /* generate instruction */
    }

    return e;
}
Exemple #8
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;
}