Camelia, the Perl 6 bug

IRC log for #parrot, 2012-06-08

Parrot | source cross referenced

| Channels | #parrot index | Today | | Search | Google Search | Plain-Text | summary

All times shown according to UTC.

Time Nick Message
01:12 particle joined #parrot
01:54 dalek rakudo/nom: 6ab416b | pmichaud++ | src/ (4 files):
01:54 dalek rakudo/nom: Get binder to recognize QRPAs; let nqp::istype and nqp::islsit inherit from nqp.
01:54 dalek rakudo/nom: review: https://github.com/rakudo/rakudo/commit/6ab416bb56
02:09 dalek m1: 80ebf9c | jimmy++ | t/while.m1:
02:09 dalek m1: fixed t/while.m1 test
02:09 dalek m1: review: https://github.com/parrot/m1/commit/80ebf9c9d8
02:26 dalek parrot/m0: 78d1d89 | jimmy++ | src/m0/perl5/m0_interp.pl:
02:26 dalek parrot/m0: fixed Sha-Bang
02:26 dalek parrot/m0: review: https://github.com/parrot/parrot/commit/78d1d8903a
02:46 dalek m1: e9b889d | jimmy++ | / (2 files):
02:46 dalek m1: fixed run_m1.sh, so it won't ouput warning, also removed unneeded hello.m1
02:46 dalek m1: review: https://github.com/parrot/m1/commit/e9b889de6a
03:08 dalek m1: a7248e6 | jimmy++ | / (3 files):
03:08 dalek m1: add small fix to make test output
03:08 dalek m1: review: https://github.com/parrot/m1/commit/a7248e6f7b
04:43 dalek nqp: 6be8ad9 | pmichaud++ | / (2 files):
04:43 dalek nqp: Fix count overrun bug in QRPA.splice.
04:43 dalek nqp: review: https://github.com/perl6/nqp/commit/6be8ad9fd5
05:26 dalek joined #parrot
06:07 dngor joined #parrot
06:28 fperrad joined #parrot
06:54 he joined #parrot
07:31 brrt joined #parrot
08:11 lucian joined #parrot
08:51 kjs joined #parrot
09:59 kjs joined #parrot
10:09 brrt1 joined #parrot
10:22 JimmyZ joined #parrot
10:25 JimmyZ good morning, ksj
10:25 JimmyZ err, kjs
10:29 kjs hi JimmyZ
10:29 JimmyZ hello
10:30 kjs how are things?
10:33 JimmyZ kjs: not good, don't know how to fix the segfault of m0/c :P
10:36 kjs perhaps there should be some assertions added to M0
10:36 kjs I'm doing that a lot to M1, and they've caught several mistakes of mine
10:37 JimmyZ kjs: I know where/why is segfault. just don't know to fix ;)
10:37 kjs where is it?
10:38 JimmyZ kjs: for obj.m1: https://github.com/parrot/parrot​/blob/m0/src/m0/c/interp.c#L149
10:39 JimmyZ kjs: for func.m1: https://github.com/parrot/parr​ot/blob/m0/src/m0/c/ops.c#L267,  because of frame->registers[ops[1]] = ""
10:39 kjs obj.m1 runs fine on my machine (mac)
10:39 kjs on C-M0
10:40 kjs it's knwon that func won't work on C-M0
10:40 kjs since M0 is not as complete yet. See the mailing list
10:40 JimmyZ kjs: obj.m1 runs fine, because you comment that line ?
10:40 kjs which line?
10:41 JimmyZ https://github.com/parrot/parrot​/blob/m0/src/m0/c/interp.c#L149
10:41 kjs oh i might have. cant remember now
10:41 kjs i thought you put in a fix for that
10:41 * JimmyZ didn't :P
10:43 kjs I don't have time to look into this now unfortunately
10:43 kjs but I think in general we should add more assert()s and set pointers to NULL after being free()d
10:44 JimmyZ kjs: I  heard Nathan Brown will fix it this weekend in the email
10:44 JimmyZ kjs: aye
10:44 kjs i dont think promises were made ;-)
10:45 kjs I hope that a "complete" M1 implementation will motivate others to keep working on M0.
10:46 JimmyZ kjs: me too.
10:48 JimmyZ kjs++ :)
11:18 brrt1 left #parrot
11:30 dalek parrot/m0: 2f4959f | jimmy++ | src/m0/c/ (3 files):
11:30 dalek parrot/m0: fixed the test t/obj.m1 and t/string.m1 in m1 repository
11:30 dalek parrot/m0: review: https://github.com/parrot/parrot/commit/2f4959f6a4
11:30 JimmyZ joined #parrot
11:32 JimmyZ yeah, I fixed two sefault finally
11:34 kjs how did you find out how to fix it?
11:37 kjs JimmyZ: I wonder whether the fix in gc_alloc op is correct
11:38 JimmyZ kjs: yeah
11:38 JimmyZ kjs: that's the problem
11:38 kjs the spec says it's a number of bytes (sizeof(char)) that is allocated
11:38 kjs now it wiill allocate 8 times as much
11:39 JimmyZ kjs: but I don't know whether it's correct or not. I'd like to make it work first
11:39 kjs but if it's not correct, then it's hiding the real cause...
11:40 JimmyZ kjs: hmm, I need add comment 'XXX' again :P
11:40 * JimmyZ dinner&
11:40 kjs because now it's "working" just because there's a whole bunch of memory around (allocated)
11:40 kjs o
11:40 kjs ok
11:43 plobsing joined #parrot
12:12 whiteknight joined #parrot
12:13 whiteknight good morning, #parrot
12:22 lucian joined #parrot
12:30 kjs joined #parrot
12:37 dngor joined #parrot
12:53 not_gerd joined #parrot
12:53 not_gerd hello, #parrot
12:54 whiteknight hello not_gerd. How are you doing today?
12:54 not_gerd fine - the weather's unexpctedly good, so I might not stay around for much longer
12:54 not_gerd cotto: ping
12:55 whiteknight cotto is probably not awake yet
12:56 whiteknight it's probably 6AM there
12:57 not_gerd 6am - best time of the day to do some m0 design ;)
12:58 not_gerd msg cotto currently, m0 string have 2 32-bit header fields (size and encoding) - I'm pondering adding a third for a hash code
12:58 aloha OK. I'll deliver the message.
12:58 kjs not_gerd: hi there.
12:59 not_gerd kjs: hello
12:59 kjs did i remember correclty you were interested in doing a jit for M0?
13:00 not_gerd kjs: a pseudo-jit - translation to a different in-memory representation for faster interpretation
13:00 kjs not something like libjit?
13:00 not_gerd C is not the best target for writing interpreters, which is the reason why the luajit2 one is written in assembler
13:00 not_gerd however, LLVM IR is powerful enough so you can do the same thing, but portable
13:00 not_gerd that's what I'm planning to do
13:01 not_gerd (luajit2 in interpreter mode used to outperform the V8 jit)
13:01 kjs does that mean you'd reimplement M0 interpreter?
13:02 not_gerd yes
13:02 not_gerd but I first want the C implementation to stanilize
13:02 kjs which  language would that be?
13:02 not_gerd ^stabilize
13:02 kjs I thought using existing components such as libjit for jit, and libffi for ffi would be quite handy.
13:03 kjs the perl implementation is more stable :-)
13:03 not_gerd kjs: $any-language - one just needs to generate LLVM IR at compile-time
13:03 kjs as in, working.
13:03 not_gerd kjs: not all issues have been solved
13:03 not_gerd btw, I'mworking on the C implementation right now: https://github.com/parrot/parrot/pull/784
13:05 kjs ok, well obviously you're more knowledgable about those details than me :-)
13:06 kjs I think we should try to include things that have proven to be difficult in Parrot, such as threads, at an early stage
13:08 Psyche^ joined #parrot
13:08 not_gerd the current design has some unresolved issue (memory model/gc probably the most important one) and I'd like to have a working prototype before I start working on 'my' implementation
13:09 kjs sounds like a sound idea. as for the GC, i would expect that's just a subsystem that could be implemented instead of using malloc().
13:13 kjs what do you need for M0 to stabilize? Are those the things on the list you sent the link for
13:13 not_gerd sure, but you need to figure out how to flag PMC registers, how object metadata is stored, etc
13:13 not_gerd I want to know what I need to optimize for before creating an optimized implementation ;)
13:15 kjs it seems that these problems have been solved many times by existing VMs
13:15 not_gerd kjs: but never exactly the same way
13:15 kjs lua for instance, python, ruby
13:16 not_gerd the design of luajit and pypy is quite different
13:16 not_gerd just to name two prominent implementations
13:17 kjs and both are quite fast i believe
13:17 kjs maybe i'm ignorant, but arent we trying to reinvent the wheel?
13:24 not_gerd kjs: nothing wrong with that as long as the perfect wheel hasn't been found...
13:24 kjs not_gerd: that sounds as if you're confident you can find a faster wheel :-)
13:25 not_gerd kjs: not really, but how would I know if I don't try
13:26 not_gerd alternatively, find some money and hire the guys who've been working on dynamic language vms for several decades
13:26 not_gerd don't know how happy they are right now at Google ;)
13:26 kjs ah but there's no fun in that!
13:32 not_gerd msg cotto I'd also like to add CFG_SEED to CONFIG
13:32 aloha OK. I'll deliver the message.
13:51 not_gerd ans with https://github.com/gerdr/parrot/commit/f​5de111022a6eabbbd85afcd4cb1a73d66a876e0 , I'm off for now
13:51 not_gerd ^and
13:52 not_gerd left #parrot
13:53 brambles joined #parrot
13:54 JimmyZ luajit2 is not portable?
13:58 brambles_ joined #parrot
14:04 dalek parrot/m0: c74de6b | jimmy++ | src/m0/c/ops.c:
14:04 dalek parrot/m0: add a comment so we're not hiding the real cause
14:04 dalek parrot/m0: review: https://github.com/parrot/parrot/commit/c74de6b0b6
14:13 jashwanth joined #parrot
14:17 PacoAir joined #parrot
14:51 JimmyZ joined #parrot
15:06 dalek rakudo/nom: 8bb2fad | pmichaud++ | src/core/MapIter.pm:
15:06 dalek rakudo/nom: Use QRPA for ListIter's $!rest in MapIter.
15:06 dalek rakudo/nom: review: https://github.com/rakudo/rakudo/commit/8bb2fadddd
15:22 jashwanth joined #parrot
15:26 alvis not_gerd++ # +1 on https://github.com/parrot/parrot/pull/784
15:34 dmalcolm joined #parrot
16:25 bluescreen joined #parrot
16:42 not_gerd joined #parrot
16:48 not_gerd msg JimmyZ luajit2 is portable insofar as Mike makes mone porting it
16:48 aloha OK. I'll deliver the message.
16:52 alvis aloha: help
16:52 aloha alvis: Ask me for help about: status, insult, auth, chanop, seen, github::announce, infobot, xkcd, convert, msg, vars, karma, maths, translate, github::pullrequests, clock, loader (say 'help <modulename>').
16:52 alvis dalek: help
16:54 alvis dalek is, me thinks, dead. Don't know how to check on it. :(
16:55 Coke they're working on it.
16:55 Coke your commit to CREDITS borked it a bit.
16:57 kjs joined #parrot
17:01 alvis left #parrot
17:01 Coke sorear++ has likely fixed it. momentito.
17:02 alvis joined #parrot
17:08 dalek m1: e1bebdf | kjs++ | src/ (5 files):
17:08 dalek m1: work in progress. small code refactoring. plan for macro for generationg instructions. abstract away scope opening and closing.
17:08 dalek m1: review: https://github.com/parrot/m1/commit/e1bebdfe82
17:22 dalek m1: 4dc64a2 | kjs++ | src/ (3 files):
17:22 dalek m1: improve symbol handling
17:22 dalek m1: review: https://github.com/parrot/m1/commit/4dc64a2ef8
17:31 zby_home joined #parrot
17:34 alvis_ joined #parrot
17:35 contingencyplan joined #parrot
17:45 not_gerd msg cotto any thoughts on https://github.com/parrot/parro​t/pull/784#issuecomment-6208779 ?
17:46 aloha OK. I'll deliver the message.
17:50 moritz anybody wants to make rakudo happy and implement foldcase? it's already in icu: http://icu-project.org/apiref/icu4c/ustring​_8h.html#ab6709b5a5c1606cf0d3ea24934d9acce
17:54 whiteknight moritz: Create a ticket. You can assign it to me initially
17:54 moritz whiteknight: will do, thanks
17:55 whiteknight moritz: What is case-folding?
17:57 moritz whiteknight: it's an operation that canonicalizes the case of a string so that you can compare two strings independently of case
17:57 moritz you can't use upper-caseing for that because then titlecase characters won't compare correctly
17:58 moritz and you can't use lower-casing, because the German 'ß' should compare equal to 'SS', but if you lower-case 'SS', then 'ss' is not equal to 'ß'
17:59 whiteknight ...
17:59 whiteknight languages and encodings are lolfail
18:00 whiteknight If we're going to implement case-folding, we're going to have to do the same thing for ASCII, utf8, utf16, ucs2 and all the other formats we're supposed to supoort
18:00 whiteknight support
18:01 moritz huh? can't we delegate that to ICU?
18:01 whiteknight I don't know. Maybe? I don't know a lot about encodings
18:07 dalek rakudo/nom: 5a415c9 | moritz++ | src/core/Cool.pm:
18:07 dalek rakudo/nom: return Int type object from failed Str.index
18:07 dalek rakudo/nom: review: https://github.com/rakudo/rakudo/commit/5a415c9933
18:07 aloha (parrot/parrot) Issues opened : 786 (Expose icu's FoldCase operation to user space) by moritz : https://github.com/parrot/parrot/issues/786
18:08 mtk joined #parrot
18:22 mtk joined #parrot
18:24 NotFound joined #parrot
18:24 NotFound ~~
18:24 whiteknight hello NotFound
18:25 NotFound Hi
18:28 rindolf joined #parrot
18:29 rindolf Hi all. Should I package parrot-4.4.0 for Mageia Linux or parrot-4.3.0? This page is a little confusing - http://www.parrot.org/download .
18:29 whiteknight 4.3.0, I think
18:29 whiteknight That's the supported one
18:29 NotFound (case-folding): don't need to do it for all encodings, just one. User can recode if they need to.
18:30 whiteknight NotFound: So what happens if somebody calls the casefold op on an ASCII string?
18:30 NotFound whiteknight: one result.
18:31 NotFound source, any.
18:32 moritz fc($ascii) does the same as lc($ascii)
18:32 whiteknight but still, somewhere we need to make that mapping
18:33 rindolf whiteknight: Gentoo have already packaged 4.4.0. :-(
18:33 rindolf So I'll have a false positive here - http://check.mageia.org/cau​ldron/shlomif/updates.html .
18:33 NotFound Yes, but you just need source conevrsion, it will be simpler.
18:34 whiteknight rindolf: They're both good releases. Well-tested and good quality
18:35 rindolf whiteknight: OK.
18:35 rindolf whiteknight: I'll go with 4.3.0 for the time being.
18:36 whiteknight rindolf: Thanks. Sorry about the confusion
18:37 rindolf whiteknight: no problem.
18:37 whiteknight rindolf: Out of curiosity, is there any documentation we could update to have cleared this up sooner?
18:38 rindolf whiteknight: well, maybe the page there.
18:38 whiteknight link?
18:46 rindolf whiteknight: http://www.parrot.org/download
18:47 whiteknight Okay, I'll look at it and make sure it is up to date with information for packagers
18:47 whiteknight rindolf++
19:08 not_gerd bye, #parrot
19:08 not_gerd left #parrot
19:20 rindolf whiteknight: thanks. :-)
19:22 lucian joined #parrot
19:30 TonyC joined #parrot
19:38 nopaste joined #parrot
19:50 brrt joined #parrot
19:57 dmalcolm joined #parrot
20:08 preflex joined #parrot
20:14 preflex_ joined #parrot
20:16 dalek winxed: 82ab077 | NotFound++ | t/medium/0 (3 files):
20:16 dalek winxed: update style and improve check in some tests
20:16 dalek winxed: review: https://github.com/NotFoun​d/winxed/commit/82ab0771a5
20:23 brrt i'm getting a segfault in winxed upon compreg('nqp');
20:31 NotFound brrt: the compreg builtin just generates a compreg op, it must be a parrot initialization problem.
20:31 brrt i've loaded up gdb, but i'm not getting much wises
20:31 brrt wiser
20:32 brrt happens in Parrot_oo_find_vtable_override
20:32 benabik brrt: Does $P0 = compreg 'nqp' also segfault?
20:32 benabik In a PIr file.
20:35 moritz it does not
20:35 moritz at least not here
20:39 brrt joined #parrot
20:40 brrt benabik: i'm checking it out
20:41 fperrad joined #parrot
20:42 brrt nope, no segfault
20:43 brrt compreg is not the problem, load_language is
20:44 brrt oh, whats more
20:44 brrt it doesn't happen with pir
20:47 NotFound brrt --verbose
20:47 brrt :-)... loading 'verbose' module
20:48 brrt when I create a file that contains: function main[main]() { load_language("nqp"); } it segfaults in the aformentioned function
20:49 brrt function main[main]() { compreg("nqp") } does not crash
20:49 NotFound brrt: ugly. It can be a winxed driver problem. What happens if you compile it to pir and run the pir?
20:49 brrt thats what i'm going to try out
20:49 brrt no crash
20:49 brrt NULL PMC access
20:49 brrt but thats ok
20:51 NotFound I need to talk with whiteknight, the winxed driver may need a change, or perhaps the pbc_to_exe generated startup code.
20:51 brrt yes, probably
20:51 brrt and if so I'd probably want to know too
20:52 brrt a propos.. do you know if nqp even registers a HLL compiler?
20:54 NotFound brrt: the nqp bundled with parrot does not work with load_language, because it does not follow the rules about names an location.
20:54 brrt what about the nqp not bundled with parrot
20:54 brrt or for that matter, rakudo
20:55 NotFound brrt: I don't know its current state in that matter.
20:55 brrt hmm, it is of no great importance right now
20:56 rurban brrt: Can you add a testcase for this bug?
20:56 NotFound For the bundled one, examples/nqp.winxed in the winxed source tree works.
21:00 rurban brrt: sorry, forget it.
21:00 brrt oh, thats weird
21:01 brrt NotFound: yes, that one works
21:01 brrt rurban: why forget it?
21:01 rurban When it's not supported and known not to work, why add a testcase
21:02 NotFound brrt: I can't reproduce the problem in parrot master. It just throws "couldn't find a compiler..." for me.
21:02 brrt .. its really weird, and somewhat embarassing
21:02 brrt but i can't reproduce it either anymore
21:03 NotFound This was in a non optimized build, going to try again optimized.
21:03 brrt this is very frustrating indeed
21:04 NotFound rurban: "not to work" can be fine, segfaulting is never fine.
21:04 brrt i'm wondering if my build was just corrupt now
21:05 NotFound brrt: probably a missing dependency in the Makefile
21:05 NotFound It happens sometimes.
21:05 brrt yes, but rather stupid, still
21:05 brrt strange as well, as I haven't been able... oh wait
21:05 brrt i know
21:06 brrt i've just cleaned my parrot directory, and parrot happens to look in the build_dir for its search path
21:06 brrt which is now clean, and thus does not contain problematic files anymore
21:07 NotFound brrt: Installed parrot looks in the build dir?
21:07 brrt i do believe so
21:09 brrt src/library.c, Parrot_lib_update_paths_from_config_hash, line 245
21:10 brrt add $build_dir/runtime/parrot/include to  include, library, lang, dynext
21:10 brrt well, not include, but you get my point
21:11 NotFound Looks like we have 4 config keys with references to the build tree; build_dir, coveragedir, libparrot_likflags and rpath_blib
21:12 brrt build_dir is the one that is used
21:16 rurban Installed parrot has a config logic to ignore build_dir
21:21 brrt .. that can't be it, then?
21:21 brrt ... i'll see if i can ever repeat it
21:21 brrt but I'm going to sleep now
21:22 brrt bye
21:22 rurban I wrote it long ago, but cannot remember exactly
21:26 rurban I looked, only prefix is changed on is_install. libparrot_linkflags  should not be used, inst_libparrot_linkflags instead. rpath_blib is also not used, rpath_lib instead
21:26 rurban In doubt check the config key installed
21:27 NotFound rurban: yes, there is a check for the "installed" key, src/library.c:240
21:28 rurban So builddir should be empty
21:29 rurban I forgot which parts of my make_install patches #3 were never applied. There was something on the wiki
21:29 rurban Some stat optimizations if I remember
21:29 NotFound Not empty, but is not inserted into the default search paths.
21:30 rurban Well builddir=NULL is empty
21:31 NotFound No, is NULL ;)
21:32 rurban oki
21:32 NotFound It doesn't matter in that case, no difference between skipping when NULL and inserting an empty.
21:33 NotFound Uh, no, it does not insert, it adds paths.
21:34 NotFound Now I understand better the conflicts when rebuilding with the same prefix as one already installed.
21:35 rurban You set manually --prefix to `pwd`? That should be forbidden
21:36 NotFound No, that must be even worse.
21:36 rurban in Configure.pl
21:36 dalek m1: e859453 | dukeleto++ | README.md:
21:36 dalek m1: Add note to the readme about running tests
21:36 dalek m1: review: https://github.com/parrot/m1/commit/e85945380f
21:39 dalek nqp: dceb34b | jnthn++ | src/QRegex/Cursor.nqp:
21:39 dalek nqp: Simplify and improve performance of !alt a bit; creates less junk. ~4% improvement on CORE.setting parse time.
21:39 dalek nqp: review: https://github.com/perl6/nqp/commit/dceb34b88b
21:59 dalek nqp: d738608 | jnthn++ | src/QRegex/Cursor.nqp:
21:59 dalek nqp: Similar simplification to !protoregex as just done to !alt; much less noticable difference, probably because we just pick the first answer much of the time and it works out.
21:59 dalek nqp: review: https://github.com/perl6/nqp/commit/d7386080b3
22:03 dalek parrot: 2c97f1c | NotFound++ | config/gen/makefiles/root.in:
22:03 dalek parrot: delete generated pbc_to_exe.pir in prog-clean target
22:03 dalek parrot: review: https://github.com/parrot/parrot/commit/2c97f1cbb3
22:31 dalek nqp: ac5f5fc | jnthn++ | src/ops/nqp.ops:
22:31 dalek nqp: Re-use state arrays in NFA runner, saving roughly a million PMC allocations during CORE.setting parse. Another couple of percent off.
22:31 dalek nqp: review: https://github.com/perl6/nqp/commit/ac5f5fc4a5
22:32 kjs joined #parrot
23:08 kjs make
23:09 kjs woops :-)
23:15 rurban BTW: I use alias m=make
23:19 kjs saving your fingers to type the 3 letters eh ;-)
23:24 kjs joined #parrot
23:40 dalek m1: 69f03a5 | kjs++ | src/ (3 files):
23:40 dalek m1: fix a bug in symbol declaration.
23:40 dalek m1: review: https://github.com/parrot/m1/commit/69f03a5b80
23:40 dalek m1: 49e72cc | kjs++ | src/ (5 files):
23:40 dalek m1: finish scopes the cheap way.
23:41 dalek m1: review: https://github.com/parrot/m1/commit/49e72cc1fe
23:45 whiteknight joined #parrot
23:46 whiteknight good evening, #parrot
23:46 dalek nqp: f60f402 | jnthn++ | src/ops/nqp.ops:
23:46 dalek nqp: Refactor to pull much of the NFA runner out of the op body.
23:46 dalek nqp: review: https://github.com/perl6/nqp/commit/f60f4024e9
23:46 dalek nqp: ba8bf93 | jnthn++ | src/ (3 files):
23:46 dalek nqp: Refactor the NFA ops; we needn't get the ordering back and then push it onto the bstack in a loop, we can just do it right in an op; we've a few other ops that manipulate the bstack after all. Another little win.
23:46 dalek nqp: review: https://github.com/perl6/nqp/commit/ba8bf9311b
23:46 dalek nqp: 35db044 | jnthn++ | src/stage0/ (8 files):
23:46 dalek nqp: Update bootstrap.
23:46 dalek nqp: review: https://github.com/perl6/nqp/commit/35db04446b
23:46 dalek nqp: 7176d14 | jnthn++ | src/ops/nqp.ops:
23:46 dalek nqp: Toss now-unused op.
23:46 dalek nqp: review: https://github.com/perl6/nqp/commit/7176d14a2c
23:53 dalek rakudo/nom: 0fde4a1 | jnthn++ | tools/build/NQP_REVISION:
23:53 dalek rakudo/nom: Use latest NQP for some parsing performance improvements (roughly 8% improvement for CORE.setting).
23:53 dalek rakudo/nom: review: https://github.com/rakudo/rakudo/commit/0fde4a1e37
23:56 kid51 joined #parrot

| Channels | #parrot index | Today | | Search | Google Search | Plain-Text | summary

Parrot | source cross referenced