From fa83d3f1aba932e99833244ebb38b7415b142bd7 Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Wed, 30 Jun 2021 22:43:00 +0000 Subject: Add =../2 --- builtins.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/builtins.c b/builtins.c index c2afd4e..a3a7d8c 100644 --- a/builtins.c +++ b/builtins.c @@ -22,6 +22,7 @@ BuiltinProto(builtinstring); BuiltinProto(builtincompare); BuiltinProto(builtinfunctor); BuiltinProto(builtinarg); +BuiltinProto(builtinuniv); int compareterms(Term *, Term *); @@ -75,6 +76,8 @@ findbuiltin(Term *goal) return builtinfunctor; if(Match(L"arg", 3)) return builtinarg; + if(Match(L"=..", 2)) + return builtinuniv; return nil; } @@ -362,4 +365,72 @@ builtinarg(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Term *t; for(i = 0, t = term->children; i < n->ival; i++, t = t->next); return unify(arg, t, bindings); +} + +Term * +mklist(Term *elems) +{ + if(elems == nil) + return mkatom(L"[]"); + else{ + Term *t = copyterm(elems, nil); + t->next = mklist(elems->next); + return mkcompound(L".", 2, t); + } +} + +int +listlength(Term *term) +{ + if(term->tag == AtomTerm && runestrcmp(term->text, L"[]") == 0) + return 0; + else if(term->tag == CompoundTerm && term->arity == 2 && runestrcmp(term->text, L".") == 0){ + int taillength = listlength(term->children->next); + return (taillength == -1) ? -1 : 1 + taillength; + }else + return -1; +} + +int +builtinuniv(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings) +{ + USED(database); + USED(goals); + USED(choicestack); + Term *term = goal->children; + Term *list = term->next; + + int len; + if(term->tag == VariableTerm){ + Rune *name; + Term *elems = nil; + Term *realterm; + int i; + + len = listlength(list); + if(len < 1) + return 0; + if(list->children->tag != AtomTerm) + return 0; + name = list->children->text; + + list = list->children->next; + for(i = 1; i < len; i++){ + Term *t = copyterm(list->children, nil); + elems = appendterm(elems, t); + list = list->children->next; + } + realterm = mkcompound(name, len-1, elems); + return unify(term, realterm, bindings); + }else if(term->tag == CompoundTerm){ + Term *elems = mkatom(term->text); + elems->next = term->children; + Term *reallist = mklist(elems); + return unify(list, reallist, bindings); + }else{ + Term *t = copyterm(term, nil); + t->next = mkatom(L"[]"); + Term *reallist = mkcompound(L".", 2, t); + return unify(list, reallist, bindings); + } } \ No newline at end of file -- cgit v1.2.3