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