diff options
-rw-r--r-- | TODO | 5 | ||||
-rw-r--r-- | builtins.c | 51 | ||||
-rw-r--r-- | stdlib.pl | 2 |
3 files changed, 56 insertions, 2 deletions
@@ -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 @@ -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 @@ -61,7 +61,7 @@ A @>= B :- length([], 0). length([_|Tail], Length) :- length(Tail, Length0), - Length is Length + 1. + Length is Length0 + 1. member(X, [X|_]). member(X, [_|Tail]) :- |