aboutsummaryrefslogtreecommitdiff
path: root/libs/fstring.neb
blob: f4967d6b52fbcc8715b376e14f0180bc92c9373d (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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
; bugs:
;#16> (fmt "{x} x {")
;exception! <class 'NameError'> name 'ev' is not defined


(func .fmt-parse (str cur)
    (branch
        ((eq? 0 (length str)) cur)
        ((eq? "{" (first str))
            (block
                (def tmp (.brace-parse (rest str) ""))
                (.fmt-parse (first tmp) (concat cur (first (rest tmp))))))
        (#true (.fmt-parse (rest str) (concat cur (first str))))))

(func .brace-parse :[:string] (str :string cur :string)
    ; returns (remaining value)
    (branch
        ((eq? "}" (first str))
            (list (rest str) (->string (eval (first (parse-neb cur))))))
            ;(list (rest str) (eval (first (parse-neb cur)))))
        ((eq? "," (first str))
            (.special-parse (rest str) "" (->string (eval (first (parse-neb cur))))))
            ;(.special-parse (rest str) "" (eval (first (parse-neb cur)))))
        (#true
            (.brace-parse (rest str) (concat cur (first str))))))

(func .fill-parse (str)
    (if
        (or
            (eq? 0 (length str))
            (in? (first str) (split "^<>")) ; these are aligns
            (try
                (block
                    (string->int (first str)) ; these are widths
                    #true)
                #false))
        (list str " ")
        (list (rest str) (first str))))

(func .align-parse (str)
    (if (in? (first str) (split "^<>"))
        (list (rest str) (first str))
        (list str ">")))

(func .number-parse (str cur)
    (def ret
        (try
            (string->int (first str))
            _panic_))
    (if (eq? :int (typeof ret))
        (.number-parse (rest str) (concat cur (first str)))
        (branch
            ((eq? 0 (length cur)) (list str 0))
            (#true (list str (string->int cur))))))

(func .special-parse (str cur val)
    (if (eq? "}" (first str))
        (block

            ; ,[[fill]align][width]
            ; where fill cannot be a number or ^<>

            ; there's gotta be a more elegant way to do this
            (def fill-parse (.fill-parse cur))
            (def fill (last fill-parse))
            (def align-parse (.align-parse (first fill-parse)))
            (def align (last align-parse))
            (def width-parse (.number-parse (first align-parse) ""))
            (def width (last width-parse))

            (branch
                ((>= (length val) width)
                    (list (rest str) val))
                ((eq? "<" align)  ; align left
                    (list (rest str) (concat val (.repeat (- width (length val)) fill))))
                ((eq? ">" align)  ; align right
                    (list (rest str) (concat (.repeat (- width (length val)) fill) val)))
                (#true  ; align center
                    (block
                        (def half (/ (- width (length val)) 2))
                        (if (int? half)
                            (list (rest str) (concat (.repeat half fill) val (.repeat half fill)))
                            (list (rest str) (concat (.repeat (floor half) fill) val (.repeat (+ 1 (floor half)) fill))))))))

        (.special-parse (rest str) (concat cur (first str)) val)))

(func .repeat (cnt) (.repeat cnt " "))

(func .repeat (cnt char)
    (def out "")
    (for-count cnt
        (redef out (concat out char)))
    out)


(func fmt :string (inp :string)
    ; { <neb code> , [[fill character][^<>]][:digits:]}
    (.fmt-parse inp ""))