summaryrefslogtreecommitdiff
path: root/builtins.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <peter@pmikkelsen.com>2021-07-20 23:33:15 +0000
committerPeter Mikkelsen <peter@pmikkelsen.com>2021-07-20 23:33:15 +0000
commit085e3595450d6652b62350621b470b26ae67b6de (patch)
treed650a2748898b3cfc63f075bf0394005c8c23071 /builtins.c
parent0478e6930517d63b30630c88a815d99f6e756c09 (diff)
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).
Diffstat (limited to 'builtins.c')
-rw-r--r--builtins.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/builtins.c b/builtins.c
index 9aee573..a037a23 100644
--- a/builtins.c
+++ b/builtins.c
@@ -216,10 +216,29 @@ builtinfail(Term *goal, Binding **bindings, Module *module)
}
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;
}