• 加入自定义函数共享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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    上面,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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    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;
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

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

    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;
                            }
    ;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

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

    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";
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    这里在全局,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
    
    • 1
    • 2
    • 3

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

    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;
    }	
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    运行结果:

    saving fibfind...used func[2].
    n=20;
    k=17;
    print fibfind(k, n);
    11
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    多人访问同一个springboot项目会不会出现并发问题
    Python学习:元组教程
    唯众实训授课助手 实训课堂好帮手
    算法——多数相和
    开源服务器大整理
    十二条后端开发经验分享,纯干货
    JS高级(数据类型,数据_变量_内存)
    在云时代,我们该如何看待新的开源许可证?
    信息系统项目管理教程(第4版):第二章 信息技术及其发展
    「Python编程基础」第2章:小试牛刀
  • 原文地址:https://blog.csdn.net/aaasssdddd96/article/details/133513802