shithub: pprolog

Download patch

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