42 lines
1.4 KiB
Plaintext
42 lines
1.4 KiB
Plaintext
; Tcl parser — thin layer over tcl-tokenize
|
|
; Adds tcl-parse entry point and word utility fns
|
|
|
|
; Entry point: parse Tcl source to a list of commands.
|
|
; Returns same structure as tcl-tokenize.
|
|
(define tcl-parse (fn (src) (tcl-tokenize src)))
|
|
|
|
; True if word has no substitutions — value can be read statically.
|
|
; braced words are always simple. compound words are simple when all
|
|
; parts are plain text with no var/cmd parts.
|
|
(define tcl-word-simple?
|
|
(fn (word)
|
|
(cond
|
|
((= (get word :type) "braced") true)
|
|
((= (get word :type) "compound")
|
|
(let ((parts (get word :parts)))
|
|
(every? (fn (p) (= (get p :type) "text")) parts)))
|
|
(else false))))
|
|
|
|
; Concatenate text parts of a simple word into a single string.
|
|
; For braced words returns :value directly.
|
|
; For compound words with only text parts, joins them.
|
|
; Returns nil for words with substitutions.
|
|
(define tcl-word-literal
|
|
(fn (word)
|
|
(cond
|
|
((= (get word :type) "braced") (get word :value))
|
|
((= (get word :type) "compound")
|
|
(if (tcl-word-simple? word)
|
|
(join "" (map (fn (p) (get p :value)) (get word :parts)))
|
|
nil))
|
|
(else nil))))
|
|
|
|
; Number of words in a parsed command.
|
|
(define tcl-cmd-len
|
|
(fn (cmd) (len (get cmd :words))))
|
|
|
|
; Nth word literal from a command (index 0 = command name).
|
|
; Returns nil if word has substitutions.
|
|
(define tcl-nth-literal
|
|
(fn (cmd n) (tcl-word-literal (nth (get cmd :words) n))))
|