home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / dev / lang / struct / exampleprograms / indenter.struct < prev    next >
Text File  |  1994-02-12  |  7KB  |  246 lines

  1. ~ Struct Indenter
  2. ~ Version 1.0 by Roland Acton - August 1993
  3. ~ Internet address: xracton@ccvax.fullerton.edu
  4.  
  5. ~ Version 1.1 by Roland Acton - January 1994
  6. ~ Changes: The program now uses register variables, and makes proper
  7. ~ procedure and library calls.
  8.  
  9. ~ This is an indenting program for the Struct language. It serves as
  10. ~ a useful programming aid and also as an example of how to write a
  11. ~ simple program in Struct.
  12. ~ This program is public domain. You may use any part of it you wish
  13. ~ in a program of your own, provided that you credit me and send me
  14. ~ a copy of the program.
  15.  
  16. define procedure Kahm
  17. define procedure word=ParseCommandLine
  18. set startup Kahm
  19.  
  20. open library exec
  21. open library dos
  22.  
  23. constant indentamount=2,maxkeywords=15
  24.  
  25. global srcfilehandle:long,destfilehandle:long
  26.  
  27.  
  28.  
  29. procedure Kahm
  30. local indent:word,bufferstart:long,bufferpos:word,buffercount:word
  31. local fileline:long,linepos:word,spacebuffer:long,z:byte
  32. local counter:long,indentskip:long,keywordcount:word
  33. local keywordpointer:long,foundkeyword:word,x:byte,linepointer:long
  34. local pclsuccess:word
  35.  
  36. string (info1) "Indenter for the Struct language",10
  37. string (info2) "Version 1.1 by Roland Acton - January 1994",10,10
  38. print info1
  39. print info2
  40. proc call pclsuccess=ParseCommandLine
  41. if pclsuccess=1
  42.   libcall bufferstart=allocmem(256,0)
  43.   libcall fileline=allocmem(256,0)
  44.   libcall spacebuffer=allocmem(256,0)
  45.  
  46. ~ Strictly speaking, I should check to see if the memory allocation
  47. ~ fails, but if the system is that low on memory it's going to fail
  48. ~ for other reasons in short order.
  49.  
  50.   for counter=spacebuffer;spacebuffer+252;4
  51.     longpoke counter,32*256+32*256+32*256+32
  52.   next
  53.   libcall buffercount=read(srcfilehandle,bufferstart,256)
  54.   bufferpos=0
  55.   indent=0
  56.  
  57. ~ The section of code below is an internal buffering system. It
  58. ~ pulls in 256 bytes at a time from the source file and extracts
  59. ~ lines of source code from them.
  60.  
  61.   mainloop:
  62.   data register bufferpos,z,linepos,buffercount,fileline
  63.   address register bufferstart,fileline,indentskip
  64.   regload
  65.   linepos=0
  66.   repeat
  67.     bytepeek z=bufferstart+bufferpos
  68.     bytepoke fileline+linepos,z
  69.     bufferpos=bufferpos+1
  70.     linepos=linepos+1
  71.     if bufferpos=buffercount
  72.       libcall buffercount=read(srcfilehandle,bufferstart,256)
  73.       bufferpos=0
  74.     end if
  75.   until z=10 | buffercount=0 | linepos=256
  76.  
  77. ~ It's assumed that no line will be larger than 256 bytes. The extra
  78. ~ condition above is just to stop the program from crashing if it's
  79. ~ accidentally run on a binary file.
  80.  
  81.   for indentskip=fileline;fileline+linepos-1
  82.     bytepeek z=indentskip
  83.     if z<>32
  84.       exit
  85.     end if
  86.   next
  87.   linepos=fileline+linepos-indentskip
  88.  
  89. ~ The section of code above is designed to skip any indentation that
  90. ~ already exists.
  91.  
  92. ~ Now we have to determine which keyword, if any, the line begins
  93. ~ with. We skip over spaces and convert alphabetic characters to
  94. ~ uppercase.
  95.  
  96.   bytedata (keywords) "IF",0,"FOR",0,"WHILE",0,"REPEAT",0,"LOOP",0
  97.   bytedata "ZEROLOOP",0,"ASM",0
  98.   bytedata "ELSE",0
  99.   bytedata "ENDIF",0,"NEXT",0,"WEND",0,"UNTIL",0,"ENDLOOP",0
  100.   bytedata "ZEND",0,"ENDASM",0
  101.  
  102.   data register z,x,keywordcount,foundkeyword,indent
  103.   address register keywordpointer,linepointer,indentskip
  104.   regload
  105.   keywordcount=1
  106.   load address keywordpointer=keywords
  107.   repeat
  108.     linepointer=indentskip
  109.     foundkeyword=1
  110.     loop ;x<>0;
  111.       bytepeek z=linepointer
  112.       if z=32
  113.         linepointer=linepointer+1
  114.         bytepeek z=linepointer
  115.         back if
  116.       end if
  117.       if z=>97 & z=<122
  118.         z=z-32
  119.       end if
  120.       bytepeek x=keywordpointer
  121.       if z<>x & x<>0
  122.         foundkeyword=0
  123.       end if
  124.       linepointer=linepointer+1
  125.       keywordpointer=keywordpointer+1
  126.     end loop
  127.     if foundkeyword=1
  128.       exit
  129.     end if
  130.     keywordcount=keywordcount+1
  131.   until keywordcount>maxkeywords
  132.  
  133. ~ If the line started with a valid keyword, its number is in
  134. ~ keywordcount.
  135.  
  136. ~ Check for one of the pre-output indent changers.
  137.  
  138.   if keywordcount=>8 & keywordcount=<15
  139.     indent=indent-indentamount
  140.     if indent<0
  141.       indent=0
  142.     end if
  143.   end if
  144.  
  145. ~ Output the line.
  146.  
  147.   bytepeek z=indentskip
  148.  
  149. ~ If this is a comment line, or is blank, we do not indent it at
  150. ~ all.
  151.  
  152.   if linepos>1 & z<>126
  153.     libcall write(destfilehandle,spacebuffer,indent)
  154.   end if
  155.   libcall write(destfilehandle,indentskip,linepos)
  156.  
  157. ~ Check for one of the post-output indent changers.
  158.  
  159.   if keywordcount=<8
  160.     indent=indent+indentamount
  161.   end if
  162.  
  163. ~ If there's still something left in the input buffer, we go back to
  164. ~ get the next line.
  165.  
  166.   if buffercount>0
  167.     goto mainloop
  168.   end if
  169.   libcall freemem(bufferstart,256)
  170.   libcall freemem(fileline,256)
  171.   libcall freemem(spacebuffer,256)
  172.   libcall close(srcfilehandle)
  173.   libcall close(destfilehandle)
  174. end if
  175. end procedure
  176.  
  177.  
  178.  
  179. procedure word=ParseCommandLine
  180. local step:word,z:byte,srcfilename:long,destfilename:long
  181. local addresskludge:long
  182.  
  183. ~ If the command line appears valid, it is altered (by changing the
  184. ~ space and linefeed characters to nulls) so that it can be used to
  185. ~ open the source and destination files.
  186. ~ Note that this routine is deficient in that it cannot properly
  187. ~ handle parameters enclosed in quotes.
  188.  
  189. load address addresskludge=error1
  190. srcfilename=commandpointer
  191. commandlength=commandlength-1
  192. parsecommandline=0
  193. if commandlength>0
  194.   for step=0;commandlength-1
  195.     bytepeek z=commandpointer+step
  196.     if z=32
  197.       exit
  198.     end if
  199.   next
  200.   if step<commandlength
  201.     bytepoke commandpointer+step,0
  202.     step=step+1
  203.     destfilename=commandpointer+step
  204.     loop ;step<commandlength;step=step+1
  205.       bytepeek z=commandpointer+step
  206.       if z=32
  207.         exit
  208.       end if
  209.     end loop
  210.     if step=commandlength
  211.       bytepoke commandpointer+commandlength,0
  212.       parsecommandline=1
  213.     end if
  214.   end if
  215. end if
  216. string (error1) "Couldn't open file ",0,10
  217. if parsecommandline=1
  218.   libcall srcfilehandle=open(srcfilename,1005)
  219.   if srcfilehandle>0
  220.     libcall destfilehandle=open(destfilename,1006)
  221.     if destfilehandle>0
  222.       parsecommandline=1
  223.     else
  224.       libcall close(srcfilehandle)
  225.       print addresskludge
  226.       print destfilename
  227.       addresskludge=addresskludge+20
  228.       print addresskludge
  229.       parsecommandline=0
  230.     end if
  231.   else
  232.     print addresskludge
  233.     print srcfilename
  234.     addresskludge=addresskludge+20
  235.     print addresskludge
  236.     parsecommandline=0
  237.   end if
  238. else
  239.   string (error2) "Error in command line",10
  240.   string (error3) "Syntax: IndentStr <source-file> <destination-file>",10
  241.   print error2
  242.   print error3
  243.   parsecommandline=0
  244. end if
  245. end procedure
  246.