home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 2
/
goldfish_vol2_cd1.bin
/
files
/
dev
/
lang
/
struct
/
exampleprograms
/
indenter.struct
< prev
next >
Wrap
Text File
|
1994-02-12
|
7KB
|
246 lines
~ Struct Indenter
~ Version 1.0 by Roland Acton - August 1993
~ Internet address: xracton@ccvax.fullerton.edu
~ Version 1.1 by Roland Acton - January 1994
~ Changes: The program now uses register variables, and makes proper
~ procedure and library calls.
~ This is an indenting program for the Struct language. It serves as
~ a useful programming aid and also as an example of how to write a
~ simple program in Struct.
~ This program is public domain. You may use any part of it you wish
~ in a program of your own, provided that you credit me and send me
~ a copy of the program.
define procedure Kahm
define procedure word=ParseCommandLine
set startup Kahm
open library exec
open library dos
constant indentamount=2,maxkeywords=15
global srcfilehandle:long,destfilehandle:long
procedure Kahm
local indent:word,bufferstart:long,bufferpos:word,buffercount:word
local fileline:long,linepos:word,spacebuffer:long,z:byte
local counter:long,indentskip:long,keywordcount:word
local keywordpointer:long,foundkeyword:word,x:byte,linepointer:long
local pclsuccess:word
string (info1) "Indenter for the Struct language",10
string (info2) "Version 1.1 by Roland Acton - January 1994",10,10
print info1
print info2
proc call pclsuccess=ParseCommandLine
if pclsuccess=1
libcall bufferstart=allocmem(256,0)
libcall fileline=allocmem(256,0)
libcall spacebuffer=allocmem(256,0)
~ Strictly speaking, I should check to see if the memory allocation
~ fails, but if the system is that low on memory it's going to fail
~ for other reasons in short order.
for counter=spacebuffer;spacebuffer+252;4
longpoke counter,32*256+32*256+32*256+32
next
libcall buffercount=read(srcfilehandle,bufferstart,256)
bufferpos=0
indent=0
~ The section of code below is an internal buffering system. It
~ pulls in 256 bytes at a time from the source file and extracts
~ lines of source code from them.
mainloop:
data register bufferpos,z,linepos,buffercount,fileline
address register bufferstart,fileline,indentskip
regload
linepos=0
repeat
bytepeek z=bufferstart+bufferpos
bytepoke fileline+linepos,z
bufferpos=bufferpos+1
linepos=linepos+1
if bufferpos=buffercount
libcall buffercount=read(srcfilehandle,bufferstart,256)
bufferpos=0
end if
until z=10 | buffercount=0 | linepos=256
~ It's assumed that no line will be larger than 256 bytes. The extra
~ condition above is just to stop the program from crashing if it's
~ accidentally run on a binary file.
for indentskip=fileline;fileline+linepos-1
bytepeek z=indentskip
if z<>32
exit
end if
next
linepos=fileline+linepos-indentskip
~ The section of code above is designed to skip any indentation that
~ already exists.
~ Now we have to determine which keyword, if any, the line begins
~ with. We skip over spaces and convert alphabetic characters to
~ uppercase.
bytedata (keywords) "IF",0,"FOR",0,"WHILE",0,"REPEAT",0,"LOOP",0
bytedata "ZEROLOOP",0,"ASM",0
bytedata "ELSE",0
bytedata "ENDIF",0,"NEXT",0,"WEND",0,"UNTIL",0,"ENDLOOP",0
bytedata "ZEND",0,"ENDASM",0
data register z,x,keywordcount,foundkeyword,indent
address register keywordpointer,linepointer,indentskip
regload
keywordcount=1
load address keywordpointer=keywords
repeat
linepointer=indentskip
foundkeyword=1
loop ;x<>0;
bytepeek z=linepointer
if z=32
linepointer=linepointer+1
bytepeek z=linepointer
back if
end if
if z=>97 & z=<122
z=z-32
end if
bytepeek x=keywordpointer
if z<>x & x<>0
foundkeyword=0
end if
linepointer=linepointer+1
keywordpointer=keywordpointer+1
end loop
if foundkeyword=1
exit
end if
keywordcount=keywordcount+1
until keywordcount>maxkeywords
~ If the line started with a valid keyword, its number is in
~ keywordcount.
~ Check for one of the pre-output indent changers.
if keywordcount=>8 & keywordcount=<15
indent=indent-indentamount
if indent<0
indent=0
end if
end if
~ Output the line.
bytepeek z=indentskip
~ If this is a comment line, or is blank, we do not indent it at
~ all.
if linepos>1 & z<>126
libcall write(destfilehandle,spacebuffer,indent)
end if
libcall write(destfilehandle,indentskip,linepos)
~ Check for one of the post-output indent changers.
if keywordcount=<8
indent=indent+indentamount
end if
~ If there's still something left in the input buffer, we go back to
~ get the next line.
if buffercount>0
goto mainloop
end if
libcall freemem(bufferstart,256)
libcall freemem(fileline,256)
libcall freemem(spacebuffer,256)
libcall close(srcfilehandle)
libcall close(destfilehandle)
end if
end procedure
procedure word=ParseCommandLine
local step:word,z:byte,srcfilename:long,destfilename:long
local addresskludge:long
~ If the command line appears valid, it is altered (by changing the
~ space and linefeed characters to nulls) so that it can be used to
~ open the source and destination files.
~ Note that this routine is deficient in that it cannot properly
~ handle parameters enclosed in quotes.
load address addresskludge=error1
srcfilename=commandpointer
commandlength=commandlength-1
parsecommandline=0
if commandlength>0
for step=0;commandlength-1
bytepeek z=commandpointer+step
if z=32
exit
end if
next
if step<commandlength
bytepoke commandpointer+step,0
step=step+1
destfilename=commandpointer+step
loop ;step<commandlength;step=step+1
bytepeek z=commandpointer+step
if z=32
exit
end if
end loop
if step=commandlength
bytepoke commandpointer+commandlength,0
parsecommandline=1
end if
end if
end if
string (error1) "Couldn't open file ",0,10
if parsecommandline=1
libcall srcfilehandle=open(srcfilename,1005)
if srcfilehandle>0
libcall destfilehandle=open(destfilename,1006)
if destfilehandle>0
parsecommandline=1
else
libcall close(srcfilehandle)
print addresskludge
print destfilename
addresskludge=addresskludge+20
print addresskludge
parsecommandline=0
end if
else
print addresskludge
print srcfilename
addresskludge=addresskludge+20
print addresskludge
parsecommandline=0
end if
else
string (error2) "Error in command line",10
string (error3) "Syntax: IndentStr <source-file> <destination-file>",10
print error2
print error3
parsecommandline=0
end if
end procedure