update isl for change in lexicographic optimization
[isa.git] / yll.c
blobb2cf7b36e92e83f85a4837cb7aff62cfd95c1df8
1 #include <stdlib.h>
2 #include <string.h>
3 #include <isa/yll.h>
5 #define FL_INIT(l, f) (l) = (f) /* Specific flags location. */
6 #define FL_SET(l, f) ((l) |= (f))
7 #define FL_CLR(l, f) ((l) &= ~(f))
8 #define FL_ISSET(l, f) ((l) & (f))
10 #define F_INIT(p, f) FL_INIT((p)->flags, f) /* Structure element flags. */
11 #define F_SET(p, f) FL_SET((p)->flags, f)
12 #define F_CLR(p, f) FL_CLR((p)->flags, f)
13 #define F_ISSET(p, f) FL_ISSET((p)->flags, f)
15 static void yll_emit_space(YllEmitter *e)
17 if (F_ISSET(e->stack, YLL_ADD_SPACE))
18 fprintf(e->out, " ");
19 F_CLR(e->stack, YLL_ADD_SPACE);
22 static void yll_emit_transfer(YllEmitter *e)
24 yll_emit_space(e);
25 if (e->transfer) {
26 fprintf(e->out, "!%s", e->transfer);
27 e->transfer = 0;
28 F_SET(e->stack, YLL_ADD_SPACE);
32 static void yll_push(YllEmitter *e, YllEmitterNode *n)
34 n->next = e->stack;
35 e->stack = n;
36 n->flags = e->flags;
37 e->flags = 0;
38 e->indent += 2;
41 static void yll_pop(YllEmitter *e)
43 YllEmitterNode *n = e->stack;
44 e->stack = e->stack->next;
45 S_FREE(n);
46 e->indent -= 2;
49 static void next_doc(YllEmitter *e)
51 fprintf(e->out, "--- ");
54 static void next_anchor(YllEmitter *e)
56 YllAnchorNode *n = (YllAnchorNode*) e->stack;
57 SYMID a = n->anchor;
58 yll_pop(e);
59 e->stack->nextf(e);
60 fprintf(e->out, "&%lu", a);
61 F_SET(e->stack, YLL_ADD_SPACE);
64 static void next_seq(YllEmitter *e)
66 YllSeqNode *n = (YllSeqNode*) e->stack;
67 if (F_ISSET(e->stack, YLL_INLINE_SEQ)) {
68 if (!n->first)
69 fprintf(e->out, ", ");
70 } else
71 fprintf(e->out, "\n%*s- ", e->indent, "");
72 n->first = 0;
75 static void next_map_val(YllEmitter *e);
77 static void next_map_key(YllEmitter *e)
79 F_CLR(e->stack, YLL_ADD_SPACE);
80 fprintf(e->out, "\n%*s", e->indent, "");
81 e->stack->nextf = next_map_val;
84 static void next_map_val(YllEmitter *e)
86 fprintf(e->out, ": ");
87 e->stack->nextf = next_map_key;
90 YllEmitter* yll_new_emitter() {
91 YllEmitter *e;
92 YllEmitterNode *n;
93 e = S_ALLOC(YllEmitter);
94 n = S_ALLOC(YllEmitterNode);
95 n->nextf = next_doc;
96 e->last_anchor = 0;
97 e->stack = 0;
98 e->flags = 0;
99 e->transfer = 0;
100 yll_push(e, n);
101 e->indent = -2;
102 return e;
105 void yll_emitter_handler(YllEmitter *e, YllOutputHandler hdlr)
109 void yll_free_emitter(YllEmitter *e)
111 fprintf(e->out, "\n");
112 yll_pop(e);
113 S_FREE(e);
116 void yll_emitter_start_seq(YllEmitter *e)
118 YllSeqNode * n;
119 e->stack->nextf(e);
120 n = S_ALLOC(YllSeqNode);
121 n->en.nextf = next_seq;
122 n->first = 1;
123 yll_push(e, (YllEmitterNode *)n);
124 yll_emit_transfer(e);
125 if (F_ISSET(&n->en, YLL_INLINE_SEQ))
126 fprintf(e->out, "[");
129 void yll_emitter_end_seq(YllEmitter *e)
131 YllSeqNode *n = (YllSeqNode*) e->stack;
132 if (F_ISSET(e->stack, YLL_INLINE_SEQ))
133 fprintf(e->out, "]");
134 else if (n->first) {
135 if (F_ISSET(e->stack, YLL_ADD_SPACE))
136 fprintf(e->out, " ");
137 fprintf(e->out, "[]");
139 yll_pop(e);
142 void yll_emitter_start_map(YllEmitter *e)
144 YllEmitterNode * n;
145 e->stack->nextf(e);
146 n = S_ALLOC(YllEmitterNode);
147 n->nextf = next_map_key;
148 yll_push(e, n);
149 yll_emit_transfer(e);
152 void yll_emitter_end_map(YllEmitter *e)
154 yll_pop(e);
157 SYMID yll_emitter_anchor(YllEmitter *e)
159 YllAnchorNode * n;
160 SYMID a = ++e->last_anchor;
161 n = S_ALLOC(YllAnchorNode);
162 n->anchor = a;
163 n->en.nextf = next_anchor;
164 yll_push(e, (YllEmitterNode *)n);
165 return a;
168 void yll_emitter_alias(YllEmitter *e, SYMID id)
170 e->stack->nextf(e);
171 fprintf(e->out, "*%lu", id);
174 void yll_emitter_write_string(YllEmitter *e, const char *str)
176 e->stack->nextf(e);
177 yll_emit_transfer(e);
178 yll_emit_space(e);
179 if (strpbrk(str, "[]#:-"))
180 fputc('"', e->out);
181 fprintf(e->out, "%s", str);
182 if (strpbrk(str, "[]#:-"))
183 fputc('"', e->out);
186 void yll_emitter_write_int(YllEmitter *e, int i)
188 e->stack->nextf(e);
189 yll_emit_transfer(e);
190 yll_emit_space(e);
191 fprintf(e->out, "%d", i);
194 void yll_emitter_write_null(YllEmitter *e)
196 e->stack->nextf(e);
197 yll_emit_transfer(e);
198 yll_emit_space(e);
199 fprintf(e->out, "~");
202 void yll_emitter_set_options(YllEmitter *e, YllOption o)
204 F_SET(e, o);
207 void yll_emitter_set_transfer(YllEmitter *e, const char *t)
209 e->transfer = t;