shithub: pprolog

Download patch

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;
 }