diff options
author | Peter Mikkelsen <peter@pmikkelsen.com> | 2021-06-30 22:43:00 +0000 |
---|---|---|
committer | Peter Mikkelsen <peter@pmikkelsen.com> | 2021-06-30 22:43:00 +0000 |
commit | fa83d3f1aba932e99833244ebb38b7415b142bd7 (patch) | |
tree | c1a1cd8ffff87ca0d78dad492b92265be054c190 /builtins.c | |
parent | a106f8db4ec30b159c0fcef120c3e8b55b3ffdb8 (diff) |
Add =../2
Diffstat (limited to 'builtins.c')
-rw-r--r-- | builtins.c | 71 |
1 files changed, 71 insertions, 0 deletions
@@ -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 |