Пример #1
0
void loli_init_tl(){
	top_env = addToEnv(top_env, cons(mksym("a"), mkflt(10.0011011)));
	top_env = addToEnv(top_env, cons(t, t));
	top_env = addToEnv(top_env, cons(nil, nil));
	top_env = addToEnv(top_env, cons(quote, quote));
	top_env = addToEnv(top_env, cons(mksym("top_env"), top_env));

	//Creating Primitive Operators
	loliObj* loli_sum = mkproc(proc_sum);
	loliObj* loli_mul = mkproc(proc_mul);
	loliObj* loli_sub = mkproc(proc_sub);
	loliObj* loli_div = mkproc(proc_div);
	loliObj* loli_add1 = mkproc(proc_add1);
	loliObj* loli_sub1 = mkproc(proc_sub1);
	loliObj* loli_mod = mkproc(proc_mod);
	loliObj* loli_greater = mkproc(proc_greater);
	loliObj* loli_lesser = mkproc(proc_lesser);
	
	top_env = addToEnv(top_env, cons(mksym("+"), loli_sum));
	top_env = addToEnv(top_env, cons(mksym("*"), loli_mul));
	top_env = addToEnv(top_env, cons(mksym("-"), loli_sub));
	top_env = addToEnv(top_env, cons(mksym("/"), loli_div));
	top_env = addToEnv(top_env, cons(mksym("add1"), loli_add1));
	top_env = addToEnv(top_env, cons(mksym("sub1"), loli_sub1));
	top_env = addToEnv(top_env, cons(mksym("mod"), loli_mod));
	top_env = addToEnv(top_env, cons(mksym(">"), loli_greater));
	top_env = addToEnv(top_env, cons(mksym("<"), loli_lesser));

	loliObj* test = cons(mkint(1), cons(mkflt(2.5), cons(mkint(5), nil)));

	std::cout<<toString(apply(loli_sum, test))<<"\t"<<toString(apply(loli_mul, test))<<"\n"<<toString(apply(loli_sub, test))<<"\t"<<toString(apply(loli_div, test))<<std::endl;

	std::cout<<toString(top_env)<<std::endl;

}
Пример #2
0
static Node *val(int line, vlong val, Type *t)
{
    Node *n;

    n = mkint(line, val);
    n = mkexpr(line, Olit, n, NULL);
    n->expr.type = t;
    return n;
}
Пример #3
0
Value *lreadint()
{
    int v = 0;
    char ch;
    while (isdigit((ch = getchar()))) {
        v = v*10 + (ch - '0');
    }
    ungetc(ch, stdin);
    return mkint(v);
}
Пример #4
0
Файл: fold.c Проект: 8l/mc
static Node *val(Srcloc loc, vlong val, Type *t)
{
	Node *l, *n;

	l = mkint(loc, val);
	n = mkexpr(loc, Olit, l, NULL);
	l->lit.type = t;
	n->expr.type = t;
	return n;
}
Пример #5
0
int main(int argc, char * argv[]){
	std::cout<<nil->value<<std::endl;
	std::cout<<t->value<<std::endl;
//	std::cout<<mkflt(1.2356).value<<std::endl;
//	loliObj* c = cons(t, nil);
//	loliObj* b = cons(t, c);
//	std::cout<<tail(tail(b))->value<<std::endl;
	std::cout<<"CREATING TEST:"<<std::endl;
	loliObj* test = cons(mksym("a"), cons(mkint(3), cons(mkint(0), nil)));
//	std::cout<<"TEST HEAD: "<<head(test).value<<std::endl;
//	std::cout<<"SUM (1 2 3): "<<proc_sum(test)->value<<std::endl;
	std::cout<<"SUB (\"a\" 3 0): "<<proc_sub(test)->value<<std::endl;
///	std::cout<<"MUL (1 2 3): "<<proc_mul(test)->value<<std::endl;
	std::cout<<"DIV (\"a\" 3 0): "<<proc_div(test)->value<<std::endl;
	std::cout<<"MOD (\"a\" 3 0): "<<proc_mod(test)->value<<std::endl;
	std::cout<<"Length of (\"a\" 3 0) is: "<<prim_length(test)<<std::endl;
	loliObj* testSUM = mkproc(proc_sum);
	//cleanUp();
	//delete test;
	exit(0);
}
Пример #6
0
Cell parse(void)
{
    Cell c;
    if (read_bit()) {		/* variable */
	int i;
	for (i = 0; read_bit(); i++)
	    ;
	c = mkint(i);
    }
    else if (read_bit()) {	/* application */
	PUSH(parse());
	c = parse();
	c = pair(TOP, c);
	POP;
    }
    else			/* lambda */
	c = pair(LAMBDA, parse());

    return c;
}
Пример #7
0
void eval(Cell root)
{
    Cell *bottom = rd_stack.sp;
    PUSH(root);

    for (;;) {
	while (ispair(TOP))
	    PUSH(car(TOP));

	if (TOP == COMB_I && APPLICABLE(1))
	{ /* I x -> x */
	    POP;
	    TOP = cdr(TOP);
	}
	else if (TOP == COMB_S && APPLICABLE(3))
	{ /* S f g x -> f x (g x) */
	    Cell a = alloc(2);
	    SET(a+0, ARG(1), ARG(3));	/* f x */
	    SET(a+1, ARG(2), ARG(3));	/* g x */
	    DROP(3);
	    SET(TOP, a+0, a+1);	/* f x (g x) */
	}
	else if (TOP == COMB_K && APPLICABLE(2))
	{ /* K x y -> I x */
	    Cell x = ARG(1);
	    DROP(2);
	    SET(TOP, COMB_I, x);
	    TOP = cdr(TOP);	/* shortcut reduction of I */
	}
	else if (TOP == COMB_B && APPLICABLE(3))
	{ /* B f g x -> f (g x) */
	    Cell f, gx;
	    gx = pair(ARG(2), ARG(3));
	    f = ARG(1);
	    DROP(3);
	    SET(TOP, f, gx);
	}
	else if (TOP == COMB_C && APPLICABLE(3))
	{ /* C f g x -> f x g */
	    Cell fx, g;
	    fx = pair(ARG(1), ARG(3));
	    g = ARG(2);
	    DROP(3);
	    SET(TOP, fx, g);
	}
	else if (TOP == COMB_SP && APPLICABLE(4))
	{ /* SP c f g x -> c (f x) (g x) */
	    Cell a = alloc(3);
	    SET(a+0, ARG(2), ARG(4));	/* f x */
	    SET(a+1, ARG(3), ARG(4));	/* g x */
	    SET(a+2, ARG(1), a+0);	/* c (f x) */
	    DROP(4);
	    SET(TOP, a+2, a+1);		/* c (f x) (g x) */
	}
	else if (TOP == COMB_BS && APPLICABLE(4))
	{ /* BS c f g x -> c (f (g x)) */
	    Cell a, c;
	    a = alloc(2);
	    SET(a+0, ARG(3), ARG(4));	/* g x */
	    SET(a+1, ARG(2), a+0);	/* f (g x) */
	    c = ARG(1);
	    DROP(4);
	    SET(TOP, c, a+1);		/* c (f (g x)) */
	}
	else if (TOP == COMB_CP && APPLICABLE(4))
	{ /* BS c f g x -> c (f x) g */
	    Cell a, g;
	    a = alloc(2);
	    SET(a+0, ARG(2), ARG(4));	/* f x */
	    SET(a+1, ARG(1), a+0);	/* c (f x) */
	    g = ARG(3);
	    DROP(4);
	    SET(TOP, a+1, g);		/* c (f x) g */
	}
	else if (TOP == COMB_IOTA && APPLICABLE(1))
	{ /* IOTA x -> x S K */
	    Cell xs = pair(ARG(1), COMB_S);
	    POP;
	    SET(TOP, xs, COMB_K);
	}
	else if (TOP == COMB_KI && APPLICABLE(2))
	{ /* KI x y -> I y */
	    DROP(2);
	    car(TOP) = COMB_I;
	}
	else if (TOP == COMB_CONS && APPLICABLE(3))
	{ /* CONS x y f -> f x y */
	    Cell fx, y;
	    fx = pair(ARG(3), ARG(1));
	    y = ARG(2);
	    DROP(3);
	    SET(TOP, fx, y);
	}
	else if (TOP == COMB_READ && APPLICABLE(2))
	{ /* READ NIL f -> CONS CHAR(c) (READ NIL) f
	                -> I KI f */
	    int c = read_char();
	    if (c == EOF) {
		POP;
		SET(TOP, COMB_I, COMB_KI);
	    }
	    else {
		Cell a = alloc(2);
		SET(a+0, COMB_CONS, mkchar(c == EOF ? 256 : c));
		SET(a+1, COMB_READ, NIL);
		POP;
		SET(TOP, a+0, a+1);
	    }
	}
	else if (TOP == COMB_WRITE && APPLICABLE(1))
	{ /* WRITE x -> x PUTC RETURN */
	    POP;
	    Cell a = pair(cdr(TOP), COMB_PUTC);	/* x PUTC */
	    SET(TOP, a, COMB_RETURN);		/* x PUTC RETURN */
	}
	else if (TOP == COMB_PUTC && APPLICABLE(3))
	{ /* PUTC x y i -> putc(eval(x INC NUM(0))); WRITE y */
	    Cell a = alloc(2);
	    SET(a+0, ARG(1), COMB_INC);	/* x INC */
	    SET(a+1, a+0, mkint(0));	/* x INC NUM(0) */
	    DROP(2);
	    eval(a+1);

	    if (!isint(TOP))
		errexit("invalid output format (result was not a number)\n");
	    if (intof(TOP) >= 256)
		errexit("invalid character %d\n", intof(TOP));

	    putchar(intof(TOP));
	    POP;

	    ARG(1) = cdr(TOP);	/* y */
	    POP;
	    car(TOP) = COMB_WRITE;	/* WRITE y */
	}
	else if (TOP == COMB_RETURN)
	    return;
	else if (TOP == COMB_INC && APPLICABLE(1))
	{ /* INC x -> eval(x)+1 */
	    Cell c = ARG(1);
	    POP;
	    eval(c);

	    c = POP;
	    if (!isint(c))
		errexit("invalid output format (attempted to apply inc to a non-number)\n");
	    SET(TOP, COMB_I, mkint(intof(c) + 1));
	}
	else if (ischar(TOP) && APPLICABLE(2)) {
	    int c = charof(TOP);
	    if (c <= 0) {  /* CHAR(0) f z -> z */
		Cell z = ARG(2);
		DROP(2);
		SET(TOP, COMB_I, z);
	    }
	    else {       /* CHAR(n+1) f z -> f (CHAR(n) f z) */
		Cell a = alloc(2);
		Cell f = ARG(1);
		SET(a+0, mkchar(c-1), f);	/* CHAR(n) f */
		SET(a+1, a+0, ARG(2));		/* CHAR(n) f z */
		DROP(2);
		SET(TOP, f, a+1);		/* f (CHAR(n) f z) */
	    }
	}
	else if (isint(TOP) && APPLICABLE(1))
	    errexit("invalid output format (attempted to apply a number)\n");
	else
	    return;
	reductions++;
    }
}
Пример #8
0
Cell unabstract(Cell t)
{
    if (isint(t)) {
	if (t == mkint(0))
	    return COMB_I;
	else
	    return pair(COMB_K, mkint(intof(t)-1));
    }
    else if (ispair(t)) {
	Cell f, g;
	PUSH(cdr(t));
	PUSH(unabstract(car(t)));
	g = PUSHED(1) = unabstract(PUSHED(1));
	f = TOP;
	if (IS_K1(f)) {
	    if (g == COMB_I) {
		/* S (K x) I => x */
		f = cdr(f);
	    }
	    else if (IS_K1(g)) {
		/* S (K x) (K y) => K (x y) */
		car(g) = cdr(f);	/* x y */
		cdr(f) = g;		/* K (x y) */
	    }
	    else if (IS_B2(g)) {
		/* S (K x) (B y z) => B* x y z */
		car(f) = COMB_BS;	/* B* x */
		car(car(g)) = f;	/* B* x y z */
		f = g;
	    }
	    else {
		/* S (K x) y => B x y */
		car(f) = COMB_B;	/* B x */
		f = pair(f, g);		/* B x y */
	    }
	}
	else if (IS_K1(g)) {
	    if (IS_B2(f)) {
		/* S (B x y) (K z) => C' x y z */
		car(car(f)) = COMB_CP;
		car(g) = f;
		f = g;
	    }
	    else {
		/* S x (K y) => C x y */
		f = cdr(g);
		SET(g, COMB_C, TOP);	/* C x */
		f = pair(g, f);		/* C x y */
	    }
	}
	else if (IS_B2(f)) {
	    /* S (B x y) z => S' x y z */
	    car(car(f)) = COMB_SP;	/* S' x y */
	    f = pair(f, g);		/* S' x y z */
	}
	else {
	    /* S x y */
	    f = pair(COMB_S, f);
	    f = pair(f, PUSHED(1));
	}
	DROP(2);
	return f;
    }
    else
	return pair(COMB_K, t);
}
Пример #9
0
Файл: node.c Проект: oridb/mc
Node *
mkintlit(Srcloc loc, uvlong val) {
	return mkexpr(loc, Olit, mkint(loc, val), NULL);
}
Пример #10
0
void Translator::insns_stm(const Stm & stm, vm_assembler & vmasm, LocalEnv * lenv){

    switch(stm.kind){
    case stm_kind_expression:
        this->insns_val(*stm.u.e, vmasm, lenv);
        break;
    case stm_kind_assignment:
        this->insns_val(*stm.u.a->val, vmasm, lenv);
        if (stm.u.a->target->kind == expr_kind_var){
            if (lenv->is_toplevel || lenv->is_global(stm.u.a->target->u.var)){
                vmasm.GSET(vm_operand::name(stm.u.a->target->u.var), stm.pos);
            } else if (lenv != NULL && lenv->exists(stm.u.a->target->u.var)){
                vmasm.LSET(vm_operand::integer(lenv->look_var(stm.u.a->target->u.var)), stm.pos);
            } else if(! lenv->is_toplevel) {
                cerr << "compile error:::" << endl;
                cerr << "   " << stm.pos.filename << ":" << stm.pos.line_no << endl;
            } else {
                vmasm.GSET(vm_operand::name(stm.u.a->target->u.var), stm.pos);
            }
        } else if (stm.u.a->target->kind == expr_kind_subscript){
            Expr & sub = *stm.u.a->target;
            this->insns_push(*(*sub.u.sub)[0], vmasm, lenv);
            this->insns_push(*(*sub.u.sub)[1], vmasm, lenv);
            this->insns_val(*stm.u.a->val, vmasm, lenv);
            vmasm.SETITEM(stm.pos);
        }
        break;
    case stm_kind_del:
        if (stm.u.e->kind == expr_kind_subscript){
            this->insns_push(*(*stm.u.e->u.sub)[0], vmasm, lenv);
            this->insns_val(*(*stm.u.e->u.sub)[1], vmasm, lenv);
            vmasm.DELITEM(stm.pos);
        } else {
            cerr << "not implemented @ " << __FILE__ << ":" << __LINE__ << endl; exit(1);
        }
        break;
    case stm_kind_pass:
        // do nothing
        break;
    case stm_kind_return:
        this->insns_val(*stm.u.e, vmasm, lenv);
        vmasm.RET(stm.pos);
        break;
    case stm_kind_break:
        compile_error("no loop to break", stm.pos);
        break;
    case stm_kind_continue:
        compile_error("no loop to continue", stm.pos);
        break;
    case stm_kind_print:
        this->insns_val(*stm.u.e, vmasm, lenv);
        vmasm.PRINT(stm.pos);
        break;
    case stm_kind_global:
        if (! lenv->is_global(stm.u.g)){
            compile_error("invalid global declare", stm.pos);
        }
        break;
    case stm_kind_if:
    {
        queue<int> goto_endif_queue;

        for(vector<StmIfBranch*>::iterator itr = stm.u.i->begin()
                ; itr != stm.u.i->end(); itr++){
            if( (*itr)->elsep ){
                this->insns_stms((*itr)->s, vmasm, lenv);
            } else {
                this->insns_val(*(*itr)->e, vmasm, lenv);
                int gotoinst = vmasm.insns.size();
                vmasm.GOTOIFNOT(vm_operand::integer(-1), (*itr)->e->pos);
                this->insns_stms((*itr)->s, vmasm, lenv);
                if (itr != stm.u.i->end() - 1){
                    goto_endif_queue.push(vmasm.insns.size());
                    vmasm.GOTO(vm_operand::integer(-1), (*itr)->s.back()->pos);
                }
                vmasm.insns[gotoinst].operand = (void *)vmasm.insns.size();
            }
        }

        while(! goto_endif_queue.empty()){
            vmasm.insns[goto_endif_queue.front()].operand = (void *)vmasm.insns.size();
            goto_endif_queue.pop();
        }
    }
        break;
    case stm_kind_while:
    {
        int start_addr = vmasm.insns.size();
        this->insns_val(*stm.u.w->e, vmasm, lenv);
        int gotoif_addr = vmasm.insns.size();
        vmasm.GOTOIFNOT(vm_operand::integer(-1), stm.pos);
        
        vector<int> break_addrs;
        this->insns_loop_stms(stm.u.w->b, vmasm, start_addr, break_addrs, lenv);
        
        vmasm.GOTO(vm_operand::integer(start_addr), stm.pos);
        
        int endwhile_addr = vmasm.insns.size();
        vmasm.insns[gotoif_addr].operand = (void *)endwhile_addr;
        for(int i = 0;i < (int)break_addrs.size();i++){
            vmasm.insns[break_addrs[i]].operand = (void *)endwhile_addr;
        }
    }
        break;
    case stm_kind_for:
    {
        if (!lenv->is_toplevel && !lenv->exists(stm.u.f->x)){
            compile_error("loop variable '" + *stm.u.f->x + "' is not allocated.", stm.pos);
        }
        if (!lenv->is_toplevel && lenv->loopvar_queue.empty()){
            compile_error("loop local variables are not allocated.", stm.pos);
        }
        
        int loopvar = 0;
        int loopvar_index = 0;
        int loopvar_limit = 0;
        int loopseq = 0;

        // for range-for-loop
        int loopvar_step = 0;

        // 0 ... normal loop
        // 1 ... range(N) loop
        // 2 ... range(N, M) loop
        // 3 ... range(N, M, L) loop
        int loop_type = 0;
        if (stm.u.f->e->kind == expr_kind_call
            && stm.u.f->e->u.call->f->kind == expr_kind_var
            && stm.u.f->e->u.call->f->u.var->compare("range") == 0){
            loop_type = stm.u.f->e->u.call->args.size();
        }

        if (lenv->is_toplevel){
            switch (loop_type){
            case 1:
                loopvar_limit = lenv->current_offset();
                lenv->add_var(); // loop var limit
                vmasm.PUSH(stm.pos);

                loopvar_step = lenv->current_offset();
                lenv->add_var(); // loop var step
                vmasm.PUSH(stm.pos);
                break;
            case 2:
                loopvar_limit = lenv->current_offset();
                lenv->add_var(); // loop var limit
                vmasm.PUSH(stm.pos);

                loopvar_step = lenv->current_offset();
                lenv->add_var(); // loop var step
                vmasm.PUSH(stm.pos);
                break;
            case 3:
                loopvar_limit = lenv->current_offset();
                lenv->add_var(); // loop var limit
                vmasm.PUSH(stm.pos);

                loopvar_step = lenv->current_offset();
                lenv->add_var(); // loop var step
                vmasm.PUSH(stm.pos);
                break;
            default:
                loopvar_index = lenv->current_offset();
                lenv->add_var(); // loop var index
                vmasm.PUSH(stm.pos);

                loopvar_limit = lenv->current_offset();
                lenv->add_var(); // loop var index limit
                vmasm.PUSH(stm.pos);

                loopseq = lenv->current_offset();
                lenv->add_var(); // loop sequence
                vmasm.PUSH(stm.pos);
            }
        } else {
            if (! lenv->is_global(stm.u.f->x)){
                loopvar = lenv->look_var(stm.u.f->x);
            }
            switch (loop_type){
            case 1:
                loopvar_limit = lenv->loopvar_queue.front();
                loopvar_step = lenv->loopvar_queue.front() + 1;
                break;
            case 2:
                loopvar_limit = lenv->loopvar_queue.front();
                loopvar_step = lenv->loopvar_queue.front() + 1;
                break;
            case 3:
                loopvar_limit = lenv->loopvar_queue.front();
                loopvar_step = lenv->loopvar_queue.front() + 1;
                break;
            default:
                loopvar_index = lenv->loopvar_queue.front();
                loopvar_limit = lenv->loopvar_queue.front() + 1;
                loopseq = lenv->loopvar_queue.front() + 2;
            }
            lenv->loopvar_queue.pop();
        }
        
        vector<int> break_addrs;

//         switch (loop_type){
//         case 1:
//             cerr << "not implemented @ " << __FILE__ << ":" << __LINE__ << endl; exit(1);
//             break;
//         case 2:
//             cerr << "not implemented @ " << __FILE__ << ":" << __LINE__ << endl; exit(1);
//             break;
//         case 3:
//             cerr << "not implemented @ " << __FILE__ << ":" << __LINE__ << endl; exit(1);
//             break;
//         default:
//             break;
//         }

        // **** initialize ****
        switch (loop_type){
        case 1:
            vmasm.IMMVAL_NUM(vm_operand::pyval(mkint(0)), stm.pos);
            if (lenv->is_toplevel || lenv->is_global(stm.u.f->x)){
                vmasm.GSET(vm_operand::name(stm.u.f->x), stm.pos);
            } else {
                vmasm.LSET(vm_operand::integer(loopvar), stm.pos);
            }
            this->insns_val(*stm.u.f->e->u.call->args[0], vmasm, lenv);
            vmasm.LSET(vm_operand::integer(loopvar_limit), stm.pos);
            break;
        case 2:
            this->insns_val(*stm.u.f->e->u.call->args[0], vmasm, lenv);
            if (lenv->is_toplevel || lenv->is_global(stm.u.f->x)){
                vmasm.GSET(vm_operand::name(stm.u.f->x), stm.pos);
            } else {
                vmasm.LSET(vm_operand::integer(loopvar), stm.pos);
            }
            this->insns_val(*stm.u.f->e->u.call->args[1], vmasm, lenv);
            vmasm.LSET(vm_operand::integer(loopvar_limit), stm.pos);
            break;
        case 3:
            cerr << "not implemented @ " << __FILE__ << ":" << __LINE__ << endl; exit(1);
            break;
        default:
            vmasm.IMMVAL_NUM(vm_operand::pyval(Py_val::mk_int(0)), stm.pos);
            vmasm.LSET(vm_operand::integer(loopvar_index), stm.pos); // init loopvar index
            this->insns_val(*stm.u.f->e, vmasm, lenv);
            vmasm.LSET(vm_operand::integer(loopseq), stm.pos); // set loop seqence
            vmasm.LEN(stm.pos);
            vmasm.LSET(vm_operand::integer(loopvar_limit), stm.pos); // set loop limit
        }
        // **** initialize ****

        
        if (loop_type == 0){
            vmasm.LREF_PUSH(vm_operand::integer(loopvar_index), stm.pos);
        } else {
            if (lenv->is_toplevel || lenv->is_global(stm.u.f->x)){
                vmasm.GREF_PUSH(vm_operand::name(stm.u.f->x), stm.pos);
            } else {
                vmasm.LREF_PUSH(vm_operand::integer(loopvar), stm.pos);
            }
        }

        int first_addr = vmasm.insns.size(); // skip loopvar increment if firsttime
        vmasm.GOTO(vm_operand::integer(-1), stm.pos);

        
        // **** increment step ****
        int start_addr = vmasm.insns.size();
        switch (loop_type){
        case 1:
            if (lenv->is_toplevel || lenv->is_global(stm.u.f->x)){
                vmasm.GINC(vm_operand::name(stm.u.f->x), stm.pos);
                vmasm.GREF_PUSH(vm_operand::name(stm.u.f->x), stm.pos);
            } else {
                vmasm.LINC(vm_operand::integer(loopvar), stm.pos);
                vmasm.LREF_PUSH(vm_operand::integer(loopvar), stm.pos);
            }
            break;
        case 2:
            if (lenv->is_toplevel || lenv->is_global(stm.u.f->x)){
                vmasm.GINC(vm_operand::name(stm.u.f->x), stm.pos);
                vmasm.GREF_PUSH(vm_operand::name(stm.u.f->x), stm.pos);
            } else {
                vmasm.LINC(vm_operand::integer(loopvar), stm.pos);
                vmasm.LREF_PUSH(vm_operand::integer(loopvar), stm.pos);
            }
            break;
        case 3:
            cerr << "not implemented @ " << __FILE__ << ":" << __LINE__ << endl; exit(1);
            break;
        default:
            vmasm.LINC(vm_operand::integer(loopvar_index), stm.pos);
            vmasm.LREF_PUSH(vm_operand::integer(loopvar_index), stm.pos);

        }
        
        vmasm.insns[first_addr].operand = (void*)vmasm.insns.size();
        // condition check
        vmasm.LREF(vm_operand::integer(loopvar_limit), stm.pos);
        vmasm.NUMLT2(stm.pos);
        // **** increment step ****


            
        // goto end if loopvar_index >= loopvar_limit
        break_addrs.push_back(vmasm.insns.size());
        vmasm.GOTOIFNOT(vm_operand::integer(-1), stm.pos);


            
        // **** load loop sequence ****
        switch (loop_type){
        case 1:
            break;
        case 2:
            break;
        case 3:
            cerr << "not implemented @ " << __FILE__ << ":" << __LINE__ << endl; exit(1);
            break;
        default:
            vmasm.LREF_PUSH(vm_operand::integer(loopseq), stm.pos);
            vmasm.LREF(vm_operand::integer(loopvar_index), stm.pos);
            vmasm.GETITEM(stm.pos);
            if (lenv->is_toplevel || lenv->is_global(stm.u.f->x)){
                vmasm.GSET(vm_operand::name(stm.u.f->x), stm.pos);
            } else {
                vmasm.LSET(vm_operand::integer(loopvar), stm.pos);
            }
        }
        // **** load loop sequence ****

        this->insns_loop_stms(stm.u.f->b, vmasm, start_addr, break_addrs, lenv);
        vmasm.GOTO(vm_operand::integer(start_addr), stm.pos);

        int endfor_addr = vmasm.insns.size();
        for (int i = 0;i < (int)break_addrs.size();i++){
            vmasm.insns[break_addrs[i]].operand = (void*)endfor_addr;
        }

        if (lenv->is_toplevel){
            lenv->pop_var(); // loop var index
            vmasm.POP(stm.pos);

            lenv->pop_var(); // loop var index limit
            vmasm.POP(stm.pos);

            lenv->pop_var(); // loop sequence
            vmasm.POP(stm.pos);
        }
    }
        break;
    case stm_kind_fundef:

        LocalEnv * prev_lenv = lenv;
        lenv = new LocalEnv(stm.u.d->f);

        // register arguments as local variable
        for(vector<symbol_t>::iterator itr = stm.u.d->ps.begin();
            itr != stm.u.d->ps.end(); itr++){
            lenv->add_var(*itr);
        }
        // allocate stack for local vars
        this->scan_defun_local_var(stm.u.d->b, lenv);

        py_val_t self;
        if (prev_lenv->is_toplevel){
            vmasm.GDEFUN(vm_operand::name(stm.u.d->f), stm.pos);
            vmasm.GOTO(vm_operand::integer(-1), stm.pos);
            vmasm.fundef(stm.u.d->f, stm.u.d->ps.size()
                         , lenv->size() - stm.u.d->ps.size(), *genv, stm.pos);
            self = genv->lookup_sym(stm.u.d->f);
        } else {
            vmasm.LDEFUN(
                vm_operand::pyval(
                    self = Py_val::mk_vm_ifun(stm.u.d->f
                                              , stm.u.d->ps.size()
                                              , lenv->size() - stm.u.d->ps.size()
                                              , vmasm.insns.size() + 2
                                              , stm.pos))
                , stm.pos);
            vmasm.GOTO(vm_operand::integer(-1), stm.pos);
            prev_lenv->add_var(stm.u.d->f);
        }

        lenv->self = self;
        
        int goto_index = vmasm.label_index - 1;

        for(vector<Stm*>::iterator itr = stm.u.d->b.begin()
                ; itr != stm.u.d->b.end(); itr++){
            this->insns_stm(**itr, vmasm, lenv);
        }
        if (stm.u.d->b.back()->kind != stm_kind_return){
            vmasm.RET(stm.u.d->b.back()->pos);
        }
        vmasm.insns[goto_index].operand = (void*)vmasm.label_index;

        delete(lenv);
        lenv = prev_lenv;
        break;
    }
}
Пример #11
0
static integer *new_rid(rid_manager * ridm, const vector* v, size_t level, bool *done) {
  *done = true;
  integer * i = mkint((int)ridm->d1++);
  return i;
}