         Q L   H A C K E R ' S   J O U R N A L
      ===========================================
           Supporting  All  QL  Programmers
      ===========================================
         #20                        March 1995 
      
    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
     5615 Botkins Rd 
     Huber Heights, OH 45424 USA
     (513) 233-2178
     swensotc@ss2.sews.wpafb.af.mil
     tswenson@dgis.dtic.dla.mil


EDITOR'S FORUMN

   Another few months, another issue.  I don't know if there
is any special significance to putting out issue #20, but it
looks nice to have a zero in the 1's place.

   One thing nice to report is that the number of QHJ
readers is increasing (at least direct readers).  I keep
running into more QLers on the Internet.  I find some and
some find me.  The e-mail list is now over 120 (mostly
outside the US).  The hard copy mailing list is in the
mid-30's (mostly in the US).  I have no idea how many
people read the QHJ through friends, BBS's, and archives on
the Internet.

   One bit of news; there will be a QL show in Oak Ridge,
Tennessee, USA, on 10 June.  The show has moved from
Newport, Rhode Island, where it has been held two times in
the past.  I plan to attend (it's only about a 5 hour drive
for me).  I'll bring some QHJ issues, all past issues on
disk, my Sinclair Internet Resouce list, and disks with
Freeware programming languages and tools.  Hope to see  you
there.

   I've noticed two things in the latest issue of the
International QL Report.  Pedro Reina talks about QLIMPO, a
C tool that helps write code for different platforms (
currently QDOS and MS-DOS, but with an eye out for UNIX). 
QLIMPO is comprised of 17 objects with 156 functions. 
Pedro has tried to use an Object-Oriented approach to
writing this package.  QLIMPO is placed in the public
domain and all documentation is in Spanish.  More details
can be found in the March/April 1995 issue of IQLR.

   The other is an article by Norman Dunbar entitled "The
PE - an idiot's guide!"  This is a simple article on the
Pointer Environment, what it does, how it works, etc. 
Instead of getting into the PE manual, as a beginner this
article is a must.  This is the best, most detailed,
article I have seen on the PE.  I hope Norman (or someone)
would consider putting this article out as a little
pamphlet or booklet.  It's too good to remain just as an
article in a newsletter/magazine.  Needless to say, I
really liked the article.

PROGRAM PROPOSAL - DESCRIPTOR

   In looking through listings of new uploads to the
MS-DOS/Windows site CICA, I came up with an idea for a
program for the QL.  Not having the full expertise or time
to work on it, I thought I would present the idea here. 
Hopefully someone will run with it.

   Descriptor is a program that allows for each QDOS file
to have a "long file name" or description.  The best way to
describe this program is to show how it will work.

   When a user is ready to enter a file name into a program
(such as Quill), he hits ALT-Q (Query).  The Descriptor
window pops up.  The user enters a description of the file
(something like a long file name).  Examples would be:

      MFR: Memo to my Boss     (MFR stands for Memo For Record)
      Letter to Mom dated 11/28/94
      Article for QHJ on programming
      
   Descriptor would then look up all of the file descrip-
tors that have the string in them.  If more than one is
found, the user is allowed to choose.  The real filename
(ie. flp1_text_txt) is then entered into the program (via
the keyboard buffer).

   The program allows you to almost ignore the real file
name for a file and use the long descriptor.

   How it all should work:
   
   Each disk will have a database file (text file) that
links file names to descriptors.  The file will be called
descriptor_db.  The format will be:

       filename_ext:descriptor
       
   Descriptor only deems the first : in the file as
important.  This means that colons are allowed in the
decriptor.

   Descriptor will have three functions:  Query, Add file,
Delete file.

   ALT - Q is the hotkey for the Query function.
   
   ALT - A is the hotkey for the Add File function.  Right
before saving a file, hit ALT-A, enter the file name and
then the descriptor.  The file name will be entered into the
program for you.

   ALT - D is the hotkey for the Delete File function. The
user will query for a file (via descriptor).  Select the
proper file and it will be deleted (out of the database and
off the disk).  It may be usefull to delete out of the
database but not off the disk.

   In theory this should work fairly well.  In practise, I
don't know how well it would do.  It would help in keeping
track of a bunch of text files or Quill files.  I've used
this type of file naming in a Unix office automation
package called Alis (by Applix).  It really is much easier
to keep track of documents, esp. with lots of memo's and
such.

REVERSE STRING

   In one of the progamming newsgroups I read, I saw a
couple of postings dealing with how to reverse a string or
a list.  A short example would be to take the string
"abcde" and make it "edcba".This little puzzle seemed
interesting, so I thought I would give it a shot myself.

   My first approach is purely interative.  Find the length
of the string and then do a FOR loop backwards through the
string, adding each character to another string.

   DEFine FuNction reverse$ (in$)
      LOCal rev$, length
      rev$=""
      length = LEN(in$)
      FOR x = length TO 1 STEP -1
         rev$ = in$(x)
      NEXt x
      RETURN rev$
   END DEFine
   
   The examples I saw were recursive based, so I thought I
would try that approach.
   
   DEFine FuNction reverse$ (in$)
      LOCal temp$      
      if LEN(in$)=1 THEN RETURN in$
      temp$ = reverse$( in$( 2 TO )
      RETURN temp$ & in$(1)
   END DEFine
   
   How I wrote this remided me of how I used to do a few
Lisp programs.  You have to start the procedure with the end
condition first.  You have to think about how you want the
recursion to stop and check for this condition at the start.
I then decided to try this program in Lisp using the WS-Lisp
interpreter.  My first attempt was very similar to the
example below.  When I was looking at the example code that
came with WS-Lisp, I found that it had a reverse function
in that example code.  I saw that my code was going in the
same direction as the example code, but my syntax was
lacking.  Below is the example code.

   (de reverse (rev_list)
      (cond
         ( (isatom rev_list) rev_list )
         ( t (append (reverse (cdr rev_list)) (list (car rev_list))))
         ) ; end of cond
      ) ; end of de revverse

   Then upon further looking, there was another version of
a reverse program that also came with WS-Lisp.  It's a bit
longer than the first version and not quite as easy to read
(at least for me).  It seems to rely on the simplest Lisp
words.  I don't know if it was written to use the lowest
level Lisp words or not.  Anyway, it's another example to
ponder.

(de rev (liste)
   (cond
      ( (isnull liste) liste )
      ( (isnull (cdr liste)) liste )
      ( t
         (cons
            (car (rev (cdr liste)))
            (rev
               (cons
                  (car liste)
                  (rev (cdr (rev (cdr liste))))
               )
            )
         )
      ) ; end of t
   )  ; end of cond
)  ; end of de
      
   I'm sure my SuperBasic programs are not the most elegant
and can be improved upon.  As they said in college, "I leave
it as an excerise to the reader."

GST QC C COMPILER - A REVIEW

   I recently found out about another C compiler.  Peter
Tillier send me a copy (legal, of course) of a C compiler
by GST.  Peter says that the compiler is now available from
Quanta for about 15 pounds.

   The compiler seems to be a cross between Small-C and
Metacomco QL C.  Like Small-C, it supports a subset of the C
language, but it supports more than Small-C.  Like QL C, it
has a compiler, a assembler, and linker.  It even uses a
link setup file like QL C.  And, like C68, even though it
has a number of programs to do a full compile, it
has a front end to drive the whole process.

   In short, QC is based on K&R C and supports:
        switch, for, do, goto statements
   logical operators && ||        unary operators  !  ~
   comma expressions              assignment operators
   long / short integers          unsigned values
   initialised local variables    static and extern
   single dimension arrays        pointers
   
   The preprocessor supports the standard commands, but also
supports the inclusion of assembly code.  There is a section
in the manual that describes how the compiler uses the
various 68000 registers.

   The standard C function library is supported with more
functions that Small-C.  QDOS support is complete, although
different than some of the other compilers.  It does
support trap1, trap2 and trap3 (usefull for doing your own
tinkering with QDOS).

   The manual is fairly complete.  It does not give much
example code, but it documents the compiler fairly well. 
The error messages are fully listed and there is even an
index.

   The compiler fits in between Small-C and QL C (with C68
being far above all C compilers).  If you are used to
working with Small-C, then QC is a step up in what parts of
C are supported.  QC provides a greater ability to help in
porting than Small-C.  QC is not as complicated to use as
C68 can be.  Sometimes I find the full capability of C68
kind of daunting.

   I have not had to really use QC, but from what I can see,
I kind of like it.  I'm sure I'll always like Small-C, but
in those areas that Small-C does not cut it, QC would be a
good compiler to use.

RECENT FREEWARE - APL

   Richard Zidlicky has ported a version of APL to the QL. 
APL stands for A Programming Language.  APL is known for
being about the worst write-only language.  APL uses
special symbols as it's operators.  This means that it
usually requires a special keyboard, thereby making it a
language not easy to port.  APL is also an interpreted
language.

   This particular version of APL is based on a freeware
Unix version that does not use any special symbols, only
the symbols in ASCII.  This means that you can not type
standard written APL code directly in to this APL.  You
have to do some converting first.

   Since I have only used APL once in College, I really
can't say much about this port.  It does seem to run with
the example code provided with it.  I tried to port over
some APL code, but I did not know how to translate the funny
symbols into the ASCII symbols.  As I said, APL is not an
easy language to deal with.

   Below are a few examples of APL code that came with the
interpreter.
   
   a{1 2 3           C assign a vector to a
   b{3 4 5           C                    b
   a+b               C skalar addition
   aXb               C        mult
   a%b               C        division
   aJ.*b             C        inner produkt

now for a few matrix operations

   a{4 4R16?17       C random matrix
   L<bs>%            C invert it
   b{I4
   x{bL<bs>%a        C solve ax=b

   (a+.Xx)-b         C .. is that true?

   a{5 4R20?21      
   Ra                C now we have 5x4
   b{I5

   APL is designed for matrix operations and is great if you
are doing some fairly complex math operations.  I have a
book on computer generated music which is based on APL.  I'm
sure the use of APL is limited in the QL community, but it
is always nice to have another language for the QL.

   This port of APL also comes with some Signal utilites
written by Richard.  Signals allow communications between
processes.  If this is something you are looking for, then
pick up a copy of APL and get the utilities thrown in.

WORD WRAP

   Now that I have an HP Deskjet 520 inkjet printer, I'm
starting to think about what type of output I could do on
it.  I've found the price of any word processors that
support it to be a bit too steep.  I have rigged up Quill
to support one of the fonts built into the DJ520.  I would
like to use one of the proportional fonts, but Quill (and
all text editors) are all monospace based.

   I have written a short print filter that supports the
DJ520.  It supports dot commands (like ROFF or old
WordStar) that do things like Bold, Italics, new page, etc.
 The next step is to add some word wrap facility.  Below is
the source code for a program that does just word wrapping.
 It takes in a file, wraps all the words based on the page
width (in characters) and outputs the results to another
file.

   This program is really just a sort test program to focus
on how to do word wrapping.  By itself it would be rather
limited (unless used in a piping environment like Unix). 
The page width should not be hard coded into the program,
but loaded at runtime (either typed in or as a command line
arguement).

   The program expects a few things about the input file. 
It expects a blank line between paragraphs.  It expects the
space, tab, or newline characters to divide words. 
Non-ASCII characters are not handled.

   The next step in this program is to add the support of
proportional fonts.  As is the program treats every
character as the same width.  With proportional fonts,
characters differ in width (an i is smaller than a w).  Once
adding proportional fonts is added, then different sized
fonts can be added (12 point, 20 point, etc).  Output needs
to be based on the size of the output (in inches) and not
based on the number of characters.

/* wrap_c
   This program takes a file as input and reads in each
      word and reformats the paragraphs based on WIDTH
      to the ouput file.
   This program expects a blank line between paragraphs.
*/

#include <stdio_h>
#define WIDTH   40

main() {
   char  file1[30], file2[30], str[30];
   int   fd1, fd2, temp, length, cur_len;

   printf("Enter Input File Name : \n");
   gets(file1);
   fd1 = fopen(file1,"r");
   if (fd1 == NULL)  {
      printf("Did not open file: %s",file1);
      abort(1);
   }

   printf("Enter Output File Name: \n");
   gets(file2);
   fd2 = fopen(file2,"w");
   if (fd2 == NULL) {
      printf("Did not open file: %s",file2);
      abort(1);
   }
   cur_len = 0;
   while ( 1 == 1) {
      temp = get_word(str,fd1);
      if ( temp == -1)
        {  fputc('\n',fd2);
           fclose(fd1);
           fclose(fd2);
           abort(0); }
      if ( temp == -2) {
         fputc('\n',fd2);
         fputc('\n',fd2);
         cur_len = 0;
      }
      else {
         length = strlen(str);
         if ( (cur_len + length) > WIDTH) {
            fputc('\n',fd2);
            fputs(str,fd2);
            cur_len = length;
         }
         else {
            cur_len = cur_len + length + 1;
            fputc(' ',fd2);
            fputs(str,fd2);
         }
      }
   } /* end while */
}
/* get_word ( string, file pointer )
     gets the next word in the file. End of a word is
space, tab, or LF. A LF with no word means the end of a
paragraph.
      Return values are:
         0 - no error
        -1 - End of File (EOF)
        -2 - End of Line (EOL)
             (meaning end of paragraph)
*/
get_word( str, fd)
   char str[30];   int fd;
{
   int count, c, lf;

   str[0] = '\0';
   lf = NO;
   count = 0;
   while ( 1 == 1) {
      if ( ( c = getc(fd) ) == EOF )  return(-1);
      if ( ( c > 32 ) && ( c < 127 ) ) {
         str[count] = c;
         count++;
      }
/* Space   Tab   CR */
      if ((c == 32) || (c == 9) || (c == 10)) {
         if ( c == 10 )  lf = YES;
         if ((count == 0) && (lf == YES))  return(-2);
         if ( count > 0 ) {
            str[count] = '\0';
            return(0);
         }
      }
   }
}

RECENT FREEWARE - INFORM

   INFORM is a language used to create text adventure
games. It is based on the text adventures that the company
INFOCOM used to produce.  The adventures were composed of
two data files and two programs.  The adventure is first
written in the INFORM language and compiled with INFORM. 
This creates a datafile that is then read by ZIP (the
adventure interpreter) with runs the adventure.  ZIP is
available for the QL ported by Luke Roberts.  So now with
INFORM, the full process can be done on the QL.

   The INFORM language resembles C in some respects, but the
more purely adventure related words look more like a
database programming language (ie. fairly verbose).  To give
you an idea of what the language covers, here are a few
chapter titles from the INFORM Language Manual: Objects,
Properties and Attributes; Places, Scenery, and the Map;
Causing Actions and Making New Ones; Containers, Supporters,
and Sub-objects; Doors; Things to Enter, Travel In and Push
Around; Living Creatures and Conversation; Starting, Moving,
Changing and Killing the Player; Classes of Objects; Adding
Verbs and Grammer to the Parser; etc.

   The INFORM Language Manual is fairly thick and seems to
cover the language fairly well.  It's about 100 pages and
semi-tutorial, and not just a reference guide.  The compiler
comes with a number of different sample adventures to learn
from and compile.

   I have not had a change to give the compiler a spin.  I
don't know what the demand for text adventures is, but for
those interested, it's always handy to have the capability
to do what you want.  The combination of INFORM and ZIP
totally opens up the door to text adventures for the QL. 
INFORM allows you to compile your own adventures.  ZIP
allows you to run your adventures or run other adventures
from other platforms.

   If you are interested in text adventures based on the
INFORM language there is a main archive site for such
information.  It's ftp.gmd.de in the directory:

     if-archive/infocom/compilers/inform
          
OBJECT ORIENTED PROGRAMMING ON THE QL

   I've been watching the current trend in programming move
toward the Object Oriented paradigm for some time now and I
stil have no idea of what the real differences between
Object Oriented Progamming (OOP) and procedural program
-ming.  I have yet to see an article that compares the
differences using an example program.  To give an example,
here is some text describing OOP:

   "An object is essentially a black box that contains
internal state information.  You send an object a message
which causes the object to perform some operation. ... One
aspect of an object is that you do not have to know what is
inside - or how it works - to be able to use it.  From a
programming point of view this is very handy.  You can
develop a series of objects for someone to use.  If you need
to change what goes on inside, the users of the objects
should be unaware."

    To me this sounds like someone describing a procedure
and not an object.  Who really knows the internals of such
procedures or fuctions like fopen or getc.  You can take out
the word object and replace it with procedure and it would
still be make sense.

   Wanting to try to give OOP a try, I have been looking for
a language for the QL that will do some OOP.  I found XLISP
for the QL.  This version of XLISP is XLISP Plus, which has
some object oriented features built in.

   One of the documents that comes with XLISP Plus is "XLisp
2.0 Object Primer" by Tim Mikkelsen.  This document give an
introduction into the object oriented features of XLISP. 
How Classes, Objects, Messages, and such work.  There are a
few examples to learn by.

   When I first saw this document, I though "Ah, Here is my
chance to learn and try out OOP on the QL."  Then the
reality of learn Lisp hit me.  I have been tinkering with
Lisp (along with other non-procedural languages like FORTH)
for a few years.  I must admit that I really can't get the
hang of the language.  I'm too stuck in my iterative
thinking and find it a real bear to read Lisp code.  So
there goes my grand idea of learning OOP.  Besides from what
I can gather from the examples, I don't see the advantages
it has over procedural programming.

   But, for those willing to give it a try the capability is
there.  If anyone does figure XLisp and OOP out, I hope they
will try their best to fill in the rest of us.

   While on the subject of Lisp, Scheme (a dialect of Lisp)
is also available for the QL.  Scheme is an offshoot from
Common Lisp (which is what XLisp Plus is based on).

QHJ FREEWARE AWARDS
   
   Over the last couple of weeks I have seen a number of
award shows, like the Screen Actors Guild Awards, Grammy
Awards, Peoples Choice Awards and the Comedy Awards.  This
started me thinking about awards and lack of them in the QL
community.  Now magazines, newspapers, and other print media
have thier own version of awards.  Computer Language
magazine has it's Jolt award (named for the soda Jolt - with
twice the caffine as Coke).  So I think it's time for the
QHJ Freeware Awards.

   Programmers are an unrewarded lot, especially so for
Freeware programmers.  Commercial programmers will get
monitary compensation.  The same goes for Shareware
programmers (but even less money and hoping that all users
will register the software).  But for Freeware programmers,
the main emphasis is on free.  They do it for the fun on
it. Some will write software for themselves and distribute
it to others.  Some will write software for the challenge
of the task.  Either way, it's a lot of effort for very
little payback.

   The QHJ Freeware Awards is designed to recognize the best
Freeware programs and programmers over the last year.  I've
created five different catagories:

     Best Pointer Environment Freeware Program
     Best Non-PE Freeware Program
     Best Freeware Port to the QL
     Best Freeware Language or Language Utility
     Freeware Programmer of the Year

   The time for the awards are for 1994.  If a program was
ported before 1994, but did not make a big impact until
1994, then it can be considered. 
          
   I had originally thought about just deciding the winners
myself, as some magazines will do.  But, I really thought it
would be better to get some input from the QL community.  My
exposure to all the Freeware out there is limited.  I could
only judge on those that I have tried.  Getting input from
readers would make the awards truely representative of the
QL community.

   So, please look over the categories listed above, review
what Freeware software you know, and send me your vote for
each award.  You can send them by mail, e-mail, phone,
carrier pigeon, what ever.  I will tally the results and
report the results in the next issue.  Deadline for the
votes is 1 May 1995.  I hope to have the next issue ready
by then.  Issue or not, I will make some sort of
announcement of some sort at the US QL show on 10 June in
Oak Ridge, Tennesse.

   I plan to whip up some sort of paper award using Page
Designer 3 and my DJ 520 (which means I have to actually
learn PD3).   I hope to be able to mail the award to each
individual programmer that wins.
