用户函数自动共享全局output数组功能

y_tab解释程序中,虽然有了用户自定义函数的功能,能够按照值传递规则传递参数,但是仍然不能传递引用。传递引用比较复杂,并且最终会在细粒度上对变量引用的解释产生影响。y_tab不打算实现这个功能。但是可以增加一个全局的,名字叫output的特殊数组,让每个用户自定义函数自动拥有这个数组,从而获得函数之间共享全局数据的功能。

这只要在初始化时,在全局和局部符号表中插入一个名叫output的数组,并且从不清除它。

struct abpvector {
        VALUE_TYPE *vector;
        VALUE_TYPE **abp;
} output;
...
void init_whatever()
{
        int i;
        int k;

        for(k=0; k<2; k++) {
                memset(&symtab_compile[k],0,sizeof(struct symtab));
                memset(&funxat_compile[k],0,sizeof(struct funxat));
                for(i=0; i<MAXARRAY; i++) {
                        symtab_compile[k].avartab[i] =
                                symtab_compile[k].array[i];
                }

                strcpy(symtab_compile[k].arraytab[0].name,"output");
                symtab_compile[k].arraycount=1;
                funxat_compile[k].avars=1;

                symtab_compile[k].used_const0=0;
                funxat_compile[k].strtab = symtab_compile[k].strtab;
                funxat_compile[k].consttab = symtab_compile[k].consttab;
                funxat_compile[k].labeltab = symtab_compile[k].gototab;
                funxat_compile[k].consttab[0].type = 0;
                funxat_compile[k].consttab[0].u.value = 1;
                funxat_compile[k].constcount = 1;
                funxat_compile[k].labelcount = 0;
        }
        tmpnamecount=0;
        dmc=0;
        top=0;
        swc= -1;
        funxvt_main = &stk->e[0];
        funxvt_main->func = &funxat_compile[0];
        funxvt_main->bp = symtab_compile[0].var;
        funxvt_main->abp = symtab_compile[0].avartab;

        output.vector = funxvt_main->abp[0];
        output.abp = &output.vector;
}

上面,strcpy()的这几句,在符号表中增加"output"符号,最后output的2句,给这个数组分配固定空间。

此外,还要在调用用户自定义函数分配空间时,及用户自定义函数返回回收分配空间时,跳过这个output数组。

void alloc_context(struct funxat *f)
{
        struct funxvt *context;
        struct segment *seg;
        int i;

        ++top;
        if (top >= SEGLEN) {
                seg = (struct segment *)Malloc(sizeof(struct segment));
                seg->wrap = stk;
                stk = seg;
                top =0;
        }
        context = &stk->e[top];
        context->func = f;
        if (f->vars) {
                context->bp = (VALUE_TYPE *)Malloc(sizeof(VALUE_TYPE)*f->vars);
                memset(context->bp,0, sizeof(VALUE_TYPE)*f->vars);
                //........ .......... .... ............... ..
        }
        else context->bp = NULL;
        if (f->avars>1) {
                context->abp = (VALUE_TYPE**)Malloc(
                        sizeof(VALUE_TYPE*) * f->avars);
                context->abp[0] = output.vector;
                for(i=1; i<f->avars; i++) {
                        context->abp[i] =
                        (VALUE_TYPE *)Malloc(sizeof(VALUE_TYPE)*MAXCELL);
                        memset(context->abp[i],0,sizeof(VALUE_TYPE)*MAXCELL);
                }
        }
        else context->abp = output.abp;
}
void free_context()
{
        struct funxvt *context;
        struct funxat *f;
        struct segment *seg;
        int i,j;

        if (top == 0 && stk->wrap==NULL) {
                printf("runtime stack corrupt!\n");
                return;
        }
        context = &stk->e[top];
        f = context->func;
//............. .... ....... .. ......... .........
        if (context->bp) {
                for(i=0; i<f->vars; i++) context->bp[i]=dummy_value;
                free(context->bp);
                context->bp =NULL;
        }
        if (f->avars>1) {
                for(i=1; i<f->avars; i++) {
                        for(j=0; j<MAXCELL; j++) context->abp[i][j]=dummy_value;
                        free(context->abp[i]);
                }
                free(context->abp);
                context->abp= NULL;
        }
        else context->abp= NULL;

        --top;
        if (top <0) {
                seg = stk->wrap;
                free(stk);
                stk=seg;
                top = SEGLEN-1;
        }
}

当然,在清理符号表时,也跳过这个符号。

ss:
        | ss ls   { int exception=0;
                        execute_e_ls((struct node*)$2, 0, &exception);
                        free_compile(&funxat_compile[dmc]); }
        | ss error {error_state=1;} '\n' {
                        if (dmc == DM_FOR_LOCAL) {
                                free_compile(&funxat_compile[dmc]);
                                symtab_compile[dmc].varcount=0;
                                symtab_compile[dmc].arraycount=1;
                                symtab_compile[dmc].used_const0=0;
                                funxat_compile[dmc].avars=1;
                                while(swc>=0) popswitch();
                                dmc = DM_FOR_GLOBAL;
                        }
                        free_compile(&funxat_compile[dmc]);
                        error_state = 0;
                        }
        | ss defs       {
                                free_compile(&funxat_compile[dmc]);
                                symtab_compile[dmc].varcount=0;
                                symtab_compile[dmc].arraycount=1;
                                symtab_compile[dmc].used_const0=0;
                               	funxat_compile[dmc].avars=1;
                             	dmc = DM_FOR_GLOBAL;
                        }
;

现在编译,运行,来试一试快速排序例子:

output[] = {17,13,31, 18, 19, 112, 14, 125, 11,111,
        7,3,1, 8, 9, 12, 4, 25, 1,21};

func patition(left, right)
{
        key = left;
        while (left < right)
        {
                while (left < right && output[right] >= output[key])
                        right--;
                while (left < right && output[left] <= output[key])
                        left++;
                x=output[right];
                output[right]=output[left];
                output[left]=x;
        }
        mid = left;
        x=output[mid];
        output[mid]=output[key];
        output[key]=x;
        return mid;
}

func QuickSort(left, right)
{
        mid = patition(left,right);
        if (left < mid - 1) QuickSort(left, mid-1);
        if (mid + 1 < right) QuickSort(mid+1, right);
}

for(i=0; output[i]; i++);
n=i;
QuickSort(0, n-1);
i=0;
while(i<n) print output[i++], "\b";
print "END";


这里在全局,patition()函数,QuickSort()函数之间共享了output[]数组的数据。

运行结果:

saving patition...used func[0].
saving QuickSort...used func[1].
1 1 3 4 7 8 9 11 12 13 14 17 18 19 21 25 31 111 112 125 END

再跑个斐波拉挈查找看看:

func fibfind(k, n)
{
	prev=1;
	fn= 1;
	while(fn <n) {
		fn+=prev;
		prev= fn-prev;
	}
part_nonfib:
	if (p==n) return -1;
	while (fn>n-p) {
		prev=fn-prev;
		fn-=prev;

	}
	p+=fn-1;


	if(output[p]==k) return p;
	if(output[p++] <k) goto part_nonfib;

	p-=fn;

	while (fn>1) {

		prev= fn-prev;
		fn-=prev;
		p+=fn-1;
		if (output[p]==k) return p;
		if (output[p++]>k) {
			p-=fn;
		}
	}
	if (output[p]==k) return p;
	return -1;
}	

运行结果:

saving fibfind...used func[2].
n=20;
k=17;
print fibfind(k, n);
11
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值