📄 oper.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 + -