⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prmt4.c

📁 Unix下的MUD客户端程序
💻 C
字号:
/* prmt4.c: Primitive functions: functions, misc, files */#include "vt.h"#include "prmt.h"#ifdef PROTOTYPESstatic Prog *prog_pcall(int, int);#endifextern String ptext;extern Dframe *dstack, frame_error, suspend_frame;extern dpos, dsize;extern Unode rmt_ring, win_ring, key_ring, file_ring;extern Array *gvars;extern Estate *events;extern int loading;static Unode *dummies[] = { &rmt_ring, &win_ring, &key_ring, &file_ring };#define ringdummy(t) (dummies[(t) - F_RMT])static Dframe *ftemp = NULL;static int tempsize = 0;/* Generates a temporary program to run a primitive */static Prog *prog_pcall(pnum, argc)	int pnum, argc;{	Prog *new;	new = New(Prog);	new->code = Newarray(Instr, 3);	new->code[0].type = I_PCALL;	new->code[1].pc.pnum = pnum;	new->code[1].pc.argc = argc;	new->code[2].type = I_STOP;	new->refs = 1;	new->avarc = new->reqargs = 0;	new->lvarc = 0;	return new;}/* Function primitives */PDECL(pr_find_func){	Func *func;				    	Tcheck1(F_SPTR);	func = find_func(Soastr(Dp));	if (!func || !func->cmd)		return;	Dset_elem(*rf, F_FPTR, Dfunc, func);}PDECL(pr_find_prmt){	int pnum;	Tcheck1(F_SPTR);	pnum = find_prmt(Soastr(Dp));	if (pnum == -1)		return;	Dset_elem(*rf, F_FPTR, Dpnum, pnum);}PDECL(pr_func_name){	Tcheck1(F_FPTR);	Dset_sptr(*rf, istr_s(Dp.Dfunc->name), 0);}PDECL(pr_callv){	int fargc = 0, copy, i;	Dframe *df, arg0;	Tcheckgen(argv->type != F_FPTR && argv->type != F_PPTR);	arg0 = argv[0];	for (i = 1; i < argc;) {		df = &argv[i];		Tcheckgen(df->type != F_INT || i == argc - 1			  || df->Dval >= 0 && df[1].type != F_APTR			  || df->Dval < 0 && argc - i - 1 < -df->Dval);		fargc += (df->Dval < 0) ? -df->Dval : df->Dval;		i += (df->Dval < 0) ? -df->Dval + 1 : 2;	}	if (fargc) {		if (tempsize < fargc) {			ftemp = tempsize ? Rearray(ftemp, Dframe, tempsize,				fargc) : Newarray(Dframe, fargc);			tempsize = fargc;		}		for (df = ftemp, i = 1; i < argc;) {			if (argv[i].Dval < 0) {				Copy(&argv[i + 1], df, -argv[i].Dval, Dframe);				df += -argv[i].Dval;				i += -argv[i].Dval + 1;				continue;			}			copy = min(argv[i].Dval,				   argv[i + 1].Asize - argv[i + 1].Dapos);			copy = max(copy, 0);			if (copy)				Copy(&Aelem(argv[i + 1]), df, copy, Dframe);			df += copy;			while (copy++ < argv[i].Dval)				df++->type = F_NULL;			i += 2;		}		ref_frames(fargc, ftemp);		deref_frames(argc, argv);		dpos -= argc;		while (dpos + fargc > dsize)			double_dstack();		Copy(ftemp, &dstack[dpos], fargc, Dframe);		move_frames_refs(fargc, ftemp, &dstack[dpos]);		dpos += fargc;	} else {		deref_frames(argc, argv);		dpos -= argc;	}	if (arg0.type == F_FPTR) {		if (fargc < arg0.Dfunc->cmd->reqargs)			Prmterror(("Not enough arguments to function %s",				  arg0.Dfunc->name));		cpush(arg0.Dfunc->cmd, fargc, 1, 0);	} else		cpush(prog_pcall(arg0.Dpnum, fargc), 0, 1, fargc);	Dset_elem(*rf, F_EXCEPT, Dval, INTERP_NOFREE);}PDECL(pr_detach){	Tcheckgen(T1 != F_FPTR && T1 != F_PPTR);	if (T1 == F_FPTR) {		if (argc <= Dp1.Dfunc->cmd->reqargs)			Prmterror(("Not enough arguments to function %s",				  Dp1.Dfunc->name));		cpush(Dp1.Dfunc->cmd, argc - 1, 0, 0);	} else		cpush(prog_pcall(Dp1.Dpnum, argc - 1), 0, 0, argc - 1);	interp();	deref_frame(&dstack[dpos - 1]);	dstack[dpos - 1].type = F_NULL;	Dset_elem(*rf, F_EXCEPT, Dval, INTERP_NOFREE);}PDECL(pr_abort){	*rf = frame_error;}/* Array primitives */PDECL(pr_alloc){	Tcheckgen(argc < 1 || argc > 2 || T1 != F_INT		  || argc == 2 && T2 != F_ASSOC);	Int1 = max(Int, 1);	if (argc == 1) {		Dset_aptr(*rf, add_array(Int1, dfalloc(Int1), 0, 0, 0), 0);		rf->Darray->r.refs = 0;		return;	}	Dset_elem(*rf, F_PLIST, Dplist, New(Plist));	rf->Dplist->assoc = Dp2.Dassoc;	rf->Dplist->array = add_array(Int1, dfalloc(Int1), 0, 0, 1);	rf->Dplist->array->r.plist = rf->Dplist;	rf->Dplist->refs = 0;}PDECL(pr_new_assoc){	Dset_elem(*rf, F_ASSOC, Dassoc, New(int));	*rf->Dassoc = 0;}PDECL(pr_lookup){	Plist *p = NULL;	if (T1 == F_ASSOC) {		Dset_int(*rf, lookup(Dp1.Dassoc, Soastr(Dp2)));		return;	}	if (T1 == F_PLIST)		p = Dp1.Dplist;	else if (T1 == F_WIN && Un1->Wobj && Un1->Wobj->type == F_PLIST)		p = Un1->Wobj->Dplist;	else if (T1 == F_RMT && Un1->Robj && Un1->Robj->type == F_PLIST)		p = Un1->Robj->Dplist;	Tcheckgen(!p || T2 != F_SPTR);	Dset_aptr(*rf, p->array, lookup(p->assoc, Soastr(Dp2)));}PDECL(pr_acopy){	int copy, i;	Tcheck3(F_APTR, F_APTR, F_INT);	if (Int3 <= 0)		return;	if (Int3 > Dp1.Asize - Dp1.Dapos) {		if (Dp1.Darray->fixed)			Int3 = Dp1.Asize - Dp1.Dapos;		else			extend_array(Dp1.Darray, Dp1.Dapos + Int3);	}	if (tempsize < Int3) {		ftemp = tempsize ? Rearray(ftemp, Dframe, tempsize, Int3)				 : Newarray(Dframe, Int3);		tempsize = Int3;	}	copy = min(Int3, Dp2.Asize - Dp2.Dapos);	copy = max(copy, 0);	if (copy)		Copy(&Aelem(Dp2), ftemp, copy, Dframe);	for (i = copy; i < Int3; i++)		ftemp[i].type = F_NULL;	ref_frames(Int3, ftemp);	deref_frames(Int3, &Aelem(Dp1));	Copy(ftemp, &Aelem(Dp1), Int3, Dframe);	move_frames_refs(Int3, ftemp, &Aelem(Dp1));}PDECL(pr_base){	if (T == F_PLIST) {		Dset_aptr(*rf, Dp.Dplist->array, 0);		return;	}	Tcheckgen(T != F_APTR && T != F_SPTR);	*rf = Dp;	*((T == F_APTR) ? &rf->Dapos : &rf->Dspos) = 0;}PDECL(pr_garbage){	rf->type = F_INT;	rf->Dval = garbage();}/* Miscellaneous primitives */PDECL(pr_parse){	Tcheck1(F_SPTR);	parse(Soastr(Dp));}PDECL(pr_head){	Tcheckgen(T != F_INT || Int < F_RMT || Int > F_FILE);	if (!ringdummy(Int)->next->dummy)		Dset_elem(*rf, Int, Dunode, ringdummy(Int)->next);}PDECL(pr_tail){	Tcheckgen(T != F_INT || Int < F_RMT || Int > F_FILE);	if (!ringdummy(Int)->prev->dummy)		Dset_elem(*rf, Int, Dunode, ringdummy(Int)->prev);}PDECL(pr_next){	Tcheckgen(T < F_RMT || T > F_FILE);	if (!Un->next->dummy)		Dset_elem(*rf, Dp.type, Dunode, Un->next);}PDECL(pr_prev){	Tcheckgen(T < F_RMT || T > F_FILE);	if (!Un->prev->dummy)		Dset_elem(*rf, Dp.type, Dunode, Un->prev);}PDECL(pr_type){	Dset_int(*rf, Dp.type);}PDECL(pr_find_var){	Tcheck1(F_SPTR);	Dset_aptr(*rf, gvars, get_vindex(Soastr(Dp)));}PDECL(pr_sleep){	Estate *image, **e;	Tcheck1(F_INT);	image = suspend(1);	image->timer = time((long *) NULL) + Int;	for (e = &events; *e && (*e)->timer <= image->timer; e = &(*e)->next);	image->next = *e;	*e = image;	*rf = suspend_frame;}PDECL(pr_quit){	cleanup();	exit(0);}PDECL(pr_rndseed){	Tcheck1(F_INT);	srand(Int);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -