forked from kanaka/mal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
printer.fs
114 lines (100 loc) · 2.49 KB
/
printer.fs
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
require str.fs
require types.fs
\ === printer protocol and implementations === /
def-protocol-method pr-buf ( readably? str-addr str-len this -- str-addr str-len )
def-protocol-method pr-seq-buf ( readably? str-addr str-len this -- str-addr str-len )
: pr-str { obj }
true new-str obj pr-buf rot drop ;
\ Examples of extending existing protocol methods to existing type
MalDefault
extend pr-buf
{ this }
s" #<" str-append
this mal-type @ type-name str-append
a-space
this int>str str-append
s" >" str-append ;;
drop
MalNil extend pr-buf drop s" nil" str-append ;; drop
MalTrue extend pr-buf drop s" true" str-append ;; drop
MalFalse extend pr-buf drop s" false" str-append ;; drop
MalList
extend pr-buf
-rot s" (" str-append ( list str-addr str-len )
rot pr-seq-buf
s" )" str-append ;;
extend pr-seq-buf { list }
list MalList/count @ 0 > if
list MalList/start @ { start }
start @ pr-buf
list MalList/count @ 1 ?do
a-space
start i cells + @ pr-buf
loop
endif ;;
drop
MalVector
extend pr-buf
MalVector/list @
-rot s" [" str-append ( list str-addr str-len )
rot pr-seq-buf
s" ]" str-append ;;
drop
MalMap
extend pr-buf
MalMap/list @
-rot s" {" str-append ( list str-addr str-len )
rot { list }
list MalList/count @ { count }
count 0 > if
list MalList/start @ { start }
start @ pr-buf a-space start cell+ @ pr-buf
count 2 / 1 ?do
a-space
start i 2 * cells + @ pr-buf a-space
start i 2 * 1+ cells + @ pr-buf
loop
endif
s" }" str-append ;;
drop
MalInt
extend pr-buf
MalInt/int @ int>str str-append ;;
drop
MalSymbol
extend pr-buf
unpack-sym str-append ;;
drop
MalKeyword
extend pr-buf { kw }
s" :" str-append
kw unpack-keyword str-append ;;
drop
: escape-str { addr len }
s\" \"" str-append
addr len + addr ?do
i c@ case
[char] " of s\" \\\"" str-append endof
[char] \ of s\" \\\\" str-append endof
10 of s\" \\n" str-append endof
13 of s\" \\r" str-append endof
-rot i 1 str-append rot
endcase
loop
s\" \"" str-append ;
MalString
extend pr-buf
dup MalString/str-addr @
swap MalString/str-len @
4 pick if
escape-str
else
str-append
endif ;;
drop
Atom
extend pr-buf { this }
s" (atom " str-append
this Atom/val @ pr-buf
s" )" str-append ;;
drop