ref: 085e3595450d6652b62350621b470b26ae67b6de
parent: 0478e6930517d63b30630c88a815d99f6e756c09
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Tue Jul 20 19:33:15 EDT 2021
The iso standard want's call(G) to throw a type_error(callable, G), when G contains parts that cannot be called, but it is OK for parts of G to be variables, such as G=(write(hey), X).
--- a/builtins.c
+++ b/builtins.c
@@ -216,10 +216,29 @@
}
int
+canbecalled(Term *t)
+{
+ if(t->tag == VariableTerm || t->tag == AtomTerm)
+ return 1;
+ if(t->tag != CompoundTerm)
+ return 0;
+
+ if(t->arity == 2 && (runestrcmp(t->text, L",") == 0 || runestrcmp(t->text, L";") == 0))
+ return canbecalled(t->children) && canbecalled(t->children->next);
+ else
+ return 1;
+}
+
+int
builtincall(Term *goal, Binding **bindings, Module *module)
{
USED(bindings);
- goalstack = addgoals(goalstack, goal->children, module);
+ Term *callgoal = goal->children;
+
+ if(!canbecalled(callgoal))
+ Throw(typeerror(L"callable", callgoal));
+
+ goalstack = addgoals(goalstack, callgoal, module);
return 1;
}