shithub: pprolog

Download patch

ref: 3f26a0f2a1f699e628136ec5be6178b5ab40fc44
parent: 66a7040df6897e60ee1a513b95f4b04e687bbf0a
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Sat Jul 3 17:16:58 EDT 2021

Make the goalstack global just like the choicestack

--- a/builtins.c
+++ b/builtins.c
@@ -5,14 +5,14 @@
 #include "dat.h"
 #include "fns.h"
 
-#define BuiltinProto(name) int name(Term *, Term *, Goal **, Binding **)
+#define BuiltinProto(name) int name(Term *, Term *, Binding **)
 #define Match(X, Y) (runestrcmp(name, X) == 0 && arity == Y)
 #define Throw(What) do{\
 	Goal *g = malloc(sizeof(Goal)); \
 	g->goal = What; \
 	g->catcher = nil; \
-	g->next = *goals; \
-	*goals = g; \
+	g->next = goalstack; \
+	goalstack = g; \
 	return 1; \
 }while(0)
 
@@ -128,17 +128,16 @@
 }
 
 int
-builtinfail(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinfail(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
 	USED(goal);
-	USED(goals);
 	USED(bindings);
 	return 0;
 }
 
 int
-builtincall(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtincall(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
 	USED(bindings);
@@ -146,17 +145,16 @@
 	Goal *g = malloc(sizeof(Goal));
 	g->goal = goal->children;
 	g->catcher = nil;
-	g->next = *goals;
-	*goals = g;
+	g->next = goalstack;
+	goalstack = g;
 
 	return 1;
 }
 
 int
-builtincut(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtincut(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 
 	Choicepoint *cp = choicestack;
@@ -171,10 +169,9 @@
 }
 
 int
-builtinvar(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinvar(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 	Term *arg = goal->children;
 	return (arg->tag == VariableTerm);
@@ -181,10 +178,9 @@
 }
 
 int
-builtinatom(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinatom(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 	Term *arg = goal->children;
 	return (arg->tag == AtomTerm);
@@ -191,10 +187,9 @@
 }
 
 int
-builtininteger(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtininteger(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 	Term *arg = goal->children;
 	return (arg->tag == NumberTerm && arg->numbertype == NumberInt);
@@ -201,10 +196,9 @@
 }
 
 int
-builtinfloat(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinfloat(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 	Term *arg = goal->children;
 	return (arg->tag == NumberTerm && arg->numbertype == NumberFloat);
@@ -211,10 +205,9 @@
 }
 
 int
-builtinatomic(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinatomic(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 	Term *arg = goal->children;
 	return (arg->tag == AtomTerm || arg->tag == NumberTerm);
@@ -221,10 +214,9 @@
 }
 
 int
-builtincompound(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtincompound(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 	Term *arg = goal->children;
 	return (arg->tag == CompoundTerm);
@@ -231,10 +223,9 @@
 }
 
 int
-builtinnonvar(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinnonvar(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 	Term *arg = goal->children;
 	return (arg->tag != VariableTerm);
@@ -241,10 +232,9 @@
 }
 
 int
-builtinnumber(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinnumber(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 	Term *arg = goal->children;
 	return (arg->tag == NumberTerm);
@@ -306,10 +296,9 @@
 }
 
 int
-builtincompare(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtincompare(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	Term *order = goal->children;
 	Term *t1 = order->next;
 	Term *t2 = t1->next;
@@ -328,10 +317,9 @@
 }
 
 int
-builtinfunctor(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinfunctor(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 
 	Term *term = goal->children;
 	Term *name = term->next;
@@ -366,10 +354,9 @@
 }
 
 int
-builtinarg(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinarg(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 
 	Term *n = goal->children;
 	Term *term = n->next;
@@ -403,10 +390,9 @@
 }
 
 int
-builtinuniv(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinuniv(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	Term *term = goal->children;
 	Term *list = term->next;
 
@@ -477,10 +463,9 @@
 }
 
 int
-builtinis(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinis(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	Term *result = goal->children;
 	Term *expr = result->next;
 
@@ -493,7 +478,7 @@
 }
 
 int
-builtincatch(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtincatch(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
 	USED(bindings);
@@ -505,30 +490,29 @@
 	Goal *catchframe = malloc(sizeof(Goal));
 	catchframe->goal = recover;
 	catchframe->catcher = catcher;
-	catchframe->next = *goals;
-	*goals = catchframe;
+	catchframe->next = goalstack;
+	goalstack = catchframe;
 
 	Goal *g = malloc(sizeof(Goal));
 	g->goal = catchgoal;
 	g->catcher = nil;
-	g->next = *goals;
-	*goals = g;
+	g->next = goalstack;
+	goalstack = g;
 
 	return 1;
 }
 
 int
-builtinthrow(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinthrow(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
 	USED(bindings);
-	USED(goals);
 
 	Term *ball = goal->children;
 
 	print("Throwing: %S\n", prettyprint(ball, 0, 0, 0));
 	Goal *g;
-	for(g = *goals; g != nil; g = g->next){
+	for(g = goalstack; g != nil; g = g->next){
 		if(g->catcher == nil)
 			continue;
 
@@ -539,12 +523,12 @@
 				exits("exception");
 				return 0;
 			}else{
-				*goals = g->next;
+				goalstack = g->next;
 				Goal *newgoal = malloc(sizeof(Goal));
 				newgoal->goal = copyterm(g->goal, nil);
 				newgoal->catcher = nil;
-				newgoal->next = *goals;
-				*goals = newgoal;
+				newgoal->next = goalstack;
+				goalstack = newgoal;
 				applybinding(newgoal->goal, *bindings);
 
 				Choicepoint *cp = choicestack;
@@ -559,17 +543,16 @@
 }
 
 int
-builtincurrentprologflag(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtincurrentprologflag(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
 	USED(goal);
-	USED(goals);
 	USED(bindings);
 	return 0;
 }
 
 int
-builtinsetprologflag(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinsetprologflag(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
 	USED(bindings);
@@ -589,10 +572,9 @@
 }
 
 int
-builtinopen(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinopen(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 
 	Term *sourcesink = goal->children;
@@ -626,10 +608,9 @@
 }
 
 int
-builtinclose(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinclose(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 	
 	Term *stream = goal->children;
@@ -653,10 +634,9 @@
 }
 
 int
-builtincurrentinput(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtincurrentinput(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 
 	Term *stream = goal->children;
@@ -668,10 +648,9 @@
 }
 
 int
-builtincurrentoutput(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtincurrentoutput(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 
 	Term *stream = goal->children;
@@ -683,10 +662,9 @@
 }
 
 int
-builtinsetinput(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinsetinput(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 
 	Term *stream = goal->children;
@@ -707,10 +685,9 @@
 }
 
 int
-builtinsetoutput(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinsetoutput(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 
 	Term *stream = goal->children;
@@ -731,10 +708,9 @@
 }
 
 int
-builtinreadterm(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinreadterm(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 
 	Term *stream = goal->children;
@@ -763,10 +739,9 @@
 }
 
 int
-builtinwriteterm(Term *database, Term *goal, Goal **goals, Binding **bindings)
+builtinwriteterm(Term *database, Term *goal, Binding **bindings)
 {
 	USED(database);
-	USED(goals);
 	USED(bindings);
 	
 	Term *stream = goal->children;
--- a/dat.h
+++ b/dat.h
@@ -2,7 +2,7 @@
 typedef struct Binding Binding;
 typedef struct Goal Goal;
 typedef struct Choicepoint Choicepoint;
-typedef int (*Builtin)(Term *, Term *, Goal **, Binding **);
+typedef int (*Builtin)(Term *, Term *, Binding **);
 
 struct Term
 {
@@ -67,4 +67,5 @@
 int flagdoublequotes;
 
 /* Staate of the running system */
-Choicepoint *choicestack;
\ No newline at end of file
+Choicepoint *choicestack;
+Goal *goalstack;
\ No newline at end of file
--- a/eval.c
+++ b/eval.c
@@ -16,8 +16,6 @@
 int
 evalquery(Term *database, Term *query, Binding **resultbindings)
 {
-	Goal *goals;
-
 	if(choicestack == nil){
 	/*
 		The goal stack has the original query at the very bottom, protected by a catch frame where the ->goal field is nil.
@@ -25,18 +23,18 @@
 		and to get the result we can unify the original query with the one at the bottom of the stack, to get the bindings
 		applied.
 	*/
-		goals = malloc(sizeof(Goal));
-		goals->goal = copyterm(query, nil);
-		goals->catcher = nil;
-		goals->next = nil;
+		goalstack = malloc(sizeof(Goal));
+		goalstack->goal = copyterm(query, nil);
+		goalstack->catcher = nil;
+		goalstack->next = nil;
 		Goal *protector = malloc(sizeof(Goal));
 		protector->goal = nil;
 		protector->catcher = mkvariable(L"catch-var");
-		protector->next = goals;
-		goals = protector;
+		protector->next = goalstack;
+		goalstack = protector;
 
 		/* Now add the actual goals */
-		goals = addgoals(goals, query);
+		goalstack = addgoals(goalstack, query);
 
 		clausenr = 2; /* Start at two since 0 is for the facts in the database, and 1 is for queries */
 	}else{
@@ -43,16 +41,20 @@
 		goto Backtrack;
 	}
 
-	while(goals->goal != nil){
+	while(goalstack->goal != nil){
 		Term *dbstart;
 		Term *goal;
+		Goal *oldgoalstack;
 
 		dbstart = database;
 Retry:
-		goal = goals->goal;
+		print("Loop run\n");
+		goal = goalstack->goal;
+		oldgoalstack = goalstack;
+		goalstack = goalstack->next;
 
-		if(goals->catcher){
-			goals = goals->next;
+		if(oldgoalstack->catcher){
+			print("Was catchframe\n");
 			continue;
 		}
 
@@ -61,11 +63,11 @@
 
 		Binding *bindings = nil;
 		Term *clause = nil;
-
+		
 		/* Try to see if the goal can be solved using a builtin first */
 		Builtin builtin = findbuiltin(goal);
 		if(builtin != nil){
-			int success = builtin(database, goal, &goals->next, &bindings);
+			int success = builtin(database, goal, &bindings);
 			if(!success)
 				goto Backtrack;
 		}else{
@@ -75,7 +77,7 @@
 				if(clause->next != nil){
 					/* Add a choicepoint. Note we create a choicepoint every time, so there is room for improvement. */
 					Choicepoint *cp = malloc(sizeof(Choicepoint));
-					cp->goalstack = copygoals(goals);
+					cp->goalstack = copygoals(oldgoalstack);
 					cp->next = choicestack;
 					cp->retryclause = clause->next;
 					cp->id = clause->clausenr;
@@ -90,17 +92,15 @@
 				Choicepoint *cp = choicestack;
 				choicestack = cp->next;
 				/* freegoals(goals) */
-				goals = cp->goalstack;
+				goalstack = cp->goalstack;
 				dbstart = cp->retryclause;
 				goto Retry;
 			}
 		}
-		
-		goals = goals->next;
 
 		/* Apply bindings to all goals on the stack except catchframes */
 		Goal *g;
-		for(g = goals; g != nil; g = g->next){
+		for(g = goalstack; g != nil; g = g->next){
 			if(g->goal != nil && g->catcher == nil)
 				applybinding(g->goal, bindings);
 		}
@@ -109,11 +109,11 @@
 		if(clause != nil && clause->tag == CompoundTerm && clause->arity == 2 && runestrcmp(clause->text, L":-") == 0){
 			Term *subgoal = copyterm(clause->children->next, nil);
 			applybinding(subgoal, bindings);
-			goals = addgoals(goals, subgoal);
+			goalstack = addgoals(goalstack, subgoal);
 		}
 	}
-	goals = goals->next;
-	unify(query, goals->goal, resultbindings);
+	goalstack = goalstack->next;
+	unify(query, goalstack->goal, resultbindings);
 	return 1;
 }
 
--- a/repl.c
+++ b/repl.c
@@ -15,6 +15,8 @@
 		print("?- ");
 		Term *query = parse(fd, nil, 1);
 		Binding *bindings = nil;
+		choicestack = nil;
+		goalstack = nil; /* should free old choicestack and goalstack */
 		int success;
 FindMore:
 		success = evalquery(database, query, &bindings);