############################################################################ # # File: interpp.icn # # Subject: Program to interpret Icon programs # # Author: Jerry Nowlin # # Date: December 30, 1991 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # This program is kind of like an interactive version of BASIC in that Icon # expressions are entered with line numbers and you can resequence them list # them etc. and execute all the lines entered. There is no editor built # in. You have to retype a line to change it. # # Documentation is lacking but there is a "?" help command that lists all # the other commands. # ############################################################################ # # See also: interpe.icn # ############################################################################ global WHITE, # the white space cset MFLAG, # the modified flag PRTBL # the program table procedure main(arg) local line, lno, pline # define the needed cset WHITE := ' \t\n\f' # initialize the program table PRTBL := table() # initialize the modified flag MFLAG := 0 # get all the input writes("Icon> ") while line := read() do { # scan the input line line ? { # skip any initial white space tab(many(WHITE)) # check for program lines (they have line numbers) if lno := tab(many(&digits)) & tab(many(WHITE)) then { # get the program line pline := tab(0) # store the line in the program table PRTBL[numeric(lno)] := pline # set the modified flag MFLAG +:= 1 } # read command else if (tab(upto(WHITE)) | tab(0)) == ("read" | "r") then { readprog() # clear the modified flag MFLAG := 0 } # write command else if (tab(upto(WHITE)) | tab(0)) == ("write" | "w") then { writeprog() # clear the modified flag MFLAG := 0 } # delete command else if (tab(upto(WHITE)) | tab(0)) == ("delete" | "d") then { delprog() # set the modified flag MFLAG +:= 1 } # sequence command else if (tab(upto(WHITE)) | tab(0)) == ("sequence" | "s") then { seqprog() } # list command else if (tab(upto(WHITE)) | tab(0)) == ("list" | "l") then { listprog() } # execute command else if (tab(upto(WHITE)) | tab(0)) == ("execute" | "e") then { execprog() } # help command else if (tab(upto(WHITE)) | tab(0)) == ("help" | "h" | "?") then { helpprog() } # quit command else if (tab(upto(WHITE)) | tab(0)) == ("quit" | "q") then { quitprog() } # invalid syntax input else { write("Syntax Error: ",line) helpprog() } } writes("Icon> ") } end procedure execprog() local runargs, out, prog, line, command static tmpfile initial tmpfile := "TMPFILE.icn" # get any runtime arguments runargs := tab(0) # create the temporary Icon file (out := open(tmpfile,"w")) | # or mention the problem and fail (write("I can't open '",tmpfile,"' for writing") & fail) # sort the program table prog := sort(PRTBL) # put the program in the file every line := !prog do { write(out,line[2]) } close(out) # format the command to execute the program command := "icont -s " || tmpfile || " -x " || runargs # add the command to remove the temporary file command ||:= " ; rm -f " || tmpfile # execute the command system(command) end procedure seqprog() local begno, incno, prog, lno, l # initialize the sequencing numbers begno := incno := 10 # skip any white space tab(many(WHITE)) # get an initial line number begno := numeric(tab(many(&digits))) # skip any white space tab(many(WHITE)) # get a increment number incno := numeric(tab(many(&digits))) # sort the program table prog := sort(PRTBL) # reinitialize it PRTBL := table() # sequence the program lines starting with begno by incno lno := begno every l := !prog do { PRTBL[lno] := l[2] lno +:= incno } end procedure readprog() local readfile, response, in, lno, line # get a possible command line file name tab(many(WHITE)) readfile := tab(upto(WHITE) | 0) # if there was no file with the command get one if /readfile | *readfile = 0 then { writes("Read file name: ") readfile := read() } # make sure a modified file has been written if MFLAG > 0 then { writes("Write before reading over current program? ") response := read() if any('yY',response) then writeprog() } # initialize the program table PRTBL := table() # read the program from the read file in := open(readfile,"r") lno := 10 every line := !in do { PRTBL[lno] := line lno +:= 10 } close(in) # tell them what you did write("Read '",readfile,"'...",*PRTBL," lines") end procedure writeprog() local writefile, prog, out, l # get a possible command line file name tab(many(WHITE)) writefile := tab(upto(WHITE) | 0) # if there was no file with the command get one if /writefile | *writefile = 0 then { writes("Write file name: ") writefile := read() } # sort the program table prog := sort(PRTBL) # write the program to the write file out := open(writefile,"w") every l := !prog do { write(out,l[2]) } close(out) # tell them what you did write("Write '",writefile,"'...",*PRTBL," lines") end procedure delprog() local begno, endno, prog, l, lno # initialize the line numbers begno := 0 endno := 99999 # skip any white space tab(many(WHITE)) # get an initial line number begno := endno := numeric(tab(many(&digits))) # skip any white space tab(many(WHITE)) # get a final line number endno := numeric(tab(many(&digits))) # sort the program table prog := sort(PRTBL) # reinitialize it PRTBL := table() # delete the program lines between the optional numbers every l := !prog do { lno := numeric(l[1]) if (lno < begno) | (lno > endno) then PRTBL[lno] := l[2] } end procedure listprog() local begno, endno, prog, l, lno # initialize the line numbers begno := 0 endno := 99999 # skip any white space tab(many(WHITE)) # get an initial line number begno := endno := numeric(tab(many(&digits))) # skip any white space tab(many(WHITE)) # get a final line number endno := numeric(tab(many(&digits))) # sort the program table prog := sort(PRTBL) # list the program lines between the optional numbers every l := !prog do { lno := numeric(l[1]) if (lno >= begno) & (lno <= endno) then write(right(lno,5),": ",l[2]) if lno > endno then break } end procedure helpprog() static helpmsg # define the help message initial { helpmsg := [ "<<< Icon Expression Syntax >>>", "", "lineno expression", "", "<<< Command Summary >>>", " (1st character works)", "", "read [ file ]", "write [ file ]", "list [ begno [ endno ] ]", "delete [ begno [ endno ] ]", "sequence [ begno [ increment ] ]", "execute [ args ]", "quit", "help" ] } # print it every write(!helpmsg) end procedure quitprog() local response # make sure a modified file has been written if MFLAG > 0 then { writes("Write before quitting? ") response := read() if any('yY',response) then writeprog() } stop("Goodbye.") end