Maxime Devos <maximede...@telenet.be> writes: > [[PGP Signed Part:Undecided]] > Op 30-09-2023 om 15:17 schreef Christine Lemmer-Webber: >> Haven't fully caught up on this thread, but as a side note I have a >> mostly-finished implementation of a Wisp parser which takes a very >> different approach than Arne's, and was more understandable to me >> personally, a bit more functional and recursive-descent style. >> I could make it available if anyone is curious. >> Would love to see Wisp in Guile proper! > > I think I technically can't count as ‘curious’ here, as I don't think > I'll actually read this other implementation, but I would be > interested in it nonetheless (to potentially replace Arne's > implementation later, once it's complete), because it sounds like you > might have avoided the REPR (*) bug thing from Arne's implementation. > > (*) Extremely unlikely to be a problem in practice, but still a bug. > > Best regards, > Maxime Devos.
Well it looks like I did make it available already, I just forgot, and didn't advertise it much: https://gitlab.com/dustyweb/rewisp/-/blob/main/rewisp.scm?ref_type=heads It really isn't very complete, but here's some of the example data I was using: (define wisp-fac-noinfix-repeat "\ define : factorial n ; foo __ if : zero? n ____ . 1 ____ * n : factorial : - n 1 define : factorial n __ if : zero? n ____ . 1 ____ * n : factorial : - n 1") scheme@(rewisp)> ,pp (parse-lines->sexp (call-with-input-string wisp-fac-noinfix-repeat read-wisp-lines)) $6 = ((define (factorial n) (if (zero? n) 1 (* n (factorial (- n 1))))) (define (factorial n) (if (zero? n) 1 (* n (factorial (- n 1)))))) What's kind of interesting is to look at it before the parse-lines->sexp step though: scheme@(rewisp)> ,pp (call-with-input-string wisp-fac-noinfix-repeat read-wisp-lines) $7 = (#<<line> indent: 0 args: (#<syntax:unknown file:1:0 define> (#<syntax:unknown file:1:9 factorial> #<syntax:unknown file:1:19 n>))> #<<line> indent: 4 args: (#<syntax:unknown file:2:4 if> (#<syntax:unknown file:2:9 zero?> #<syntax:unknown file:2:15 n>))> #<<line> indent: 7 args: (#<<DOT> source-loc: #(#f 2 7)> #<syntax:unknown file:3:9 1>)> #<<line> indent: 7 args: (#<syntax:unknown file:4:7 *> #<syntax:unknown file:4:9 n> (#<syntax:unknown file:4:13 factorial> (#<syntax:unknown file:4:25 -> #<syntax:unknown file:4:27 n> #<syntax:unknown file:4:29 1>)))> #f #<<line> indent: 0 args: (#<syntax:unknown file:6:0 define> (#<syntax:unknown file:6:9 factorial> #<syntax:unknown file:6:19 n>))> #<<line> indent: 4 args: (#<syntax:unknown file:7:4 if> (#<syntax:unknown file:7:9 zero?> #<syntax:unknown file:7:15 n>))> #<<line> indent: 7 args: (#<<DOT> source-loc: #(#f 7 7)> #<syntax:unknown file:8:9 1>)> #<<line> indent: 7 args: (#<syntax:unknown file:9:7 *> #<syntax:unknown file:9:9 n> (#<syntax:unknown file:9:13 factorial> (#<syntax:unknown file:9:25 -> #<syntax:unknown file:9:27 n> #<syntax:unknown file:9:29 1>)))>) So what it does is rewisp builds up a set of lines and parses each line individually, noting its indentation level and the "arguments" that appear in it. It then has a separate step to assemble it into a sexp structure by examining the indentation level and whether or not it sees the special <DOT> record. Guile's syntax records are used so that this would be able to work correctly with the rest of Guile's tools. So, that's it... first, read each line one by one, don't try to figure out its relationship to the other lines, and we have a flat structure. Next, turn that flat structure into a nested structure. I thought the design was pretty good. - Christine