summaryrefslogtreecommitdiff
path: root/ipl/packs/idol/idolmain.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/packs/idol/idolmain.icn')
-rw-r--r--ipl/packs/idol/idolmain.icn215
1 files changed, 215 insertions, 0 deletions
diff --git a/ipl/packs/idol/idolmain.icn b/ipl/packs/idol/idolmain.icn
new file mode 100644
index 0000000..ffcad95
--- /dev/null
+++ b/ipl/packs/idol/idolmain.icn
@@ -0,0 +1,215 @@
+#
+# Idol: Icon-derived object language, version 8.0
+#
+# SYNOPSIS:
+#
+# idol -install
+# idol prog[.iol] ... [-x args ]
+# prog
+#
+# FILES:
+#
+# ./prog.iol : source file
+# ./prog.icn : Icon code for non-classes in prog.iol
+# ./idolcode.env/i_object.* : Icon code for the universal object type
+# ./idolcode.env/classname.icn : Icon files are generated for each class
+# ./idolcode.env/classname.u[12] : translated class files
+# ./idolcode.env/classname : class specification/interface
+#
+# SEE ALSO:
+#
+# "Programming in Idol: An Object Primer"
+# (U of Arizona Dept of CS Technical Report #90-10)
+# serves as user's guide and reference manual for Idol
+#
+### Global variables
+#
+# FILES : fin = input (.iol) file, fout = output (.icn) file
+# CSETS : alpha = identifier characters, nonalpha = everything else
+# alphadot = identifiers + '.'
+# white = whitespace, nonwhite = everything else
+# TAQUES : classes in this module
+# FLAGS : comp if we should try to make an executable from args[1]
+# strict if we should generate paranoic encapsulation protection
+# loud if Idol should generate extra console messages
+# exec if we should run the result after translation
+# LISTS : links = names of external icon code to link to
+# imports = names of external classes to import
+# compiles = names of classes which need to be compiled
+#
+global fin,fout,fName,fLine,alpha,alphadot,white,nonwhite,nonalpha
+global classes,comp,exec,strict,links,imports,loud,compiles,compatible,ct
+global icontopt,tempenv
+
+#
+# initialize global variables
+#
+procedure initialize()
+ loud := 1
+ comp := 0
+ alpha := &ucase ++ &lcase ++ '_' ++ &digits
+ nonalpha := &cset -- alpha
+ alphadot := alpha ++ '.'
+ white := ' \t\f'
+ nonwhite := &cset -- white
+ classes := taque()
+ links := []
+ imports := []
+ compiles := []
+ sysinitialize()
+end
+
+procedure main(args)
+ initialize()
+ if *args = 0 then write("usage: idol files...")
+ else {
+ if (!args ~== "-version") &
+ not tryenvopen(filename("i_object",".u1")) then {
+ tempenv := 0
+ install(args)
+ }
+ every i := 1 to *args do {
+ if \exec then next # after -x, args are for execution
+ if args[i][1] == "-" then {
+ case map(args[i]) of {
+ "-c" : {
+ sysok := &null
+ if comp = 0 then comp := -1 # don't make exe
+ }
+ "-ic" : compatible := 1
+ "-quiet" : loud := &null
+ "-strict" : strict := 1
+ "-s" : sysok := &null
+ "-t" : comp := -2 # don't translate
+ "-version": return write("Idol version 8.0 of 10/6/90") & 0
+ "-x" : exec := i
+ default : icontopt ||:= args[i] || " "
+ }
+ }
+ else {
+ \tempenv +:= 1
+ if args[i] := fileroot(args[i],".cl") then {
+ push(imports,args[i])
+ }
+ else if args[i] := fileroot(args[i],".icn") then {
+ push(links,args[i])
+ icont(" -c "||args[i])
+ }
+ else if args[i] := fileroot(args[i],".u1") then {
+ push(links,args[i])
+ }
+ else if (args[i] := fileroot(args[i],".iol")) |
+ tryopen(filename(args[i],".iol"),"r") then {
+ /exe := i
+ args[i] := fileroot(args[i],".iol")
+ /fout := sysopen(filename(args[i],".icn"),"w")
+ readinput(filename(args[i],".iol"),1)
+ } else {
+ #
+ # look for an appropriate .icn, .u1 or class file
+ #
+ if tryopen(filename(args[i],".icn"),"r") then {
+ push(links,args[i])
+ icont(" -c "||args[i])
+ }
+ else if tryopen(filename(args[i],".u1")) then {
+ push(links,args[i])
+ }
+ else if tryenvopen(args[i]) then {
+ push(imports,args[i])
+ }
+ }
+ }
+ }
+ if gencode() then {
+ close(\fout)
+ if comp = 1 & (not makeexe(args,exe)) then
+ stop("Idol exits after errors creating executable")
+ } else {
+ close(\fout)
+ stop("Idol exits after errors translating")
+ }
+ }
+ #
+ # if we built an executable without separate compilation AND
+ # there's no IDOLENV class environment AND
+ # we had to install an environment then remove the environment
+ #
+ if (comp = 1) & (\tempenv < 2) & not mygetenv("IDOLENV") then uninstall()
+end
+
+#
+# tell whether the character following s is within a quote or not
+#
+procedure notquote(s)
+ outs := ""
+ #
+ # eliminate escaped quotes.
+ # this is a bug for people who write code like \"hello"...
+ s ? {
+ while outs ||:= tab(find("\\")+1) do move(1)
+ outs ||:= tab(0)
+ }
+ # see if every quote has a matching endquote
+ outs ? {
+ while s := tab(find("\""|"'")+1) do {
+ if not tab(find(s[-1])+1) then fail
+ }
+ }
+ return
+end
+
+#
+# A contemplated addition: shorthand $.foo for self.foo ?
+#
+#procedure selfdot(line)
+# i := 1
+# while ((i := find("$.",line,i)) & notquote(line[1:i])) do line[i]:="self"
+#end
+
+#
+# error/warning/message handling
+#
+procedure halt(args[])
+ errsrc()
+ every writes(&errout,!args)
+ stop()
+end
+
+procedure warn(args[])
+ errsrc()
+ every writes(&errout,!args)
+ write(&errout)
+end
+
+procedure errsrc()
+ writes(&errout,"\"",\fName,"\", line ",\fLine,": Idol/")
+end
+#
+# System-independent, but system related routines
+#
+procedure tryopen(file,mode)
+ if f := open(file,mode) then return close(f)
+end
+procedure tryenvopen(file,mode)
+ return tryopen(envpath(file),mode)
+end
+procedure sysopen(file,mode)
+ if not (f := open(file,mode)) then
+ halt("Couldn't open file ",file," for mode ",mode)
+ return f
+end
+procedure envopen(file,mode)
+ return sysopen(envpath(file),mode)
+end
+procedure writelink(s)
+ write(fout,"link \"",s,"\"")
+end
+procedure icont(argstr,prefix)
+static s
+initial { s := (mygetenv("ICONT")|"icont") }
+ return mysystem((\prefix|"") ||s||icontopt||argstr)
+end
+procedure mygetenv(s)
+ return if &features == "environment variables" then getenv(s)
+end