diff options
author | Peter Mikkelsen <peter@pmikkelsen.com> | 2021-07-07 15:42:52 +0000 |
---|---|---|
committer | Peter Mikkelsen <peter@pmikkelsen.com> | 2021-07-07 15:42:52 +0000 |
commit | 3e1e9621d1f19b221d59191ed55e78b171a5fe93 (patch) | |
tree | 2368bbc3bf1390b88978b9413f08457113b843e2 | |
parent | 91f737e4effa109cb22bc1b2000f457fa1ad88db (diff) |
Make functor/3 work according to spec
-rw-r--r-- | builtins.c | 45 | ||||
-rw-r--r-- | parser.c | 2 |
2 files changed, 33 insertions, 14 deletions
@@ -317,30 +317,49 @@ builtinfunctor(Term *goal, Binding **bindings, Module *module) Term *name = term->next; Term *arity = name->next; - if(term->tag == CompoundTerm){ - Term *realname = mkatom(term->text); - Term *realarity = mkinteger(term->arity); - if(unify(name, realname, bindings) && unify(arity, realarity, bindings)) - return 1; - }else if(arity->tag == IntegerTerm && - (name->tag == AtomTerm || name->tag == IntegerTerm || name->tag == FloatTerm)){ + if(term->tag == VariableTerm && name->tag == VariableTerm) + Throw(instantiationerror()); + if(term->tag == VariableTerm && arity->tag == VariableTerm) + Throw(instantiationerror()); + if(term->tag == VariableTerm && !(name->tag == VariableTerm || name->tag == AtomTerm || name->tag == IntegerTerm || name->tag == FloatTerm)) + Throw(typeerror(L"atomic", name)); + if(term->tag == VariableTerm && !(arity->tag == VariableTerm || arity->tag == IntegerTerm)) + Throw(typeerror(L"integer", arity)); + if(term->tag == VariableTerm && name->tag != VariableTerm && name->tag != AtomTerm && arity->tag == IntegerTerm && arity->ival > 0) + Throw(typeerror(L"atom", name)); + if(term->tag == VariableTerm && arity->tag == IntegerTerm && arity->ival < 0) + Throw(domainerror(L"not_less_than_zero", arity)); + + + if(term->tag == VariableTerm){ if(arity->ival == 0) return unify(term, name, bindings); else{ - if(name->tag != AtomTerm) - return 0; - - /* Make arity maky fresh variables */ + /* Make arity many fresh variables */ int i; Term *args = nil; for(i = 0; i < arity->ival; i++){ - Rune *varname = runesmprint("FunctorVar%d", i); - Term *arg = mkvariable(varname); + Term *arg = mkvariable(L"_"); args = appendterm(args, arg); } Term *realterm = mkcompound(name->text, arity->ival, args); return unify(term, realterm, bindings); } + }else{ + Rune *namestr; + int arityint; + + if(term->tag == CompoundTerm){ + namestr = term->text; + arityint = term->arity; + }else{ + namestr = prettyprint(term, 0, 0, 0); + arityint = 0; + } + Term *realname = mkatom(namestr); + Term *realarity = mkinteger(arityint); + if(unify(name, realname, bindings) && unify(arity, realarity, bindings)) + return 1; } return 0; } @@ -536,7 +536,7 @@ SkipWhite: goto Integer; } while(isdigitrune(peek)){ - numD += (peek - L'0') / (10 * place); + numD += (peek - L'0') / (double)(10 * place); peek = Bgetrune(parsein); } Bungetrune(parsein); |