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

World: r3wp

[Core] Discuss core issues

Geomol
24-Jan-2005
[325]
You get a new line with { in the beginning. That's REBOL way to tell 
you, you haven't finished your string. Like this:
>> s: {"^/^{"}
{

if I put in a } to finish the string, I get:
{    }
** Syntax Error: Invalid string -- }
** Near: (line 2) }
sqlab
24-Jan-2005
[326]
I see, the problem arises when you type it.
Geomol
24-Jan-2005
[327]
I would initially think, that {"^/^{"} would be a valid string with 
4 chars inside. 2 ", 1 newline and one {, but it isn't.
sqlab
24-Jan-2005
[328]
Did you check if it is the same behaviour when loading from a file?
Geomol
24-Jan-2005
[329]
yes
sqlab
24-Jan-2005
[330]
I have seen different behaviour from typing in the console and loading 
from a file

for example
>> func: [;  []]
** Syntax Error: Missing ] at end-of-script
** Near: (line 1) func: [;  []]
>>
Geomol
24-Jan-2005
[331]
eFishAnt, yes that's a string. I'm trying to build REBOL content 
within a string, so I have to figure out how to type strings within 
strings.
sqlab
24-Jan-2005
[332x2]
maybe you can use 
inp:  ["^/{"]
append your-string   inp
Seems not to work
Geomol
24-Jan-2005
[334x2]
Not really. I start with a string:
output: make string! 10000

then I go into a parse, where I build REBOL content within my output 
string. Sometimes I have to append a string (as a string) to output, 
and it fails, when I have newlines and { like characters.
I can't start with a block, because I can't append the start of a 
block to a block. I have to append a whole block to a block, and 
I don't know the full content of the block. So I start with a string.
sqlab
24-Jan-2005
[336]
What do you mean with appending the start of a block to a block?
Geomol
24-Jan-2005
[337]
appending a [
sqlab
24-Jan-2005
[338]
You can with '[
Geomol
24-Jan-2005
[339]
like:
>> blk: []
== []
>> append blk '[

No, I can't. Try it!
sqlab
24-Jan-2005
[340x4]
I have to check in a script I did short before and I thought I did 
something similar
>> append [] to-lit-word "["
== ['[]
append [] to-word "["
== [[]
t: append [] to-lit-word "["
== ['[]
>> reduce t
== [[]
>> or compose etc
Geomol
24-Jan-2005
[344]
Oki doki! :-)

I then just save my result to disk (because I can't use it directly, 
as those [ and ] are words (and not a real block). After reload of 
the result from disk, it should be real REBOL, right? Would be great, 
if I could build in a block and not a string.
sqlab
24-Jan-2005
[345x2]
Yes, that's how I try to compose some rules.
load mold works too
>> t: rejoin [ [] to-word "[" to-word "]"]
== [[ ]]
>>  load mold  t
== [[]]
>> type? first load mold t
== block!
>>
Geomol
24-Jan-2005
[347x2]
Ok, got it. Thanks!
@sqlab I've now implemented the block method instead of the string 
method, when I'm building REBOL syntax, and it works very well. Now 
I should be able to finish the first pass of my document format very 
soon, so I'm happy! :-)
sqlab
25-Jan-2005
[349]
Just one comment

You say, you do not know the content of the block you want to insert.

If you keep the reference to the block, you can always insert later 
into the block.

>> outer: append/only  [] internal: []
== [[]]
>> insert internal "test"
== []
>> outer
== [["test"]]
Geomol
25-Jan-2005
[350]
Yes, I'm aware of that REBOL trick. :-) It's because, what I'm parsing 
might be blocks within blocks in a recursive way.

XML is an example of such a structure. If I see a start-tag, I insert 
the beginning of a block in my result, then parse further in the 
document finding content and other start-tags and so on. The best 
way is to produce the output in a seriel manner from beginning to 
end, like I parse the input.
DideC
25-Jan-2005
[351]
You can use another block as a stack of  blocks references :

- When you meet a new tag, push the current block reference on the 
stack (insert tail) and make current ref to a new block.

- When you meet a close tag, pop the last reference from the stack 
in the current ref  (pick last, and remove back tail)
Sunanda
25-Jan-2005
[352]
Just a word of warning -- use the latest betas for any significantly 
nested block structure.

As I found out the hard way recently, the production releases (at 
least under windows) behave erratically when stressed with a few 
hundred nested blocks. Some problem with garbage collection, apparently.
Geomol
25-Jan-2005
[353]
@DideC

Fine suggestion! I use a similar method to stack the names of the 
tags, so I can produce the correct end-tag (like </tag>), when I'm 
at that point in the parsing. But I've found that appending >>to-word 
"["<< and >>to-word "]"<< works very well, so I've solved my problem.
Terry
25-Jan-2005
[354x2]
What's up with this?.. 

>> read http://127.0.0.1:83
connecting to: 127.0.0.1
** Script Error: Invalid argument: /
** Where: to-integer
** Near: to integer! :value
(nevermind, it was the script)
Robert
26-Jan-2005
[356]
stack: If you are interested, I have implemented a stack! object.
JaimeVargas
26-Jan-2005
[357]
Robert what does the stack! object do?
Geomol
26-Jan-2005
[358]
For a stack, I just do:
stack: []
append stack <something>
remove back tail stack
Robert
26-Jan-2005
[359]
It provides functions for pop, top, push etc. It implements a stack 
datastructure.
Volker
26-Jan-2005
[360]
stack: []

push: func[ var-block ][ insert/only stack reduce['set var-block 
reduce var-block] ]
pop: func[][ do first stack remove stack ]
a: 1 b: 2 push[a b] a: 11 b: 22 ? a ? b ? stack pop ? a ? b
; cannot push functions :(
Sunanda
26-Jan-2005
[361]
I've not needed a stack so far in REBOL.

In other languages, I usually find myself writing a complete thing 
like Robert has mentioed.

The full works in REBOL would look something like:
  stack/create "xxx"     -- create a new stack called "xxx"
  stack/push "xxx" item  -- push item 
  stack/pop "xxx" item   -- pop item
  stack/peek "xxx"       -- return top item without popping it
  stack/length? "xxx"    -- how many items
  stack/clear "xxx"      -- remove all entries

  stack/discard "xxx"    -- remove all entries and delete the stack

  stack/save "xxx" %file -- write it to a file (may not always be possible)
  stack/read "xxx" %file -- reset to contents of the file

  stack/probe "xxx"      -- return a block of all entries (for debugging)


And, as a stack has  a unique name, an application can be using more 
than one at once.
JaimeVargas
26-Jan-2005
[362x2]
I thinks the following is a bug. Should I submitted to RAMBO?
>> debase {^@^B^C}   
== #{}
>> debase/base {^@^B^C} 64
== #{}
This are invalid base64 strings. It should return NONE! or ERROR! 
I think.
Anton
26-Jan-2005
[364]
I agree -> rambo
Robert
27-Jan-2005
[365x2]
Well, yes it's not a big deal in Rebol but I prefer to use the normal 
common-sense notation for datastructures. Here it is:
stack!: make object! [
		stack: make block! []

		push: func['value /flattend][
			either (type? value) == block!
				[
					either flattend
						[foreach entry value [insert head stack entry]]
						[insert/only head stack value]
				]
				[insert head stack value]
		]

		pop: does [
			either (length? stack) > 0
			[
				value: first stack
				remove stack
				return value
			]
			[return none]
		]

		top: does [
			if not empty? [return first stack]
		]

		empty?: does [
			either (length? stack) == 0 [return true][return false]
		]

		ontop?: func ['value][
			either value == top [return true][return false]
		]

		instack?: func ['value][

   either result: find stack value [return index? result][return none]
		]

		reset: does [
			clear stack
		]

		size: does [
			return length? stack
		]

		print: does [
			probe reduce ["stack:" stack]
		]
	] ; stack
Gregg
27-Jan-2005
[367x2]
common sense

 is relative though. Bertran Meyer, the creator of Eiffel, offers 
 a powerful argument that I've come to agree with, that of Linnaean 
 Naming Conventions. For example, a stack has Push/Pop methods, a 
 queue may have Enqueue/Dequeue methods, a list Insert/Remove, a collection 
 Add/Delete. You end up with different names for methods that do the 
 same thing. They just behave differently based on the data structure.
So, in a large class library, or even a medium size one, how do you 
find all the different method names, and how do you remember them? 
His answer is that you give the methods the same name. In REBOL, 
that would mean using words like Insert, Remove, First, Last, etc. 
That's how REBOL works with all it's built-in datatypes, and we like 
it for that, so I think it's worth keeping in mind.
Volker
27-Jan-2005
[369x3]
Thats what series are about. :) And we can make our own using ports 
:)
about Roberts stack: most of that is inbuild in series, so why wrap/rename 
it?
Thats something Carl blogged about: Idioms http://www.rebol.net/article/0101.html
would be:
push -> insert stack value
pop -> remove stack ; does not return the value. 

top -> stack/1 ; with path, the if empty? stack[return none] is implicit
Gregg
27-Jan-2005
[372]
POP is about the most useful method that isn't built into REBOL. 
It's nice to be able to remove something and have it returned, rather 
than having the series returned.
Volker
27-Jan-2005
[373x2]
my push/pop has the advantage that it pushs/pops a group of variables, 
instead of single values. sometimes handy with recursive parsing.
(and 'pop knows which variables where pushed, so just "pop", not 
"pop[a b]")