home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
ipl
/
progs
/
based.icn
< prev
next >
Wrap
Text File
|
2000-07-29
|
14KB
|
541 lines
############################################################################
#
# File: based.icn
#
# Subject: Program to do BASIC-style editing
#
# Author: Chris Tenaglia
#
# Date: February 18, 1996
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# This program models a line editor for BASIC.
#
############################################################################
global chars,program,cmd,token,name
procedure main(param)
local ff, old
if find("p",map(param[1])) then ff := "\014"
else ff := "\e[2J\e[H"
chars := &cset -- '\t '
program := list()
name := &null
write("Basic Line Editor V1.3 by Tenaglia 910104.1700")
write(&host," ",&dateline,"\n")
repeat
{
writes(">")
(cmd := read()) | { quit() ; next }
if cmd == "!!" then
{
cmd := old
write("> ",cmd)
}
token := parse(cmd)
if integer(token[1]) then
{
entry(token[1])
token[1] := ""
}
old := cmd
#EJECT
case map(token[1]) of
{
"" : "ignore this case"
"load" : write(load())
"save" : write(save())
"resave" : write(resave())
"read" : write(basread())
"write" : write(baswrite())
"merge" : write(merge())
"new" : write(new())
"list" : write(print())
"renum" : write(renum())
"del" : write(del())
"dir" : write(dir())
"size" : write("Buffer contains ",*program," lines.")
"find" : write(search())
"cls" : write(ff)
"compile": write(compile())
"build" : write(build())
"test" : write(build(),run())
"run" : write(run())
"ver" : write("Basic Line Editor V1.3 by Tenaglia 910104.1700")
"date" : write(&host," ",&dateline)
"time" : write(&host," ",&dateline)
"help" : write(help())
"?" : write(help())
"$" : write(shell())
"exit" : break
"quit" : break
default : write("\007What ?")
}
}
write("Returning to operating system")
write(&host," ",&dateline)
end
procedure quit() # allows CTRL_Z exit under VMS
local test
writes("QUIT! Are you sure? Y/N :")
(test := read()) | stop("Returning to operating system\n",&host," ",&dateline)
if map(test)[1] == "y" then stop("Returning to operating system\n",&host," ",&dateline)
return
end
#SUB LOAD, SAVE, AND RESAVE COMMANDS
#EJECT
procedure load()
local file, in, lnum
if not(token[2]) then
{
writes("_file:")
if (file := string(read())) == "" then return
} else file := token[2]
lnum := 0
(in := open(file)) | return ("Can't open " || file)
name := file
program := []
while put(program,((lnum+:=10) || " " || read(in))) do
not(find("00",lnum)) | (writes("."))
close(in)
return ("\n" || file || " loaded.")
end
procedure save()
local file, i, line, lnum, out, text
if not(token[2]) then
{
writes("_file:")
if (file := string(read())) == "" then return
} else file := token[2]
(out := open(file,"w")) | return ("Can't open " || file)
name := file
every line := !program do
{
i := upto(' \t',line)
lnum := line[1:i]
text := line[i+1:0]
write(out,text)
not(find("00",lnum)) | (writes("."))
}
close(out)
return ("\n" || file || " saved.")
end
procedure resave()
local i, line, lnum, out, text
if not(string(name)) then return("Nothing LOADed to resave.")
(out := open(name,"w")) | return ("Can't open " || name)
every line := !program do
{
i := upto(' \t',line)
lnum := line[1:i]
text := line[i+1:0]
write(out,text)
not(find("00",lnum)) | (writes("."))
}
close(out)
return ("\n" || name || " resaved.")
end
#SUB READ, WRITE, AND MERGE COMMANDS
#EJECT
procedure basread()
local file, in, line, lnum, test
if not(token[2]) then
{
writes("_file:")
if (file := string(read())) == "" then return
} else file := token[2]
lnum := 0
(in := open(file)) | return ("Can't open " || file)
name := file
program := []
while line := read(in) do
{
test := (line[1:upto(' \t',line)]) | ""
if integer(test) then put(program,line)
not(find("00",(lnum+:=10))) | (writes("."))
}
close(in)
return ("\n" || file || " read in.")
end
procedure baswrite()
local file, lnum, out
if not(token[2]) then
{
writes("_file:")
if (file := string(read())) == "" then return
} else file := token[2]
(out := open(file,"w")) | return ("Can't open " || file)
name := file ; lnum := 0
every write(out,!program) do
not(find("00",(lnum+:=10))) | (writes("."))
close(out)
return ("\n" || file || " writen out.")
end
procedure merge()
local file, i, in, line, lnum
if not(token[2]) then
{
writes("_file:")
if (file := string(read())) == "" then return
} else file := token[2]
(in := open(file)) | return ("Can't open " || file)
every line := !in do
{
(lnum := integer(line[1:(i:=upto(' \t',line))])) | next
cmd := line
entry(lnum)
not(find("00",lnum)) | writes(".")
}
close(in)
return (file || " merged in current buffer.")
end
#SUB DIR, DEL, AND NEW COMMANDS
#EJECT
procedure dir()
local spec
spec := (token[2]) | ("")
if &host == "MS-DOS" then
{
system(("dir/w " || spec))
return ""
}
if find("nix",map(&host)) then
system(("ls -l " || spec || " | more")) else
system(("dir " || spec))
return ""
end
procedure del()
local From, To, element, lnum, num, other
if (From := integer(token[2])) & (To := integer(token[3])) then
{
other := []
every element := !program do
{
lnum := element[1:upto(' \t',element)]
if (lnum >= From) & (lnum <= To) then next
put(other,element)
}
program := copy(other)
return ("Lines " || From || " - " || To || " deleted.")
}
if not(num := integer(token[2])) then
{
writes("_line:")
(num := integer(read())) | (return ("Not a line number."))
}
other := []
every element := !program do
{
lnum := element[1:upto(' \t',element)]
if lnum = num then next
put(other,element)
}
program := copy(other)
return ("Line " || num || " deleted.")
end
procedure new()
program := []
name := &null
return ("Buffer cleared.")
end
#SUB FIND COMMAND
#EJECT
procedure search()
local From, To, delta, diff, i, item, j, k, l, line, lnum
if (From := token[2]) & (To := token[3]) then
{
diff := (*token[3]) - (*token[2])
every i := 1 to *program do
{
line := program[i]
l := upto(' \t',line) + 1
delta:= 0
every j := find(From,line,l) do
{
k := j + delta
line[k+:*From] := ""
line[((k-1)|(1))] ||:= To
delta +:= diff
writes(".")
}
program[i] := line
}
return ""
}
if not(item := token[2]) then
{
writes("_string:")
if (item := read()) == "" then return ""
}
every i := 1 to *program do
{
line := program[i]
l := upto(' \t',line) + 1
if find(item,line,l) then
{
lnum := line[1:l-1]
writes(lnum,",")
}
}
return ""
end
#SUB COMPILATION AND RUNNING ROUTINES
#EJECT
procedure compile() # compile only
local fid, opt
local i, ext, command, val
find(".",name) | return "Can't compile! Language &or Filename not recognized"
i := last(".",name)
fid := map(name[1:i])
ext := map(name[i:0])
command := case ext of
{
".icn" : "icont -c " || name
".c" : "cc " || opt || " " || name
".f" : "f77 "|| opt || " " || name
".asm" : "asm "|| opt || " " || name
".p" : "pc " || opt || " " || name
".for" : "fortran " || name
".bas" : "basic " || name
".cob" : "cobol " || name
".mar" : "macro " || name
".pas" : "pascal " || name
default: return "Can't compile! Language &or Filename not recognized"
}
write("Issuing -> ",command)
val := system(command)
return " Completion Status = " || val
end
procedure build() # compile and link
local i, ext, command, val1, val2, fid
find(".",name) | return "Can't compile! Language &or Filename not recognized"
i := last(".",name)
fid := map(name[1:i])
ext := map(name[i:0])
command := case ext of
{
".icn" : ["icont " || name]
".c" : ["cc " || name]
".f" : ["f77 " || name]
".asm" : ["asm " || name]
".p" : ["pc " || name]
".for" : ["fortran " || name, "link " || fid]
".bas" : ["basic " || name, "link " || fid]
".cob" : ["cobol " || name, "link " || fid]
".mar" : ["macro " || name, "link " || fid]
".pas" : ["pascal " || name, "link " || fid]
default: return "Can't compile! Language &or Filename not recognized"
}
write("Issuing -> ",command[1])
val1 := system(command[1])
val2 := if *command = 2 then
{
write("And Issuing -> ",command[2])
system(command[2])
} else -1
return " Completion status = " || val1 || " and " || val2
end
procedure run() # run built ware
local i, ext, command, val, fid
find(".",name) | return "Can't compile! Language &or Filename not recognized"
i := last(".",name)
fid := map(name[1:i])
ext := map(name[i:0])
command := case ext of
{
".icn" : "iconx " || fid
".c" : fid
".f" : fid
".asm" : fid
".p" : fid
".com" : "@" || name
".for" : "run " || fid
".bas" : "run " || fid
".cob" : "run " || fid
".mar" : "run " || fid
".pas" : "run " || fid
default: return "Can't Run ! Language &or Filename not recognized"
}
write("Issuing -> ",command)
val := system(command)
return " Completion status = " || val
end
#SUB LIST AND RENUM COMMANDS
#EJECT
procedure print()
local From, To, items, line
if *token = 1 then
{
every write(!program)
return ""
}
if not(numeric(token[2])) then return proc_list()
From := integer(token[2])
To := integer(token[3])
if not(integer(To)) then
{
every line := !program do
{
items := parse(line)
if items[1] > From then return ""
if items[1] = From then
{
write(line)
return ""
}
}
return ""
}
every line := !program do
{
items := parse(line)
if items[1] < From then next
if items[1] > To then return ""
write(line)
}
return ""
end
#
procedure proc_list()
local flag, line
flag := 0
every line := !program do
{
if find("procedure",line) & find(token[2],line) then flag := 1
if flag = 1 then write(line)
if (parse(line)[2] == "end") & (flag = 1) then
{
write("")
flag := 0
}
}
return ""
end
#
procedure renum()
local inc, line, lnum, other
(lnum := integer(token[2])) | (lnum := 10)
(inc := integer(token[3])) | (inc := 10)
other := list()
every line := !program do
{
line[1:upto(' \t',line)] := lnum
put(other,line)
not(find("00",lnum)) | (writes("."))
lnum +:= inc
}
program := copy(other)
return ("\nProgram renumbered.")
end
#SUB ON LINE HELP DISPLAY
#EJECT
procedure help()
write("Basic Line Editor V1.3 by Tenaglia")
write(" This editor works on the same principle as basic interpreter")
write(" environments. The lines are all prefixed with line numbers.")
write(" These line numbers are used to reference lines in the file.")
write(" The line numbers are not written to, or read from the file.")
write(" This editor is designed to work on a hard copy terminal like")
write(" a teletype or decwriter as well as a crt.")
write("Command Summary : (parameters are space delimited)")
write(" NEW - erase buffer | CLS - clear screen or form feed")
write(" LOAD file - load file | SAVE file - save file")
write(" READ file - read w/line numbers | WRITE file - write w/line numbers")
write(" RESAVE - resave current file | MERGE file - insert w/line numbers")
write(" DIR [spec]- list directory | SIZE - lines in editing buffer")
write(" RENUM - renumber the lines | VER - current version number")
write(" COMPILE - current source | BUILD - compile & link")
write(" TEST - compile,link, & run | RUN - run last compiled")
write(" $ - command to system (shell) | HELP or ? - this help screen")
write(" TIME or DATE - displays time | !! - repeat last command")
write("*---------------------------------+--------------------------------------*")
write(" LIST or DEL [from [to]] - list or delete line(s)")
write(" FIND str [repl] - find or replace string")
return " EXIT or QUIT - return to operating system"
end
#SUB LINE ENTRY AND HANDY PARSER PROCEDURE
#EJECT
procedure entry(stuff)
local element, finish, flag, lnum, other
other := list()
flag := "i"
finish := 9999999
every element := !program do
{
lnum := integer(element[1:upto(' \t',element)])
if stuff = lnum then
{
put(other,cmd)
stuff := finish
next
}
if stuff < lnum then
{
put(other,cmd)
stuff := finish
}
put(other,element)
}
if stuff ~= finish then put(other,cmd)
program := copy(other)
end
procedure shell()
local command
command := cmd[find(" ",cmd):0]
if trim(detab(command))=="" then return "No shell command"
system(command)
return "\nReturn to editor"
end
procedure parse(line)
local tokens
tokens := []
line ? while tab(upto(chars)) do put(tokens,tab(many(chars)))
return tokens
end
procedure last(substr,str)
local i
every i := find(substr,str)
return i
end