ref: 6ae2e2bb7bebdc3f4d450f1ddc6c69a02c3f4998
parent: 2d7f3ffa770b6eb698566b6566d7e37f10193744
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Tue Jun 29 13:51:20 EDT 2021
Parse lists and {a,b,c} syntax (What is this even called?)
--- a/example.pl
+++ b/example.pl
@@ -11,4 +11,9 @@
could_be_friends(Person1, Person2) :-
likes(Person1, Thing1),
likes(Person2, Thing2),
- Thing1 = Thing2.
\ No newline at end of file
+ Thing1 = Thing2.
+
+list1(A) :- A = [1,2,3,4].
+list2(A) :- A = [a,b|c].
+
+curly(A) :- A = {one,two,three}.
\ No newline at end of file
--- a/parser.c
+++ b/parser.c
@@ -59,7 +59,8 @@
CurlyBracketLeftTok = 1<<10, /* 1024 */
CurlyBracketRightTok = 1<<11, /* 2048 */
CommaTok = 1<<12, /* 4096 */
- EofTok = 1<<13, /* 8192 */
+ PipeTok = 1<<13, /* 8192 */
+ EofTok = 1<<14, /* 16384 */
};
static Biobuf *parsein;
@@ -72,6 +73,8 @@
void nexttoken(void);
Term *fullterm(int, Rune *, Term *);
Term *term(void);
+Term *listterm(int);
+Term *curlybracketterm(void);
Term *compound(void);
Term *parseoperators(Term *);
void match(int);
@@ -162,6 +165,12 @@
result = mkatom(L",");
match(CommaTok);
break;
+ case SquareBracketLeftTok:
+ result = listterm(1);
+ break;
+ case CurlyBracketLeftTok:
+ result = curlybracketterm();
+ break;
default:
print("Cant parse term of token type %d\n", lookahead.tag);
syntaxerror("term");
@@ -172,6 +181,38 @@
}
Term *
+listterm(int start)
+{
+ if(start)
+ match(SquareBracketLeftTok);
+
+ if(lookahead.tag == SquareBracketRightTok){
+ match(SquareBracketRightTok);
+ return mkatom(L"[]");
+ }else if(lookahead.tag == PipeTok){
+ match(PipeTok);
+ Term *t = fullterm(SquareBracketRightTok, nil, nil);
+ match(SquareBracketRightTok);
+ return t;
+ }else{
+ Term *t = fullterm(CommaTok|PipeTok|SquareBracketRightTok, nil, nil);
+ if(lookahead.tag == CommaTok)
+ match(CommaTok);
+ t->next = listterm(0);
+ return mkcompound(L".", 2, t);
+ }
+}
+
+Term *
+curlybracketterm(void)
+{
+ match(CurlyBracketLeftTok);
+ Term *result = fullterm(CurlyBracketRightTok, nil, nil);
+ match(CurlyBracketRightTok);
+ return mkcompound(L"{}", 1, result);
+}
+
+Term *
compound(void)
{
Rune *name = lookahead.text;
@@ -368,6 +409,7 @@
if(peek == L'%'){
while(peek != L'\n')
peek = Bgetrune(parsein);
+ Bgetrune(parsein);
peek = Bgetrune(parsein);
}
@@ -520,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;
@@ -527,6 +569,7 @@
case L')': lookahead.tag = ParenRightTok; break;
case L']': lookahead.tag = SquareBracketRightTok; break;
case L'}': lookahead.tag = CurlyBracketRightTok; break;
+ case L'|': lookahead.tag = PipeTok; break;
}
return;
}