Re: [COMMIT] Subs and co-routines in Parrot
On Sat, Jun 08, 2002 at 01:15:48AM -0400, Dan Sugalski wrote: > First, we need to beef up ret, but that's a problem of definition. It > should walk the control stack until it hits something it can return, > so we can undo exception handler pushes, scope change, and suchlike > things. (My problem, I'll update the docs) Why does ret need to be so smart? We can have an opcode that pop exception handlers (we need it anyway) and a ret that just return. If this turn out later to be a performance bottleneck, it will always be possible to optimize this by adding an opcode that performs both. > Second, in the final go, the callco op won't be needed--call should > be sufficient, but that'll need support in the PMCs. Alternatively, I think you can just replace the definition of yield by: inline op yield (in INT) { struct Parrot_Sub * sub = (struct Parrot_Sub*)interpreter->pmc_reg.registers[0]->data; sub->init = OFFSET($1); stack_pop(interpreter, interpreter->control_stack, &dest, STACK_ENTRY_DESTINATION); goto ADDRESS(dest); } -- Jerome
Re: Subs for parrot
On Fri, Jun 07, 2002 at 01:50:27AM -0400, Dan Sugalski wrote: > So, in total, we need: > > *) Original routine entry point > *) Current routine entry point > *) Native/bytecode flag > *) Opcode table > *) Global namespace chain > *) "default" lexical scope > *) All the register sets > *) All the stack frames > > Needless to say, we don't want all subs to switch this in--we want > perl 6 *faster* than perl 5, not slower. Because of this, it seems to > make sense to have multiple PMCs that have specialized knowledge of > how to invoke themselves, as well as a vtable entry for invocation. Making a function call via a vtable entry does not seems cheap to me, especially when you consider that in the common case, you only need to save the return address and jump to the sub entry point. (Switching the global namespace chain and the lexical scope does not cost anything: it just means passing the closure as an additional argument to the sub.) A continuation can be invoked just like any other function. The first opcode of its body can then switch the stack frames. (The register do not need to be switched if we specify that callcc does not preserve them.) Switching to native call and switching the opcode table is probably the trickiest point. Maybe we can use a stub: the body of the sub would be a special opcode that performs the switch, executes the sub, and returns. I don't think this is signifiantly slower than what you are proposing. And it may be possible to inline the stub body. -- Jerome
Re: [COMMIT] Subs and co-routines in Parrot
At 09:50 AM 6/8/2002 +0200, Jerome Vouillon wrote: >Alternatively, I think you can just replace the definition of yield >by: > > inline op yield (in INT) { > struct Parrot_Sub * sub = > (struct Parrot_Sub*)interpreter->pmc_reg.registers[0]->data; > sub->init = OFFSET($1); > stack_pop(interpreter, interpreter->control_stack, > &dest, STACK_ENTRY_DESTINATION); > goto ADDRESS(dest); > } What would that accomplish? If yield is to suspend the current coroutine and return back to the controlling context, you don't need an argument to yield, unless you wish to yield and jump to a different address than you were called from, but is that the semantics of a co-routine yielding? -Melvin
Re: [COMMIT] Subs and co-routines in Parrot
At 09:50 AM 6/8/2002 +0200, Jerome Vouillon wrote: >On Sat, Jun 08, 2002 at 01:15:48AM -0400, Dan Sugalski wrote: > > First, we need to beef up ret, but that's a problem of definition. It > >Why does ret need to be so smart? We can have an opcode that pop >exception handlers (we need it anyway) and a ret that just return. If >this turn out later to be a performance bottleneck, it will always be >possible to optimize this by adding an opcode that performs both. Because ret needs to do more than pop exception handlers. It needs to know how to restore the state of the caller. If you call a routine that brings its own environment, that environment needs to be restored on ret. Right now all it does is pop the return address from the global interpreter control stack, but continuations, etc. will have their own control stack, so they must restore the caller's before returning. Also if the callee has to return values we have to get those values to the caller somehow. Since we aren't on the caller's stack, we have to transfer return values implicitly. The Java VM does this by popping values off of the local stack, and onto the callee's stack upon return. -Melvin
Re: Apoc 5 questions/comments
On Fri, 7 Jun 2002, Peschko, Edward wrote: : Let me get this straight. the grammar of Perl is reprogrammable, : and expressed in perl6. And a script is parsed using this grammar, : on the fly, hence portions of scripts could have different grammars : than other parts. Where have you been for the last two years? This is not news. : So exactly how is this going to be fast? I'm assuming that perl : gets its speed in parsing its own code by having the parser/lexer : code written in C and compiled to machine code form - as I see it, : there would be a lot of overhead in running any modifiable on-the-fly : parser - wouldn't the parser itself have to be recompiled each time : the script was being parsed, before any compilation pass was made? No, the standard parser will be distributed as Parrot machine code. This is a conventional language bootstrap on an unconventional machine. : And if the syntax of the regex engine *itself* was being modified, : wouldn't there have to be a 'source' regex engine that was used to : parse the modified regex engine, bootstrap itself, and which then : would be used to compile perl? No, you're confusing the run-time engine with the parser. The regex engine is Parrot itself, which is written in C. There is no separate regex engine. : And what's the deal with this caller(MY).parser stuff? That indicates in the abstract that we're switching parsers for the rest of the caller's lexical scope. Don't take the particular notation too seriously. But it's fundamental to Perl 6 that the "mumble" of mumble { ... } is allowed to have control of how the ... is parsed. : Oh boy now I've gone and done it. *My* head's exploded. If your head has exploded, you should avoid sausage factories. Larry
Re: Near-term schedule
On Fri, Jun 07, 2002 at 11:23:56PM -0400, Dan Sugalski wrote: > 2) A revamped stack system so we can support exceptions What is the intent for stacks ? -- Jason
Re: several changes committed (IO, miniparrot)
At 12:55 AM -0400 6/8/02, Josh Wilmes wrote: > >Although I should mention that it's not verifying the presence of these >headers- it just assumes they are available. It does that because the >intent is to use this has_header.h for miniparrot, where we won't be doing >any probing. The assumption is that if C89 says it will be there, it will >be there, darn it. This is perfectly fine. We're assuming a minimum C89 level of ANSI compiler compliance. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: [COMMIT] Subs and co-routines in Parrot
On Sat, Jun 08, 2002 at 12:30:36PM -0400, Melvin Smith wrote: > Right now all it [ret] does is pop the return address from the global > interpreter control stack, but continuations, etc. will have their own > control stack, so they must restore the caller's before returning. Continuations never return. I don't see what other kind of functions may have their own stack. [...] > The Java VM does this by popping values off of the local stack, and > onto the callee's stack upon return. I think this is a design mistake of the Java VM. It would have been more efficient to keep the local variables on the stack. -- Jerome
Re: [COMMIT] Subs and co-routines in Parrot
On Sat, Jun 08, 2002 at 12:20:55PM -0400, Melvin Smith wrote: > At 09:50 AM 6/8/2002 +0200, Jerome Vouillon wrote: > >Alternatively, I think you can just replace the definition of yield > >by: > > > >inline op yield (in INT) { > > struct Parrot_Sub * sub = > >(struct Parrot_Sub*)interpreter->pmc_reg.registers[0]->data; > > sub->init = OFFSET($1); > > stack_pop(interpreter, interpreter->control_stack, > >&dest, STACK_ENTRY_DESTINATION); > > goto ADDRESS(dest); > >} > > What would that accomplish? > > If yield is to suspend the current coroutine and return back to the > controlling context, you don't need an argument to yield, unless you > wish to yield and jump to a different address than you were called > from, but is that the semantics of a co-routine yielding? You mentioned in a previous mail: "On a return, we can set the entry address back to the "start" of the co-routine for another call." The argument to the "yield" opcode was intended to allow this. But you're right: one could just as well put a "branch" just after the "yield". -- Jerome
Re: [COMMIT] Subs and co-routines in Parrot
On Fri, Jun 07, 2002 at 07:40:14PM -0400, Melvin Smith wrote: > The support isn't complete, for example, co-routines, etc. need to > swap in their own context, which right now they don't do. Instead of using some space on the stack, co-routines can store all their local variables into their closure. Then, there is no need to swap in any context. -- Jerome
Re: Subs for parrot
At 10:40 AM +0200 6/8/02, Jerome Vouillon wrote: >On Fri, Jun 07, 2002 at 01:50:27AM -0400, Dan Sugalski wrote: >> So, in total, we need: >> >> *) Original routine entry point >> *) Current routine entry point >> *) Native/bytecode flag >> *) Opcode table >> *) Global namespace chain >> *) "default" lexical scope >> *) All the register sets >> *) All the stack frames >> >> Needless to say, we don't want all subs to switch this in--we want >> perl 6 *faster* than perl 5, not slower. Because of this, it seems to >> make sense to have multiple PMCs that have specialized knowledge of >> how to invoke themselves, as well as a vtable entry for invocation. > >Making a function call via a vtable entry does not seems cheap to me, >especially when you consider that in the common case, you only need to >save the return address and jump to the sub entry point. >(Switching the global namespace chain and the lexical scope does not >cost anything: it just means passing the closure as an additional >argument to the sub.) Indirect function calls will take maybe 50 cycles, so I'm not worried about their time. Compared to perl 5, that's fast. There's more to it than that, though, on sub entry. Getting the right environment is more than just passing in a closure. >A continuation can be invoked just like any other function. The first >opcode of its body can then switch the stack frames. (The register do >not need to be switched if we specify that callcc does not preserve >them.) The thing with continuations is that the code we're invoking won't know its a continuation. That information's kept as metadata in the sub PMC. (And we do need to restore the registers, otherwise we're going to see a lot of stack pushing and popping every time we take a continuation, and I don't know that it's worth it) >Switching to native call and switching the opcode table is probably >the trickiest point. Maybe we can use a stub: the body of the sub >would be a special opcode that performs the switch, executes the sub, >and returns. I don't think this is signifiantly slower than what you >are proposing. And it may be possible to inline the stub body. I'm proposing we abstract it all away and embed all the code in the sub invocation vtable entry. That way the code can be a straight-line, specialized chunk that does exactly what's needed with no twiddling about with conditionals or whatnot. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: [COMMIT] Subs and co-routines in Parrot
At 9:50 AM +0200 6/8/02, Jerome Vouillon wrote: >On Sat, Jun 08, 2002 at 01:15:48AM -0400, Dan Sugalski wrote: >> First, we need to beef up ret, but that's a problem of definition. It >> should walk the control stack until it hits something it can return, >> so we can undo exception handler pushes, scope change, and suchlike >> things. (My problem, I'll update the docs) > >Why does ret need to be so smart? We can have an opcode that pop >exception handlers (we need it anyway) and a ret that just return. If >this turn out later to be a performance bottleneck, it will always be >possible to optimize this by adding an opcode that performs both. There's more than just exception handlers going on the control stack. Anything that needs rolling back or undoing (like localized variables or scope entry) will have an undo marker put on the control stack that gets called when we pop its entry off the control stack. It's an easy way to remember overwritten values--you put an "overwritten" entry on the control stack with the old value, and we restore it when we pop the entry off the stack. > > Second, in the final go, the callco op won't be needed--call should >> be sufficient, but that'll need support in the PMCs. > >Alternatively, I think you can just replace the definition of yield >by: > > inline op yield (in INT) { > struct Parrot_Sub * sub = > (struct Parrot_Sub*)interpreter->pmc_reg.registers[0]->data; > sub->init = OFFSET($1); > stack_pop(interpreter, interpreter->control_stack, > &dest, STACK_ENTRY_DESTINATION); > goto ADDRESS(dest); > } Bit too simplistic there--we need to potentially return data from the yield, the stacks need to have their current positions remembered, the caller's stacks need to be restored (I think--we might be able to cheat with this one a bit), and the rest of the register sets need remembering for later resumption. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Near-term schedule
At 1:43 PM -0400 6/8/02, Jason Gloudon wrote: >On Fri, Jun 07, 2002 at 11:23:56PM -0400, Dan Sugalski wrote: > >> 2) A revamped stack system so we can support exceptions > >What is the intent for stacks ? They need to be more formally turned to frames (though each sub may have multiple frames), the frame data needs to be decoupled from the frame metadata, and we need to implement COW for both the frame metadata and the frame data. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: [COMMIT] Subs and co-routines in Parrot
At 8:15 PM +0200 6/8/02, Jerome Vouillon wrote: >On Sat, Jun 08, 2002 at 12:30:36PM -0400, Melvin Smith wrote: >> Right now all it [ret] does is pop the return address from the global >> interpreter control stack, but continuations, etc. will have their own >> control stack, so they must restore the caller's before returning. > >Continuations never return. I don't see what other kind of functions >may have their own stack. Co-routines. >[...] >> The Java VM does this by popping values off of the local stack, and >> onto the callee's stack upon return. > >I think this is a design mistake of the Java VM. It would have been >more efficient to keep the local variables on the stack. Yeah, that's too much work for me. I'd rather do something simpler, even if that boils down to "we return a single ParrotList with all the return values in it, stuck in P0". -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: [COMMIT] Subs and co-routines in Parrot
At 8:30 PM +0200 6/8/02, Jerome Vouillon wrote: >On Fri, Jun 07, 2002 at 07:40:14PM -0400, Melvin Smith wrote: >> The support isn't complete, for example, co-routines, etc. need to >> swap in their own context, which right now they don't do. > >Instead of using some space on the stack, co-routines can store all >their local variables into their closure. Then, there is no need to >swap in any context. You still need to store the stack frames created since the start of the coroutine when picking up after the yield. Otherwise we're declaring that coroutines can't use any stack at the point a yield is called, which is a rather big thing to declare. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: [COMMIT] Subs and co-routines in Parrot
At 08:15 PM 6/8/2002 +0200, Jerome Vouillon wrote: >I think this is a design mistake of the Java VM. It would have been >more efficient to keep the local variables on the stack. Define efficient. I assume they made their choices for more than one reason, and I'd hesitate to call it a design mistake unless I was really sure what those reasons were. Personally I wasn't so I can't say. -Melvin
Re: [COMMIT] Subs and co-routines in Parrot
At 08:27 PM 6/8/2002 +0200, Jerome Vouillon wrote: >On Sat, Jun 08, 2002 at 12:20:55PM -0400, Melvin Smith wrote: > > What would that accomplish? > > > > If yield is to suspend the current coroutine and return back to the > > controlling context, you don't need an argument to yield, unless you > > wish to yield and jump to a different address than you were called > > from, but is that the semantics of a co-routine yielding? > >You mentioned in a previous mail: > "On a return, we can set the entry address back to the "start" of the >co-routine for another call." >The argument to the "yield" opcode was intended to allow this. >But you're right: one could just as well put a "branch" just after >the "yield". I'm confused. Why does the yield want to set the return address of the coroutine back to the start? Given that I've never implemented them before, I'm not saying the way I'm doing it is right. I assume yield should suspend the co-routine, return to its caller, and the caller can 'call' the co-routine again. Do I have the semantics wrong? -Melvin
Re: [COMMIT] Subs and co-routines in Parrot
At 08:30 PM 6/8/2002 +0200, Jerome Vouillon wrote: >On Fri, Jun 07, 2002 at 07:40:14PM -0400, Melvin Smith wrote: > > The support isn't complete, for example, co-routines, etc. need to > > swap in their own context, which right now they don't do. > >Instead of using some space on the stack, co-routines can store all >their local variables into their closure. Then, there is no need to >swap in any context. At more risk of admitting more of my ignorance... We have to store the closure's variables somewhere, if not on a stack, where? -Melvin
Re: [COMMIT] Subs and co-routines in Parrot
At 3:35 PM -0400 6/8/02, Melvin Smith wrote: >At 08:30 PM 6/8/2002 +0200, Jerome Vouillon wrote: >>On Fri, Jun 07, 2002 at 07:40:14PM -0400, Melvin Smith wrote: >>> The support isn't complete, for example, co-routines, etc. need to >>> swap in their own context, which right now they don't do. >> >>Instead of using some space on the stack, co-routines can store all >>their local variables into their closure. Then, there is no need to >>swap in any context. > >At more risk of admitting more of my ignorance... > >We have to store the closure's variables somewhere, if not on a stack, where? In scratchpads. The way perl 5 does it is that every subroutine has a scratchpad, and all the variables declared in that subroutine are in the scratchpad. (The parser plays some games with scratchpad access when there are multiple variables with the same name in a sub, but in different blocks) Makes closures a lot easier, since you don't have to play games with stack copying or anything. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: [COMMIT] Subs and co-routines in Parrot
At 03:48 PM 6/8/2002 -0400, Dan Sugalski wrote: >At 3:35 PM -0400 6/8/02, Melvin Smith wrote: >At more risk of admitting more of my ignorance... >> >>We have to store the closure's variables somewhere, if not on a stack, where? > >In scratchpads. The way perl 5 does it is that every subroutine has a >scratchpad, and all the variables declared in that subroutine are in the >scratchpad. (The parser plays some games with scratchpad access when there >are multiple variables with the same name in a sub, but in different >blocks) Makes closures a lot easier, since you don't have to play games >with stack copying or anything. But scratchpads are still a tangible entity that has to be allocated and takes space to store variables. How are they better than a GC'd, random access stack object? -Melvin
Re: [COMMIT] Subs and co-routines in Parrot
At 02:36 PM 6/8/2002 -0400, Dan Sugalski wrote: >At 8:15 PM +0200 6/8/02, Jerome Vouillon wrote: >>On Sat, Jun 08, 2002 at 12:30:36PM -0400, Melvin Smith wrote: >>> The Java VM does this by popping values off of the local stack, and >>> onto the callee's stack upon return. >> >>I think this is a design mistake of the Java VM. It would have been >>more efficient to keep the local variables on the stack. > >Yeah, that's too much work for me. I'd rather do something simpler, even >if that boils down to "we return a single ParrotList with all the return >values in it, stuck in P0". Thats fine by me. I was giving a real world example that we could relate to, not saying it was optimum. Implementing Parrot is new ground for me; I've worked on a VM before, but it wasn't capable of things like closures, continuations, etc. I feel like I'd be more productive if people would provide numbers, samples or some sort of reference for what they are proposing as an alternative to how I did it, so I can understand why the current way is less efficient. Otherwise, when someone says, "Thats not efficient." and leaves off, I have to go research and figure out why for myself. -Melvin
Re: [netlabs #590] Can't Print the Sequence slash + zero
> --- start of forwarded message --- > Date: 7 Jun 2002 21:36:26 - > From: Joe Yates (via RT) <[EMAIL PROTECTED]> > Cc: recipient list not shown: ; > Subject: Re: [netlabs #590] Ticket Resolved > Message-Id: > > Dear Daniel, > > I hope I'm not being a pain. The response to my report was that "This'll be > fixed when we've got the Parrot IO support rolled out." Have you any idea > how far down the line that's going to be? No, I got no idea, but the problem wasn't in the Parrot IO but in the assembler. Daniel Grunblatt.
Re: [COMMIT] Subs and co-routines in Parrot
At 08:30 PM 6/8/2002 +0200, Jerome Vouillon wrote: >On Fri, Jun 07, 2002 at 07:40:14PM -0400, Melvin Smith wrote: > > The support isn't complete, for example, co-routines, etc. need to > > swap in their own context, which right now they don't do. > >Instead of using some space on the stack, co-routines can store all >their local variables into their closure. Then, there is no need to >swap in any context. I'm all for optimizing routine calls too. Actually I like the idea of optimizing away needless scratchpad or stack allocation. That way if routines never need it, we don't take a performance hit for simple sub calls. Maybe it means setting a flag on stack segments, so each sub call can tell if it needs to alloc a local stack or not. If I'm not clarifiying: assume we call coroutine A, and all it does is simple calculations in registers, then there is no need to alloc a scratchpad or stack, unless A calls B, and then A can relegate to B. Comments? -Melvin
Re: several changes committed (IO, miniparrot)
On Sat, Jun 08, 2002 at 01:39:56PM -0400, Dan Sugalski wrote: > At 12:55 AM -0400 6/8/02, Josh Wilmes wrote: > > > >Although I should mention that it's not verifying the presence of these > >headers- it just assumes they are available. It does that because the > >intent is to use this has_header.h for miniparrot, where we won't be doing > >any probing. The assumption is that if C89 says it will be there, it will > >be there, darn it. > > This is perfectly fine. We're assuming a minimum C89 level of ANSI > compiler compliance. hosted, or freestanding? [arrgh? were those the correct terms? the minimal one doesn't have errno.h or most of the other headers, IIRC. And wince is only the minimal one] Nicholas Clark -- Even better than the real thing:http://nms-cgi.sourceforge.net/
RE: several changes committed (IO, miniparrot)
Nicholas Clark: # On Sat, Jun 08, 2002 at 01:39:56PM -0400, Dan Sugalski wrote: # > At 12:55 AM -0400 6/8/02, Josh Wilmes wrote: # > > # > >Although I should mention that it's not verifying the presence of # > >these # > >headers- it just assumes they are available. It does that # because the # > >intent is to use this has_header.h for miniparrot, where # we won't be doing # > >any probing. The assumption is that if C89 says it will # be there, it will # > >be there, darn it. # > # > This is perfectly fine. We're assuming a minimum C89 level of ANSI # > compiler compliance. # # hosted, or freestanding? Hosted. Freestanding isn't complete enough to do anything with--you don't even have file I/O. Besides, you'll most likely be cross-compiling for WinCE. --Brent Dax <[EMAIL PROTECTED]> @roles=map {"Parrot $_"} qw(embedding regexen Configure) Early in the series, Patrick Stewart came up to us and asked how warp drive worked. We explained some of the hypothetical principles . . . "Nonsense," Patrick declared. "All you have to do is say, 'Engage.'" --Star Trek: The Next Generation Technical Manual
Parrot build failure, Win32 (missing include apa/inet.h?)
Standard MSVC++ 6.0 setup, last known to work: Thursday. Updated with completely clean tree, built with defaults (as I always do) and here's how it went: C:\projects\parrot\parrot>perl Configure.pl Parrot Version 0.0.6 Configure 2.0 Copyright (C) 2001-2002 Yet Another Society Hello, I'm Configure. My job is to poke and prod your system to figure out how to build Parrot. The process is completely automated, unless you passed in the `--ask' flag on the command line, in which case it'll prompt you for a few pieces of info. Since you're running this script, you obviously have Perl 5--I'll be pulling some defaults from its configuration. Checking MANIFEST...done. Setting up Configure's data structures...done. Checking for --miniparrot...done. Loading platform hints file...done. Determining what C compiler and linker to use...done. Determining what types Parrot should use...done. Determining what opcode files should be compiled in...done. Setting up experimental systems...done. Probing for C headers...done. Determining some sizes...done. Computing native byteorder for Parrot's wordsize...done. Figuring out how to pack() Parrot's types...done. Figuring out what formats should be used for sprintf...done. Determining if your C compiler is actually gcc...done. Determining architecture, OS and JIT capability...done. Verifying that the compiler supports function pointer casts...done. Determining if your compiler supports computed goto...done. Generating config.h...done. Writing Parrot::Config module...done. Generating Makefiles...done. Moving platform files into place...done. Okay, we're done! You can now use `make' (or your platform's equivalent to `make') to build your Parrot. After that, you can use `make test' to run the test suite. Happy Hacking, The Parrot Team C:\projects\parrot\parrot>nmake Microsoft (R) Program Maintenance Utility Version 6.00.8168.0 Copyright (C) Microsoft Corp 1988-1998. All rights reserved. C:\Perl\bin\perl.exe vtable_h.pl C:\Perl\bin\perl.exe make_vtable_ops.pl > vtable.ops C:\Perl\bin\perl.exe ops2c.pl C core.ops debug.ops io.ops rx.ops vtable.ops C:\Perl\bin\perl.exe ops2c.pl CPrederef core.ops debug.ops io.ops rx.ops vtable.ops cl -nologo -O1 -MD -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT-I./include -DHAS_JIT -DI386 -Fotest_main.obj -c test_main.c test_main.c cl -nologo -O1 -MD -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT-I./include -DHAS_JIT -DI386 -Foexceptions.obj -c exceptions.c exceptions.c ../include\parrot/parrot.h(66) : fatal error C1083: Cannot open include file: 'arpa/inet.h': No such file or directory NMAKE : fatal error U1077: 'cl' : return code '0x2' Stop. C:\projects\parrot\parrot>
Re: Apoc 5 questions/comments
Dave Storrs yiked: > Yikes. Ok, I obviously badly misunderstood that. I'll go back > and reread it. So, can you provide an example of a "pattern nested > within a closure", since I obviously didn't understand? Sure: m/ if { /? ::: / and print $0.{comment} } / The C? ::: /> pattern is nested within a closure, so if it backtracks over the :::, it fails, but that failure doesn't propagate out to the enclosing C regex, as it would if it had been: m/ if [ /? ::: / { print $comment } / BTW, the reason the previous example *did* was because the closure executed an: ...or fail after trying the nested regex. > > > my &rx := /(xxx)/; > > > > > > Should that be a $ instead of a & on the rx variable? > > > > That ain't a variable, friend, that there's a gen-u-ine subroutine! > > And it's being bound to a regex!! > > (It's really just another way to give a regex a name ;-) > > Hmmm...what are the implications, here? The results of the match > are passed as arguments to the func? No. > When you run the func, the regex is called? Yes. > Something else? No. > > > Can subroutines that aren't used in regexen use 'fail' to throw an > > > exception? If so, how is it different from 'die' when used outside a > > > regex? > > > > As I understand it, it isn't (currently). > > Just to be sure I understood: you meant that (A) yes, you can use > fail in a subroutine outside a regex, and (B) if you do, it is no > different from die. Is that correct? As Larry pointed out, I had forgotten that C usually just returns C, unless C is in effect, in which case it's like C. Damian
Re: Apoc 5 questions/comments
Trey Harris wrote: > I guess this is as good an opportunity as any to be sure I've got what's > going on. So, here's a first, simple, addmitedly broken hack at a simple > parser for xml-ish start tags and empty entities: > > rule lt { \< } > rule gt { \> } > rule identifier { > # I don't know the XML identifier rules, but let's pretend: > [ | \d | _ ]* > } Or just: \w* > rule val { > [ # quoted >$b := <['"]> >( [ \\. | . ]*? ) >$b > ] | # or not >(\H+) > } Not quite. Assigning to $b is a capture. So now you have more than one capture in the first branch, so the paren-captured value won't come back on its own. And you don't really want to allow vertical spaces in the unquoted value either, so \S is more appropriate. And the precedence of | is still low, so the [...] are unnecessary (though not wrong in themselves). And \\.|. is just \\?. (but again, not wrong in itself). So you want: rule val { $delim := <['"]> $data := ( [\\?.]*? ) $delim | $data := (\S+) } > rule parsetag :w { > $tagname := > %attrs := [ () = > () > ]* >/? > > } > > for <$fh> { > while m:e// { >print "Found tag $0{tagname}\n"; >print " $a = '$v'\n" for $0{attrs}.kv -> $a, $b; > } > } > > My questions are: > > 1. Does the match in my rule get passed correctly? I.e., I have >parens in alternations, will whichever one gets matched become the >return value of the whole rule? I believe not, since you're also caputuring the delimiter. I've discussed the need to do complex capturing internally, but still return a simple value with Larry. My suggested solutions were either a special assertion: rule val { [ $delim := <['"]> $data := ( [\\?.]*? ) $delim | $data := (\S+) ] } or a special hypothetical variable: rule val { $delim := <['"]> $RETURN := ( [\\?.]*? ) $delim | $RETURN := (\S+) } I don't know which, if either, he will approve. Maybe both! > 2. Did I do the binding to the hash correctly? Yes, indeed. > 3. Will my I/O loop work like I expect? Depends what you expect! ;-) But you probably want this: for <$fh> { while m:c// { print "Found tag $0{tagname}\n"; for $0{attrs}.kv -> $a, $b { print " $a = '$b'\n" } } } That's is, the :c modifier rather than :e, since you're looping one-match-at-a-time via a C. If you want to grab every match at once, and then iterate them, you do want :e, but you also want a C: for <$fh> { for m:e// -> $match{ print "Found tag $match{tagname}\n"; for $match{attrs}.kv -> $a, $b { print " $a = '$b'\n" } } } Oh, and you can't use the -> on a postfix C modifier, only on a prefix C statement. Great to see someone so keen to start programming in Perl 6! Damian