ref: 50768fba487e1ec08278cdc4be614863db32a5c4
parent: 64a411ede2df42eea0e6905a4985a3e54057c677
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Tue Jun 29 14:21:31 EDT 2021
Make parse return a list of clauses. Also pretty print the entire list of clauses.
--- a/example.pl
+++ b/example.pl
@@ -16,6 +16,7 @@
could_be_friends(Person1, Person2) :-
likes(Person1, Thing1),
likes(Person2, Thing2),
+ !,
Thing1 = Thing2.
list1(A) :- A = [1,2,3,4].
--- a/fns.h
+++ b/fns.h
@@ -1,5 +1,5 @@
/* parser.c */
-void parse(int);
+Term *parse(int);
/* prettyprint.c */
Rune *prettyprint(Term *);
--- a/main.c
+++ b/main.c
@@ -29,7 +29,10 @@
int fd = open(parsetestfile, OREAD);
if(fd < 0)
exits("open");
- parse(fd);
+ Term *prog = parse(fd);
+ Term *clause;
+ for(clause = prog; clause != nil; clause = clause->next)
+ print("%S.\n", prettyprint(clause));
}
exits(nil);
--- a/parser.c
+++ b/parser.c
@@ -7,9 +7,6 @@
#define PrecedenceLevels 1200
-/* The parser doesn't produce an ast for now, it only acts like a recognizer,
- printing errors if it fails */
-
typedef struct Token Token;
typedef struct Operator Operator;
typedef struct OpInfo OpInfo;
@@ -79,50 +76,48 @@
Term *parseoperators(Term *);
void match(int);
void syntaxerror(char *);
-void prologtext(void);
+Term *prologtext(void);
-void
+Term *
parse(int fd)
{
parsein = Bfdopen(fd, OREAD);
if(parsein == nil){
print("Could not open file\n");
- return;
+ return nil;
}
initoperators();
nexttoken();
- prologtext();
+ return prologtext();
}
-void
+Term *
prologtext(void)
{
if(lookahead.tag == EofTok)
- return;
+ return nil;
Term *t = fullterm(AtomTok, L".", nil);
+ if(lookahead.tag == AtomTok && runestrcmp(lookahead.text, L".") == 0)
+ match(AtomTok);
+ else
+ syntaxerror("prologtext");
if(t->tag == CompoundTerm && runestrcmp(t->text, L":-") == 0 && t->arity == 1){
/* A Directive */
print("Got directive: %S\n", prettyprint(t));
+ t = prologtext();
}else if(t->tag == CompoundTerm && runestrcmp(t->text, L":-") == 0 && t->arity == 2){
- /* A clause with a body */
- print("Got clause with body: %S\n", prettyprint(t));
+ t->next = prologtext();
}else if(t->tag == AtomTerm || t->tag == CompoundTerm){
- /* A clause without a body */
- print("Got clause without body: %S\n", prettyprint(t));
+ t->next = prologtext();
}else{
print("Expected directive or clause as toplevel\n");
syntaxerror("prologtext");
}
- if(lookahead.tag == AtomTok && runestrcmp(lookahead.text, L".") == 0)
- match(AtomTok);
- else
- syntaxerror("prologtext");
-
- prologtext();
+ return t;
}
Term *
@@ -567,7 +562,7 @@
}
/* Other */
- if(runestrchr(L",.()]}|", peek)){
+ if(runestrchr(L",.()]}|!", peek)){
switch(peek){
case L',': lookahead.tag = CommaTok; break;
case L'(': lookahead.tag = ParenLeftTok; break;
@@ -575,6 +570,7 @@
case L']': lookahead.tag = SquareBracketRightTok; break;
case L'}': lookahead.tag = CurlyBracketRightTok; break;
case L'|': lookahead.tag = PipeTok; break;
+ case L'!': lookahead.tag = AtomTok; lookahead.text = runestrdup(L"!"); break;
}
return;
}