Wrap BlockClosure into Fn to work around a bug
[jackhill/mal.git] / gst / printer.st
1 FileStream fileIn: 'types.st'.
2
3 Object subclass: Printer [
4 Printer class >> prStr: sexp printReadably: printReadably [
5 sexp type = #fn ifTrue: [ ^'#<fn>' ].
6 sexp type = #func ifTrue: [ ^'#<func>' ].
7 sexp type = #true ifTrue: [ ^'true' ].
8 sexp type = #false ifTrue: [ ^'false' ].
9 sexp type = #nil ifTrue: [ ^'nil' ].
10
11 sexp type = #number ifTrue: [ ^sexp value asString ].
12 sexp type = #symbol ifTrue: [ ^sexp value asString ].
13 sexp type = #keyword ifTrue: [ ^':', sexp value ].
14
15 sexp type = #string ifTrue: [
16 printReadably ifTrue: [
17 ^sexp value repr
18 ] ifFalse: [
19 ^sexp value
20 ]
21 ].
22
23 sexp type = #list ifTrue: [
24 ^self prList: sexp printReadably: printReadably
25 starter: '(' ender: ')'
26 ].
27 sexp type = #vector ifTrue: [
28 ^self prList: sexp printReadably: printReadably
29 starter: '[' ender: ']'
30 ].
31 sexp type = #map ifTrue: [
32 ^self prMap: sexp printReadably: printReadably
33 ].
34
35 sexp type = #atom ifTrue: [
36 ^'(atom ', (self prStr: sexp value printReadably: printReadably), ')'
37 ].
38
39 Error halt: 'unimplemented type'
40 ]
41
42 Printer class >> prList: sexp printReadably: printReadably
43 starter: starter ender: ender [
44 | items |
45 items := sexp value collect:
46 [ :item | self prStr: item printReadably: printReadably ].
47 ^starter, (items join: ' ') , ender
48 ]
49
50 Printer class >> prMap: sexp printReadably: printReadably [
51 | items |
52 items := sexp value associations collect:
53 [ :item |
54 (self prStr: item key printReadably: printReadably), ' ',
55 (self prStr: item value printReadably: printReadably) ].
56 ^'{', (items join: ' '), '}'
57 ]
58 ]