| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| I've been trying to write a program to search a website and in my experiments have come across something I don't understand. First my project: I want to search dictionary.reference.com from forth by way of using a shell. s" lynx -dump dictionary.reference.com/browse/spam | head -n50" (spam is the term I am looking up) I can't seem to find a way to pass variables in a string in forth and the bash (def=spam) ones don't seem to work from gforth. I want the forth word to work like this. look-up spam Since I don't know how to put a variable in a string I started thinking about storing strings in a block and building them upon execution. MVP-Forth and pygmy were used for these experiments on a thumbdrive in Winxp. My experiment went like this inside block 200: 0 ." lynx -dump dictionary.reference.com/browse/ 1 search 2 | head -n50" I used the -TRAILING word when creating my words to call these strings, and was able to get the first two strings to combine without spaces and cleanly. When I called the last one by using something like: (I used block to call each string) 200 BLOCK 64 + 128 -TRAILING SPACE TYPE line 1 on block 200 displayed with line 2. I'm leaving some definitions out for brevity but my final word looked like this : LOOK-UP DOTQ SRCH ENDQ ; What can be going on here? Am I missing something on the stack? What should I be looking at? matthew p.s. If I should be looking at a different way to implement this this program I am open to pointers in the right direction. p.p.s. I've been working through SF so if there is something in the first edition you want to call my attention too, please do. |
|
#2
| |||
| |||
| Matthew <Matthewk@letterboxes.xx.org> writes: > I've been trying to write a program to search a website and in > my experiments have come across something I don't understand. > > First my project: > > I want to search dictionary.reference.com from forth by way of > using a shell. > > s" lynx -dump dictionary.reference.com/browse/spam | head -n50" > (spam is the term I am looking up) > > I can't seem to find a way to pass variables in a string in > forth and the bash (def=spam) ones don't seem to work from gforth. What you need is just string library, nothing more, nothing less. You won't find one on the net, this is the Forth way (it works best when code isn't published), You only need to catenate strings: 1) "lynx -dump dictinary.reference.com/browse/"; 2) some you define; 3) " | head -n 50". Call the system. Since system is actually the system(3) function from POSIX, you should know the consequences. Welcome to quoting hell! > I want the forth word to work like this. > > look-up spam > > Since I don't know how to put a variable in a string I started > thinking about storing strings in a block and building them > upon execution. MVP-Forth and pygmy were used for these > experiments on a thumbdrive in Winxp. > > My experiment went like this inside block 200: > > 0 ." lynx -dump dictionary.reference.com/browse/ > 1 search > 2 | head -n50" > > I used the -TRAILING word when creating my words to call these > strings, and was able to get the first two strings to combine > without spaces and cleanly. > > When I called the last one by using something like: > (I used block to call each string) > > 200 BLOCK 64 + 128 -TRAILING SPACE TYPE > > line 1 on block 200 displayed with line 2. .... > What can be going on here? Am I missing something on the stack? > What should I be looking at? It's alright. This is how it is to work. Blocks are just raw 1024-octet length chunks of data, which are treated as 16 lines of 64 bytes usually. "64 +" shifts pointer to the second line, "128" selects two lines (the second and the third) "-trailing" removes trailing spaces of the selected string (which includes two lines), "space" prints blank space, type prints string you got as result of "-trailing" above, that is two lines of your block. > p.s. If I should be looking at a different way to implement > this this program I am open to pointers in the right direction. Yes, you're going wrong direction. You want to use strings (write your string library, it is up to you). > p.p.s. I've been working through SF so if there is something in > the first edition you want to call my attention too, please do. You should use modern SF edition, which was edited by Marcel Hendrix and others. -- CE3OH... |
|
#3
| |||
| |||
| Matthew <Matthewk@letterboxes.xx.org> wrote: > I want to search dictionary.reference.com from forth by way of > using a shell. > > s" lynx -dump dictionary.reference.com/browse/spam | head -n50" > (spam is the term I am looking up) > > I can't seem to find a way to pass variables in a string in > forth and the bash (def=spam) ones don't seem to work from gforth. > > I want the forth word to work like this. > > look-up spam So, the first thing is to make a string with a constant prefix and a constant suffix, and the middle can change? And then you want to pass that string to the OS to be executed, and it will return stuff to your Forth program. > Since I don't know how to put a variable in a string I started > thinking about storing strings in a block and building them > upon execution. MVP-Forth and pygmy were used for these > experiments on a thumbdrive in Winxp. > > My experiment went like this inside block 200: > > 0 ." lynx -dump dictionary.reference.com/browse/ > 1 search > 2 | head -n50" > > I used the -TRAILING word when creating my words to call these > strings, and was able to get the first two strings to combine > without spaces and cleanly. > > When I called the last one by using something like: > (I used block to call each string) > > 200 BLOCK 64 + 128 -TRAILING SPACE TYPE > > line 1 on block 200 displayed with line 2. As Aleksej explained, line 0 starts at 0 + and line 1 starts at 64 + . > I'm leaving some definitions out for brevity but my final word > looked like this > > : LOOK-UP DOTQ SRCH ENDQ ; It sounds like you're using blocks as buffers to store your string fragments. There's nothing wrong with that. It works and it can be quite convenient once you know how. If you don't mind compiling strings, look at S" and SLITERAL . Strings you make with these get compiled into your code and you can't get rid of them without deleting the code, so you probably won't want all your strings that way. To store strings as data it really doesn't get more convenient than typing them into blocks with a text editor, unless you already have them stored somewhere and you want to copy them into your own data structure. To do that you might want Wil Baden's PLACE word, in his Toolbelt. I don't have a link to that handy but if you google baden and toolbelt you'll find it. So, you get your preamble string. Maybe from a block, and you remove trailing spaces and put it into a buffer, either a block, or at PAD or at HERE or inside your own allotted buffer. You know how many characters you moved. Add one for a space and now you know where n the buffer to add your variable region, that in your example is "spam". Add that, and where it ends is the new length. Maybe put in another space? That tells you where to put your second constant region. Where that ends is the length of the string. Then to pass the string to DOS or Windows you need to end it with a zero. So do that. If your buffer is a block your string can be up to 1023 characters long plus the trailing zero. If you use PAD the limit may be as little as 80 characters or 132 because the guy who wrote your Forth system might have given you just a little buffer for PAD . If you used HERE it ought to be prtty much unlimited but if you do any parsing or numeric output then the system might overwrite part of your string. If you defined your own buffer then it has as much space as you gave it. I hope that made sense. |
|
#4
| |||
| |||
| Matthew <Matthewk@letterboxes.xx.org> writes: >I can't seem to find a way to pass variables in a string in >forth and the bash (def=spam) ones don't seem to work from gforth. Shell variables are local to the shell, but environment variables (which look mostly like shell variables in shells) are visible in all subprocesses, and you can access them from Gforth. E.g.: export MYVAR=foo gforth -e 's" MYVAR" getenv type cr bye' But if you want to pass "foo" to the gforth process, you can also pass it on the gforth command line: gforth -e 's" foo" type cr bye' Concerning storing strings in Forth variables: Strings are represented as two items on the stack and some related stuff in memory. What I then do is to store the two stack items in a 2VARIABLE. And I manage the extra memory explicitly if necessary. E.g.: 2variable mystring s" foo" mystring 2! mystring 2@ type For helping with the extra memory management, Gforth has SAVE-MEM, which copies the string to newly allocated storage. This is useful if the string comes from a volatile buffer (e.g., SOURCE). >Since I don't know how to put a variable in a string I started >thinking about storing strings in a block and building them >upon execution. ALLOCATEd memory is more convenient than blocks, so I would recommend the blocks approach only when you don't have ALLOCATEd memory available. >p.p.s. I've been working through SF so if there is something in >the first edition you want to call my attention too, please do. Starting Forth comes from a time before ALLOCATEd memory was standardized (or even common) in Forth, and therefore does not mention it. As a complement to Starting Forth, you might want to work through the Gforth tutorial or any of the other modern books. - anton -- M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html New standard: http://www.forth200x.org/forth200x.html EuroForth 2008: http://www.euroforth.org/ef08.html |
|
#5
| |||
| |||
| Aleksej Saushev wrote: > Matthew <Matthewk@letterboxes.xx.org> writes: > >> [...] I've been trying to write a program to search a website and in >> my experiments have come across something I don't understand. >> >> First my project: >> >> I want to search dictionary.reference.com from forth by way of >> using a shell. >> >> s" lynx -dump dictionary.reference.com/browse/spam | head -n50" >> (spam is the term I am looking up) >> >> I can't seem to find a way to pass variables in a string in >> forth and the bash (def=spam) ones don't seem to work from gforth. > > What you need is just string library, nothing more, nothing less. > You won't find one on the net, this is the Forth way (it works > best when code isn't published), Ouch! A C version of my dynamic strings library has been on the web as part of pfe since at least April, 2000, and a Forth-94 version since June, 2003. I had thought their lack of popularity was because of a perception that they're too complicated, not that they're unknown. FWIW, I've developed the biased but firm opinion that both implementations are pretty much exactly as complicated as they should be, given their implementation of a string stack with just about optimal garbage collection, and text macro argument substitution. And they're well tested. Also there are two Forth-94 libraries for nondynamic strings, parsing.fs for parsing normal Forth-94 strings or the input stream across lines, and mstrings.fs for storing and concatenating with cell-sized count fields, either into buffers with overflow protection or into data space with contiguity protection. Also tested. They have evolved on the web since August, 2006, from stuff that goes even further back, such as the 2000 and 2002 version of Wil Baden's ToolBelt. I was just getting ready to announce recent updates for parsing.fs, mstrings.fs, and dstrings.fs, and their tests. Maybe this message can serve for that... Here's a gateway to all of that stuff: http://www-personal.umich.edu/~willi...ngs/index.html -- David |
|
#6
| |||
| |||
| Thanks for all the help. I will process all of this over the next week. matthew |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.