On Mon, Apr 04, 2011 at 05:27:24PM -0400, Wouter van Ooijen wrote: > > Is anyone realy using this "flowcode" for anything serious ? >=20 > That is the perfect one-line summary of how I feel about flowcode :) >=20 > Use C, Jal, or even Basic or assembler. Forth if you want. But flowcode=20 > ... Maybe if you grew up with Lego Mindstorm? Your mention of Forth is quite interesting. One easily available Forth compiler is PicForth, located here: http://www.rfc1149.net/devel/picforth.html For higher end PICs (18F,24F,30F,33F) FlashForth is available: http://flashforth.sourceforge.net It's self hosting, so once the kernel is loaded info the chip, simply attach a serial port and develop directly on chip. Unsure of what dump facilities are available for duplication. I've been working with Forth on and off for the last couple of years. My attraction is that unlike most high level structured languages, Forth can trivially be compiled and/or interpreted using very simple tools, because at a fundamental level it looks very much like a bytecode assembly language for a two stack based virtual machine. Just doing some testing for some control structures, I pulled together a C based forth interpreter and "assembler" in a couple of hours. Here's some sample code: ####################################################### :1+ 1 + exit :1- 0xffff + exit :invert 0xffff xor exit :negate invert 1+ exit :- negate + exit :=3D - 0=3D exit :< - 0< exit :myloop dup .x 1+ droprif0 'myloop swapr :main 0 myloop bye=20 ####################################################### Primitives (hardcoded operators) include push number, plus, and, or, xor, 2 comparison operators, along with stack operators duplicate (top element), drop (top element), and over (copy second stack element over the current top). Transfers to and from the return stack along with a few return stack operators (conditional drop for return stack, replace current top of return stack with current top of data stack) are also available. The last two are for a couple of simple control structures I was testing. Finally a primitive that leaves the current execution path and returns to the caller (called exit) is implemented) >From this small core, other operations can be built. A simple example is the use of xor and plus to build invert, negate, subtract, and compare operations above. Of course all of these can be built as primitives, but the beauty of forth is that if an operator is not built in, you can construct it from the current set and integrate it in. The "high level words" are of course not fast, but easy to build and can be converted into primitives as time (or need) allows. You can see that my Forth "assembler" is pretty trivial. Read in a single word. If it starts with a colon, then add it to the current list of words with the current address (the dictionary in forth terminology). Otherwise look up the word the dictionary and convert it to its address. The dictionary is prepopulated with the names and addresses of the primitives. The only extra directive is the single quote, known as the Forth tic operator. It simply pushes the address attached to the word onto the top of the data stack instead of assembling the address into the list for the current word. The two interesting words I was working on was droprif0 and swapr (which I think would be better named replace-r). Most forths implement structured constructs by building off a conditional and unconditional goto. This requires marking replacement spots, then backpatching the markers when the target is found. This also has the limitation of forcing compilation of control structures. I found myself attracted to Chuck Moore's (the Forth Founder) idea of conditionally leaving the current word (and returning to the caller), and an unconditional goto by changing the return address. So at a fundamental level control constructs all operate at the word level and you have to build new words. So while traditional Forth has traditional selection constructs like (cap emphesis mine): :pickone whichone? IF do-true-stuff ELSE do-false-stuff THEN do-after-if-st= uff ; all in a single word definition. In Chuck's world it would be coded something like: : do-true-stuff IFTRUE ... ; : do-false-stuff IFFALSE ... ; : pickone whichone? do-true-stuff do-false-stuff drop do-after-if stuff ; So in each of the conditional words the rest of the word gets executing if the condition is correct, otherwise just leave without executing anything more. So the the IFTRUE and IFFALSE words act as gates to the execution for= the rest of the word. Note that each leaves the condition on the top of the stack and it's the responsibility of whomever put stuff on the stack to take it off (hence the drop after the do-false-stuff). The bottom example can be compiled or interpreted and still work properly. = No markers necessary because defining the words gives the proper (and permanen= t) markers of where to go execute. Loops are done the same way instead replacing the current top of the return stack with the top of the data stack, giving a form of data driven goto: : myloop dup print 1+ 'myloop replace-r ; the latter two words constitutes tail recursion without adding to the stack= .. Again no markers are necessary, and can be interpreted or compiled properly. The start of a loop needs to be at the beginning of a defined word. It isn't perfect, but really easy to implement. Will cause a bit of word explosion since every true, false, and loop will need to be tagged. I find Forth fascinating. BAJ --=20 Byron A. Jeff Department Chair: IT/CS/CNET College of Information and Mathematical Sciences Clayton State University http://cims.clayton.edu/bjeff --=20 http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .