-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprinter.c
More file actions
126 lines (118 loc) · 3.83 KB
/
printer.c
File metadata and controls
126 lines (118 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "printer.h"
#include <stdio.h>
#include <stdlib.h>
static void indent_print(int n) {
for (int i=0;i<n;i++) putchar(' ');
}
static void print_json_string_esc(const char *s) {
putchar('"');
for (const unsigned char *p = (const unsigned char*)s; *p; ++p) {
unsigned char c = *p;
switch (c) {
case '\\': printf("\\\\"); break;
case '"': printf("\\\""); break;
case '\n': printf("\\n"); break;
case '\r': printf("\\r"); break;
case '\t': printf("\\t"); break;
default:
if (c < 0x20) printf("\\u%04x", c);
else putchar(c);
}
}
putchar('"');
}
/* recursive JSON-like AST printer */
static void print_json_node_rec(Node *n, int indent) {
indent_print(indent); printf("{\n");
indent_print(indent+2); printf("\"type\": ");
switch (n->kind) {
case NODE_OBJECT: printf("\"object\""); break;
case NODE_PROPERTY: printf("\"property\""); break;
case NODE_FUNCTION: printf("\"function\""); break;
case NODE_LIST: printf("\"list\""); break;
case NODE_STRING: printf("\"string\""); break;
case NODE_NUMBER: printf("\"number\""); break;
case NODE_BOOL: printf("\"boolean\""); break;
case NODE_IDENTIFIER: printf("\"identifier\""); break;
}
if (n->value) {
printf(",\n"); indent_print(indent+2); printf("\"value\": ");
print_json_string_esc(n->value);
}
if (n->n_children) {
printf(",\n"); indent_print(indent+2); printf("\"children\": [\n");
for (size_t i=0;i<n->n_children;i++) {
print_json_node_rec(n->children[i], indent+4);
if (i+1 < n->n_children) printf(",\n");
else putchar('\n');
}
indent_print(indent+2); putchar(']');
}
putchar('\n'); indent_print(indent); putchar('}');
}
void print_json(Node *n, Value *v, int grouped) {
//(void)grouped;
int indent = 0;
if (grouped) {
indent = 2;
}
print_json_node_rec(n, indent);
if (v) {
putchar('\n');
char *s = value_to_string(v);
indent_print(indent);
printf("EVALUATED: ");
print_json_string_esc(s);
putchar('\n');
free(s);
s = NULL;
}
}
/* XML printer */
static void print_xml_node_rec(Node *n, int indent) {
indent_print(indent);
const char *tag = "node";
switch (n->kind) {
case NODE_OBJECT: tag = "object"; break;
case NODE_PROPERTY: tag = "property"; break;
case NODE_FUNCTION: tag = "function"; break;
case NODE_LIST: tag = "list"; break;
case NODE_STRING: tag = "string"; break;
case NODE_NUMBER: tag = "number"; break;
case NODE_BOOL: tag = "boolean"; break;
case NODE_IDENTIFIER: tag = "identifier"; break;
}
printf("<%s", tag);
if (n->value) {
printf(" value=\"");
for (const unsigned char *p=(const unsigned char*)n->value; *p; ++p) {
if (*p == '&') printf("&");
else if (*p == '"') printf(""");
else putchar(*p);
}
printf("\"");
}
if (n->n_children == 0) { printf(" />\n"); return; }
printf(">\n");
for (size_t i=0;i<n->n_children;i++) print_xml_node_rec(n->children[i], indent+2);
indent_print(indent); printf("</%s>\n", tag);
}
void print_xml(Node *n, Value *v, int grouped) {
//(void)grouped;
int indent = 0;
if (grouped) {
indent = 2;
}
print_xml_node_rec(n, indent);
indent_print(indent);
if (v) {
char *s = value_to_string(v);
printf("<evaluated>");
for (char *p = s; *p; ++p) {
if (*p == '&') printf("&"); else putchar(*p);
}
printf("</evaluated>\n");
free(s);
s = NULL;
}
}