In the May 2015 issue of QUANTA, the magazine, I published a program called SBldr. It takes a S*BASIC source code file and EXecutes it, as if it were a normal machine code job. No big deal, it is true. However, the X-factor here is that if the source code doesnt contain line numbers (in which case it cant be EXecuted) SBldr adds them on the fly, as it were, allowing the program to EXecute even so.
The example below takes it to the next level. One of the points of this example utility is to demonstrate invoking an instance of the SBASIC Thing (which, in theory can be done from any programming language) and harnessing its capabilities, in this case to tokenise a S*BASIC source file. The point of the program featured is to convert S*BASIC source code seamlessly to HTML, using my sb2htm program. As such, it may be of special interest to creaking SMSQ/E users (like me) who write S*BASIC programs using an editor. Some of the techniques employed may be of interest to anyone interested in S*BASIC, but most will only work under SMSQ/E and SBASIC (although something similar might be attempted in Minerva).
If converting S*BASIC source code to HTML doesnt appeal to you, let me just quickly mention that a small modification to the program presented and explained below, enables you to compile an S*BASIC program directly from within QD (and probably other text editors) or from any FileInfo2-capable file manager, or indeed from the command line, without having to QSAVE the source file first or even to add line numbers. This may seriously speed up program development, testing and debugging.
Ill explain the program first, then the programming.
Although screens are getting bigger and better, the QL founts havent changed; if anything, they seem to be getting smaller and harder on the eye than before! While text editors like QD are better than EDIT for writing all but the simplest of programs, they still only sport black on grey or some such combination, and most have no understanding of the code that is being edited.
For me a partially useful solution was my program sb2htm, (available here). It takes a (tokenised) S*BASIC program and converts it to syntax-highlighted, navigable HTML. Colours can be changed to suit, and the browser can display founts as large and clear as you like. (Navigable here means being able to follow the flow of the program via the linked references to PROCedure and FuNction definitions, and then clicking <-Back to return to where you were). The browser's local search box, and the host OS'es fast file searching facilities, spanning multiple file names and contents, can be very useful at times, too.
So far, the downside has mainly been the number of steps taken to produce HTML ouptut of a line-numberless file in an editor such as QD:
Since I couldnt be bothered, this meant that I would be referencing an out of date version of the code most of the time.
SBhtm. This little program accomplishes a lot of work very simply and very quickly. If you add it to a hotkey, all you have to do is:
(I should mention that on saving a file in QD, it puts the current path and filename into the Stufferbuffer)
When I need to, I can use two monitors attached to my computer. I then extend the Windoze desktop to cover both. QPC2 runs in full screen mode on one monitor, while the browser is open in the second. The few steps described above make the whole thing more or less seamless, allowing me to edit the program on one screen and have a clear, easy-to-read, navigable reference in another. Particularly handy for large or complex projects. It works well for me, so I thought it would be nice to share..The result might look something like the listing below (depending on the publisher of this article).
10 REMark $$chan=4 11 : 12 REMark + ---------------------------------------------------- + 13 REMark |< SBasic to Html >| 14 REMark + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 15 REMark | Converts SBasic programs to html using sb2htm | 16 REMark | Adds line numbers to numberless code via intermed- | 17 REMark | iary file in a temporary directory | 18 REMark | | 19 REMark | Add to FileInfo2, Hotkey, or use with EX: | 20 REMark | | 21 REMark | er = FEW(<SBhtm>;"<program>_bas [;<command_line>]") | 22 REMark | | 23 REMark | SBhtm passes the optional <command_line> to sb2htm | 24 REMark | Use this to supply standard sb2htm cmdl parameters | 25 REMark | (see sb2htm manual) except the -i command. | 26 REMark | | 27 REMark | Version 0.02, pjw, 2oi5, SBASIC only! | 28 REMark + ---------------------------------------------------- + 29 : 30 REMark Config: 31 s2h$ = HOME_DIR$ & 'sb2htm_obj': REMark Html conversion program 32 out$ = 'dos3_html_': REMark Default html output to my D:/temp/ 33 tmp$ = 'ram1_sbhtmxxx': REMark Location and name of temp file 34 first% = 10: step% = 1: REMark First line and step size 35 : 36 REMark Get input file name 37 REMark Get it either from cmdl or from Stufferbuffer 38 l% = LEN(CMD$) 39 IF l% = 0 THEN 40 fnm$ = HOT_GETSTUFF$: l% = LEN(fnm$) 41 ELSE 42 fnm$ = CMD$ 43 END IF 44 IF l% < 9: Bye -12 45 : 46 REMark Process command line(s) 47 com$= '' 48 REMark Additional command line? 49 s% = ';' INSTR fnm$ 50 IF s% THEN 51 IF s% < l%: com$ = fnm$(s% + 1 TO l%) 52 l% = s% - 1: fnm$ = fnm$(1 TO l%) 53 END IF 54 : 55 REMark Extract name from file name 56 ci = FOP_DIR(fnm$): IF ci < 0: Bye ci 57 dir$ = FNAME$(#ci): CLOSE#ci 58 ci = FOP_IN(fnm$): IF ci < 0: Bye ci 59 ld% = LEN(dir$) 60 nm$ = fnm$(6 + (ld% > 0) + ld% TO l% - 4) 61 : 62 REMark Filter by extension 63 IF fnm$(l% - 2 TO l%) == 'sav' THEN 64 REMark _sav files pass straight through 65 bas = 0 66 CLOSE#ci 67 ELSE 68 REMark _bas file w/wo line number 69 IF fnm$(l% - 2 TO l%) == 'bas' THEN 70 bas = 1 71 ELSE 72 REMark Wrong file type 73 Bye -15 74 END IF 75 : 76 REMark Line numbers or not? 77 INPUT#ci; l$ 78 IF NOT l$(1) INSTR '123456789' THEN 79 : 80 REMark Process line numberless file 81 fnm$ = tmp$ & '_bas' 82 co = FOP_OVER(fnm$): IF co < 0: Bye co 83 bas = 2: i% = first%: lno$ = i% 84 BPUT#co; lno$, 32, l$, 10 85 : 86 FOR i% = first% + step% TO 32767 STEP step% 87 IF EOF(#ci): EXIT i% 88 INPUT#ci; l$: lno$ = i% 89 BPUT#co; lno$, 32, l$, 10 90 END FOR i% 91 CLOSE#co 92 END IF 93 CLOSE#ci 94 : 95 REMark Process non-sav files 96 REMark Use SBasic daughter to tokenise program 97 pip$ = 'pipe_p' & HEX$(JOBID, 32) 98 co = FOPEN(pip$ & 'o_2048'): IF co < 0: Bye co 99 : 100 REMark Slave will take instructions from here 101 cm$ = 'ci = fop_in(#0; "' & pip$ & 'o")' 102 : 103 REMark Start SBAS with our opening command 104 EXEP 'SBASIC'; cm$ 105 : 106 REMark Tell it what we want 107 PRINT#co; 'load "' & fnm$ & '"' 108 PRINT#co; 'qsave_o "' & tmp$ & '"' 109 PRINT#co; 'beep 2,2: beep 2,2': REMark Signal success 110 PRINT#co; 'quit': REMark Job done! Get rid of slave 111 fnm$ = tmp$ & '_sav' 112 END IF 113 : 114 REMark Create sb2htm command line 115 com$ = '-i!' & fnm$ & ' ' & com$ & ' -o' & out$ & nm$ & '.htm -t' & nm$ 116 IF bas = 2: com$ = com$ & ' -noff' 117 : 118 REMark Convert to tokenised file to html 119 Bye FEW(s2h$; com$) 121 : 122 REMark Tidy and quit 123 DEFine PROCedure Bye(er) 124 IF er < 0: BEEP 3000,255 125 REMark Remove any temporary files 126 IF bas: DELETE fnm$ 127 IF bas = 2: DELETE tmp$ & '_bas' 128 QUIT er 129 END DEFine Bye 130 :
SBhtm takes the name of the file to process from its command line. If there is nothing on the command line, it takes the name from the stufferbuffer. If launching the program via EX, a command line should be supplied, containing at least the filespec of the source file to be processed. Any additional parameters you want to pass on to sb2htm must be embedded in the pseudo command line, thus:
EW <SBhtm>; <filespec> & '; -odos5_'
This means: Execute the SBhtm program (compiled or not) with the file path and name given in <filespec>, ending on _bas or _sav (or .bas or .sav (but also tubas!)). The pseudo command line starts after the second semi colon. It passes through SBhtm to sb2htm to tell it you want the output sent to dos5_ instead of SBhtm's inbuilt default. Any error from (somewhere within) the process is returned in er on completion.
The program can be compiled with QLib and attached to a hotkey, thus:
ERT HOT_RES1(<key>, <path>SBhtm_obj)
If used from a hotkey, SBhtm uses its own hard-wired defaults, except for the file name, which it gets from the stufferbuffer. There are many possibilities..
Once SBhtm has a file, it checks the extension and tries to open it. Three scenarios are catered for:
To tokenise the program, an instance of SBASIC is invoked via FEP/EXEP. It is instructed to take its commands from a pipe open to SBhtm. SBhtm tells the slave SBASIC to LOAD <filespec> or the temporary file, as the case may be. Syntax errors are flagged as MISTake. After the code is successfully parsed by the SBASIC slave, it is QSAVEd to a(nother) temporary file.
All that was wanted of the slave was its access to the SBASIC parser, so the slave's job is done and it is removed. sb2htm is invoked with the resultant temporary _sav file to do its stuff, and the result squirted into the default or specified directory.
If a temporary _bas file was created, it is now deleted, ditto for a temporary _sav file, although no original files are deleted.
To calm those SuperBASIC bit-twiddlers who are no doubt horrified by my liberal use of blank lines and other puerile eye candy, at run-time SBASIC is not bothered by such trifles. It refines the tokenised program even further than SuperBASIC, which results, among many other advantages, in only effective code being encountered by the interpreter. All code that has no impact on the program's function is ruthlessly stripped away, any ambiguities resolved, and expressions and structures unravelled, leaving a much more efficient code, pretty close to that of QLib-compiled code.
There is more to say about this particular program in relation to sb2htm. It should become clear once you play around with it and sb2htm. I wrote this piece partly to plug sb2htm, which is receiving a quiet make-over back here at the lab, and will be released in due course once the final t's are crossed and i's dotted. Before trying SBhtm out, you should have correctly installed and tested sb2htm to get some idea of how it works.
The thing Id like you to take away from this, is the way SBASIC daughter jobs can be used. It doesnt take a lot of imagination to realise that instead of sending the file to sb2htm, it could be sent to Q_Liberator. So from editing your S*BASIC program in QD, within three steps you could have it compiled and, if desired, executing!
But that is left as an excercise for the fervent tinkerer.
Hint: To turn SBhtm into SBobj (no-frills, mind you) only a few minor changes need to be made, mainly to the command line com$ ;)
A copy of the source code and executable can be downloaded here