G'day everyone
I'm writing a translator which will take a Lisp-ish way of writing a language and outputting it in a more XML-ish form.
This means taking this:
(sai (ITEFORLITLITLITLIT 999999999 1 1 (SAYOPRCAP (SAYVALFOR ...) "thing"))(sayvar goose))
and changing it into this:
<@ sai><@ ITEFORLITLITLITLIT>999999999|1|1|<@ SAYOPRCAP><@ SAYVALFOR>...</@>|thing</@></@><@ sayvar>goose</@></@>
My problem is that the code below almost works, except that it converts to this:
<@ sai><@ ITEFORLITLITLITLIT>999999999|1|1|<@ SAYOPRCAP><@ SAYVALFOR>...</@>|thing</@></@>|<@ sayvar>goose</@></@>
In case you missed it, the difference is the presence of the bar character just before the <@ sayvar>goose, which is clearly "the wrong thing"
Given the recursive nature of the 'proc' define, why am I always getting the bar appearing? The rule, BTW, is that SAI's arguments (and a few others) are never bar separated, but all others have arguments separated by bar.
Kind regards,
Bruce.
P.S. Windows version of newLisp. Development version. UTF-8 EXE.
(setq res "")
(define (proc procode)
(local (codelen code separator elider)
(begin
(setq codelen (length procode))
(for (i 0 (- codelen 1) 1)
(begin
(setq code (procode i))
(when (= i 0) (setq res (append res "<@ " (string code) ">" )))
;at this point, check to see whether OMT and SAI things are used
;if so, set the separator to empty string
(setq elider (find (upper-case (string code)) '("OMT" "SAO" "OSA" "SAI" "OSI" "SAW" "OSW")))
(if (nil? elider)
(setq separator "|")
(setq separator "")
)
(when (> i 0 )
(if
(list? code) (proc code)
(atom? code) (setq res (append res (string code) ) )
)
(if (< i (- codelen 1))
(begin
(setq res (append res separator ))
)
)
)
(when (= i (- codelen 1))
(setq res (append res "</@>" ))
)
)
)
)
)
)
(setq code "(sai (ITEFORLITLITLITLIT 999999999 1 1 (SAYOPRCAP (SAYVALFOR ...) "thing"))(sayvar goose))")
(setq parsed (read-expr code))(println $0)
(proc parsed)
(print res)
(exit)
Hi - I had a go at running this, but nothing leaped out to say "this is why"... Sorry.
Perhaps you could make a simplified version of the code to see if there are any logic errors in it? And perhaps you could try stepping through the debugger with it - that's often a good way to spot what's happening.
I think I've got it partly figured out. Still have to come up with a solution, though.
(when (> i 0 )
(if
(list? code) (proc code)
(atom? code) (setq res (append res (string code) ) )
)
(if (< i (- codelen 1))
(begin
(setq res (append res separator ))
)
)
)
When one returns from the 'proc' routine, control falls to the end of the (when) thus missing the separator stuff.
Is that really the problem? I just don't know.
Bruce.
Nope. Dead end.
s(setq res "")
(define (proc procode)
(local (codelen code separator elider)
(begin
(setq codelen (length procode))
(for (i 0 (- codelen 1) 1)
(begin
(setq code (procode i))
(when (= i 0) (setq res (append res "<@ " (string code) ">" )))
;at this point, check to see whether OMT and SAI things are used
;if so, set the separator to empty string
(setq elider (find (upper-case (string code)) '("OMT" "SAO" "OSA" "SAI" "OSI" "SAW" "OSW")))
(if (nil? elider)
(setq separator "|")
(setq separator "")
)
(when (> i 0 )
(if
(list? code) (proc code)
(atom? code) (setq res (append res (string code) ) )
)
)
(when (> i 0)
(if (< i (- codelen 1))
(setq res (append res separator ))
)
)
(when (= i (- codelen 1))
(setq res (append res "</@>" ))
)
)
)
)
)
)
(setq code "(sai (ITEFORLITLITLITLIT 999999999 1 1 (SAYOPRCAP (SAYVALFOR ...) "thing"))(sayvar goose))")
(setq parsed (read-expr code))(println $0)
(proc parsed)
(print res)
(exit)
Try this
...
(local (h codelen code separator elider) # add `h` (head of current list)
...
(when (= i 0) (setq h code # set `h` here
res (append res "<@ " (string code) ">" )))
...
(setq elider (find (upper-case (string h)) '("OMT" "SAO" "OSA" "SAI" "OSI" "SAW" "OSW"))) # change `code` to `h`
...
Here is the full code:
(setq res "")
(define (proc procode)
(local (h codelen code separator elider)
(begin
(setq codelen (length procode))
(for (i 0 (- codelen 1) 1)
(begin
(setq code (procode i))
(when (= i 0) (setq h code res (append res "<@ " (string code) ">" )))
;at this point, check to see whether OMT and SAI things are used
;if so, set the separator to empty string
(setq elider (find (upper-case (string h)) '("OMT" "SAO" "OSA" "SAI" "OSI" "SAW" "OSW")))
(if (nil? elider)
(setq separator "|")
(setq separator "")
)
(when (> i 0 )
(if
(list? code) (proc code)
(atom? code) (setq res (append res (string code) ) )
)
(if (< i (- codelen 1))
(begin
(setq res (append res separator ))
)
)
)
(when (= i (- codelen 1))
(setq res (append res "</@>" ))
)
)
)
)
)
)
(setq code "(sai (ITEFORLITLITLITLIT 999999999 1 1 (SAYOPRCAP (SAYVALFOR ...) "thing"))(sayvar goose))")
(setq parsed (read-expr code))(println $0)
(proc parsed)
(print res)
(exit)
The result is:
<@ sai><@ ITEFORLITLITLITLIT>999999999|1|1|<@ SAYOPRCAP><@ SAYVALFOR>...</@>|thing</@></@><@ sayvar>goose</@></@>
Is this what you want?
kks,
Yes, that's marvellous. Thanks very much. I can now get on with the rest of the project (and figure out why your fix works.)
Kind regards,
Bruce.