From 97f9fb37e5d3176567263478444497daf990d175 Mon Sep 17 00:00:00 2001
From: Pompolic <pompolic@special-circumstanc.es>
Date: Thu, 6 Feb 2020 17:46:04 +0100
Subject: [PATCH] Pretty printer + semantic action to make TT_Dict from the
 parsed token

---
 pdf.c | 71 ++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 41 insertions(+), 30 deletions(-)

diff --git a/pdf.c b/pdf.c
index f4183d0..ffac6b4 100644
--- a/pdf.c
+++ b/pdf.c
@@ -68,9 +68,12 @@ bytes_eq(HBytes b, const char *s)
 	return strncmp(s, b.token, b.len) == 0 && b.len == strlen(s);
 }
 
+typedef HCountedArray Dict;
+
+
 /* a helper to look up a value in a dictionary */
 const HParsedToken *
-dictentry(const HCountedArray *dict, const char *key)
+dictentry(const Dict *dict, const char *key)
 {
 	HParsedToken *ent;
 	HBytes k;
@@ -116,7 +119,7 @@ struct Env {
 /*
  * custom token types
  */
-HTokenType TT_XREntry, TT_Ref, TT_Dict, TT_DictEntry;
+HTokenType TT_XREntry, TT_Ref, TT_Dict;
 
 typedef struct {
 	enum {XR_FREE, XR_INUSE, XR_OBJSTM} type;
@@ -130,14 +133,6 @@ typedef struct {
 
 typedef struct { size_t nr, gen; } Ref;
 
-typedef struct {
-	HCountedArray *seq;
-} Dict;
-
-typedef struct {
-	HParsedToken *name;
-	HParsedToken *obj;
-} DictEntry;
 
 void
 pp_xrentry(FILE *stream, const HParsedToken *tok, int indent, int delta)
@@ -171,34 +166,39 @@ pp_ref(FILE *stream, const HParsedToken *tok, int indent, int delta)
 }
 
 /* TODO XXX call pretty printer on each seq element */
+/* TODO: does the default behavior need to be overriden to only print the V: field? */
+/* TODO: booleans get printed as null */
 void
 pp_dict(FILE *stream, const HParsedToken *tok, int indent, int delta)
 {
-	assert(tok->seq);
-
 	if (tok->seq->used == 0)
 		fprintf(stream, "{ }");
-	else {
+	else if(tok->seq->used > 1)
+	{
 		fprintf(stream, "{%*s", delta - 1, "");
-		/*for (size_t i = 0; i < tok->seq->used; i++) {
-			if (i > 0) fprintf(stream, "\n%*s,%*s", indent, "", delta - 1, "");
-			h_pprint(stream, tok->seq->elements[i], indent + delta, delta); */
+		for (size_t i = 0; i < tok->seq->used-1; i++) 
+		{
+			const HCountedArray *k_v;
+			k_v = tok->seq->elements[i]->seq;
+			h_pprint(stream, k_v->elements[0], indent + delta, delta);
+			fprintf(stream, ":");
+			h_pprint(stream, k_v->elements[1], indent + delta, delta);
+			fprintf(stream, ",");
+		}
+		
 	}
+	
+	/* Special case: no comma at the end of last entry */
+	const HCountedArray *k_v;
+	k_v = tok->seq->elements[(tok->seq->used)-1]->seq;
+	h_pprint(stream, k_v->elements[0], indent + delta, delta);
+	fprintf(stream, ":");
+	h_pprint(stream, k_v->elements[1], indent + delta, delta);
+
 	if (tok->seq->used > 2)
 		fprintf(stream, "\n%*s}", indent, "");
 	else
 		fprintf(stream, " }");
-	}
-}
-
-void
-pp_dictentry(FILE *stream, const HParsedToken *tok, int indent, int delta)
-{
-	DictEntry *de = H_CAST(DictEntry, tok);
-
-	h_pprint(stream, de->name, indent, delta);
-	fprintf(stream, "\":\"", indent, delta);
-	h_pprint(stream, de->obj, indent, delta);
 }
 
 /*
@@ -407,6 +407,15 @@ act_rest(const HParseResult *p, void *env)
 bool validate_xrstm(HParseResult *, void *);
 HParsedToken *act_xrstm(const HParseResult *, void *);
 
+HParsedToken *
+act_dict(const HParseResult *p, void *env)
+{
+	Dict *dict = H_ALLOC(Dict);
+
+	//dict = H_FIELD(Dict,0);
+
+	return H_MAKE(Dict, (void*)p->ast->seq);
+}
 
 /*
  * input grammar
@@ -427,6 +436,8 @@ init_parser(struct Env *aux)
 {
 	TT_XREntry =	h_allocate_token_new("XREntry", NULL, pp_xrentry);
 	TT_Ref =	h_allocate_token_new("Ref", NULL, pp_ref);
+	TT_Dict =	h_allocate_token_new("Dict", NULL, pp_dict);
+	//TT_DictEntry = h_allocate_token_new("DictEntry", NULL, pp_dictentry);
 
 	/* lines */
 	H_RULE(cr,	p_mapch('\r', '\n'));	/* semantic value: \n */
@@ -532,7 +543,7 @@ init_parser(struct Env *aux)
 	H_RULE(dclose,	LIT(">>"));
 	H_RULE(obj,	h_indirect());
 	H_RULE(k_v,	SEQ(name, obj));
-	H_RULE(dict,	h_middle(TOKD(dopen), h_many(k_v), TOKD(dclose)));
+	H_ARULE(dict,	h_middle(TOKD(dopen), h_many(k_v), TOKD(dclose)));
 	H_RULE(array,	h_middle(TOKD(lbrack), h_many(obj), TOKD(rbrack)));
 		// XXX validate: dict keys must be unique
 
@@ -743,7 +754,7 @@ kstream(HAllocator *mm__, const HParsedToken *x, void *env)
 {
 	struct Env *aux = env;
 	const HParsedToken *dict_t = H_INDEX_TOKEN(x, 0);
-	const HCountedArray *dict = H_CAST_SEQ(dict_t);
+	const HCountedArray *dict = H_CAST(Dict, dict_t);
 	const HParsedToken *v = NULL;
 	size_t sz;
 
@@ -1323,7 +1334,7 @@ parse_xrefs(const char *input, size_t sz, size_t *nxrefs)
 		xrefs[n++] = res->ast;
 
 		/* look up the next offset (to the previous xref section) */
-		tok = dictentry(H_INDEX_SEQ(res->ast, 1), "Prev");
+		tok = dictentry(H_INDEX(Dict, res->ast, 1), "Prev");
 		if (tok == NULL)
 			break;
 		if (tok->token_type != TT_SINT) {
-- 
GitLab