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

📄 oper.c

📁 使用BorlandC++4.5编译的一个MUD客户端程序
💻 C
字号:
head	2.1;access;symbols;locks; strict;comment	@ * @;2.1date	95.10.24.15.46.14;	author tsurace;	state Release;branches;next	1.1;1.1date	95.10.12.19.30.13;	author tsurace;	state Beta;branches;next	;desc@Operator functions.@2.1log@Roll.@text@/* oper.c: Operator functions */
/* $Id: oper.c 1.1 1995/10/12 19:30:13 tsurace Beta tsurace $ */

#include "vt.h"
#include "prmt.h"

#ifdef PROTOTYPES
static int df_eq(Dframe *, Dframe *);
static int df_lt(Dframe *, Dframe *);
static int df_gt(Dframe *, Dframe *);
static void add_data_int(Dframe *, Dframe *, long);
static int incr_data(Dframe *, Dframe *);
static int decr_data(Dframe *, Dframe *);
static void postmod(Dframe *, int, Dframe *, int (*)(), int);
static void premod(Dframe *, int, Dframe *, int (*)(), int);
static void selem_asn(String *, int, int);
#else
static void selem_asn(), postmod(), premod();
#endif

extern Dframe frame_error;

/* Some specialized data routines used by the operators */

static int df_eq(df1, df2)
	Dframe *df1, *df2;
{
	if (df1->type != df2->type)
		return 0;
	switch (df1->type) {
	    case F_INT:
		return df1->Dval == df2->Dval;
	    case F_BPTR:
		return df1->Dbobj == df2->Dbobj;
	    case F_PPTR:
		return df1->Dpnum == df2->Dpnum;
	    case F_RMT:
	    case F_WIN:
	    case F_KEY:
	    case F_FILE:
		return df1->Dunode == df2->Dunode;
	    case F_SPTR:
		return df1->Distr == df2->Distr && df1->Dspos == df2->Dspos;
	    case F_APTR:
		return df1->Darray == df2->Darray && df1->Dapos == df2->Dapos;
	    case F_FPTR:
		return df1->Dfunc == df2->Dfunc;
	    case F_REG:
		return df1->Dreg == df2->Dreg;
	    case F_ASSOC:
		return df1->Dassoc == df2->Dassoc;
	    case F_PLIST:
		return df1->Dplist == df2->Dplist;
	    default:
		return 1;
	}
}

static int df_lt(df1, df2)
	Dframe *df1, *df2;
{
	if (df1->type != df2->type)
		return -1;
	switch (df1->type) {
	    case F_INT:
		return df1->Dval < df2->Dval;
	    case F_APTR:
		return df1->Darray == df2->Darray ?
		       df1->Dapos < df2->Dapos : -1;
	    case F_SPTR:
		return df1->Distr == df2->Distr ?
		       df1->Dspos < df2->Dspos : -1;
	    default:
		return -1;
	}
}

static int df_gt(df1, df2)
	Dframe *df1, *df2;
{
	if (df1->type != df2->type)
		return -1;
	switch (df1->type) {
	    case F_INT:
		return df1->Dval > df2->Dval;
	    case F_APTR:
		return (df1->Darray == df2->Darray) ?
		 df1->Dapos > df2->Dapos : -1;
	    case F_SPTR:
		return (df1->Distr == df2->Distr) ?
		 df1->Dspos > df2->Dspos : -1;
	    default:
		return -1;
	}
}

static void add_data_int(rf, df, num)
	Dframe *rf, *df;
	long num;
{
	rf->type = df->type;
	switch (df->type) {
	    case F_INT:
		rf->Dval = df->Dval + num;
	    Case F_SPTR:
		rf->Distr = df->Distr;
		rf->Dspos = df->Dspos + num;
	    Case F_APTR:
		rf->Darray = df->Darray;
		rf->Dapos = df->Dapos + num;
	    Default:
		*rf = frame_error;
	}
}

static int incr_data(rf, val)
	Dframe *rf, *val;
{
	switch (val->type) {
		case F_INT:	val->Dval++;		return 0;
		case F_APTR:	val->Dapos++;		return 0;
		case F_SPTR:	val->Dspos++;		return 0;
		default:	type_error(rf);		return -1;
	}
}

static int decr_data(rf, val)
	Dframe *rf, *val;
{
	switch (val->type) {
		case F_INT:	val->Dval--;		return 0;
		case F_APTR:	val->Dapos--;		return 0;
		case F_SPTR:	val->Dspos--;		return 0;
		default:	type_error(rf);		return -1;
	}
}

static void postmod(rf, argc, argv, func, addend)
	Dframe *rf, *argv;
	int argc, (*func)(), addend;
{
	Dframe df;

	if (T1 == F_APTR && Ainbounds(Dp1)) {
		*rf = Aelem(Dp1);
		(*func)(rf, &Aelem(Dp1));
	} else if (T1 == F_SPTR) {
		Bcheck(Dp1.Dspos < 0);
		isolate(Dp1.Distr);
		Dset_int(*rf, Soelem(Dp1));
		selem_asn(&Dp1.Sstr, Dp1.Dspos, Soelem(Dp1) + addend);
	} else if (T1 == F_BPTR) {
		(*Dp1.Dbobj)(&df);
		*rf = df;
		if ((*func)(rf, &df) != -1)
			assign_bobj(rf, Dp1.Dbobj, &df);
	} else
		Terror;
}

static void premod(rf, argc, argv, func, addend)
	Dframe *rf, *argv;
	int argc, (*func)(), addend;
{
	if (T1 == F_APTR && Ainbounds(Dp1)) {
		if ((*func)(rf, &Aelem(Dp1)) != -1)
			*rf = Aelem(Dp1);
	} else if (T1 == F_SPTR) {
		Bcheck(Dp1.Dspos < 0);
		isolate(Dp1.Distr);
		selem_asn(&Dp1.Sstr, Dp1.Dspos, Soelem(Dp1) + addend);
		Dset_int(*rf, Soelem(Dp1));
	} else if (T1 == F_BPTR) {
		(*Dp1.Dbobj)(rf);
		if ((*func)(rf, rf) != -1)
			assign_bobj(rf, Dp1.Dbobj, rf);
	} else
		Terror;
}

static void selem_asn(str, pos, val)
	String *str;
	int pos, val;
{
	if (pos >= str->c.l) {
		lcheck(str, pos + 1);
		memset(str->c.s + str->c.l, ' ', pos - str->c.l);
		str->c.s[str->c.l = pos + 1] = '\0';
	}
	if (!val)
		s_term(str, pos);
	else
		str->c.s[pos] = val;
}

/* The operator functions themselves */

PDECL(op_bor)
{
	Tcheck2(F_INT, F_INT);
	Dset_int(*rf, Int1 | Int2);
}

PDECL(op_bxor)
{
	Tcheck2(F_INT, F_INT);
	Dset_int(*rf, Int1 ^ Int2);
}

PDECL(op_band)
{
	Tcheck2(F_INT, F_INT);
	Dset_int(*rf, Int1 & Int2);
}

PDECL(op_eq)
{
	Dset_int(*rf, df_eq(&Dp1, &Dp2));
}

PDECL(op_ne)
{
	Dset_int(*rf, !df_eq(&Dp1, &Dp2));
}

PDECL(op_lt)
{
	int val;

	val = df_lt(&Dp1, &Dp2);
	Tcheckgen(val == -1);
	Dset_int(*rf, val);
}

PDECL(op_le)
{
	int val;

	val = df_gt(&Dp1, &Dp2);
	Tcheckgen(val == -1);
	Dset_int(*rf, !val);
}

PDECL(op_gt)
{
	int val;

	val = df_gt(&Dp1, &Dp2);
	Tcheckgen(val == -1);
	Dset_int(*rf, val);
}

PDECL(op_ge)
{
	int val;

	val = df_lt(&Dp1, &Dp2);
	Tcheckgen(val == -1);
	Dset_int(*rf, !val);
}

PDECL(op_sl)
{
	Tcheck2(F_INT, F_INT);
	Dset_int(*rf, Int1 << Int2);
}

PDECL(op_sr)
{
	Tcheck2(F_INT, F_INT);
	Dset_int(*rf, Int1 >> Int2);
}

PDECL(op_add)
{
	if (T2 == F_INT)
		add_data_int(rf, &Dp1, Int2);
	else if (T1 == F_INT)
		add_data_int(rf, &Dp2, Int1);
	else if (T1 == F_SPTR && T2 == F_SPTR) {
		Dset_sptr(*rf, (Dp1.Srefs == 1) ?
			       Dp1.Distr : istr_rs(Dp1.Srstr), Dp1.Dspos);
		isolate(rf->Distr);
		if (!Sinbounds(*rf))
			rf->Dspos = rf->Slen;
		s_cat(&rf->Sstr, Socstr(Dp2));
	} else
		*rf = frame_error;
	if (rf->type == F_EXCEPT)
		type_errmsg();
}

PDECL(op_sub)
{
	if (T2 == F_INT)
		add_data_int(rf, &Dp1, -Int2);
	else if (T1 == F_APTR && T2 == F_APTR && Dp1.Darray == Dp2.Darray)
		Dset_int(*rf, Dp1.Dapos - Dp2.Dapos);
	else if (T1 == F_SPTR && T2 == F_SPTR && Dp1.Distr == Dp2.Distr)
		Dset_int(*rf, Dp1.Dspos - Dp2.Dspos);
	else
		*rf = frame_error;
	if (rf->type == F_EXCEPT)
		type_errmsg();
}

PDECL(op_mult)
{
	Tcheck2(F_INT, F_INT);
	Dset_int(*rf, Int1 * Int2);
}

PDECL(op_div)
{
	Tcheck2(F_INT, F_INT);
	if (!Int2)
		Prmterror(("Divide-by-zero error"));
	Dset_int(*rf, Int1 / Int2);
}

PDECL(op_mod)
{
	Tcheck2(F_INT, F_INT);
	if (!Int2)
		Prmterror(("Modulo-by-zero error"));
	Dset_int(*rf, Int1 % Int2);
}

PDECL(op_postinc) { postmod(rf, argc, argv, incr_data, 1); }
PDECL(op_postdec) { postmod(rf, argc, argv, decr_data, -1); }
PDECL(op_preinc) { premod(rf, argc, argv, incr_data, 1); }
PDECL(op_predec) { premod(rf, argc, argv, decr_data, -1); }

PDECL(op_not)
{
	Dset_int(*rf, Dffalse(Dp1));
}

PDECL(op_compl)
{
	Tcheck1(F_INT);
	Dset_int(*rf, ~Int1);
}

PDECL(op_neg)
{
	Tcheck1(F_INT);
	Dset_int(*rf, -Int1);
}

PDECL(op_asn)
{
	*rf = Dp2;
	if (T1 == F_APTR) {
		Bcheck(!Awriteok(Dp1));
		extend_array(Dp1.Darray, Dp1.Dapos + 1);
		deref_frame(&Aelem(Dp1));
		Aelem(Dp1) = Dp2;
		ref_frame(&Aelem(Dp1));
	} else if (T1 == F_SPTR && T2 == F_INT) {
		Bcheck(Dp1.Dspos < 0);
		isolate(Dp1.Distr);
		selem_asn(&Dp1.Sstr, Dp1.Dspos, Int2);
	} else if (T1 == F_BPTR)
		assign_bobj(rf, Dp1.Dbobj, &Dp2);
	else
		Terror;
}


@1.1log@Initial revision@text@d2 1a2 1/* $Id$ */@

⌨️ 快捷键说明

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