This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/C/eval.c
2009-02-09 22:21:58 +00:00

156 lines
3.4 KiB
C

/*************************************************************************
* *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
* *
**************************************************************************
* *
* File: eval.c *
* Last rev: *
* mods: *
* comments: arithmetical expression evaluation *
* *
*************************************************************************/
#ifdef SCCS
static char SccsId[] = "%W% %G%";
#endif
/*
* This file implements arithmetic operations
*
*/
#include "Yap.h"
#include "Yatom.h"
#include "Heap.h"
#include "eval.h"
yap_error_number Yap_matherror = YAP_NO_ERROR;
static Term
Eval(Term t)
{
if (IsVarTerm(t)) {
Yap_Error(INSTANTIATION_ERROR,TermNil,"in arithmetic");
P = (yamop *)FAILCODE;
return 0L;
} else if (IsAtomTerm(t)) {
ExpEntry *p;
Atom name = AtomOfTerm(t);
if (EndOfPAEntr(p = RepExpProp(Yap_GetExpProp(name, 0)))) {
Term ti[2], terror;
/* error */
ti[0] = t;
ti[1] = MkIntegerTerm(0);
/* error */
terror = Yap_MkApplTerm(FunctorSlash, 2, ti);
Yap_Error(TYPE_ERROR_EVALUABLE, terror,
"atom %s for arithmetic expression",
RepAtom(name)->StrOfAE);
P = (yamop *)FAILCODE;
return 0L;
}
return Yap_eval_atom(p->FOfEE);
} else if (IsIntTerm(t)) {
return t;
} else if (IsApplTerm(t)) {
Functor fun = FunctorOfTerm(t);
switch ((CELL)fun) {
case (CELL)FunctorLongInt:
case (CELL)FunctorDouble:
#ifdef USE_GMP
case (CELL)FunctorBigInt:
#endif
return t;
default:
{
Int n = ArityOfFunctor(fun);
Atom name = NameOfFunctor(fun);
ExpEntry *p;
Term t1, t2;
if (EndOfPAEntr(p = RepExpProp(Yap_GetExpProp(name, n)))) {
Term ti[2];
/* error */
ti[0] = t;
ti[1] = MkIntegerTerm(n);
t = Yap_MkApplTerm(FunctorSlash, 2, ti);
Yap_Error(TYPE_ERROR_EVALUABLE, t,
"functor %s/%d for arithmetic expression",
RepAtom(name)->StrOfAE,n);
P = (yamop *)FAILCODE;
RERROR();
}
t1 = Eval(ArgOfTerm(1,t));
if (t1 == 0L)
return FALSE;
if (n == 1)
return Yap_eval_unary(p->FOfEE, t1);
t2 = Eval(ArgOfTerm(2,t));
if (t2 == 0L)
return FALSE;
return Yap_eval_binary(p->FOfEE,t1,t2);
}
}
} /* else if (IsPairTerm(t)) */ {
if (TailOfTerm(t) != TermNil) {
Yap_Error(TYPE_ERROR_EVALUABLE, t,
"string must contain a single character to be evaluated as an arithmetic expression");
P = (yamop *)FAILCODE;
return 0L;
}
return Eval(HeadOfTerm(t));
}
}
Term
Yap_Eval(Term t)
{
return Eval(t);
}
#ifdef BEAM
Int BEAM_is(void);
Int
BEAM_is(void)
{ /* X is Y */
union arith_ret res;
blob_type bt;
bt = Eval(Deref(XREGS[2]), &res);
if (bt==db_ref_e) return (NULL);
return (EvalToTerm(bt,&res));
}
#endif
static Int
p_is(CELL result, CELL in)
{ /* X is Y */
Term out;
out = Eval(Deref(in));
if (out == 0L) {
Yap_Error(EVALUATION_ERROR_INT_OVERFLOW, ARG2, "is/2");
return FALSE;
}
return Yap_unify_constant(result,out);
}
void
Yap_InitEval(void)
{
/* here are the arithmetical predicates */
Yap_InitConstExps();
Yap_InitUnaryExps();
Yap_InitBinaryExps();
Yap_InitCmpPred("is", 2, p_is, BinaryPredFlag | TestPredFlag | SafePredFlag);
}