  CREATE file.F  32 ALLOT  ( Forth file name )
  CREATE file.h  32 ALLOT  ( header file name )
  CREATE file.c  32 ALLOT  ( source file name )

LD cnames     ( Forth name to C legal name translator )
LD c          ( create C source code from Forth code )
LD optimize.rs ( add optimization rules )
LD headers    ( create headers as C structures )

interpret RULES
{ botforth }{ INCLUDE }{ EXCLUDE }{ }
{ #IFNOTDEF }{ #IFDEF }[ BL WORD ]
{ #ELSE }{ #ENDIF }{ }
{ #IF }[ 0 WORD ]

DECIMAL
( ==== File name transformations ==== )
: LOWERCASE  ( S -- s )  DUP COUNT
   FOR  DUP C@  ` A -  26 U<  IF  32 OVER C+!  ( lc ASCII ) ENDIF  1 +  NEXT 
   DROP ;

: FILE.x  ( s \ c -- s' )   OVER C@
   IF  OVER  DUP C@ +  C!  ELSE  DROP  ENDIF ;

( ==== Loader words ==== )
  CREATE first-link  32 ALLOT  ( first link in header file )
  
: FINISHED  ( -- )  ( a do nothing word for flushing Timbre ) ;

: HFILE  ( s -- )  DUP file.F 32 CMOVE  file.h 32 CMOVE
   file.h LOWERCASE  ` h FILE.x >FILE
   file.h COUNT 2 -  DUP first-link C!+  SWAP  CMOVE
   ." /* Header file for dictionary entries generated by Timbre */" CR
   ." extern void *_"  first-link COUNT TYPE  ." ;"  CR
   interpret-headers RULES  SHELL{ first-link file.F TLD }SHELL
   IF  " FINISHED" inputq PUSH  TRANSLATE  ENDIF  >CONSOLE ;

: CFILE  ( s -- )  DUP file.F $!  file.c 32 CMOVE
   file.c LOWERCASE  ` c FILE.x  >FILE
   ." /* Source file generated by Timbre */" CR CR
   ." #include " ` " EMIT ." botforth.h" ` " EMIT ."   /* interface to VFM */"
    CR
   ." #include "  ` " EMIT  file.c ` h FILE.x  COUNT TYPE  ` " EMIT
   ."  /* headers */ "
   interpret RULES  SHELL{ file.F TLD }SHELL
   IF  " FINISHED" inputq PUSH  TRANSLATE  ENDIF  >CONSOLE ;

: CLD  ( "file" -- )  ( translate a Forth file to a C file )
   BL WORD  HERE file.F $!  file.F HFILE file.F CFILE ;

: VHFILE  ( s -- )  DUP file.F 32 CMOVE  file.h 32 CMOVE
   file.h LOWERCASE  ` h FILE.x
   COUNT 2 -  DUP first-link C!+  SWAP  CMOVE
   ." /* Header file for dictionary entries generated by Timbre */" CR
   ." extern void *_"  first-link COUNT TYPE  ." ;"  CR
   interpret-headers RULES  SHELL{ first-link file.F TLD }SHELL
   IF  " FINISHED" inputq PUSH  TRANSLATE  ENDIF  FLUSH-EMITS ;

: VCFILE  ( s -- )  DUP file.F 32 CMOVE  file.c 32 CMOVE
   file.c LOWERCASE  ` c FILE.x DROP
   ." /* Source file generated by Timbre */" CR CR
   ." #include " ` " EMIT ." botforth.h" ` " EMIT ."   /* interface to VFM */"
    CR
   ." #include "  ` " EMIT  file.c ` h FILE.x  COUNT TYPE  ` " EMIT
   ."  /* headers */ "
   interpret RULES  SHELL{ file.F TLD }SHELL
   IF  " FINISHED" inputq PUSH  TRANSLATE FLUSH-EMITS  ENDIF ;

: VCLD  ( "file" -- )  ( translate a Forth file to a C )
   BL WORD  HERE file.F 32 CMOVE  file.F VHFILE  file.F VCFILE ;
