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% C invert it b{I4 x{bL%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 #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.