Q L   H A C K E R ' S   J O U R N A L
      ===========================================
           Supporting  All  QL  Programmers
      ===========================================
         #34                       December 2001 
      
    The QL Hacker's Journal (QHJ) is published by Tim
Swenson as a service to the QL Community.  The QHJ is
freely distributable.  Past issues are available on disk,
via e-mail, or via the Anon-FTP server, garbo.uwasa.fi. 
The QHJ is always on the look out for article submissions.

        QL Hacker's Journal
     c/o Tim Swenson
     2455 Medallion Dr. 
     Union City, CA 94587
     swensont@lanset.com
     http://www.geocities.com/SiliconValley/Pines/5865/


EDITOR'S FORUMN

For the second time in the life of the QHJ, I have allowed a whole
year to go between issues.  When I started the QHJ 10 years ago, I
knew something like this might happen, therefore I made the QHJ a free
publication.  This has kept any off any outside pressure to get the
next issue out.  I really only have to deal with my own pressure. 
I think we all have cycles of dedication to projects.  Sometimes when
we start a project we can't put it down, other times we can't pick it
up.  For the last year I really have not had the drive to do some
programming.  Other tasks have filled my time and interest.  Even with
some forced time off from work (yea, I'm one of the victims of the
failed new economy), I have not really spent time doing programming
work.

But, I have found the time to brush off an old issue that I've been
working on for almost 9 months.  I took the time to sit down and
finish it.

This issue focuses on freeware release of TURBO, the SuperBasic
compiler.  I've been involved with the release by editing the manuals
for both TURBO and the TURBO Toolkit.

I remembering hearing about the possible re-release of TURBO in QL
Today back in early 2000.  At the QL 2000 show in October 2000, I
happened to run across George Gwilt.  I asked him about TURBO and
hinted that I'd like to get a copy, if possible.  Soon I had TURBO and
George's Pointer Environment TURBO Kit, TurboPTR.  Not being a
previous TURBO user, I needed a manual to figure out how to use it. 
Simon Goodwin send me his original manuals, which I edited to reflect
the new TURBO.

I plan to use TURBO for all my pogramming projects.  I'm hoping that a
totally freeware SuperBasic development package (TURBO, TURBO Toolkit,
TURBO Config, and TurboPTR) will encourage a more QLer's to start
programming (kind of like what C68 did for C programming on the QL).

As of this issue, I plan to make the QHJ an electronic only
publication and sent out a print copy.  This pretty much only affects
the US readers, as I sent very few issues outside the US.  I believe
that most readers have a way to access the QHJ via web or e-mail.


TURBO COMPILER

TURBO, the SuperBasic compiler, has been updated and released for
almost a year.  Simon Goodwin is the original author with a few others
contributing to the final released product, by Digital Precision. 
George Gwilt has taken the source code and updated the program to work
on the newer QDOS and SMSQ/E systems.

TURBO comes in the following packages:

   - TURBO Toolkit 3.31
   - TURBO 4.10
   - TURBO and TURBO ToolKit manuals
   - TURBO Config
   - TurboPTR
   - TURBO Utilities
   - Task Commander

TURBO Toolkit (TTK) has been updated by Mark Knight and must be loaded
for TURBO to run.  The manuals for TURBO and TURBO Toolkit have been
updated to reflect the new versions.  TURBO Config and TurboPTR are
new tools written by George Gwilt.  TURBO Utilities is a collection of
tools for use with TURBO compiled programs.  Task Commander is a tool
that allows a TURBO compiled program to become a KEYWORD.

Like Qliberator, TURBO compiles off a program already loaded into
SuperBasic.  Unlike Qlib, a work file does not need to be created
first.

TURBO is comprised of two parts, the parser and the code generator. 
They are two separate executables, but are linked when using the
CHARGE TTK keyword.  The parser has the main user interface to TURBO. 
In the parser the user can change various compile options, including
where the destination executable will go and the runtime name of the
executable (as displayed by the JOBS command).

A lot of the compile options can be set within the SuperBasic program
itself, using TTK keywords starting with TURBO_, like TURBO_taskn,
TURBO_buffersz, TURBO_objfil, and TURBO_repfil.

Other commands like IMPLICIT$ and IMPLICIT% inform TURBO how to treat
variables.  'IMPLICIT% var1, var2' tells TURBO to treat these
variables as interger variables (var1%, var2%).  By default,
SuperBasic variables are treated as floating point, but TURBO knows
that most variables do not need to be floating point and that most
programmers do not take the time to use the percent sign in their
programs.  The IMPLICIT% allows the programmer to continue to not use
the percent sign, but tells TURBO to handle the variable as an
integer, thereby saving space (integers are smaller than floats) and
runtime.


Major Differences with Qlib:

1 - No Linking of Extensions (Toolkits)

TURBO does not support the linking of SuperBasic extensions into an
executable.  With Qlib, the extension can be linked and become part of
the executable.  The major reason for doing this is to include
commercial extensions (like Qmenu, and QPTR), into an executable
without having to distribute the extension separately.  If an
extension has to be distributed separately, then a license fee is
usually required by the owner of the extension.

It is also done not to require that an extension is loaded before the
executable is run.  If you have an extension that you think the user
will rarely use and not want to install, linking into the executable
makes it transparent to the user.

The downside is that if the extension gets updated, then the older
version will stay in the executable.  Keeping the extension out of the
executable will allow the extension to be updated and not require a
recompile.  Some older QL programs are rendered inoperable due to an
older extension clashing with SMSQ/E.

2 - Fussier about SuperBasic

Qlib can compile almost any SuperBasic that would run on the QL. 
TURBO is fussier about what SuperBasic code it will compile.

An example is how file names are used.  In SuperBasic a file name does
not need to have quotes around it.  In TURBO, they are needed.  

   Qlib  -  open #3,win1_file_ext
   TURBO -  open #3,'win1_file_ext'

Plus TURBO has a number of keywords (from TURBO Toolkit) that help
TURBO know more about the application.  They have a tendency to give
the program a more TURBO feel.  With Qlib, any compiler directives are
put in REMark statements and not using keywords.

3 - Executable Speed

The major benefit that TURBO has over Qlib, is that resultant
executable is faster than one compiled by Qlib.  I had no first hand
knowledge of this difference so I decided to compile a program with
both Qlib and TURBO and compile the time it took to run the program. 
For the test I used the Ratcliff/Obershelp Pattern Matching algorithm
as listed in QHJ #1.  The main function is percent_alike().  The
program I wrote called the fuction 1000 times, using the arguments of
Pennsylvania and Pencilvania.  Since I was using a Q40 as a test
machine, I needed the program to run long enough to give me some
meaningfull numbers.  1000 times turned out to be long enough.

Here is a table of the results:
  
     SBASIC       12 secs.
     Qlib          8 secs.
     TURBO         5 secs.

The test program is below:


100 LET x = DATE
110 OPEN #3,scr_100x100a100x100
120 BORDER #3,2,2: INK #3,4: PAPER #3,0 : CLS #3
130 FOR l = 1 to 1000
140 LET wordpercent = percent_alike("pennsylvania",
     "pencilvaneya")
150 END FOR l
160 LET y = DATE
170 PRINT #3,"Time : ";y-x
180 FOR z = 1 TO 4000 : LET test = COS(z) : END FOR z
190 CLOSE #3
200 DEFine FuNction percent_alike(a$,b$)
210   LOCal total    
220   total = num_alike(a$,b$)
230   RETURN int( total/(LEN(a$)+LEN(b$))*100)    
240 END DEFine percent_alike
250 DEFine FuNction num_alike (a$, b$)
260   LOCal total, temp$, a1, a2, b1, b2, large$
270   total = 0
280   IF a$=b$ THEN RETURN LEN(a$)*2
290   IF LEN(a$)=1 AND LEN(b$)=1 THEN RETURN 0    
300   IF LEN(a$) > LEN(b$) THEN
310      temp$ = a$
320      a$ = b$
330      b$ = temp$
340   ENDIF    
350   IF LEN(a$)=1 THEN RETURN (a$ INSTR b$)
360   large$ = find_gt_com$ (a$, b$)
370   IF large$ = "" THEN RETURN 0
380   length = LEN(large$)
390   total = length*2
400    a1 = large$ INSTR a$
410    a2 = a1 + length
420    b1 = large$ INSTR b$
430    b2 = b1 + length    
440    IF (a1>1) OR (b1>1) THEN
450       total = total+num_alike (a$(1 TO (a1-1)), b$(1 TO (b1-1)))
460    ENDIF    
470    IF (a2<>LEN(a$)+1) OR (b2<>LEN(b$)+1) THEN
480       total = total+num_alike (a$(a2 TO), b$(b2 TO))
490    ENDIF
500    RETURN total
510 END DEFine percent_alike
520 DEFine FuNction find_gt_com$ (a$, b$)
530    LOCAL temp$, i, j, temp, large$    
540    IF LEN(a$) > LEN(b$) THEN
550       temp$ = a$
560       a$ = b$
570       b$ = temp$
580    ENDIF    
590    LET large$=""    
600    FOR i = 1 TO LEN(a$)
610       FOR j = i TO LEN(a$)
620          temp = a$(i TO j) INSTR b$
630          IF (temp<>0) AND (LEN(a$(i TO j))>LEN(large$)) 
             THEN large$=a$(i to j)
640       END FOR j
650    END FOR i    
660    RETURN large$
670 END DEFINE find_gt_com
    
In general, using TURBO takes a little more work than using
Qliberator.  Both can compile simple progams without any changes. 
TURBO gives the programmer a little more control over the end product
with a variety of commands that control how the executable is
compiled.  The end result is that TURBO is more powerful than
Qliberator, but the power comes at the price of needing to know more
about TURBO to get to that power.

The TURBO manuals do a pretty good job of documenting TURBO and the
use of the various TURBO Toolkit commands.  In some places it does go
into a little too much detail for the average programmer.

Converting from Qlib to TURBO can take time and be a little painfull. 
For some there may not be a need to convert over, as QLib may be
working just fine for them.  But, as TURBO keeps being updated, the
Qlib user may hit a problem with Qlib on newer platforms.  Plus, I
think there is an advantage to using a freeware compiler.


TURBO CONFIG

TURBO does not support standard Qjump Config Blocks.  George Gwilt has
created TURBO Config, a tool that allows Config blocks to be added to
TURBO compiled programs.  After creating some data statements that get
merged with the source code, another tool takes the Config block
information and adds it to the compiled program.

T_CONFIG_DATA is the program that takes your Config bock definition
and creates two files.  The first is the data statements with dummy
data holders.  The second fiile is the actual data that will be put
into the Config block.

T_CONFIG_LOAD is the program that takes the Config block data and puts
it into the compiled program.

The process goes something like this:

   - Write your program.
   - Use T_CONFIG_DATA to create the DATA statements and to define the
data. 
   - Merge the DATA statements with your program. 
   - Compile the program.
   - Use T_CONFIG_LOAD to load the Config block data into the
executable.

The Config block data is read by using READ statements and selecting
the right item by using RESTORE statements.  Due to the way strings
are stored, they must be read twice, with the second read getting the
real string.  Below is an example:

10 RESTORE 1000
20 READ int1
30 READ int2
40 RESTORE 1004
50 READ string1$ : READ string1$
60 RESOTRE 1006
70 READ string2$ : READ string2$
100 PRINT "Int #1: ";int1
110 PRINT "Int #2: ";int2
120 PRINT "String #1: ";string1$
130 PRINT "String #2: ";string2$
140 STOP
998 DATA "$'#*","ctest     !!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
1000 DATA -4444: REMark First Integer
1002 DATA -4444: REMark Second Integer
1004 DATA "XX","00000000000"
1006 DATA "XX","11111111111"


TurboPTR

TURBO is not compatible with all SuperBasic extensions, esp. those
with array paramaters or return values through parameters.  QPTR is
one such set of extensions.  So, to create Pointer Environment
programs using TURBO, George Gwilt has written TurboPTR, which is a
freeware replacement to QPTR.

TurboPTR is comprised of the following elements:

   TPTR              - a set of extensions
   TPTR_BAS          - a set of SuperBasic routines that get merged
                       with your program.
   TPTR_SETF.TASK    - a program that helps setup the window
                       definitions (inc. sprites and such).

TurboPRT also comes with some example sprites and three example
programs.  

I'm not a PE programmer so I can't say much about TurboPTR other than
I hope to find the time to try it out.


TASK COMMANDER

Task Commander is a utility that will convert a TURBO compiled program
into a resident extension or Toolkit, that can be RESPRed and seen as
a new keyword in SuperBacis.

Task Commander will produce a keyword that will produce the same
effect as EXEC or EX.  Task Commander is not designed for creating
library extension with many keywords.  The program is fairly simple
and only does this one thing.  Documentation comes with the program
that quickly explains how to use the program and even how it works.

TURBO UTILITIES

Another zip file contains a number of other TURBO utilites:  LIBRARY
MANAGER, DATASPACE and Utility_Task.

The zip file does not come with documentation, and briefly explains
the programs:

   LIBRARY MANAGER  - pulls out procedures from large SuperBasic
programs.

   DATASPACE - used to ajust the data space requirements in programs
already compiled.

   Utility_task - Neat little utility program that does three things:
Charager Graphics Editor, Sound Effects Editor, and Toolkit Default
Editor.

TURBO SUPPORT PAGE

To assist in the support of TURBO, I've created a TURBO Support Page
on my web page.  The page will list the various reported bugs to both
TURBO and TURBO Toolkit.  Each bug will list what it is, what platform
the bug has been seen on (QDOS, SMSQ/E, etc), and the status of work
on the bug.  Using this page should take some work off of George Gwilt
and leave him to concentrate on actually fixing bugs.  

My web page is: www.geocities.com/SiliconValley/Pines/5865  or
    www.geocities.com/svenqhj/

Since Geocities was bought by Yahoo, you can also use a Yahoo name
instead of the longer original Geocities layout.


BETTERBASIC AND CROSSREF

BetterBasic and CrossRef are two SuperBasic programming utilities
written by Chas Dillon (of THE EDITOR fame).  Chas has released these
two programs into the Public Domain.  He has released the source code
but not any executables.

I decided to take the two programs, see what changes they needed to be
compiled with the new TURBO, compile them, and make them available. 
Both compiled without a problem.  [documentation ?]

BetterBasic is a SuperBasic structure analyzing tool that does sort of
a grammer check on a SuperBasic program, making changes as it sees
fit and making recommendations for other areas.  Looking at the source
code, it looks like it will also handle a form of IBM basic (I'm
guessing GW-BASIC) as the program was modified in 1992 to handle
"IBM".

CrossRef is a cross reference generator for SuperBasic programs.  It
generates a three part report on the program.  Part one being an index
listing of all program variables, procedures and functions.  The
second part is a listing of system and extension command/functions. 
The third part is a listing of "suspicious" variables, functions, or
procedures.  An optional fourth report provides a procedure trace
giving a dynamic call hierarchy.

Both BetterBasic and CrossRef are available off my web site:
   www.geocities.com/SiliconValley/Pines/5856/


DISK TEXT SEARCH UTILITY

Over the years, to keep various e-mails and newsgroup postings, I've
printed them out and kept them at home.  I've thought about storing
them as files on disk, but finding the information I need would not
be too easy.  I was looking for a utility that would search the files
on disk, find files with from a search string, display the files,
showing the lines where the search string was found.

While at SGI, we had a tool that did this and it was used heavily by
the technical support teams.

Creating something similar on the QL could be difficult if building it
from scratch.  Being a Unix user for years, I know that it is easier
to build a new tools by hooking together a number of existing tools. 
On the QL the Unix search utility GREP is available.  It has options
to report back the file name, the line number, and the line of text,
where a search string has been found.  Now I needed a way to view the
information in such a way as to browse through it.  HTML and an HTML
browser was not quite the way to go.

Dilwyn Jones had written a text browser, that allows links to other
files, but it does not allow links to specific lines with a file. 
After some badgering by myself and Darren Branaugh, Dilwyn has now
added that feature to his VIEWER program (as of version 1.20).

So, with a tool to search files and a tool to display the results, all
this is left to write is a program that links the two together. 
Listed below is that program.

Basically, here is what the program does.  The user enters a search
string.  The program then calls GREP with the command line options to
report back the name of the file, the line number on which the string
is found and the line itself.  The program searches all '_txt' files
in a given directory.  The results of the GREP are sent to a tempory
file on RAM1_.  The program then reads in this file, creating proper
links for VIEWER.  Since VIEWER is not designed for lines greater than
80 characters, the line in which the string is found, is shortened to
about 30 or so characters.  The program then calls VIEWER with the
links file as an argument.  Using VIEWER the user can then browse
through the results of the search, looking to find the right text
file.

There is one possible major drawback with the way the program is
written.  Since the program has to wait for GREP to finish executing
before it can continue, it uses EXEC_W instead of EXEC to execute the
program.  If there are other multitasking programs, this might
interfere with them.  It would be possible to write a polling routine
to wait for GREP to finish, but would complicate the simple program. 
A more polished version would find a proper solution to the problem.

For those interested, GREP can be found in the C68 distribution and
VIEWER is available off of Dilwyn Jones' web page.

100 PRINT "Enter Search String"
110 INPUT search$
120 cmd_line$ = "-n "&search$&" *txt > ram1_temp_txt"
130 EXEC_W grep;cmd_line$
140 OPEN #4,ram1_temp_txt
150 OPEN_NEW #5,ram1_link_txt
160 REPeat loop
170 INPUT #4,in$
180 IF EOF(#4) THEN EXIT loop
190 x = ":" INSTR in$
200 file$ = in$( 1 TO x-1)
210 in$ = in$ (x+1 TO )
220 x = ":" INSTR in$
230 line_num$ = in$(1 TO x-1)
240 text$ = in$(x+1 TO )
250 x = search$ INSTR text$
260 length = LEN(text$)
270 IF x > 15 THEN 
280    first = 15
290  ELSE 
300    first = x-1
310  END IF 
320 IF length > x+15 THEN 
330    last = 15
340 ELSE 
350    last = length
360 END IF 
370 text$ = text$(x-first TO x+last)
380 PRINT #5,"<<";file$;"$";text$;"@";line_num$;">>"
390 END REPeat loop
400 CLOSE #4
410 CLOSE #5
420 DELETE ram1_temp_txt
430 EXEC_W flp1_viewer_rtm;"ram1_link_txt"







    Source: geocities.com/svenqhj