shithub: pprolog

ref: d2a0828140c31514c514b8e4fb9a4d52c389d8fe
dir: pprolog/repl.c

View raw version
#include <u.h>
#include <libc.h>
#include <bio.h>

#include "dat.h"
#include "fns.h"

Rune parsefindmore(int);
void dogc(void);

void
repl(void)
{
	int fd = 0; /* Standard input */
	while(1){
		print("?- ");
		replquery = parse(fd, nil, 1);
		replbindings = nil;
		choicestack = nil;
		goalstack = nil;
		int success;
		int firsttime = 1;
FindMore:
		success = evalquery(replquery, &replbindings);
		dogc();
		if(firsttime){
			print(" ");
			firsttime = 0;
		}
		if(success == 0)
			print("  false.\n");
		else{
			if(replbindings == nil)
				print("  true");
			else{
				while(replbindings){
					print("  %S = %S%s", 
						replbindings->name, 
						prettyprint(replbindings->value, 0, 0, 0), 
						replbindings->next ? ",\n " : "");
					replbindings = replbindings->next;
				}
			}
			if(choicestack != nil){
				print("\n");
				if(parsefindmore(fd) == L';'){
					print(";");
					goto FindMore;
				}else
					print(".\n");
			}else{
				print(".\n");
			}
		}
	}
}

Rune
parsefindmore(int fd)
{
	int consctl = open("/dev/consctl", OWRITE);
	if(consctl > 0)
		write(consctl, "rawon", 5);
	else{
		print("Could not open /dev/consctl\n");
		exits("open");
	}

	fd = dup(fd, -1);
	Biobuf *input = Bfdopen(fd, OREAD);
	Rune peek = Bgetrune(input);
	Bterm(input);

	if(consctl > 0){
		write(consctl, "rawoff", 6);
		close(consctl);
	}
	return peek;
}

void
dogc(void)
{
	vlong amount = collectgarbage();
	if(amount != 0 && debug)
		print("Collected %lld bytes of garbage\n", amount);
}