r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[All] except covered in other channels

Gabriele
2-May-2006
[2174]
i wonder if it's possible to experiment with it with mezz code.
BrianH
2-May-2006
[2175x2]
make rule! [[locals] [rules]]
Using a variant on Carl's new make function! syntax.
Gabriele
2-May-2006
[2177]
would rule! really be different than function! ?
BrianH
2-May-2006
[2178]
A new function type where the code block would be executed by the 
parse engine rather than the DO engine.
Gabriele
2-May-2006
[2179x3]
but you can't call it outside of parse anyway
and you can't use functions inside parse either
so it's just rule!: function!
BrianH
2-May-2006
[2182x2]
You could keep the spec block mostly the same as function!, just 
like rebcode does. Calling it would call parse on its first argument. 
This would be sort-of like a parse rule compiler.
Calling it directly I mean.
Gabriele
2-May-2006
[2184x2]
but that wouldn't be very useful inside parse then
well... i need to get some sleep. this is a very interesting topic 
though. i hope we can improve parse on r3 too (the problem is deciding 
where to stop).
BrianH
2-May-2006
[2186x2]
I need some dinner, so I'll think about this a bit and come up with 
a set of appropriate parse functions and their equivalent rewrite 
code.
Parse operations I mean.
BrianH
4-May-2006
[2188x2]
Here are some minimum additonal parse operations, and some workarounds 
that could be used to replace them until they are implemented.

fail ==> [end skip]
check (code) ==> (tmp1: unless (code) [fail]) tmp1
remove rule ==> tmp1: rule tmp2: :tmp1 (remove/part :tmp1 :tmp2)

replace rule (code) ==> tmp1: rule tmp2: :tmp1 (tmp1: change/part 
:tmp1 (code) :tmp2) :tmp1

replace-only rule (code) ==> tmp1: rule tmp2: :tmp1 (tmp1: change/part/only 
:tmp1 (code) :tmp2) :tmp1

into-string rule ==> set tmp1 string! (tmp1: unless parse tmp1 rule 
[fail]) tmp1


Note that if parse operations are changed to take refinements or 
if these are being done as rewrite rules, replace-only and into-string 
could be expressed as remove/only and into/string. This would be 
slower in a native implementation, but about the same in rewrite 
rules. It would look more REBOL-like if that matters to you.


A rewrite engine for these workarounds will need temporaries for 
their implementation. The caller would need to provide a block of 
their own temporaries, and would not be able to reuse them in their 
code. The rewriter will need to count temporaries and complain if 
the caller doesn't provide enough. As with all parse rules, these 
temporaries will not be recursion-safe. Directly nested rules should 
be fine as long as there are enough temporaries provided.
I'm still working on parse extensions to enable recursion-safe temporary 
variables. Obviously they are a bit more involved.
Anton
4-May-2006
[2190]
I did that last year. Let's see.. the interface is make-recursive-rule 
which takes a parse rule block and outputs one that saves and restores 
temporary variables at the right time. It extends the parse dialect 
with a new 'recurse-into keyword. 

Make-recursive-rule essentially just looks for   [ recurse-into rule 
]   and replaces it with   [ save-vars   rule   restore-vars ]
BrianH
4-May-2006
[2191x2]
Anton, I would like to see that. As it is, Gabriele and I started 
this discussion with an idea towards seeing what could be fixed in 
REBOL 3. I'm trying to come up with simple operations that parse 
could be extended with, the minimum necessary I hope. Bear with me 
or a moment.
Here's my first attempt at a pattern for recursion-safe temporaries:


use [var ...] [rule ...] ==> (tmp1: use [var ...] copy/deep [[rule 
...]]) tmp1


It would only work with a directly specified variable and rule block, 
and you should only use the temporaries directly in the rule block 
or they won't get rebound. Now, using REBOL 3's closure (probably 
better):


use [var ...] [rule ...] ==> (tmp1: do closure [/local var ...] [[rule 
...]]) tmp1


Of course this is just an example. An actual rewrite engine would 
premake the closure and insert it directly instead of making it in 
the rule and doing it. REBOL's existing function recursion support 
wouldn't work because the function returns before the rule is run.


I would prefer a native implementation of this operation if possible.
Anton
5-May-2006
[2193x2]
My save-vars just pushes the temp variable values onto a stack, and 
restore-vars pops them.
I'll upload it, hang on.
BrianH
5-May-2006
[2195]
How does it know which vars to push?
Anton
5-May-2006
[2196x4]
You tell it.
eg. 
rule: [
	recurse-into [var1 var2] some-rule
]

becomes:
rule: [
	save-vars [var1 var2]
	some-rule
	restore-vars [var1 var2]
]
(essentially)
http://home.wilddsl.net.au/anton/rebol/library/make-recursive-rule.r
BrianH
5-May-2006
[2200x2]
Earlier in this discussion I suggested parse rule closures...
The use operation above would be a good semantic model for parse 
rule closures with recursion-safe temporaries. Imagine a new datatype 
called rule!, a parse rule block bundled with a recursion-safe context 
for local variables. You would create one with a mezzanine like this:


parse-rule: func [locals [block!] rule [block!]] [make rule! reduce 
[locals rule]]


It would be the equivalent of a function made by the HAS mezzanine 
- local variables, no parameters. The rule would be prebound to the 
context and the context would be fixed up on recursion just like 
function contexts are. Any time parse would accept a rule block! 
it would also accept a rule! value.
Anton
5-May-2006
[2202x2]
That would be good.
Using a stack as I have is faster, because we are not creating new 
objects (or values if they are the same), but it's not quite as elegant 
as your parse-rule above.
BrianH
5-May-2006
[2204]
The trick is the addition of a new data type. It would allow the 
context to be fixed up internally. The rule! datatype would be a 
lot faster than even your stack model, and safer too. The use operation 
above would be a lot slower than your stacks though.
Anton
5-May-2006
[2205]
Yes, I think you should submit that for Rebol 3
BrianH
5-May-2006
[2206]
That and the simple operations I wrote above.
Volker
5-May-2006
[2207]
I use Antons method sometimes, with an aditional trick: the push 
saves thevarnames too, and the pop is just "pop".
Maxim
5-May-2006
[2208]
Can I vote in r3 to add to-any.. which stops at the first matching 
rules in the order of the block being parsed, as opposed to the order 
in the parse rules  This would make many rules simpler or make parse 
easier to use in Q&D stuff.
Anton
5-May-2006
[2209]
(actually, my method also pushes the var names as well as their values.)
Gabriele
17-May-2006
[2210]
http://www.colellachiara.com/soft/Misc/rewrite.html
BrianH
17-May-2006
[2211x4]
Looks good to me. BTW, the mk2: in

    not match data [mk1: rules* mk2: (mk2: change/part mk1 prod mk2) 
    :mk1]
isn't used by your code. Did you mean mk1: instead?
The mk2: in the paren I mean..
What you mean here depends on whether you intend the rewrite to go 
through the entire data set before doing another pass (then you change 
the mk2: to mk1: ), or whether you want the next pass to pick up 
exactly where the previous one started (then you remove the mk2: 
as it isn't used).
Looking further t the docs, it appears that the existing behavior 
is what you intend. Better locality I guess. In that case, you might 
as well remove the mk2: from inside the paren in that line, as it 
doesn't do anything.
Gregg
17-May-2006
[2215]
Gabriele's need to delimit the rules with '| brings up another old 
mezzanine thought: rejoin/with. I created a separate mezz, called 
DELIMIT, but this is a fairly common need IME. Should we start another 
ML thread? :-)
Pekr
17-May-2006
[2216]
start another RAMBO thread :-) ... add it as a wish - I think it 
is the only channel RT actually scans, but of course not sure ...
Gabriele
17-May-2006
[2217]
Brian, yes, that's because earlier i had :mk2 after the paren, but 
I changed it to :mk1 because it's faster when you want to iteratively 
apply a rule.
BrianH
18-May-2006
[2218x2]
That's the locality I was talking about.
The match functiion has a line
    parse block recurse
near the end that should be
    parse data recurse
Brett
18-May-2006
[2220]
Gabriele, rewrite - very nice and I expect endlessly useful. Thanks 
for publishing it.
BrianH
19-May-2006
[2221x2]
Here is a suggestion for match - add /any and /case refinements like 
the parse refinements, and then change the line:
    parse data recurse
to this line, indented properly if needed:

    do pick pick [[parse parse/case] [parse/all parse/all/case]] none? 
    all none? case data recurse


It's the quickest way to pass along refinements I've figured out 
yet, short of rebcode apply.
Once rebcode is in REBOL, it would be a quicker way to implement 
match. That apply operation is nice.
Robert
3-Jun-2006
[2223]
After going nuts for some while now, I'll ask the community maybe 
someoe has a good tip for me:

I need an application that can do two things with more than 2 persons 
at the same time:
- video conferencing

- application sharing (or at least having one exporting his desktop 
to a number of users)


I thought that netmeeting might be good but it's quite old and doesn't 
seem to be further developed.