World: r3wp
[Core] Discuss core issues
older newer | first last |
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 [373x3] | 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]") | |
pop: partly agreed. but i use the top of stack directly, and poping really means "no longer needed. i don't use push var change var pop var but push value use stack/1 pop | |
Terry 27-Jan-2005 [376] | Is there someway to have a function stored as a string, and then do it, without triggering the actual function name? ie: N: {o: func [inpu][print join inpu "ing"]} so that i get.. do N "test" >> testing |
Volker 27-Jan-2005 [377] | do do N "test" |
Terry 27-Jan-2005 [378] | hehe, thanks |
Geomol 27-Jan-2005 [379] | So far I've push'ed and pop'ed stacks (blocks) at the bottom, because I presure, it's faster that from the top (because of memory allocation). But I haven't actually tested it, and if it's true in all cases. Does anyone have experience with that? |
Terry 27-Jan-2005 [380] | boo-boo: func [inpu][if error? try inpu [print "error"]] boo-boo [do do N "test"] |
older newer | first last |