예제 #1
0
파일: test_parser.c 프로젝트: kenkam/turtle
/**
 *  tests varnum()
 */
static char * test_varnum() {
    Logo good, b_var, b_number;
    int ret;
    printf("Testing %s\n", __FUNCTION__);
    
    /* good input */
    good = setup(4, "20");
    insert_line(good, "H");
    /* decimals and negative numbers */
    insert_line(good, "2.5");
    insert_line(good, "-2.5");
    /* bad input */
    b_var = setup(1, "AB");
    b_number = setup(1, "209x");
    
    /* test them */
    ret = varnum(good->lines[0], good);
    mu_assert("error, ret != 0", ret == 0);
    ret = varnum(good->lines[1], good);
    mu_assert("error, ret != 0", ret == 0);
    ret = varnum(good->lines[2], good);
    mu_assert("error, ret != 0", ret == 0); 
    ret = varnum(good->lines[3], good);
    mu_assert("error, ret != 0", ret == 0);    
    ret = varnum(b_var->lines[0], b_var);
    mu_assert("error, ret != PARSE_ERR", ret == PARSE_ERR);
    ret = varnum(b_number->lines[0], b_number);
    mu_assert("error, ret != PARSE_ERR", ret == PARSE_ERR);
    
    tear_down(good);
    tear_down(b_var);
    tear_down(b_number);
    return 0;
}
예제 #2
0
/**
 *  tests varnum()
 */
static char * test_varnum() {
    Logo good, b_var, b_number;
    int ret;
    float op;
    printf("Testing %s\n", __FUNCTION__);
    
    /* good input */
    good = setup(4, "20");
    /* decimals and negative numbers */
    insert_line(good, "2.5");
    insert_line(good, "-2.5");
    insert_line(good, "A");
    /* bad input */
    b_var = setup(3, "AB");
    /* non existant var */
    insert_line(b_var, "C");
    insert_line(b_var, "3-");
    b_number = setup(1, "209x");
    
    /* test them */
    ret = varnum(good->lines[0], good, &op);
    mu_assert("error, ret != 0", ret == 0);
    mu_assert("error, op not set correctly", op == 20);
    ret = varnum(good->lines[1], good, &op);
    mu_assert("error, ret != 0", ret == 0);
    mu_assert("error, op not set correctly", op == 2.5);
    ret = varnum(good->lines[2], good, &op);
    mu_assert("error, ret != 0", ret == 0);
    mu_assert("error, op not set correctly", op == -2.5);
    /* set the var A */
    set_var("A", good->vars, 20);
    ret = varnum(good->lines[3], good, &op);
    mu_assert("error, ret != 0", ret == 0);
    mu_assert("error, op not set correctly", op == 20);
    ret = varnum(b_var->lines[0], b_var, &op);
    mu_assert("error, ret != PARSE_ERR", ret == PARSE_ERR);
    ret = varnum(b_var->lines[1], b_var, &op);
    mu_assert("error, ret != VAR_ERR", ret == VAR_ERR);    
    ret = varnum(b_var->lines[2], b_var, &op);
    mu_assert("error, ret != VAR_ERR", ret == PARSE_ERR);   
    ret = varnum(b_number->lines[0], b_number, &op);
    mu_assert("error, ret != PARSE_ERR", ret == PARSE_ERR);
    
    tear_down(good);
    tear_down(b_var);
    tear_down(b_number);
    return 0;
}
예제 #3
0
파일: compiler.c 프로젝트: yewton/tinyca
/**
 * コードを生成する
 * @param FILE     *ofp  出力先
 * @param char     *file ファイル名
 * @param FEnvCPtr fenvc 関数の型環境
 * @param EnvCPtr  envc  変数の型環境
 * @param ExpPtr   ep    式
 * @return int           成否
 */   
int codegen(FILE *ofp, const char *file, FEnvCPtr fenv, EnvCPtr env, ExpPtr ep) {
    TyType t;
    TyTypesPtr ts;
    EnvCPtr env1 = NULL;
    ExpsPtr es = NULL;
    FuncT ft = {0};
    char l[LABEL_NAME_MAX_SIZE] = "";
    char m[LABEL_NAME_MAX_SIZE] = "";
    char dty[2] = "";
        
    if(NULL == ep) {
        return 0;
    }
    switch(ep->t) {
    case VAR_EXP:
        t = find_var_c(ep->of.var, env);
        switch(t) {
        case FLOAT_TYPE:
            pr_instr(ofp, "fload %d", varnum(ep->of.var, env));
            break;
        default:
            pr_instr(ofp, "iload %d", varnum(ep->of.var, env));
            break;
        }
        break;
    case INT_EXP:
        pr_instr(ofp, "ldc %d", ep->of.intval);
        break;
    case FLOAT_EXP:
        pr_instr(ofp, "ldc %f", ep->of.floatval);
        break;
    case PRIM_EXP:
        codegen(ofp, file, fenv, env, ep->of.Prim.exp1);
        codegen(ofp, file, fenv, env, ep->of.Prim.exp2);
        switch(ep->of.Prim.op) {
        case PLUS_OP:
            pr_instr(ofp, "iadd");
            break;
        case FPLUS_OP:
            pr_instr(ofp, "fadd");
            break;
        case MINUS_OP:
            pr_instr(ofp, "isub");
            break;
        case FMINUS_OP:
            pr_instr(ofp, "fsub");
            break;
        case MUL_OP:
            pr_instr(ofp, "imul");
            break;
        case FMUL_OP:
            pr_instr(ofp, "fmul");
            break;
        }
        break;
    case LET_EXP:
        codegen(ofp, file, fenv, env, ep->of.Let.exp1);
        switch((norm(ep->of.Let.tvar.ttp))->t) {
        case FLOAT_TYPE:
            pr_instr(ofp, "fstore %d", newvar());
            break;
        default:
            pr_instr(ofp, "istore %d", newvar());
            break;
        }
        env1 = envc_alloc();
        strncpy_s(env1->var, MAX_VAR_NAME_LENGTH, ep->of.Let.tvar.var, strlen(ep->of.Let.tvar.var));
        env1->t = (norm(ep->of.Let.tvar.ttp))->t;
        env1->next = env;
        codegen(ofp, file, fenv, env1, ep->of.Let.exp2);
        break;
    case IF_EXP:
        newlabel(l, "else");
        newlabel(m, "endif");
        codegen(ofp, file, fenv, env, ep->of.If.bp->exp1);
        codegen(ofp, file, fenv, env, ep->of.If.bp->exp2);
        switch((norm(ep->of.If.bp->ttp))->t) {
        case FLOAT_TYPE:
            pr_instr(ofp, "fcmpl");
            pr_instr(ofp, "ifne %s", l);
            break;
        default:
            pr_instr(ofp, "if_icmpne %s", l);
            break;
        }
        codegen(ofp, file, fenv, env, ep->of.If.exp1);
        pr_instr(ofp, "goto %s", m);
        fprintf_s(ofp, "%s:\n", l);
        codegen(ofp, file, fenv, env, ep->of.If.exp2);
        fprintf_s(ofp, "%s:\n", m);
        break;
    case APP_EXP:
        for(es = ep->of.App.exps; NULL != es; es = es->next) {
            codegen(ofp, file, fenv, env, es->elm);
        }
        ft = find_func_c(ep->of.App.var, fenv);
        fprintf_s(ofp, "\tinvokestatic %s/%s(", file, ep->of.App.var);
        for(ts = ft.tys; NULL != ts; ts = ts->next) {
            desc_of_ty(dty, ts->t);
            fprintf_s(ofp, "%s", dty);
            printf("dty -> %s\n", dty);
        }
        desc_of_ty(dty, ft.fty);
        fprintf_s(ofp, ")%s\n", dty);
        break;
    }
    return 1;
}