aboutsummaryrefslogtreecommitdiff
path: root/ps/printer.ps
blob: 956bb18d812091be574d748faf254aa2fcec4cd9 (plain)
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
(in printer.ps\n) print

% requires types.ps to be included first

% ast print_readably -> _pr_str -> string
/_pr_str { 4 dict begin
    /print_readably exch def
    dup
    /func? exch xcheck def % executable function
    /obj exch cvlit def
    obj _sequential? {
        obj _list? { (\() (\)) }{ ([) (]) } ifelse
        obj /data get ( ) print_readably _pr_str_args
        exch concatenate concatenate
    }{ obj _hash_map? {
        ({)
        % get array of contents with keys stringified
        [ obj /data get { exch dup length string cvs exch } forall ]
        ( ) print_readably _pr_str_args
        concatenate
        (}) concatenate
    }{ obj _mal_function? { % if user defined function
        (<\(fn* )
        obj /params get print_readably _pr_str
        ( )
        obj /ast get print_readably _pr_str
        (\)>)
        concatenate concatenate concatenate concatenate
    }{ obj _atom? { % if atom
        (\(atom ) 
        obj /data get print_readably _pr_str
        (\))
        concatenate concatenate
    }{ /arraytype obj type eq { % if list or code block
        % accumulate an array of strings
        func? { (<builtin_fn* { ) }{ (\() } ifelse
        obj ( ) print_readably _pr_str_args
        concatenate
        func? { ( } >) }{ (\)) } ifelse
        concatenate
    }{ /integertype obj type eq { % if number
        /slen obj 10 add log ceiling cvi def
        obj 10 slen string cvrs
    }{ /stringtype obj type eq { % if string
        print_readably {
            (") obj (") concatenate concatenate
        }{
            obj
        } ifelse
    }{ null obj eq { % if nil
        (nil)
    }{ true obj eq { % if true
        (true)
    }{ false obj eq { % if false
        (false)
    }{ /nametype obj type eq { % if symbol
        obj dup length string cvs
    }{
        (<unknown>)  
    } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse
end } def

% array delim print_readably -> _pr_str_args -> new_string
/_pr_str_args { 3 dict begin
    /print_readably exch def
    /delim exch def
    /args exch def
    ()
    args length 0 gt { %if any elements
        [
            args { %foreach argument in array
                print_readably _pr_str
            } forall 
        ]
        { concatenate delim concatenate } forall
        dup length delim length sub 0 exch getinterval % strip off final delim
    } if
end } def