Пример #1
0
static void generate_app(struct vec *v,OBJ ast)
{
	OBJ procedure;
	OBJ primitive;
	OBJ cell;
	OBJ formals;

	if(obj_app_type(ast) == 0) /* procedure */
	{
		generate_begin(v,obj_app_params(ast));
		procedure = obj_app_data(ast);
		formals = obj_procedure_formals(procedure);
		while(obj_pairp(formals))
		{
			emit(v,PUSH);
			emitv(v,car(formals));
			emit(v,SET_CDR);
			emit(v,POP);
			formals = cdr(formals);
		}
		if(!nullp(formals))
		{
			emit(v,PUSH);
			emitv(v,formals);
			/* fixme: something should do to support other form formals */
		}
		emit(v,PUSH);
		emitv(v,procedure);
		emit(v,obj_app_tail(ast)?TAIL_CALL:CALL);
	}
	else if(obj_app_type(ast) == 1) /* primitive */
	{
		generate_begin(v,obj_app_params(ast));
		primitive = obj_app_data(ast);
		switch(obj_primitive_type(primitive))
		{
		case DATA:
			emit(v,obj_primitive_opcode(primitive));
			emitv(v,obj_primitive_data(primitive));
			break;
		case FUNCALL:
			emit(v,obj_primitive_opcode(primitive));
			emitv(v,obj_primitive_proc(primitive));
			break;
		default:
			emit(v,obj_primitive_opcode(primitive));
		}
	}
	else if(obj_app_type(ast) == 2) /* uninitialized procedure */
	{
		cell = obj_app_data(ast);
		generate_begin(v,obj_app_params(ast));
		emit(v,PUSH);
		emitv(v,cell);
		emit(v,UNINIT_REF);
		emit(v,BIND);
		emit(v,obj_app_tail(ast)?TAIL_CALL:CALL);
	}
}
Пример #2
0
static void generate_lambda(struct vec *v,OBJ ast)
{
	struct vec vec;
	OBJ procedure;
	unsigned length;
	OBJ code;

	vec.begin = malloc(100);
	vec.end = vec.begin + 100;
	vec.cur = vec.begin;

	generate_r(&vec,obj_lambda_body(ast));
	emit(&vec,RET);
	length = vec.cur - vec.begin;
	code = obj_make_string_2(length);
	memcpy(obj_string_data(code),vec.begin,length);
	free(vec.begin);

	procedure = obj_make_procedure(obj_lambda_env(ast),code,obj_lambda_formals(ast));

	emit(v,PUSH);
	emitv(v,procedure);
}
Пример #3
0
static char* declare_label(struct vec *v)
{
	char *ret = v->cur;
	emitv(v,0);
	return ret;
}
Пример #4
0
void genobj( void )
{
    short int *symbol, *target;
    short int *p, *q, *r;
    short int action;
    set_size *mp;
    a_sym *sym;
    a_pro *pro;
    an_item *item;
    a_state *x;
    a_shift_action *tx;
    a_reduce_action *rx;
    int i, j, savings;

    for( i = nterm; i < nsym; ++i )
        symtab[i]->token = i - nterm;

    label = OPTENTRY( nstate - 1 );

    emitins( JMP, TOKENTRY( startstate->sidx ) );

    target = CALLOC( nsym, short int );
    for( i = 0; i < nsym; ++i )
        target[i] = DEFAULT;
    symbol = CALLOC( nsym, short int );
    for( i = 0; i < nstate; ++i ) {
        x = statetab[i];
        q = symbol;
        for( tx = x->trans; (sym = tx->sym) != NULL; ++tx ) {
            if( sym == eofsym ) {
                action = ACCEPT;
            } else if( sym->idx < nterm ) {
                action = TOKENTRY(tx->state->sidx);
            } else {
                action = OPTENTRY(tx->state->sidx);
            }
            *q++ = sym->idx;
            target[sym->idx] = action;
        }
        savings = 0;
        for( rx = x->redun; (pro = rx->pro) != NULL; ++rx ) {
            action = PROENTRY( pro->pidx );
            mp = Members( rx->follow );
            if( mp - setmembers > savings ) {
                savings = mp - setmembers;
                r = q;
            }
            while( --mp >= setmembers ) {
                *q++ = *mp;
                target[*mp] = action;
            }
        }
        action = DEFAULT;
        if( savings ) {
            action = target[*r];
            p = r;
            while( --savings >= 0 ) {
                target[*p++] = DEFAULT;
            }
        }

        emitins( LBL, TOKENTRY( x->sidx ) );
        emitins( SCAN, 0 );
        emitins( LBL, OPTENTRY( x->sidx ) );
        emitins( CALL, VBLENTRY( x->sidx ) );
        q = symbol;
        for( j = nterm; j < nsym; ++j ) {
            if( target[j] != DEFAULT ) {
                *q++ = j;
            }
        }
        if( q != symbol ) {
            emitv( symbol, target, q - symbol );
            for( p = symbol; p < q; ++p ) {
                target[*p] = DEFAULT;
            }
        }
        emitins( LBL, VBLENTRY( x->sidx ) );

        q = symbol;
        for( j = 0; j < nterm; ++j ) {
            if( target[j] != DEFAULT ) {
                *q++ = j;
            }
        }
        emitt( symbol, target, q - symbol, action );
        for( p = symbol; p < q; ++p ) {
            target[*p] = DEFAULT;
        }
    }

    FREE( target );
    FREE( symbol );

    for( i = 0; i < npro; ++i ) {
        pro = protab[i];
        if( pro != startpro ) {
            for( item = pro->item; item->p.sym != NULL; ) {
                ++item;
            }
            emitins( LBL, PROENTRY( pro->pidx ) );
            emitins( ACTION, PROPACK( item - pro->item, i ) );
            emitins( REDUCE, PROPACK( item - pro->item, pro->sym->token ) );
        }
    }

    writeobj( label + 1 );
}