Not just your directory, the repo is in a mess. I left arc a vibrant cottage industry a month ago, and have returned to a ghost town, it seems :( Can you answer another question of mine?
For a time you could call apply on macros. That ability seems to have fallen off since the support for the call* table. I noticed you tried to add it after, but nex3 reverted the change. I've been struggling to create an entry for macros in call using just two args, without success. It seems the only way is to add an ugly special case into ar-apply. Have you thought about this at all?
Heh, let me know if I'm making no sense, and I'll include commit ids, etc.
parsecomb.arc has not been maintained. The current parser combinator library that is maintained is raymyers's lib/treeparse.arc , but you have to coerce strings to parse into 'cons cells.
For that matter the fix in lib/parsecomb.arc should probably be to mapdelay:
Yeah, that was the first thing I was going to try, then I got sidetracked :)
Can you elaborate on how I can use treeparse for more generalized parsing? Like if I just have a file with flat text and want to generate a list of strings separated by empty lines?
treeparse is very generalized, so expect to write a lot of code.
As for files: the lib/scanner.arc library allows you to treat input streams (e.g. input files) as if they were a list of characters, which is what treeparse accepts (treeparse can work with "real" lists and scanners).
Treeparse usually returns a list of characters, but this behavior can be modified by using a 'filt parser.
Just off the top of my head (untested!):
(require "lib/scanner.arc")
(require "lib/treeparse.arc") ; could use cps_treeparse.arc
(let (list-str newline line oneline lastline allparse) nil
; converts a list of chars to a string
(= list-str
[string _])
; support \r\n, \n\r, \n, and \r
(= newline
; alt & seq's semantics should be obvious
(alt
(seq #\return #\newline)
(seq #\newline #\return)
#\newline
#\return))
(= line
; lots of characters that could be anything...
; but *not* newlines!
(many (anything-but newline)))
(= oneline
(seq line
newline)))
; in case the last line doesn't end in newline
(= lastline
line)
(= allparse
(seq
; many is greedy, but will still pass
; if there are none
(many
; the filter function has to return a list
(filt [list (list-str _)]
oneline))
; might not exist; will still pass whether
; it exists or not
(maybe
(filt [list (list-str _)]
lastline))))
(def lines-from-scanner (s)
(parse allparse s)))
(def lines-from-file (f)
(w/infile s f
(lines-from-scanner (scanner-input s))))
p.s. performance may be slow. cps_treeparse.arc is a more optimized version (maybe 25% faster on average, which most of the speedup in many and seq IIRC, which could be twice the speed), but does not support the "semantics" feature.
Achtung! The CPS variant is written in, of all things, continuation passing style, which is hard on the eyes. It is thus expected to be much harder to read than the straightforward treeparse.
Achtung! In a single Arc session, it is safe to use only treeparse or cps_treeparse. Never load both in the same session.
Achtung! Some of treeparse's features are not supported by cps_treeparse.
doesn't work when s is a scanner -- s remains unchanged. I looked at the code and convinced myself that macros like zap that call setforms won't work for new types. Does that make sense?