Open gregspurrier opened 9 years ago
Do you treat symbols that end in .
differently? because thats when it fails for me here.
Also, it fails inside shen.elim-def
:
faust ~/p/s/shen-ruby git:master✓ > ./bin/srrepl
Loading.... Completed in 4.02 seconds.
Shen, copyright (C) 2010-2015 Mark Tarver
www.shenlanguage.org, Shen 17
running under Ruby, implementation: ruby 2.0.0
port 0.13.0 ported by Greg Spurrier
(0-) (read-from-string "(defcc <a> a := [/.];)")
[[defcc <a> a := [cons /. []] ;]]
(1-) (shen.elim-def (hd (read-from-string "(defcc <a> a := [/.];)")))
undefined method `hd' for nil:NilClass
(2-) (shen.elim-def [/.])
[/.]
(3-) (shen.elim-def (hd (read-from-string "(defcc <a> a := [a.];)")))
undefined method `hd' for nil:NilClass
(4-) (shen.elim-def (hd (read-from-string "(defcc <a> a := [/.a];)")))
[defun <a> [V583] [if [and [cons? [hd V583]] [= a [hd [hd V583]]]] [shen.pair [hd [shen.pair [tl [hd V583]] [shen.hdtl V583]]] [cons /.a []]] [fail]]]
Ok, I know why it fails. It doesn't break on chibi-shen because I use my own overwritten version of shen.grammar_symbol?
.
This is a bug in Shen, I would suggest that for now you use your own custom version of shen.grammar_symbol?
.
The problem (in yacc.shen):
(define grammar_symbol?
S -> (and (symbol? S)
(let Cs (strip-pathname (explode S))
(and (= (hd Cs) "<") (= (hd (reverse Cs)) ">")))))
(define strip-pathname
Cs -> Cs where (not (element? "." Cs))
[_ | Cs] -> (strip-pathname Cs))
strip-pathname
doesn't take into account that some symbols may end with .
and still considers those as namespaced, this breaks for /.
. In that case it returns an empty list and thats why it ends doing (hd [])
.
I'm going to report this to Mark using the bug submission form.
For reference, here is the super ugly version I'm using in chibi-shen:
(define (scm.shen-grammar_symbol? val)
(and (symbol? val)
(let* ((s (symbol->string val))
(end (string-cursor-end s))
(start (string-cursor-start s))
(c (string-cursor-prev s end)))
(and (equal? #\> (string-cursor-ref s c))
(or (equal? #\< (string-cursor-ref s start))
(let loop ((c (string-cursor-prev s c)))
(if (or (string-cursor<? c start)
(equal? #\. (string-cursor-ref s c)))
(equal? #\< (string-cursor-ref s (string-cursor-next s c)))
(loop (string-cursor-prev s c)))))))))
Oh. Interesting. So my initial suspicion about it being the behavior of (hd [])
was correct after all. Thanks for debugging this and reporting it to Mark.
For now I can work around it with (defcc <a> a := [(intern "/.")];)
.
Ok, good. If you decide to override Shen's code my suggestion is to re-use shen.grammar_symbol?
as-is, with an extra check for /.
. Somthing like:
(define grammar_symbol?
S -> (and (symbol? S) (not (= S /.))
(let Cs (strip-pathname (explode S))
(and (= (hd Cs) "<") (= (hd (reverse Cs)) ">")))))
This works in both the SBCL and chibi-scheme ports. The latter is important because, like ShenRuby, chibi-shen raises an error when
hd
is applied to the empty list. This suggests this is a ShenRuby bug rather than a case of Shen accidentally relying on(hd [])
returning[]
as it does in the CL ports.