summaryrefslogtreecommitdiff
path: root/builtins.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtins.c')
-rw-r--r--builtins.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/builtins.c b/builtins.c
index a3a7d8c..4a2161f 100644
--- a/builtins.c
+++ b/builtins.c
@@ -23,6 +23,7 @@ BuiltinProto(builtincompare);
BuiltinProto(builtinfunctor);
BuiltinProto(builtinarg);
BuiltinProto(builtinuniv);
+BuiltinProto(builtinis);
int compareterms(Term *, Term *);
@@ -78,6 +79,8 @@ findbuiltin(Term *goal)
return builtinarg;
if(Match(L"=..", 2))
return builtinuniv;
+ if(Match(L"is", 2))
+ return builtinis;
return nil;
}
@@ -433,4 +436,52 @@ builtinuniv(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack,
Term *reallist = mkcompound(L".", 2, t);
return unify(list, reallist, bindings);
}
+}
+
+#define ToFloat(t) (t->numbertype == NumberInt ? (double)t->ival : t->dval)
+
+Term *
+aritheval(Term *expr)
+{
+ /* Not every arithmetic operation is defined right now. */
+
+ if(expr->tag == NumberTerm)
+ return expr;
+ else if(expr->tag == CompoundTerm && expr->arity == 2){
+ Term *A = aritheval(expr->children);
+ Term *B = aritheval(expr->children->next);
+ Term *result = mknumber(NumberInt, 0, 0);
+
+ if(A == nil || B == nil)
+ return nil;
+ if(runestrcmp(expr->text, L"+") == 0){
+ if(A->numbertype == NumberInt && B->numbertype == NumberInt){
+ result->numbertype = NumberInt;
+ result->ival = A->ival + B->ival;
+ }else{
+ result->numbertype = NumberFloat;
+ result->dval = ToFloat(A) + ToFloat(B);
+ }
+ }else
+ return nil;
+ return result;
+ }else
+ return nil;
+}
+
+int
+builtinis(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings)
+{
+ USED(database);
+ USED(goals);
+ USED(choicestack);
+ Term *result = goal->children;
+ Term *expr = result->next;
+
+
+ Term *realresult = aritheval(expr);
+ if(realresult)
+ return unify(result, realresult, bindings);
+ else
+ return 0;
} \ No newline at end of file