2015-02-06 08:38:34 +03:00
|
|
|
require types.fs
|
|
|
|
|
|
|
|
: safe-type ( str-addr str-len -- )
|
|
|
|
dup 256 > if
|
2015-02-13 03:27:00 +03:00
|
|
|
drop 256 type ." ...<lots more>"
|
2015-02-06 08:38:34 +03:00
|
|
|
else
|
|
|
|
type
|
|
|
|
endif ;
|
|
|
|
|
|
|
|
\ === mutable string buffer === /
|
|
|
|
\ string buffer that maintains an allocation larger than the current
|
|
|
|
\ string size. When appending would cause the string size exceed the
|
|
|
|
\ current allocation, resize is used to double the allocation. The
|
|
|
|
\ current allocation is not stored anywhere, but computed based on
|
|
|
|
\ current string size or str-base-size, whichever is larger.
|
|
|
|
64 constant str-base-size
|
|
|
|
|
|
|
|
: new-str ( -- addr length )
|
|
|
|
str-base-size allocate throw 0 ;
|
|
|
|
|
|
|
|
: round-up ( n -- n )
|
|
|
|
2
|
|
|
|
begin
|
|
|
|
1 lshift 2dup <
|
|
|
|
until
|
2015-02-06 10:38:58 +03:00
|
|
|
nip ;
|
2015-02-06 08:38:34 +03:00
|
|
|
|
|
|
|
: str-append { buf-addr buf-str-len str-addr str-len }
|
|
|
|
buf-str-len str-len +
|
|
|
|
{ new-len }
|
|
|
|
new-len str-base-size > if
|
|
|
|
buf-str-len new-len xor buf-str-len > if
|
|
|
|
buf-addr new-len round-up resize throw
|
|
|
|
to buf-addr
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
str-addr buf-addr buf-str-len + str-len cmove
|
|
|
|
buf-addr new-len ;
|
|
|
|
|
|
|
|
\ define a-space, to append a space char to a string
|
|
|
|
bl c,
|
|
|
|
here constant space-str
|
|
|
|
: a-space space-str 1 str-append ;
|
|
|
|
|
|
|
|
: str-append-char ( buf-addr buf-str-len char -- buf-addr buf-str-len )
|
2015-02-06 10:38:58 +03:00
|
|
|
pad ! pad 1 str-append ;
|
2015-02-06 08:38:34 +03:00
|
|
|
|
|
|
|
: int>str ( num -- str-addr str-len )
|
|
|
|
s>d <# #s #> ;
|
|
|
|
|
|
|
|
|
|
|
|
\ === printer protocol and implementations === /
|
|
|
|
|
|
|
|
def-protocol-method pr-buf ( str-addr str-len this -- str-addr str-len )
|
2015-02-13 03:27:00 +03:00
|
|
|
def-protocol-method pr-seq-buf ( str-addr str-len this -- str-addr str-len )
|
|
|
|
def-protocol-method pr-pairs-buf ( str-addr str-len this -- str-addr str-len )
|
2015-02-06 08:38:34 +03:00
|
|
|
|
|
|
|
: pr-str { obj }
|
|
|
|
new-str obj pr-buf ;
|
|
|
|
|
|
|
|
\ Examples of extending existing protocol methods to existing type
|
|
|
|
MalDefault
|
|
|
|
extend pr-buf
|
|
|
|
{ this }
|
|
|
|
s" #<MalObject" str-append a-space
|
|
|
|
this int>str str-append
|
|
|
|
s" >" str-append ;;
|
|
|
|
drop
|
|
|
|
|
|
|
|
MalNil
|
|
|
|
extend pr-buf
|
|
|
|
drop s" nil" str-append ;;
|
|
|
|
drop
|
|
|
|
|
2015-02-07 18:01:31 +03:00
|
|
|
: pr-buf-list-item ( list str-addr str-len -- list str-addr str-len)
|
|
|
|
rot dup MalList/cdr @ swap MalList/car @ 2swap rot pr-buf ;
|
|
|
|
|
2015-02-13 03:27:00 +03:00
|
|
|
MalList
|
|
|
|
extend pr-buf
|
|
|
|
-rot s" (" str-append ( list str-addr str-len )
|
|
|
|
rot pr-seq-buf
|
|
|
|
s" )" str-append ;;
|
|
|
|
extend pr-seq-buf
|
|
|
|
\ currently assumes list chain through to the end
|
|
|
|
-rot pr-buf-list-item
|
2015-02-06 08:38:34 +03:00
|
|
|
begin ( list str-addr str-len )
|
|
|
|
2 pick mal-nil <>
|
|
|
|
while
|
2015-02-07 18:01:31 +03:00
|
|
|
a-space pr-buf-list-item
|
2015-02-06 08:38:34 +03:00
|
|
|
repeat
|
2015-02-13 03:27:00 +03:00
|
|
|
rot drop ;;
|
|
|
|
extend pr-pairs-buf
|
|
|
|
-rot pr-buf-list-item a-space pr-buf-list-item
|
|
|
|
begin ( list str-addr str-len )
|
|
|
|
2 pick mal-nil <>
|
|
|
|
while
|
|
|
|
s" , " str-append
|
|
|
|
pr-buf-list-item a-space pr-buf-list-item
|
|
|
|
repeat
|
|
|
|
rot drop ;;
|
|
|
|
drop
|
2015-02-07 07:58:41 +03:00
|
|
|
|
2015-02-13 03:27:00 +03:00
|
|
|
MalArray
|
2015-02-07 07:58:41 +03:00
|
|
|
extend pr-buf
|
|
|
|
-rot s" (" str-append ( list str-addr str-len )
|
2015-02-13 03:27:00 +03:00
|
|
|
rot pr-seq-buf
|
2015-02-07 07:58:41 +03:00
|
|
|
s" )" str-append ;;
|
2015-02-13 03:27:00 +03:00
|
|
|
extend pr-seq-buf { ary }
|
|
|
|
ary MalArray/start @ { start }
|
|
|
|
start @ pr-buf
|
|
|
|
ary MalArray/count @ 1 ?do
|
|
|
|
a-space
|
|
|
|
start i cells + @ pr-buf
|
|
|
|
loop ;;
|
|
|
|
extend pr-pairs-buf { ary }
|
|
|
|
ary MalArray/start @ { start }
|
|
|
|
start @ pr-buf a-space start cell+ @ pr-buf
|
|
|
|
ary MalArray/count @ 2 / 1 ?do
|
|
|
|
s" , " str-append
|
|
|
|
a-space
|
|
|
|
start i 2 * cells + @ pr-buf a-space
|
|
|
|
start i 2 * 1+ cells + @ pr-buf
|
|
|
|
loop ;;
|
2015-02-07 07:58:41 +03:00
|
|
|
drop
|
|
|
|
|
|
|
|
MalVector
|
|
|
|
extend pr-buf
|
|
|
|
MalVector/list @
|
|
|
|
-rot s" [" str-append ( list str-addr str-len )
|
2015-02-13 03:27:00 +03:00
|
|
|
rot pr-seq-buf
|
2015-02-07 07:58:41 +03:00
|
|
|
s" ]" str-append ;;
|
2015-02-06 08:38:34 +03:00
|
|
|
drop
|
|
|
|
|
2015-02-07 18:01:31 +03:00
|
|
|
MalMap
|
|
|
|
extend pr-buf
|
|
|
|
MalMap/list @
|
|
|
|
-rot s" {" str-append ( list str-addr str-len )
|
2015-02-13 03:27:00 +03:00
|
|
|
rot pr-pairs-buf
|
2015-02-07 18:01:31 +03:00
|
|
|
s" }" str-append ;;
|
|
|
|
drop
|
|
|
|
|
2015-02-06 08:38:34 +03:00
|
|
|
MalInt
|
|
|
|
extend pr-buf
|
|
|
|
MalInt/int @ int>str str-append ;;
|
|
|
|
drop
|
|
|
|
|
2015-02-13 03:27:00 +03:00
|
|
|
MalFn
|
|
|
|
extend pr-buf
|
|
|
|
drop s" #<fn>" str-append ;;
|
|
|
|
drop
|
|
|
|
|
2015-02-06 08:38:34 +03:00
|
|
|
MalSymbol
|
|
|
|
extend pr-buf
|
2015-02-13 03:27:00 +03:00
|
|
|
unpack-sym str-append ;;
|
|
|
|
drop
|
|
|
|
|
|
|
|
MalKeyword
|
|
|
|
extend pr-buf { kw }
|
|
|
|
s" :" str-append
|
|
|
|
kw unpack-keyword str-append ;;
|
2015-02-06 08:38:34 +03:00
|
|
|
drop
|
2015-02-06 10:38:58 +03:00
|
|
|
|
|
|
|
: insert-\ ( str-addr str-len insert-idx -- str-addr str-len )
|
|
|
|
-rot 0 str-append-char { addr len }
|
|
|
|
dup dup addr + dup 1+ ( i i from to )
|
|
|
|
rot len swap - cmove> ( i ) \ shift " etc to the right
|
|
|
|
addr + [char] \ swap c! \ escape it!
|
|
|
|
addr len
|
|
|
|
;
|
|
|
|
|
|
|
|
MalString
|
|
|
|
extend pr-buf
|
|
|
|
dup MalString/str-addr @
|
|
|
|
swap MalString/str-len @
|
|
|
|
{ addr len }
|
|
|
|
|
|
|
|
s\" \"" str-append
|
|
|
|
0 ( i )
|
|
|
|
begin
|
2015-02-07 07:58:41 +03:00
|
|
|
dup len <
|
|
|
|
while
|
2015-02-06 10:38:58 +03:00
|
|
|
dup addr + c@ ( i char )
|
|
|
|
dup [char] " = over [char] \ = or if ( i char )
|
|
|
|
drop dup addr len rot insert-\ to len to addr
|
|
|
|
1+
|
|
|
|
else
|
2015-02-07 07:58:41 +03:00
|
|
|
dup 10 = if ( i ) \ newline?
|
|
|
|
drop dup addr len rot insert-\ to len to addr
|
2015-02-06 10:38:58 +03:00
|
|
|
dup addr + 1+ [char] n swap c!
|
|
|
|
1+
|
2015-02-07 07:58:41 +03:00
|
|
|
else
|
|
|
|
13 = if ( i ) \ return?
|
|
|
|
dup addr len rot insert-\ to len to addr
|
|
|
|
dup addr + 1+ [char] r swap c!
|
|
|
|
1+
|
|
|
|
endif
|
2015-02-06 10:38:58 +03:00
|
|
|
endif
|
|
|
|
endif
|
|
|
|
1+
|
2015-02-07 07:58:41 +03:00
|
|
|
repeat
|
2015-02-06 10:38:58 +03:00
|
|
|
drop addr len str-append
|
|
|
|
s\" \"" str-append ;;
|
|
|
|
drop
|