加入自定义函数共享output数组功能

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

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

c 复制代码
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数组。

c 复制代码
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;
}
c 复制代码
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;
        }
}

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

c 复制代码
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;
                                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;
                                dmc = DM_FOR_GLOBAL;
                        }
;

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

c 复制代码
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[]数组的数据。

运行结果:

clike 复制代码
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

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

c 复制代码
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;
}	

运行结果:

clike 复制代码
saving fibfind...used func[2].
n=20;
k=17;
print fibfind(k, n);
11
相关推荐
盼海2 小时前
排序算法(五)--归并排序
数据结构·算法·排序算法
搬砖的小码农_Sky8 小时前
C语言:数组
c语言·数据结构
先鱼鲨生9 小时前
数据结构——栈、队列
数据结构
一念之坤9 小时前
零基础学Python之数据结构 -- 01篇
数据结构·python
IT 青年10 小时前
数据结构 (1)基本概念和术语
数据结构·算法
熬夜学编程的小王10 小时前
【初阶数据结构篇】双向链表的实现(赋源码)
数据结构·c++·链表·双向链表
liujjjiyun10 小时前
小R的随机播放顺序
数据结构·c++·算法
Reese_Cool12 小时前
【数据结构与算法】排序
java·c语言·开发语言·数据结构·c++·算法·排序算法
djk888812 小时前
.net将List<实体1>的数据转到List<实体2>
数据结构·list·.net
搬砖的小码农_Sky13 小时前
C语言:结构体
c语言·数据结构