TweetFollow Us on Twitter

Forth Blocks
Volume Number:1
Issue Number:10
Column Tag:Forth Forum

"Converting Forth Blocks to Ascii Text"

"Accuracy in Modula-2 Reviewed"

By Jörg Langowski, Chemical Engineer, Fed. Rep. of Germany, MacTutor Editorial Board

With the advent of other Forth systems than MacForth, and Forth-related packages such as NEON, a utility is needed that lets us quickly convert the MacForth 'Blocks' format into a standard ASCII text file and back. NEON, for instance, expects its input from a normal text file. Also this Journal expects its input from a MacWrite file, and after I have written an example program, cutting it out of the Forth screens and pasting it into my column is quite cumbersome.

So here is a routine that does this job automatically (it contains some ideas out of a program on one Call-A.P.P.L.E. public domain disk). At the same time we are going to learn something about the Standard File Interface package, which is undocumented (but fully usable) in MacForth 1.1.

What do we need to know to convert files from Blocks to Text format and back? The type of a Blocks file is BLKS and the creator M4TH, a Text file such as saved by 'text only' MacWrite or MDS Edit is of type TEXT and creator MACA (this probably stands for Mac Ascii). In principle, both files contain ASCII text, which, however, is organized differently.

The format of a Blocks file

MacForth blocks files consist of screens , each of which contain 16 lines of 64 characters. One line is always 64 characters long and padded with blanks after the last character. This format is a relic from early FORTH times and - in my opinion - rather obsolete. But since the MacForth editor uses it, we have to live with it. The length of a file is of course very simply related to the number of screens; each screen occupies exactly 1024 bytes.

Text files, on the other hand, contain lines of ASCII characters which are separated by carriage returns (CR).

One very simple thing that one can try out to communicate between the two types of files is to change type and creator of a Blocks file to TEXT and MACA, hoping that it is recognized by Edit, for example. When I tried this, it would show a file that had only one line (of course, since there are no CRs). So we do have to read the Blocks file, line by line, and create a new text file to which we write those lines.

Reading Forth blocks

A Forth block in a file is accessed through the word BLOCK, which accepts the block number on top of stack and returns the address of a buffer that contains the block. The block is automatically read in if it is not already there.

The position of a line in the block is at (64 * line number). The word >LINE.START in the program example returns the address of a line in a given block. We then remove trailing blanks from this line, add a CR at the end and write it to the Text file (which we have opened before). This is what the word COPY.BLOCK does, which is called from the main menu: It traverses the Blocks file line by line and writes the Text file.

ASCII to Blocks conversion

The reverse direction is a little bit more complicated. The total number of lines in a blocks file is known exactly from its size, so we know ahead of time how many screens we have to convert; also a Text file can be extended arbitrarily by just adding lines. Not so the other way around: a Blocks file must be extended by appending blocks before writing to them, and the end of a Text file is known only when an end-of-file occurs.

In the example, each text line is read into the string variable TEXT.BUF with the character count in the first byte and the actual line in the following bytes. This string is then copied into a new line in the buffer; when 11 lines have been processed in this way, the buffer is written out to disk (UPDATE FLUSH) and the Blocks file extended by one block. The last five lines of each block stay blank for easier editing. Some editing is necessary because the block boundaries will often split your definitions.

Choosing input and output files - the standard file package

So the principle of this utility routine has been set up. But we still have to open the files that we want to work on. To make file access more comfortable, let's use the standard Macintosh file package to select those files.

You've seen the dialog boxes that make up the interface to this package many times. Whenever you are supposed to select a file for input, a Mac application that conforms to the User Interface standards will show you a list of files to select from and option buttons that let you change drives, eject disks or quit the operation.

When you select a file for output (or save) you are presented with an input box with a default file name:

and when the file name that you give already exists on that disk, the standard file package will ask for reconfirmation to overwrite that file.

All these functions are built into two toolbox routines, SFGetFile and SFPutFile. MacForth provides built-in interfaces to those routines, the words (GET.FILE) and (PUT.FILE). The Forth words expect less parameters than the corresponding toolbox traps.

(GET.FILE) needs, from bottom to top of stack:

- a point (2*16 bit) where the top left of the dialog box is to be located;

- the address of a prompt string (zero for no prompt);

- the address of a list of file types to be displayed;

- the number of different file types;

- the address of a reply record.

(PUT.FILE) needs:

- the top left point;

- the address of a prompt string;

- the address of a string which may contain the default file name and later contains the actual file name;

- the address of a reply record.

Information about the user's response to the dialog box is contained in the reply record. The format is:

- 2 bytes boolean, true if OK, false if Cancel button was clicked;

- 4 bytes of file type information;

- 2 bytes integer, contain the volume reference number (important if volume was changed);

- 2 bytes integer, file version number, not used here;

- 64 bytes that contain the file name in Mac string format (count byte plus characters).

The list of file types is an array of 4 byte integers; each 4-byte cell contains one valid type designator, such as PICT, TEXT, DATA, etc. On calling (GET.FILE), only those files corresponding to one of the designators will be displayed. Invisible files will be displayed, too.

In our program, input and output files are set up using the standard file interface by the words TEXT.OPEN, BLOCK.OPEN, TEXT.CREATE and BLOCK.CREATE. After the dialog has been processed, the volume reference number (which might have been changed from the default volume) is moved into the file's FCB and the type and creator fields are set depending on whether a Text or a Blocks file is written. Thereafter, the actual file conversion takes place.

During the execution of the conversion routines the activate event is switched off. If you don't do this, the main Forth window would be activated again after the first file dialog has been processed, executing an ABORT and jumping back to the 'ok' prompt, quitting your program. Try this out and see what happens when you leave out line 6 in the CHANGE.MENU definition.

With that little routine, creating MacWrite listings from your Forth programs will be easy now.

Floating point glitches in Modula-2

Even though I am responsible for Forth, I must make one more Modula comment.

Watch out when you're using math!

I have become extremely careful in this respect. The 32-bit routines are fast, true. In order to be useful, they should also give correct results (within rounding errors). This is not so. Try the example in listing 2 (WindowIO is a module of my own that just sets up a standard window for I/O). The program just keeps adding smaller and smaller numbers to 1.0, which I did originally as an accuracy test. The output is shown there, too. Sometimes the output routine seems to fail, sometimes the addition itself. And I thought this was a system I could use for some of my calculations in the lab oh well. No more comments.

Surprisingly enough, though, a non-linear curve fitting program that I wrote in Modula seems to work well, without major problems. It may be that the bug shows up only when the numbers are close to integers (???). Any comments from readers with similar experiences are appreciated, any help even more. (Richard Ohran, are you reading this? If not, a bug report will follow.)

Listing 1: Converting text to blocks files

( Forth <-> Ascii Conversion)              ( © 1985 MacTutor by J. Langowski 
)

: tx-blks ;

variable ifile#  -1 ifile# ! 
variable ofile# -1  ofile# !    
: ifile ifile# @ ;  : ofile ofile# @ ;

hex 4D414341 constant "maca decimal
create ="blks      "blks ,
create ="textdata  "text , "data ,

18 field +fcb.name    22 field +fcb.vrefnum
32 field +fcb.type    36 field +fcb.creator

( standard file reply record fields )
00 field +good    : @good  +good w@ ;
02 field +ftype   : @ftype +ftype @ ;
06 field +vrefnum : @vrefnum +vrefnum <w@ ;
10 field +fname

create ireply 80 allot    
ireply +fname constant iname
create oreply 80 allot    
oreply +fname constant oname
variable screen#        variable cur.line#
create text.buf 100 allot 
99 constant text.read.limit
5 constant ch.menu

: moverefnum  ( file#\reply -- )
    @vrefnum  swap >fcb +fcb.vrefnum w! ;

: get.input.name 
      >r >r >r
      100 100 xy>point  0   r>  r>  r@
      (get.file) page r> @good 
      0= if abort then  ;

: get.save.name
      page >r >r >r  
      100 100 xy>point  r>  r>  r@
      (put.file) r> @good 
      0= if abort then ;

: text.open  
    next.fcb ifile# ! 
    page ." Text file to convert:"
    ="textdata 2 ireply get.input.name
    iname ifile assign 
    ifile ireply moverefnum
    ifile open   ?file.error
    ifile rewind ?file.error ;

: block.open
    next.fcb ifile# ! 
    page ." Blocks file to convert:"
    ="blks 1 ireply get.input.name
    iname ifile assign 
    ifile ireply moverefnum
    ifile open  ?file.error  ifile select ;

: block.create 
   next.fcb ofile# !
   " Mac Tutor Blocks" 
   oname over c@ 1+ cmove
   " Save as:" oname oreply get.save.name
   oname ofile assign
   ofile oreply moverefnum ofile delete
   ofile create.blocks.file ?file.error
   ofile open ?file.error  ofile select
   2 ofile append.blocks  
   1 screen# !   0 cur.line# !
   0 block b/buf bl fill update flush ;

:  text.create 
   next.fcb ofile# !
   " Mac Tutor Text" oname over c@ 1+ cmove
   " Save as:" oname oreply get.save.name
   oname ofile assign    
   ofile oreply moverefnum ofile delete
   ofile create.file ?file.error
   ofile open ?file.error  ofile rewind
   ofile get.file.info
   "text ofile >fcb +fcb.type !
   "maca ofile >fcb +fcb.creator !
   ofile set.file.info  ;

: >line.start ( block\line -- addr of line)
  64 * swap block + ;

: write.line 
    >line.start 64 -trailing
    over over + 13 swap c!  ( add CR )
    1+  ofile write.text  ;

: write.screen
    dup 16 0 do dup i ( screen\line )
    over over . 2 spaces . cr ( debug )
    write.line  loop drop ( n ) ;

: copy.block  ifile get.eof b/buf /
    0 do  i . cr i write.screen
      do.events drop loop ;

: read.line  ifile current.position
   text.buf 1+  text.read.limit  
   ifile  read.text
   ifile current.position swap -  
   text.buf  c!  ;

: copy.line 
  read.line  ?eof not
  if cur.line# @ dup .
     64 * screen# @ dup . cr 
     block +  text.buf 1+  swap
     text.buf c@ 1- cmove  
     1 cur.line# +!  cur.line# @ 10 >
     if 0 cur.line# !   update flush
        1 screen# +!  1 ofile append.blocks
     then  do.events drop true
  else update flush false then ;

: copy.text  begin copy.line not until ;

: >text block.open text.create copy.block ;

: >block text.open block.create copy.text ;

: change.menu
    0 " Change" ch.menu new.menu
    " Forth->Ascii;Ascii->Forth;"  
    ch.menu append.items draw.menu.bar
    ch.menu menu.selection:
    1 activate.event scale -1 xor events !
    0 hilite.menu
     case  1 of  >text      endof
           2 OF  >block     endof endcase
    events on do.events abort ;

change.menu

Listing 2: Modula 2 FP 'accuracy test'

MODULE Accuracy;

FROM InOut IMPORT ReadCard, WriteCard, 
        WriteString, WriteLn, ClearScreen;
FROM RealInOut IMPORT ReadReal, GWriteReal;
FROM WindowIO IMPORT SetupWindow;
FROM EventManager IMPORT Button;
VAR  a,b : REAL;  
 
BEGIN
SetupWindow
("Accuracy test",40,40,350,450,4,9);
a := 1.0; b := 1.0;
WriteString 
("        a           b           a+b"); WriteLn;

REPEAT 
  b := b/10.0;
  GWriteReal(a,12); GWriteReal(b,12);
  GWriteReal(a+b,12); WriteLn;
  WHILE Button() DO END;
UNTIL (b = 0.0);

REPEAT UNTIL Button();

END Accuracy.

Listing 3: Output of the Accuracy program

(terminated before underflow occurred). Note that b is sometimes printed as zero, although a+b seems to be correct; and for some smaller values of b (1.0E-19 to 1.0E-25) a+b starts to behave very strange.

        a          b          a+b
    1.000000   0.1000000      1.100000
    1.000000   0.01000000     1.010000
    1.000000   0.00000000     1.001000
    1.000000   0.00010000     1.000100
    1.000000   0.00001000     1.000010
    1.000000   0.00000100     1.000001
    1.000000   0.00000010     1.000000
    1.000000   1.0000E-08     1.000000
    1.000000   1.0000E-09     1.000000
    1.000000   1.0000E-10     1.000000
    1.000000   1.0000E-11     1.000000
    1.000000   0.0000E-13     1.000000  ?
    1.000000   1.0000E-13     1.000000
    1.000000   1.0000E-14     1.000000
    1.000000   1.0000E-15     1.000000
    1.000000   1.0000E-16     1.000000
    1.000000   1.0000E-17     1.000000
    1.000000   0.0000E-19     1.000000  ?
    1.000000   1.0000E-19     2.844674  ???
    1.000000   1.0000E-20     1.184467  ??
    1.000000   1.0000E-21     1.018447  ??
    1.000000   0.0000E-23     1.001845  ??
    1.000000   1.0000E-23     1.000184  ?
    1.000000   1.0000E-24     1.000018  ?
    1.000000   1.0000E-25     1.000002  ?
    1.000000   0.0000E-27     1.000000  ?
    1.000000   1.0000E-27     1.000000
    1.000000   1.0000E-28     1.000000
    1.000000   1.0000E-29     1.000000
    1.000000   1.0000E-30     1.000000
    1.000000   1.0000E-31     1.000000
    1.000000   1.0000E-32     1.000000
    1.000000   1.0000E-33     1.000000
    1.000000   1.0000E-34     1.000000
    1.000000   1.0000E-35     1.000000
 
AAPL
$118.93
Apple Inc.
-0.07
MSFT
$47.81
Microsoft Corpora
+0.06
GOOG
$541.83
Google Inc.
+1.46

MacTech Search:
Community Search:

Software Updates via MacUpdate

Adobe Photoshop Elements 13.0 - Consumer...
Adobe Photoshop Elements 12--the #1 selling consumer photo editing software--helps you edit pictures with powerful, easy-to-use options and share them via print, the web, Facebook, and more.Version... Read more
Skype 7.2.0.412 - Voice-over-internet ph...
Skype allows you to talk to friends, family and co-workers across the Internet without the inconvenience of long distance telephone charges. Using peer-to-peer data transmission technology, Skype... Read more
HoudahSpot 3.9.6 - Advanced file search...
HoudahSpot is a powerful file search tool built upon MacOS X Spotlight. Spotlight unleashed Create detailed queries to locate the exact file you need Narrow down searches. Zero in on files Save... Read more
RapidWeaver 6.0.3 - Create template-base...
RapidWeaver is a next-generation Web design application to help you easily create professional-looking Web sites in minutes. No knowledge of complex code is required, RapidWeaver will take care of... Read more
iPhoto Library Manager 4.1.10 - Manage m...
iPhoto Library Manager lets you organize your photos into multiple iPhoto libraries. Separate your high school and college photos from your latest summer vacation pictures. Or keep some photo... Read more
iExplorer 3.5.1.9 - View and transfer al...
iExplorer is an iPhone browser for Mac lets you view the files on your iOS device. By using a drag and drop interface, you can quickly copy files and folders between your Mac and your iPhone or... Read more
MacUpdate Desktop 6.0.3 - Discover and i...
MacUpdate Desktop 6 brings seamless 1-click installs and version updates to your Mac. With a free MacUpdate account and MacUpdate Desktop 6, Mac users can now install almost any Mac app on macupdate.... Read more
SteerMouse 4.2.2 - Powerful third-party...
SteerMouse is an advanced driver for USB and Bluetooth mice. It also supports Apple Mighty Mouse very well. SteerMouse can assign various functions to buttons that Apple's software does not allow,... Read more
iMazing 1.1 - Complete iOS device manage...
iMazing (was DiskAid) is the ultimate iOS device manager with capabilities far beyond what iTunes offers. With iMazing and your iOS device (iPhone, iPad, or iPod), you can: Copy music to and from... Read more
PopChar X 7.0 - Floating window shows av...
PopChar X helps you get the most out of your font collection. With its crystal-clear interface, PopChar X provides a frustration-free way to access any font's special characters. Expanded... Read more

Latest Forum Discussions

See All

Mystery Case Files: Dire Grove, Sacred G...
Mystery Case Files: Dire Grove, Sacred Grove HD Review By Jennifer Allen on November 28th, 2014 Our Rating: iPad Only App - Designed for the iPad A decent new installment for the popular Mystery Case Files series.   | Read more »
Castaway Paradise – Tips, Tricks, and St...
Ahoy there, castaways: Were you curious about our own thoughts regarding this pristine shipwreck? Check out our Castaway Paradise review! Castaway Paradise is out for iOS, finally giving mobile gamers the opportunity to enjoy the idyllic lifestyle... | Read more »
Castaway Paradise VIP Subs are on Sale f...
Castaway Paradise VIP Subs are on Sale for a Limited Time, and a Special Holiday Update is Coming Soon Posted by Rob Rich on November 28th, 2014 [ | Read more »
Primitive Review
Primitive Review By Jordan Minor on November 28th, 2014 Our Rating: :: FOLK ARTUniversal App - Designed for iPhone and iPad True to its name, Primitive is about as straightforward as runners get.   | Read more »
7 tips to get ahead of the competition i...
7 tips to get ahead of the competition in Dynasty of Dungeons Posted by Simon Reed on November 28th, 2014 [ permalink ] Playcrab has launched their action-packed new dungeon crawler, Dynasty of Dungeons, today. | Read more »
Master of Tea Kung Fu Review
Master of Tea Kung Fu Review By Jordan Minor on November 28th, 2014 Our Rating: :: ONE DROP RULESUniversal App - Designed for iPhone and iPad Master of Tea Kung Fu is a creative and complex caffeinated brawler.   | Read more »
Monster Strike Review
Monster Strike Review By Campbell Bird on November 28th, 2014 Our Rating: :: BILLIARD STRATEGYUniversal App - Designed for iPhone and iPad Collect monsters and battle by flinging them across the battlefield in this strangely... | Read more »
Proun+ Review
Proun+ Review By Jennifer Allen on November 28th, 2014 Our Rating: :: TWITCHY RACINGUniversal App - Designed for iPhone and iPad Twitchy racing aplenty in Proun+, an enjoyably tricky title.   | Read more »
Lucha Amigos (Games)
Lucha Amigos 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Forget Ninja Turtles, and meet Wrestlers Turtles! Crazier, Spicier and…Bouncier! Sling carapaces of 7 Luchadores to knock all... | Read more »
Record of Agarest War Zero (Games)
Record of Agarest War Zero 1.0 Device: iOS Universal Category: Games Price: $7.99, Version: 1.0 (iTunes) Description: HyperDevbox Holiday Turkey Black Friday Special Pricing! To celebrate the opening of the holiday season HyperDevbox... | Read more »

Price Scanner via MacPrices.net

Up To 75% Off Infovole Text Apps Over Black F...
Infovole’s entire range of apps, including the Textkraft family of word processors for iPads and iPhones, is being offered at 50-75% off over the Black Friday and Cyber Monday weekend. The five-day... Read more
Black Friday: Up to $60 off Mac minis, NY tax...
 B&H Photo has new 2014 Mac minis on sale for up to $60 off MSRP as part of their Black Friday sale. Shipping is free, and B&H charges NY sales tax only: - 1.4GHz Mac mini: $449.99 $50 off... Read more
Black Friday: 27-inch 5K iMac for $2299, save...
 B&H Photo continues to offer Black Friday sale prices on the 27″ 3.5GHz 5K iMac, in stock today and on sale for $2299 including free shipping plus NY sales tax only. Their price is $200 off MSRP... Read more
Karalux Announces 24K Gold-Plated iPhone 6
Karalux, a Vietnam-based jewellery firm, has launched a unique 24 karat gold-plated iPhone 6 version with gold-cast monolithic dragon on its back panel. The real 24 karat gold plated enclosure doesn’... Read more
Black Friday: 13-inch 2.6GHz Retina MacBook P...
 B&H Photo has lowered their price for the 13″ 2.6GHz/128GB Retina MacBook Pro to $1159 for Black Friday. That’s $140 off MSRP, and it’s the lowest price for this model (except for Apple’s $1099... Read more
View all the Black Friday sales on our Mac Pr...
We’ve updated our Mac Price Trackers with the latest information on prices, bundles, and availability on systems from Apple’s authorized internet/catalog resellers. View Black Friday sale prices at a... Read more
Black Friday: 11-inch MacBook Air for $779, s...
 Best Buy has lowered their price for the 2014 11″ 1.4GHz/128GB MacBook Air to $779.99 for Black Friday. That’s $120 off MSRP. Choose free shipping or free local store pickup (if available). Sale... Read more
Apple Store Black Friday sale for 2014: $100...
BLACK FRIDAY The Apple Store has posted their Black Friday deals for 2014. Receive a $100 PRODUCT(RED) branded iTunes gift card with the purchase of select Macs, $50 with iPads, and $25 with iPods,... Read more
Black Friday: 15% off iTunes Gift Cards
Staples is offering 15% off $50 and $100 iTunes Gift Cards on their online store as part of their Black Friday sale. Click here for more information. Shipping is free. Best Buy is offering $100... Read more
BEVL Releases Dock Tailored for iPhone 6 and...
Seattle based BEVL has released their first product: an iPhone dock that is divergent in build quality, rock-solid function and visual simplicity to complement the iPhone. BEVL is now accepting... Read more

Jobs Board

*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Senior Event Manager, *Apple* Retail Market...
…This senior level position is responsible for leading and imagining the Apple Retail Team's global event strategy. Delivering an overarching brand story; in-store, Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.