Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #19366 > unrolled thread

Tcl Forth + TclForth !

Started byWolf Wejgaard <wejgaard@gmail.com>
First post2013-02-02 00:32 -0800
Last post2013-02-10 07:52 -0800
Articles 9 — 6 participants

Back to article view | Back to comp.lang.forth


Contents

  Tcl Forth + TclForth ! Wolf Wejgaard <wejgaard@gmail.com> - 2013-02-02 00:32 -0800
    Re: Tcl Forth + TclForth ! "A. K." <akk@nospam.org> - 2013-02-02 10:26 +0100
    Re: Tcl Forth + TclForth ! mhx@iae.nl (Marcel Hendrix) - 2013-02-02 12:14 +0200
      Re: Tcl Forth + TclForth ! Wolf Wejgaard <wejgaard@gmail.com> - 2013-02-05 02:15 -0800
      Re: Tcl Forth + TclForth ! mhx@iae.nl (Marcel Hendrix) - 2013-02-06 20:52 +0200
    Re: Tcl Forth + TclForth ! "Rod Pemberton" <do_not_have@notemailnotz.cnm> - 2013-02-05 06:24 -0500
      Re: Tcl Forth + TclForth ! Brad Eckert <hwfwguy@gmail.com> - 2013-02-06 09:28 -0800
      Re: Tcl Forth + TclForth ! Wolf Wejgaard <wejgaard@gmail.com> - 2013-02-10 04:37 -0800
    Re: Tcl Forth + TclForth ! Eduardo Costa <edu500ac@gmail.com> - 2013-02-10 07:52 -0800

#19366 — Tcl Forth + TclForth !

FromWolf Wejgaard <wejgaard@gmail.com>
Date2013-02-02 00:32 -0800
SubjectTcl Forth + TclForth !
Message-ID<cb1a1fe1-3015-4bac-a63a-d37819721776@googlegroups.com>
Hi, 

have you ever wished for a true multi-platform Forth system which runs 
on all desktops? So have I, and finally I have found a satisfying solution 
that I would like to describe here: TclForth.

TclForth is a Forth system that uses Tcl as its native language. It is not a 
Forth system running in Tcl nor is it Tcl running in Forth but rather a 
cooperation of both worlds: The Forth code and colon words are compiled 
to Tcl procedures that handle arguments and results on a stack. The Forth 
and Tcl procedures coexist in the Tcl namespace and are all taken care of 
by the Tcl runtime system. Thus, the Tcl bytecode interpreter is also the 
inner interpreter of TclForth. For more see http://wiki.tcl.tk/37199. 

I have built applications with TclForth for a while and now release it as 
an open source Google Code project at http://tclforth.googlecode.com. 
The system is prepared as self-contained double-click executables for Windows 
and OS-X (starpacks) and as a set of source files for Tcl in Linux and elsewhere. 
Installation = unzip, but have a look at the installation page in the wiki anyway. 
There is also a preliminary user guide.

I have not attempted to pack all of Tcl into Forth words. There are the usual 
standard words of Forth and Tcl and a set of Tk words that I have needed so far. 
You are welcome to add whatever you miss. 

If, of course, if you are actually willing to embrace Tcl for a rich multi-platform 
Forth system. 

Best wishes,

Wolf Wejgaard
http://holonforth.com

[toc] | [next] | [standalone]


#19367

From"A. K." <akk@nospam.org>
Date2013-02-02 10:26 +0100
Message-ID<510cdbbf$0$6624$9b4e6d93@newsspool2.arcor-online.net>
In reply to#19366
On 02.02.2013 09:32, Wolf Wejgaard wrote:
> Hi,
>
> have you ever wished for a true multi-platform Forth system which runs
> on all desktops? So have I, and finally I have found a satisfying solution
> that I would like to describe here: TclForth.
>
> TclForth is a Forth system that uses Tcl as its native language. It is not a
> Forth system running in Tcl nor is it Tcl running in Forth but rather a
> cooperation of both worlds: The Forth code and colon words are compiled
> to Tcl procedures that handle arguments and results on a stack. The Forth
> and Tcl procedures coexist in the Tcl namespace and are all taken care of
> by the Tcl runtime system. Thus, the Tcl bytecode interpreter is also the
> inner interpreter of TclForth. For more see http://wiki.tcl.tk/37199.
>
> I have built applications with TclForth for a while and now release it as
> an open source Google Code project at http://tclforth.googlecode.com.
> The system is prepared as self-contained double-click executables for Windows
> and OS-X (starpacks) and as a set of source files for Tcl in Linux and elsewhere.
> Installation = unzip, but have a look at the installation page in the wiki anyway.
> There is also a preliminary user guide.
>
> I have not attempted to pack all of Tcl into Forth words. There are the usual
> standard words of Forth and Tcl and a set of Tk words that I have needed so far.
> You are welcome to add whatever you miss.
>
> If, of course, if you are actually willing to embrace Tcl for a rich multi-platform
> Forth system.
>
> Best wishes,
>
> Wolf Wejgaard
> http://holonforth.com
>

Really really nice work!!
Thank you for publishing it!!

Andreas

[toc] | [prev] | [next] | [standalone]


#19369

Frommhx@iae.nl (Marcel Hendrix)
Date2013-02-02 12:14 +0200
Message-ID<02899101018434@frunobulax.edu>
In reply to#19366
Wolf Wejgaard <wejgaard@gmail.com> write Re: Tcl Forth + TclForth !
[..]
> If, of course, if you are actually willing to embrace Tcl for a rich multi-platform 
> Forth system. 

But Tcl is so terribly verbose!

Below is a wish script that is piped to the tcl interpreter. The S~ 
words send text to tcl's stdin and return tcl's stdout. The Forth 
part ends with MyTEST. It does a simple sum. 

The wish script is in the same file as the Forth code and starts after 
WISH:, ending on the first empty line.

Can you demonstrate how Tcl Forth does this in an elegant and 
compact manner?

-marcel

-- ax+b8.frt -------------------------

NEEDS -tcltk
ANEW -ax+b8

4 SET-PRECISION

0 VALUE stop?

0e FVALUE x	0e FVALUE y
0e FVALUE x1    0e FVALUE y1
0e FVALUE x2    0e FVALUE y2

: DoX ( -- ) x2 x1 F-   y2 y1 F- F/   y y1 F- F*   x1 F+ TO x  S" set x " x (F.) $+ do-TCL 2DROP ;
: DoY ( -- ) y2 y1 F-   x2 x1 F- F/   x x1 F- F*   y1 F+ TO y  S" set y " y (F.) $+ do-TCL 2DROP ;

: MyTEST ( -- )
	CLEAR stop?
	BEGIN  	stop? 0= 
	WHILE  	S~ puts stdout $cmd~ DUP
	   	0= IF  2DROP 
	   	 ELSE  EVALUATE
	   	       S~ set cmd ""~ 2DROP
	        ENDIF
		S~ update~ 2DROP
	REPEAT ;

-- Wishing --------------------------------------------------------------------

[DEFINED] -tcltk [IF] OPEN-WISH  ( load and activate the Tcl/Tk interpreter ) [THEN]

WISH:
proc send_DOXY {} {
   global cmd x y x1 y1 x2 y2
   set cmd [format "%e TO x  %e TO y  %e TO x1  %e TO y1  %e TO x2  %e TO y2  DoX DoY" $x $y $x1 $x2 $y1 $y2]
}
proc send_DOX {} {
   global cmd x y x1 y1 x2 y2
   set cmd [format "%e TO x  %e TO y  %e TO x1  %e TO y1  %e TO x2  %e TO y2  DoX" $x $y $x1 $x2 $y1 $y2]
}
proc send_DOY {} {
   global cmd x y x1 y1 x2 y2
   set cmd [format "%e TO x  %e TO y  %e TO x1  %e TO y1  %e TO x2  %e TO y2  DoY" $x $y $x1 $x2 $y1 $y2]
}
proc send_STOP {} {
   global cmd 
   set cmd "TRUE TO stop?"
}
proc send_BELL {} {
   global cmd 
   set cmd "BELL"
}
set x1 4
set y1 0
set x2 20
set y2 100
set x 0
set y 0
set cmd ""
label .lbl_x1   -text "x1 ="
label .lbl_y1   -text "y1 ="
label .lbl_x2   -text "x2 ="
label .lbl_y2   -text "y2 ="
label .lbl_newx -text "x ="
label .lbl_newy -text "y ="
entry .x1 -width 8 -relief sunken -textvariable x1
entry .y1 -width 8 -relief sunken -textvariable y1
entry .x2 -width 8 -relief sunken -textvariable x2
entry .y2 -width 8 -relief sunken -textvariable y2
entry .x  -width 8 -relief sunken -textvariable x
entry .y  -width 8 -relief sunken -textvariable y
bind .x1 <Return> {send_DOXY}
bind .y1 <Return> {send_DOXY}
bind .x2 <Return> {send_DOXY}
bind .y2 <Return> {send_DOXY}
bind .x  <Return> {send_DOY}
bind .y  <Return> {send_DOX}
button .b_compx -text "Compute x" -command send_DOX
button .b_compy -text "Compute y" -command send_DOY
button .b_beep  -text "Beep"      -command send_BELL
button .b_exit  -text "Exit"      -command send_STOP
grid .lbl_x1   -row 1 -column 1 -padx 2 -pady 2
grid .x1       -row 1 -column 2 -padx 2 -pady 2
grid .lbl_y1   -row 1 -column 3 -padx 2 -pady 2
grid .y1       -row 1 -column 4 -padx 2 -pady 2
grid .lbl_x2   -row 2 -column 1 -padx 2 -pady 2
grid .x2       -row 2 -column 2 -padx 2 -pady 2
grid .lbl_y2   -row 2 -column 3 -padx 2 -pady 2
grid .y2       -row 2 -column 4 -padx 2 -pady 2
grid .lbl_newx -row 3 -column 1 -padx 2 -pady 2
grid .x        -row 3 -column 2 -padx 2 -pady 2
grid .b_compy  -row 4 -column 3 -padx 2 -pady 2
grid .lbl_newy -row 4 -column 1 -padx 2 -pady 2
grid .y        -row 4 -column 2 -padx 2 -pady 2
grid .b_compx  -row 3 -column 3 -padx 2 -pady 2
grid .b_beep   -row 5 -column 1 -padx 2 -pady 2
grid .b_exit   -row 5 -column 4 -padx 2 -pady 2


CR .( ****** click on the "Exit" button to terminate ... ) MyTEST

[DEFINED] -tcltk [IF] CLOSE-WISH [THEN]

[toc] | [prev] | [next] | [standalone]


#19447

FromWolf Wejgaard <wejgaard@gmail.com>
Date2013-02-05 02:15 -0800
Message-ID<a3ea3c8d-43b1-42f0-8eb6-f2cdc6886b18@googlegroups.com>
In reply to#19369
Am Samstag, 2. Februar 2013 11:14:01 UTC+1 schrieb Marcel Hendrix:

> Wolf Wejgaard <wejg...@gmail.com> write Re: Tcl Forth + TclForth !
> [..]
> > If, of course, if you are actually willing to embrace Tcl for a rich multi-platform
> > Forth system.
> 
> But Tcl is so terribly verbose!
> 
> Below is a wish script that is piped to the tcl interpreter. The S~
> words send text to tcl's stdin and return tcl's stdout. The Forth
> part ends with MyTEST. It does a simple sum.
> 
> The wish script is in the same file as the Forth code and starts after
> WISH:, ending on the first empty line.
> 
> Can you demonstrate how Tcl Forth does this in an elegant and
> compact manner?
> 
> -marcel
> 
>

Ok, good idea! Let's me test TclForth on a foreign project and maybe clarify a few points.

I first started with comments to your code and how I would do it in TclForth, but then saw
that this needs a full working version in order to make sense. 

So here is a TclForth version of your program. Please copy it to a file with extension .fth 
in the TclForth source directory and load it via the File menu in the TclForth console. 

I add comments below. Only one point is needed now: The Forth words coexist with Tcl in 
the codespace, therefore the pipe mechanism reduces to a call.


\ ---- Start of TclForth version ----

  0 variable x       0 variable y
  4 variable x1      0 variable y1
20. variable x2   100. variable y2

code .%e ( x -- ) printnl [format %e $x]

: DoX ( -- ) x2 y1 - y2 y1 - / y y1 - * x1 + dup x ! .%e 
  
: DoY ( -- ) y2 y1 - x2 x1 - / x x1 - * x1 + dup y ! .%e  

tcl toplevel .t ; wm title .t "TclForth Version"

code Labels ( -- )
   label .t.lbl_x1   -text "x1 ="
   label .t.lbl_y1   -text "y1 ="
   label .t.lbl_x2   -text "x2 ="
   label .t.lbl_y2   -text "y2 ="
   label .t.lbl_newx -text "x ="
   label .t.lbl_newy -text "y ="

code makeentry ( e -- )  entry .t.$e -width 8 -relief sunken -textvariable $e

: Entries ()
   "x1" makeentry  
   "y1" makeentry  
   "x2" makeentry  
   "y2" makeentry  
   "x" makeentry   
   "y" makeentry  
;

code Bindings ()
   bind .t.x1 <Return> {DoX; DoY}
   bind .t.y1 <Return> {DoX; DoY}
   bind .t.x2 <Return> {DoX; DoY}
   bind .t.y2 <Return> {DoX; DoY}
   bind .t.x  <Return> {DoY}
   bind .t.y  <Return> {DoX}

code BELL () printnl "Beep"

code Buttons ()
   button .t.b_compx -text "Compute x" -command DoX
   button .t.b_compy -text "Compute y" -command DoY
   button .t.b_beep  -text "Beep"      -command BELL

code makegrid ( r c w -- )  grid $w -row $r -column $c -padx 2 -pady 2

: TheGrid ()
   1 1 ".t.lbl_x1" makegrid   1 2 ".t.x1" makegrid
   1 3 ".t.lbl_y1" makegrid   1 4 ".t.y1" makegrid  
   2 1 ".t.lbl_x2" makegrid   2 2 ".t.x2" makegrid
   2 3 ".t.lbl_y2" makegrid   2 4 ".t.y2" makegrid
   3 1 ".t.lbl_newx" makegrid   3 2 ".t.x" makegrid  3 3 ".t.b_compx" makegrid 
   4 1 ".t.lbl_newy" makegrid   4 2 ".t.y" makegrid  4 3 ".t.b_compy" makegrid   
   5 1 ".t.b_beep" makegrid  
  
Labels Entries Bindings Buttons TheGrid

\ ---- End of TclForth version ---


---------------------------------------------------------------------------------------

Comments:
---------

0 variable x       0 variable y
-- The Forth variables are implemented as Tcl variables and take ints and floats 
and anything else, that can exist on the stack, strings, lists. 

code .%e ( x -- ) printnl [format %e $x]
-- Pack Tcl features into Forth code words.

: DoX ( -- ) x2 y1 - y2 y1 - / y y1 - * x1 + dup x ! .%e 
  
: DoY ( -- ) y2 y1 - x2 x1 - / x x1 - * x1 + dup y ! .%e  
-- 
1. TclForth definitions are terminated by an empty line. "endcode" and ";" are optional.

2. The Forth math operators are converted to Tcl exec expressions, which handle float 
and int.

x !
-- The TclForth variables are objects with a set of messages. You could also write "x set"
or "x put" - see the source, it's trivial to add messages to the object, so I couldn't decide. 

tcl toplevel .t ; wm title .t "TclForth Version"
-- A command line starting with "tcl" is passed to the Tcl interpreter. 

toplevel .t ; wm title .t "TclForth Version"
-- A custom window for your program. The main window . is already used by the Forth console.

code Labels ( -- )
   label .t.lbl_x1   -text "x1 ="
   label .t.lbl_y1   -text "y1 ="
   ...
-- TclForth can handle Tk notation in code words. You have all of Tk at your disposal.

code Bindings ()
   bind .t.x1 <Return> {DoX; DoY}
   bind .t.y1 <Return> {DoX; DoY}
   ...
-- DoX and DoY are Forth words that are here called from Tcl code! No problem since Forth 
words and Tcl commands are both procedures in the Tcl code space. They differ only in the way 
they handle their arguments, formal versus stack. DoX and DoY take no argument, so nothing to
add. If, say, DoX wants a parameter x, push it before the call: "push $x; DoX"  

Finally, there is no stop button. Just close the window.

--

Now, I don't know if the TclForth version satifies your measure of "elegant and compact"
but I am certainly happy to have the Forth and Tcl worlds combined. TclForth is not perfect, 
but it does what I need. 

Wolf

[toc] | [prev] | [next] | [standalone]


#19517

Frommhx@iae.nl (Marcel Hendrix)
Date2013-02-06 20:52 +0200
Message-ID<17831597018434@frunobulax.edu>
In reply to#19369
Wolf Wejgaard <wejgaard@gmail.com> writes Re: Tcl Forth + TclForth !

> Am Samstag, 2. Februar 2013 11:14:01 UTC+1 schrieb Marcel Hendrix:

>> Wolf Wejgaard <wejg...@gmail.com> write Re: Tcl Forth + TclForth !
[..]
>> But Tcl is so terribly verbose!
[..] 
> Ok, good idea! Let's me test TclForth on a foreign project and maybe clarify a few points.
>
> I first started with comments to your code and how I would do it in TclForth, but then saw
> that this needs a full working version in order to make sense. 

> So here is a TclForth version of your program. Please copy it to a file with extension .fth 
> in the TclForth source directory and load it via the File menu in the TclForth console. 

> I add comments below. Only one point is needed now: The Forth words coexist with Tcl in 
> the codespace, therefore the pipe mechanism reduces to a call.

I have to say that the communication became a lot simpler!

However, I see now that I can temporarily revector TYPE to get rid of converting everything 
to strings explicitly. TYPE can then type to a send/receive loop in a background task.
Old Tcl's did not like this, they (or Windows) somehow got confused when a thread manipulates
stdio via pipes.

I would still miss the variables that are visible to both Tcl and Forth. However, I can
CREATE DOES> a tcl-var that accepts any object using TO etc.

Looking at your translation of the WISH script: It is slightly simpler because of code words. 
But your code words simply send strings to TCL and I can fake that easily by redirecting ."  
(Of course, this is automatic when TYPE is revectored).

code .%e ( x -- ) printnl [format %e $x]

  then becomes

tcl: .%e ( x -- ) ." printnl [format %e $x]" ;tcl

Hmm, no I would need a "$-parser" in ." to handle $x. Not so simple, but also no rocket 
science.

From then on there isn't much difference anymore. Wish stays as verbose as ever.
OTOH, that is probably exactly what you wanted. (But not what I was hoping for.)

Thank you for this thought-provoking posting.

-marcel

[toc] | [prev] | [next] | [standalone]


#19453

From"Rod Pemberton" <do_not_have@notemailnotz.cnm>
Date2013-02-05 06:24 -0500
Message-ID<keqq2b$mmc$1@speranza.aioe.org>
In reply to#19366
"Wolf Wejgaard" <wejgaard@gmail.com> wrote in message
news:cb1a1fe1-3015-4bac-a63a-d37819721776@googlegroups.com...
>
> have you ever wished for a true multi-platform Forth
> system which runs on all desktops?

No.

> So have I, and finally I have found a satisfying solution
> that I would like to describe here: TclForth.

So, the numerous versions of Forth coded in C, i.e.,
multi-platform Forth systems, were unsatisfying solutions?
Unsatisfying how?  Solutions to what?  Are those versions
any less complete, less functional, than TclForth ... ?

> TclForth is a Forth system that uses Tcl as its native language.
> It is not a Forth system running in Tcl nor is it Tcl running in
> Forth but rather a cooperation of both worlds: The Forth code
> and colon words are compiled to Tcl procedures that handle
> arguments and results on a stack.  The Forth and Tcl procedures
> coexist in the Tcl namespace and are all taken care of
> by the Tcl runtime system. Thus, the Tcl bytecode interpreter is
> also the inner interpreter of TclForth. For more see [link]
>
> I have built applications with TclForth for a while and now
> release it as an open source Google Code project at [link].
> The system is prepared as self-contained double-click
> executables for Windows and OS-X (starpacks) and as a set
> of source files for Tcl in Linux and elsewhere.
> Installation = unzip, but have a look at the installation page
> in the wiki anyway.  There is also a preliminary user guide.
>
> I have not attempted to pack all of Tcl into Forth words. There
> are the usual standard words of Forth and Tcl and a set of Tk
> words that I have needed so far.  You are welcome to add
> whatever you miss.
>
> If, of course, if you are actually willing to embrace Tcl for a
> rich multi-platform Forth system.
>

Apparently, I'm confused.  Why Tcl?  Why not Java?  Java is not as
widely available as C, but Java is far more widely available than
Tcl.  So, I'd think that C should be your first choice, followed
by Java, followed by ...

I don't intend to sound harsh.  I appreciate you posting your
work.


Rod Pemberton


[toc] | [prev] | [next] | [standalone]


#19511

FromBrad Eckert <hwfwguy@gmail.com>
Date2013-02-06 09:28 -0800
Message-ID<26893ea9-e2af-46a3-b497-4f4d14306d46@googlegroups.com>
In reply to#19453
On Tuesday, February 5, 2013 4:24:13 AM UTC-7, Rod Pemberton wrote:
> 
> Apparently, I'm confused.  Why Tcl?  Why not Java?  Java is not as
> widely available as C, but Java is far more widely available than
> Tcl.  So, I'd think that C should be your first choice, followed
> by Java, followed by ...
> 

But it's from Wolf. That alone makes it worth looking at.

[toc] | [prev] | [next] | [standalone]


#19606

FromWolf Wejgaard <wejgaard@gmail.com>
Date2013-02-10 04:37 -0800
Message-ID<c83df110-5ef6-4efa-b25e-2a2ad95fb580@googlegroups.com>
In reply to#19453
Am Dienstag, 5. Februar 2013 12:24:13 UTC+1 schrieb Rod Pemberton:
...
> Apparently, I'm confused.  Why Tcl?  Why not Java?  Java is not as
> widely available as C, but Java is far more widely available than
> Tcl.  So, I'd think that C should be your first choice, followed
> by Java, followed by ...
>
> I don't intend to sound harsh.  I appreciate you posting your 
> work. 
>
> Rod Pemberton 

Thanks. 

Actually I did try Java first. See http://www.holonforth.com/tools/java/holonj.htm

--

Wolf Wejgaard
http://holonforth.com

[toc] | [prev] | [next] | [standalone]


#19608

FromEduardo Costa <edu500ac@gmail.com>
Date2013-02-10 07:52 -0800
Message-ID<65ce44b5-02fc-41ab-8778-b4da9e88678b@googlegroups.com>
In reply to#19366
I am curious about one point. IMHO, Forth earned its popularity from its speed, and tiny compiler. I am writing internet applications, mostly in Lisp. An application in Bigloo (a Scheme Lisp compiler) requires me to upload 4 Megabytes of statically compiled code; otherwise, my program will not run in the inexpensive hosting service I use. I tried to compile my programs with GambitC, and 6 megabytes is not enough; I am still receiving error messages from the server. In Common Lisp, I need to upload the whole sbcl compiler to make the hosting server to work, i. e., 40 megabytes. In Python, I would need 40 megabytes too. I tried to use Java with a Lisp to Java converter called Linj, and I was required to upload the whole Java Virtual Machine, almost 200 megabytes.

SP-forth required me to upload 130 kilobytes, that included the case insensitive package, local variables, floating point, etc. Lina Forth required something around 300 kilobytes. Both SP-forth and Lina Forth are fast. In many of my applications, SP-forth beats optimized C.  In small benchmarks, optimized C wins marginally. Of course, the programs compiled with SP-forth are much smaller than programs compiled with C.

My question. Why don't you write a TCL wrapper around a few popular Forth compilers. I mean, you could write a wrapper around SP-Forth, Lina Forth, for example. One of my students wrote a wrap around sbcl Lisp. Her wrap was based on ltk, and ABLE. The tcl/tk server is based on tclkit, that pack all tk in a small file of 2 megabytes. Here is her project:

code.google.com/p/winsbcl

If you do this wrap, you will have a fast Forth, with a fine IDE. Since most versions of Forth lack an IDE, I guess your distribution would be a success. You could pack tclkit with your distribution.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.forth


csiph-web