Chuck Moore is the Diogenes of computing. I try to adapt his ideas (that I comprehend) to my computing needs.
Color Forth parses at edit time. It merges the edit, compile and run times. This removes programmers' context switches and maximizes "flow".
It is native to Plan 9.
The startup dictionary words are built with Plan 9 amd64 assembly language.
It does not use Shannon encoding for storing names.
It does not use blocks for storage. It uses the Plan 9's disk and virtual file systems.
It is comprehensible, contemporary and has a network-aware ecosystem (device drivers and applications). It is a saner UNIX.
Parameter stack (Data stack) and Return stack similar to other Forth's.
A word to be typed into the editor is classified by what it should do. Colours distinguish actions: tags tags.h. Fonts and font styles are used for the colour blind: color blind tags - WIP.
To enter a word in the editor, We type the first character of the requisite tag, such as T for a Textcomment and then type the word followed by a space. To enter a Stringcompile, the first character is a "(double quotes). A Stringcompile ends when the pattern 'space"space' ( " ) is typed. If the first character is not a recognized tag key, the editor assumes that the word being typed uses the same tag as the previous word. Tag
The function readfile() is the parser.
cf/edit Source editor
cf/run JIT interpreter. The word main() is the entry point.
totext fromtext Translates source to/from a textual representation.
tops Generates a Postscript file from the source.
test Unit tests of the startup dictionary words.
test1 More unit tests.
helloworld Edit the source. I am redirecting the standard error to a file to see the data stack while editing.
: bin ; cf/edit helloworld.cf >>[2]edit.log
helloworld factorial Run the source.
: bin ; cf/run helloworld.cf
Hello World!
: bin ; cf/run factorial.cf
24
To build a textual representation of the source:
cf/run totext.cf helloworld.cf helloworld.cft
cf/run totext.cf factorial.cf factorial.cft
To build a PDF of the source:
cf/run tops.cf helloworld.cf helloworld.ps
ps2pdf helloworld.ps helloworld.pdf
page -Rw helloworld.pdf
Color Forth source The extension .cf identifides Color Forth source files.
tohtml Generate HTML files of the source.
An Operating System similar to Inferno but using Color Forth instead of Limbo.
Editor and interpreter (Plan9port utilities) for Linux (x86, x86-64, PowerPC, and ARM), FreeBSD (x86, x86-64), Mac OS X (x86, x86-64, and Power PC), NetBSD (x86 and PowerPC), OpenBSD (x86 and PowerPC), SunOS (x86-64 and Sparc), Dragonfly BSD (x86-64).
Chuck's ColorForth, Brad's Rainbow Forth, Uriel's Felix Forth (ff), JonesForth, Leo Brodie and Karig.
A Forth and a Macro dictionary. The Words in the dictionaries at startup are in assembler.
bye exit the process
forth switch dictionary to forth
macro switch dictionary to macro
jump defines a jump table. word... number jump word0 word1 word2 ... ;
Here variable containing the location of the end of used code space. Executing a variable puts it's address on the stack.
Vhere variable containing the location of the end of used data space.
Base variable containing the base used to interpret numbers.
nargs number of command line arguments.
arg puts the location of the nth command line argument on the stack. 1 arg puts the location of the 1st argument on the stack.
, puts the top of stack at the end of the code space and increment Here.
1, puts a byte from top of stack at the end of the code space and increment Here.
2, puts 2 bytes from the top of stack at the end of the code space and increment Here.
2, puts 4 bytes from the top of stack at the end of the code space and increment Here.
dup ( n -- n n )
drop ( n -- )
swap ( a b -- b a )
nip ( a b -- b )
over ( a b -- a b a )
tuck ( a b -- b a b )
rot ( a b c -- b c a )
-rot ( a b c -- c a b )
+ ( n1 n2 -- n1+n2 )
- ( n1 n2 -- n1-n2 )
* ( n1 n2 -- n1*n2 )
*/ ( n1 n2 n3 -- (n1*n2)/n3 )
/ ( n1 n2 -- n1/n2 -- quotient )
/mod ( n1 n2 -- n1/n2 n1%n2 -- quotient remainder )
mod ( n1 n2 -- n1%n2 -- remainder )
2* ( n -- n*2 )
shl ( n1 n2 -- n1< 2/ ( n -- n/2 ) sar ( n1 n2 -- n1>>n2 ) not ( n -- n ) not does not change the EFLAGS register. Performs a bitwise NOT operation (each 1 is set to 0, and each 0 is set to 1) on the top of stack. and ( n1 n2 -- n1&n2 ) or ( n1 n2 -- n1|n2 ) xor ( n1 n2 -- n1 xor n2 )
count ( a -- a+1 *a ). Parses a counted string and puts the length byte on the top of stack and the address of the contents below it.
test ( n -- n ). Doesnot change the stack contents but sets the EFLAGS for a following if(jz) or -if(jns).
execute ( a -- ). calla
belongs ( n low high -- ). Sets the ZF and SF flag for if or -if to use. If low <= n <= high, ZF = 0 and SF = 1 else ZF = 1 and SF = 0. Remember that in Forth, false = 0, true = -1
max ( n1 n2 -- n )
min ( n1 n2 -- n )
@ ( a -- n ) Fetch 8 bytes from the address a
! ( n a -- ) Store n at a
c@ ( a -- c ) Fetch a byte from the address a
c! ( c a -- ) Store a byte at address a
A ( -- a ) Load A register to the stack
A! ( a -- ) Store the top of stack into the A register
@+ ( -- n ) Fetch from address in A; increment A by 8.
c@+ ( -- c ) Fetch a byte from address in A; increment A
!+ ( -- n ) Store to address in A; increment A by 8.
c!+ ( -- c ) Store a byte to address in A; increment A
B ( -- a ) Load B register to the stack
B! ( a -- ) Store the top of stack into the B register
B@+ ( -- n ) Fetch from address in B; increment B by 8.
cB@+ ( -- c ) Fetch a byte from address in B; increment B
B!+ ( -- n ) Store to address in B; increment B by 8.
cB!+ ( -- c ) Store a byte to address in B; increment B
fill ( address count byte -- ) Fill count bytes of memory, beginning at the address, with value byte
erase ( address count -- ) Fill count bytes of memory, beginning at the address, with zeroes
move ( source destination count -- ) Copies a region of memory count bytes long beginning at source,
to memory beginning at destination. The move works even if the memory regions overlap.mark ( -- ) store HERE, VHERE, LIST, MACRO and FORTH at MARK
forget( -- ) restore HERE, VHERE, LIST, MACRO and FORTH from MARK
sysexits ( &errorstr -- ) exit
sysopen ( cstr mode -- fd )
sysclose ( fd -- n )
sysread ( fd a n -- n2 )
callsterminate if fd == 0 and returns -1. ( fd a n -- n2|-1 )
syswrite ( fd a n -- n2|-1 )
sysfstat ( fd a n -- n2 )
sysseek ( fd pos type -- n )
syscreate ( cstr mode perm -- fd )
sysbind ( cstrold cstrnew flags -- int )
sysmount ( fd afd cstrold flags spec -- int )
; compiles a RET or if the last assembly instruction was a call, it changes it to a jmp.
literalcompiles code that puts the current top of stack on the stack at run time.
if jz then. This uses the Eflags ZF and not the top of stack.
-if jns then. This usse the Eflags SF.
then the preceding if or -if jumps here.
begin until jumps here if the top of stack is not zero
until jump to begin if the top of stack is not zero. If the top of stack is a zero, drop the top of stack and continue after the jmp instruction to begin.
push move the top of stack to the return stack
pop move the top of return stack to the data stack
dup drop swap nip over tuck rot -rot Stack manipulation routines as in other forths.
+ - * */ / /mod mod 2* shl 2/ sar not and or xor count test @ ! c@ c! A A! @+ !+ c@+ c!+ c!- B B! B@+ B!+ cB@+ cB!+ These macros compile the corresponding forth words' code at HERE.
Do not calculate the memory locations of HERE, VHERE, and such state. Use hardcoded offsets load/store those memory locations.
Support UNIX style keyboard shortcuts.