r - format.go
1 package r
2
3 import (
4 "fmt"
5 "io"
6 "strings"
7
8 "vimagination.zapto.org/parser"
9 )
10
11 var indent = []byte{'\t'}
12
13 type indentPrinter struct {
14 io.Writer
15 }
16
17 func (i *indentPrinter) Write(p []byte) (int, error) {
18 var (
19 total int
20 last int
21 )
22
23 for n, c := range p {
24 if c == '\n' {
25 m, err := i.Writer.Write(p[last : n+1])
26 total += m
27
28 if err != nil {
29 return total, err
30 }
31
32 _, err = i.Writer.Write(indent)
33 if err != nil {
34 return total, err
35 }
36
37 last = n + 1
38 }
39 }
40
41 if last != len(p) {
42 m, err := i.Writer.Write(p[last:])
43 total += m
44
45 if err != nil {
46 return total, err
47 }
48 }
49
50 return total, nil
51 }
52
53 func (i *indentPrinter) Print(args ...interface{}) {
54 fmt.Fprint(i, args...)
55 }
56
57 func (i *indentPrinter) Printf(format string, args ...interface{}) {
58 fmt.Fprintf(i, format, args...)
59 }
60
61 func (i *indentPrinter) WriteString(s string) (int, error) {
62 return i.Write([]byte(s))
63 }
64
65 func (t Token) printType(w io.Writer, v bool) {
66 var typ string
67
68 switch t.Type {
69 case TokenWhitespace:
70 typ = "Whitespace"
71 case TokenLineTerminator:
72 typ = "LineTerminator"
73 case TokenWhitespaceLineTerminator:
74 typ = "WhitespaceLineTerminator"
75 case TokenExpressionTerminator:
76 typ = "ExpressionTerminator"
77 case TokenComment:
78 typ = "Comment"
79 case TokenStringLiteral:
80 typ = "StringLiteral"
81 case TokenNumericLiteral:
82 typ = "NumericLiteral"
83 case TokenIntegerLiteral:
84 typ = "IntegerLiteral"
85 case TokenComplexLiteral:
86 typ = "ComplexLiteral"
87 case TokenBooleanLiteral:
88 typ = "BooleanLiteral"
89 case TokenNull:
90 typ = "Null"
91 case TokenNA:
92 typ = "NA"
93 case TokenIdentifier:
94 typ = "Identifier"
95 case TokenKeyword:
96 typ = "Keyword"
97 case TokenEllipsis:
98 typ = "Ellipsis"
99 case TokenOperator:
100 typ = "Operator"
101 case TokenSpecialOperator:
102 typ = "SpecialOperator"
103 case TokenGrouping:
104 typ = "Grouping"
105 case parser.TokenDone:
106 typ = "Done"
107 case parser.TokenError:
108 typ = "Error"
109 default:
110 typ = "Unknown"
111 }
112
113 fmt.Fprintf(w, "Type: %s - Data: %q", typ, t.Data)
114
115 if v {
116 fmt.Fprintf(w, " - Position: %d (%d: %d)", t.Pos, t.Line, t.LinePos)
117 }
118 }
119
120 func (t Tokens) printType(w io.Writer, v bool) {
121 if t == nil {
122 io.WriteString(w, "nil")
123
124 return
125 }
126
127 if len(t) == 0 {
128 io.WriteString(w, "[]")
129
130 return
131 }
132
133 io.WriteString(w, "[")
134
135 ipp := indentPrinter{w}
136
137 for n, t := range t {
138 ipp.Printf("\n%d: ", n)
139 t.printType(w, v)
140 }
141
142 io.WriteString(w, "\n]")
143 }
144
145 func (c Comments) printType(w io.Writer, v bool) {
146 Tokens(c).printType(w, v)
147 }
148
149 func (c Comments) printSource(w io.Writer, v bool) {
150 if len(c) > 0 {
151 printComment(w, c[0].Data)
152
153 line := c[0].Line
154
155 for _, c := range c[1:] {
156 io.WriteString(w, "\n")
157
158 line++
159
160 if line < c.Line {
161 io.WriteString(w, "\n")
162
163 line++
164 }
165
166 printComment(w, c.Data)
167 }
168
169 if v {
170 io.WriteString(w, "\n")
171 }
172 }
173 }
174
175 func printComment(w io.Writer, c string) {
176 if !strings.HasPrefix(c, "#") {
177 io.WriteString(w, "#")
178 }
179
180 io.WriteString(w, c)
181 }
182
183 type formatter interface {
184 printType(io.Writer, bool)
185 printSource(io.Writer, bool)
186 }
187
188 func format(f formatter, s fmt.State, v rune) {
189 switch v {
190 case 'v':
191 f.printType(s, s.Flag('+'))
192 case 's':
193 f.printSource(s, s.Flag('+'))
194 }
195 }
196
197 // String implements the fmt.Stringer interface.
198 func (a AssignmentType) String() string {
199 switch a {
200 case AssignmentNone:
201 return "AssignmentNone"
202 case AssignmentEquals:
203 return "AssignmentEquals"
204 case AssignmentLeftAssign:
205 return "AssignmentLeftAssign"
206 case AssignmentRightAssign:
207 return "AssignmentRightAssign"
208 case AssignmentLeftParentAssign:
209 return "AssignmentLeftParentAssign"
210 case AssignmentRightParentAssign:
211 return "AssignmentRightParentAssign"
212 default:
213 return "Unknown"
214 }
215 }
216
217 func (a AssignmentType) printType(w io.Writer, _ bool) {
218 io.WriteString(w, a.String())
219 }
220
221 func (a AssignmentType) printSource(w io.Writer, _ bool) {
222 switch a {
223 case AssignmentEquals:
224 io.WriteString(w, "=")
225 case AssignmentLeftAssign:
226 io.WriteString(w, "<-")
227 case AssignmentRightAssign:
228 io.WriteString(w, "->")
229 case AssignmentLeftParentAssign:
230 io.WriteString(w, "<<-")
231 case AssignmentRightParentAssign:
232 io.WriteString(w, "->>")
233 }
234 }
235
236 // String implements the fmt.Stringer interface.
237 func (a AdditionType) String() string {
238 switch a {
239 case AdditionNone:
240 return "AdditionNone"
241 case AdditionAdd:
242 return "AdditionAdd"
243 case AdditionSubtract:
244 return "AdditionSubtract"
245 default:
246 return "Unknown"
247 }
248 }
249
250 func (a AdditionType) printType(w io.Writer, _ bool) {
251 io.WriteString(w, a.String())
252 }
253
254 func (a AdditionType) printSource(w io.Writer, _ bool) {
255 switch a {
256 case AdditionAdd:
257 io.WriteString(w, "+")
258 case AdditionSubtract:
259 io.WriteString(w, "-")
260 }
261 }
262
263 // String implements the fmt.Stringer interface.
264 func (a AndType) String() string {
265 switch a {
266 case AndNone:
267 return "AndNone"
268 case AndVectorized:
269 return "AndVectorizes"
270 case AndNotVectorized:
271 return "AndNotVectorized"
272 default:
273 return "Unknown"
274 }
275 }
276
277 func (a AndType) printType(w io.Writer, _ bool) {
278 io.WriteString(w, a.String())
279 }
280
281 func (a AndType) printSource(w io.Writer, _ bool) {
282 switch a {
283 case AndVectorized:
284 io.WriteString(w, "&")
285 case AndNotVectorized:
286 io.WriteString(w, "&&")
287 }
288 }
289
290 // String implements the fmt.Stringer interface.
291 func (m MultiplicationType) String() string {
292 switch m {
293 case MultiplicationNone:
294 return "MultiplicationNone"
295 case MultiplicationMultiply:
296 return "MultiplicationMultiply"
297 case MultiplicationDivide:
298 return "MultiplicationDivide"
299 default:
300 return "Unknown"
301 }
302 }
303
304 func (m MultiplicationType) printType(w io.Writer, _ bool) {
305 io.WriteString(w, m.String())
306 }
307
308 func (m MultiplicationType) printSource(w io.Writer, _ bool) {
309 switch m {
310 case MultiplicationMultiply:
311 io.WriteString(w, "*")
312 case MultiplicationDivide:
313 io.WriteString(w, "/")
314 }
315 }
316
317 // String implements the fmt.Stringer interface.
318 func (o OrType) String() string {
319 switch o {
320 case OrNone:
321 return "OrNone"
322 case OrVectorized:
323 return "OrVectorized"
324 case OrNotVectorized:
325 return "OrNotVectorized"
326 default:
327 return "Unknown"
328 }
329 }
330
331 func (o OrType) printType(w io.Writer, _ bool) {
332 io.WriteString(w, o.String())
333 }
334
335 func (o OrType) printSource(w io.Writer, _ bool) {
336 switch o {
337 case OrVectorized:
338 io.WriteString(w, "|")
339 case OrNotVectorized:
340 io.WriteString(w, "||")
341 }
342 }
343
344 // String implements the fmt.Stringer interface.
345 func (r RelationalOperator) String() string {
346 switch r {
347 case RelationalNone:
348 return "RelationalNone"
349 case RelationalGreaterThan:
350 return "RelationalGreaterThan"
351 case RelationalGreaterThanOrEqual:
352 return "RelationalGreaterThanOrEqual"
353 case RelationalLessThan:
354 return "RelationalLessThan"
355 case RelationalLessThanOrEqual:
356 return "RelationalLessThanOrEqual"
357 case RelationalEqual:
358 return "RelationalEqual"
359 case RelationalNotEqual:
360 return "RelationalNotEqual"
361 default:
362 return "Unknown"
363 }
364 }
365
366 func (r RelationalOperator) printType(w io.Writer, _ bool) {
367 io.WriteString(w, r.String())
368 }
369
370 func (r RelationalOperator) printSource(w io.Writer, _ bool) {
371 switch r {
372 case RelationalGreaterThan:
373 io.WriteString(w, ">")
374 case RelationalGreaterThanOrEqual:
375 io.WriteString(w, ">=")
376 case RelationalLessThan:
377 io.WriteString(w, "<")
378 case RelationalLessThanOrEqual:
379 io.WriteString(w, "<=")
380 case RelationalEqual:
381 io.WriteString(w, "==")
382 case RelationalNotEqual:
383 io.WriteString(w, "!=")
384 }
385 }
386
387 // String implements the fmt.Stringer interface.
388 func (s SubsetType) String() string {
389 switch s {
390 case SubsetNone:
391 return "SubsetNone"
392 case SubsetList:
393 return "SubsetList"
394 case SubsetStructure:
395 return "SubsetStructure"
396 default:
397 return "Unknown"
398 }
399 }
400
401 func (s SubsetType) printType(w io.Writer, _ bool) {
402 io.WriteString(w, s.String())
403 }
404
405 func (s SubsetType) printSource(w io.Writer, _ bool) {
406 switch s {
407 case SubsetList:
408 io.WriteString(w, "$")
409 case SubsetStructure:
410 io.WriteString(w, "@")
411 }
412 }
413
414 // String implements the fmt.Stringer interface.
415 func (u UnaryType) String() string {
416 switch u {
417 case UnaryAdd:
418 return "UnaryAdd"
419 case UnaryMinus:
420 return "UnaryMinus"
421 default:
422 return "Unknown"
423 }
424 }
425
426 func (u UnaryType) printType(w io.Writer, _ bool) {
427 io.WriteString(w, u.String())
428 }
429
430 func (u UnaryType) printsource(w io.Writer, _ bool) {
431 switch u {
432 case UnaryAdd:
433 io.WriteString(w, "+")
434 case UnaryMinus:
435 io.WriteString(w, "-")
436 }
437 }
438