ref: 329c6975c44fcbe1cf7c9d93ab6164495f432213
parent: 2c166a1496c5638924d29df9dcf6c125a31ce18c
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Wed Jun 30 20:52:41 EDT 2021
Start implementation of is/2
--- a/TODO
+++ b/TODO
@@ -2,4 +2,7 @@
* Stop copying the entire goal stack into every choicepoint
* Stop creating choicepoints when it is not needed
* How to implement builtins nicely?
-* Right now we copy and allocate a lot, but almost never free stuff.
\ No newline at end of file
+* Right now we copy and allocate a lot, but almost never free stuff.
+* Many builtins should really throw an error, but they just fail for now.
+* Exceptions (throw, catch)
+* Modules
--- a/builtins.c
+++ b/builtins.c
@@ -23,6 +23,7 @@
BuiltinProto(builtinfunctor);
BuiltinProto(builtinarg);
BuiltinProto(builtinuniv);
+BuiltinProto(builtinis);
int compareterms(Term *, Term *);
@@ -78,6 +79,8 @@
return builtinarg;
if(Match(L"=..", 2))
return builtinuniv;
+ if(Match(L"is", 2))
+ return builtinis;
return nil;
}
@@ -433,4 +436,52 @@
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
--- a/stdlib.pl
+++ b/stdlib.pl
@@ -61,7 +61,7 @@
length([], 0).
length([_|Tail], Length) :-
length(Tail, Length0),
- Length is Length + 1.
+ Length is Length0 + 1.
member(X, [X|_]).
member(X, [_|Tail]) :-