On Thu, 13 Jan 2011, Byron Jeff wrote: > Let's snip even more... > > On Thu, Jan 13, 2011 at 07:33:39PM -0500, smplx wrote: >>> Actually with the exception of integers, that is not the FORTH way of >>> doings things. What is done instead is the data (or addresses to the da= ta) >>> is pushed on the stack where routines operate on them. FORTH thinking i= s a >>> zero parameter subroutine system. So parameters are not encoded after t= he >>> routine. Take a simple example of printing a string. In a typical langu= age >>> there would be: >>> >>> print "the string to print" >>> >>> So in the VM the thought would be: >>> >>> PRINTTOKEN >>> >>> But FORTH is postfix all the way. So the implementation is: >>> >>> PRINTTOKEN >> >> Actually C does it the same way. It pushes all the actual parameters of = a >> function onto the runtime stack and then calls the subroutine >> coressponding to the function. > > The C compiler does it the same way. FORTH "cheats" by making the > programmer do the parsing. > >>> The "something about the string on the stack" are some combination of >>> integers such as the address of the string and its length. At the end o= f >>> the day it ends up being pushes of integers on the stack. That's alread= y >>> implemented. So we're done without having the tack something after the >>> PRINTTOKEN. >> >> Exactly how a C compiler would do it. It allocates space for the string >> somewhere else and passes the address on the stack to the function. > > But instead of the compiler doing the job, the word that represents the > string does the job instead. So in FORTH the compiler is integrated into > the runtime and the programmer can extend the compiler. But isn't that what I was saying by letting the subroutine look at=20 embedded information that comes after the function call. Your example of=20 the ".s" seems to be nothing more. It looks at stuff coming after it=20 instead of takeing stuff off the stack. > An excellent > discussion can be found in the online book "Starting Forth" in this > chapter: > > http://www.forth.com/starting-forth/sf11/sf11.html Yes I have a fair understanding of what forth does, addmitedly now=20 obscured by the passing of time, but I think there might be more to be=20 gained from this discussion if I don't just regurgitate someone elses=20 thoughts. >> >> Yes I understand what you're saying: the parser is incredibly trivial. >> However it still needs to be able to tell the difference between numbers >> and words, > > Yes. > >> to generate "LIT " inline for a number and to lookup the >> token coressponding to a word in the dictionary and generate >> inline for that word. > > Correct. > >> So how much extra work is there in checking that >> is greater than 8 bits wide and instead generating "CALL " >> (where is the 16 bit address of the subroutine coressponding to >> ) > > Well that's the debate. It isn't too terribly complicated to do. In my experience (I know a little bit about writing compilers and=20 interpreters) I belive this would actually be very simple. > >>> I look at tokens as a type of Huffman encoding scheme. Presume that >>> processing a token and a direct address takes about the same amount of = time >>> (I have to do this because I haven't yet done the actual timings). A to= ken >>> takes half the space of the direct address. So half the space and the s= ame >>> execution time is a win especially when heavily used routines are >>> tokenized. >> >> So if you're talking about Huffman encoding then stuff that occures most >> often or executes most often should be represented in the least number o= f >> bits and stuff that occures least often or executes least often is >> represented in far more bits. > > The basic idea. But in this case we're upgrading in discrete bit sizes. You mean whole bytes right? > >> This is exactly what using prefix >> instructions would allow you to do. >> >> Say you had an 8 bit VM instruction to push a constant to the evaluation >> stack. Lets say the instruction looked like: >> >> 0x8n >> >> where is the 4 bit constant in the range 0 to 15 > > OK. That's just like what I talked about in my last post. > >> >> As you noted elsewhere programs tend to use small constants a lot. >> >> now lets say once in a while you actually wanted to push an 8 bit >> constant. You might "extend" your VM instruction with a prefix instructi= on >> like: >> >> 0x9m >> >> now when the VM sees 0x9m 0x8n it actually pushes the 8 bit constant >> onto the stack. This is how the old transputer actually works - it >> actually had a 3 level eveluation stack and 8 bit instructions. > > But this complicates the interpreter and sucks up token space. Since it's > going to take up two bytes anyway why not have a single token followed by > an 8 bit value? No actually such an extension to the interpreter is incredibly simple.=20 Bare in mind that the transputer executed its code one 8 bit machine=20 instruction per CPU cycle. If you're interested in the details I would=20 refer you to the transputer docs. But in any case I wasn't suggesting you should actually do it this way=20 I was just using this as an example of how using prefix instructions can=20 produce more compact code by allowing the most common stuff to be packed=20 much more efficiently at the expence of less common stuff. Instead of=20 using just one bit to differentiate between token and absolute address=20 (and losing 128 tokens) use just one token, speed up access to the first=20 256 subroutines and reduce speed of access of remaining subroutines. >>>>> BTW I have a design goal of running threads out of RAM so that tempor= ary >>>>> words can be written and tested in RAM before being committed to flas= h. >>>> >>>> Yes I understood you wanted to be able to execute your VM code from RA= M. >>> >>> But I need to think through if that is a worthy goal or am I simply >>> pressing my own expectations as this design goal. >> >> Well don't forget the possibility of executing code out of an external >> EEPROM. > > Oh that going to be slow. That's what I was thinking when I wrote my firs= t > VM for the PIC many years ago. With the current crop of chips, it's > not a design goal. But slow compared to what? You've already got a VM that's slugging the the= =20 MCU by at least a factor of 8 over native code (probably much much more if= =20 you look at a good optimising compiler). Surely being able to execute BIG=20 programs on a tiny system would be a big point in its favour given that it= =20 can't compete on raw speed. Hey, part of your dev environment could=20 actually be in the external EEPROM if it is mostly written in forth=20 itself. The dev env would be interacting with a human anyway so it=20 wouldn't mater if it were slow. Anyway what about initiating the next token fetch before you start to=20 execute the current one. That should reduce latency a bit. Can't you get=20 SPI EEPROMs that run at 4MHz now anyway? >>> Forth is designed as an interactive "noodling" system with immediate >>> interactive debugging. Type a list at the prompt and it immediately >>> executes. This does cause some issues in terms of immediate words which= are >>> designed to execute only in the compiling environment. So you're going to have some sort of debugging support embedded in your=20 setup. Ok that wont need to be big if you're only allowing some kind of=20 "stop" instruction to be added inline in the code (it does mean that you=20 need to be able to edit code in situ however which would affect absolute=20 addresses to subroutine - keep that in mind). But something that is FAR=20 more useful would be the ability to set one or more break addresses on the= =20 executable. That is going to increase your fetch / execute overhead. Also=20 what about breaking on variable write? That would be a god send for=20 debugging. Debugging overheads would sure make external program execution=20 overheads less of an issue. >> So are you saying you want to be able to have this thing self=20 hosting? > > Absolutely. > >> Do >> you intend to just attach a keyboard and display to it and enter code >> directly? > > Serial interface. > Will you be allowing interrupts to be handled by your forth program while=20 it is being debugged (to keep background stuff alive)? Will there be some=20 kind of single stepping through the forth code? Regards Sergio Masci =3D=3D=3D Do NOT send emails to this email address directly. This email address is only valid for the PICLIST. Anything else gets dumpped without me ever seeing it. --=20 http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .