home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / OL.LZH / IDOL.LZH / IDOLBOOT.ICN < prev    next >
Text File  |  1991-07-18  |  40KB  |  1,266 lines

  1. global fin,fout,fName,fLine,alpha,alphadot,white,nonwhite,nonalpha
  2. global classes,comp,exec,strict,links,imports,loud,compiles,compatible,ct
  3. procedure gencode()
  4. #line 11 "idol.iol"
  5.   if \loud then write("Class import/export:")
  6.  
  7.  
  8.  
  9.   every cl := (__self1 := classes).__methods.foreach_t(__self1.__state) do (__self2 := cl).__methods.writespec(__self2.__state)
  10.  
  11.  
  12.  
  13.   repeat {
  14.     added := 0
  15.     every super:= ((__self2 := ((__self1 := classes).__methods.foreach_t(__self1.__state))).__methods.foreachsuper(__self2.__state) | !imports) do{
  16.       if /(__self1 := classes).__methods.lookup(__self1.__state,super) then {
  17.     added := 1
  18.     fname := filename(super)
  19.     readinput(envpath(fname),2)
  20.     if /(__self1 := classes).__methods.lookup(__self1.__state,super) then halt("can't import class '",super,"'")
  21.     writesublink(fname)
  22.       }
  23.     }
  24.     if added = 0 then break
  25.   }
  26.  
  27.  
  28.  
  29.   every (__self2 := ((__self1 := classes).__methods.foreach_t(__self1.__state))).__methods.transitive_closure(__self2.__state)
  30.  
  31.  
  32.  
  33.   if \loud then write("Generating code:")
  34.   writesublink("i_object")
  35.   every s := !links do writelink(s)
  36.   write(fout)
  37.   every out := (__self1 := classes).__methods.foreach(__self1.__state) do { 
  38.     name := filename((__self1 := out).__methods.name(__self1.__state))
  39.     (__self1 := out).__methods.write(__self1.__state)
  40.     put(compiles,name)
  41.     writesublink(name)
  42.   }
  43.   if *compiles>0 then return cdicont(compiles)
  44.   else return
  45. end
  46. procedure readinput(name,phase,ct2)
  47. #line 686 "idol.iol"
  48.     if \loud then write("\t",name)
  49.     fName := name
  50.     fLine := 0
  51.     fin   := sysopen(name,"r")
  52.     ct    := \ct2 | constant()
  53.     while line := readln("wrap") do {
  54.     line ? {
  55.         tab(many(white))
  56.         if ="class" then {
  57.         decl := class()
  58.         (__self1 := decl).__methods.read(__self1.__state,line,phase)
  59.         if phase=1 then {
  60.             (__self1 := decl).__methods.writemethods(__self1.__state)
  61.             (__self1 := classes).__methods.insert(__self1.__state,decl,(__self2 := decl).__methods.name(__self2.__state))
  62.         } else (__self1 := classes).__methods.insert_t(__self1.__state,decl,(__self2 := decl).__methods.name(__self2.__state))
  63.         }
  64.         else if ="procedure" then {
  65.         if comp = 0 then comp := 1
  66.         decl := method("")
  67.         (__self1 := decl).__methods.read(__self1.__state,line,phase)
  68.         (__self1 := decl).__methods.write(__self1.__state,fout,"")
  69.         }
  70.         else if ="record" then {
  71.         if comp = 0 then comp := 1
  72.         decl := declaration(line)
  73.         (__self1 := decl).__methods.write(__self1.__state,fout,"")
  74.         }
  75.         else if ="global" then {
  76.         if comp = 0 then comp := 1
  77.         decl := vardecl(line)
  78.         (__self1 := decl).__methods.write(__self1.__state,fout,"")
  79.         }
  80.         else if ="const" then {
  81.         (__self1 := ct).__methods.append(__self1.__state,constdcl(line) )
  82.             }
  83.         else if ="method" then {
  84.         halt("readinput: method outside class")
  85.             }
  86.         else if ="#include" then {
  87.         savedFName := fName
  88.         savedFLine := fLine
  89.         savedFIn   := fin
  90.         tab(many(white))
  91.         readinput(tab(if ="\"" then find("\"") else many(nonwhite)),
  92.               phase,ct)
  93.         fName := savedFName
  94.         fLine := savedFLine
  95.         fin   := savedFIn
  96.             }
  97.     }
  98.     }
  99.     close(fin)
  100. end
  101. procedure readln(wrap)
  102. #line 745 "idol.iol"
  103.   count := 0
  104.   prefix := ""
  105.   while /finished do {
  106.  
  107.     if not (line := read(fin)) then fail
  108.     fLine +:= 1
  109.     if match("#include",line) then return line
  110.     line[ 1(x<-find("#",line),notquote(line[1:x])) : 0] := ""
  111.     line := trim(line,white)
  112.  
  113.     x := 1
  114.     while ((x := find("$",line,x)) & notquote(line[1:x])) do {
  115.       z := line[x+1:0] ||" "
  116.       case line[x+1] of {
  117.  
  118.  
  119.  
  120.         "(": line[x+:2] := "{"
  121.         ")": line[x+:2] := "}"
  122.         "<": line[x+:2] := "["
  123.         ">": line[x+:2] := "]"
  124.  
  125.  
  126.  
  127.         "!"|"*"|"@"|"?": {
  128.           z ? {
  129.         move(1)
  130.         tab(many(white))
  131.         if not (id := tab(many(alphadot))) then {
  132.           if not match("(") then halt("readln can't parse ",line)
  133.           if not (id := tab(&pos<bal())) then
  134.           halt("readln: cant bal ",&subject)
  135.         }
  136.         Op := case line[x+1] of {
  137.         "@": "activate"
  138.         "*": "size"
  139.         "!": "foreach"
  140.         "?": "random"
  141.         }
  142.         count +:= 1
  143.         line[x:0] :=
  144.         "(__self"||count||" := "||id||").__methods."||
  145.         Op||"(__self"||count||".__state)"||tab(0)
  146.       }
  147.         }
  148.  
  149.  
  150.  
  151.     "[": {
  152.         z ? {
  153.         if not (middle := tab((&pos<bal(&cset,'[',']'))-1)[2:0]) then
  154.             halt("readln: can't bal([) ",&subject)
  155.         tail := tab(0)|""
  156.         line := line[1:x]||"$index("||middle||")"||(tab(0)|"")
  157.         }
  158.     }
  159.         default: {
  160.  
  161.  
  162.  
  163.         reverse(line[1:x])||" " ? {
  164.         tab(many(white))
  165.         if not (id := reverse(tab(many(alphadot)))) then {
  166.             if not match(")") then halt("readln: can't parse")
  167.             if not (id := reverse(tab(&pos<bal(&cset,')','('))))
  168.             then halt("readln: can't bal ",&subject)
  169.         }
  170.         objlen := &pos-1
  171.         }
  172.         count +:= 1
  173.         front := "(__self"||count||" := "||id||").__methods."
  174.         back := "__self"||count||".__state"
  175.  
  176.  
  177.  
  178.  
  179.         z ? {
  180.         ="$"
  181.         tab(many(white))
  182.         if not (methodname := tab(many(alphadot))) then
  183.             halt("readln: expected a method name after $")
  184.         tab(many(white))
  185.         methodname ||:= "("
  186.         if ="(" then {
  187.             tab(many(white))
  188.             afterlp := &subject[&pos]
  189.         }
  190.         else {
  191.             afterlp := ")"
  192.             back ||:= ")"
  193.         }
  194.         methlen := &pos-1
  195.         }
  196.         if line[x+1] == "$" then {
  197.         c := if afterlp[1] ~== ")" then "" else "[]"
  198.         methodname[-1] := "!("
  199.         back := "["||back||"]|||"
  200.         } else {
  201.         c := if (\afterlp)[1] == ")" then "" else ","
  202.         }
  203.         line[x-objlen : (((*line>=(x+methlen+1))|0)\1)] :=
  204.         front || methodname || back || c
  205.     }
  206.       }
  207.     }
  208.     if /wrap | (prefix==line=="") then finished := line
  209.     else {
  210.     prefix ||:= line || " "
  211.     prefix ? {
  212.  
  213.  
  214.         if ((*prefix = bal()) & (not find(",",prefix[-2]))) then
  215.         finished := prefix[1:-1]
  216.     }
  217.     }
  218.   }
  219.   return (__self1 := ct).__methods.expand(__self1.__state,finished)
  220. end
  221. record idol_object(__state,__methods)
  222.  
  223. procedure declaration_read(self,decl)
  224. #line 63 "idol.iol"
  225.     decl ? (
  226.       (tab(many(white)) | "") ,
  227.  
  228.       (self.tag := =("procedure"|"class"|"method"|"record")) ,
  229.       (tab(many(white)) | "") ,
  230.  
  231.       (self.name := tab(many(alpha))) ,
  232.  
  233.       (tab(find("(")+1)),
  234.       (tab(many(white)) | "") ,
  235.       ((__self1 := (self.fields := classFields())).__methods.parse(__self1.__state,tab(find(")"))))
  236.     ) | halt("declaration/read can't parse decl ",decl)
  237.   end
  238. procedure declaration_write(self,f)
  239. #line 81 "idol.iol"
  240.      write(f,(__self1 := self).__methods.String(__self1.__state))
  241.   end
  242. procedure declaration_String(self)
  243. #line 87 "idol.iol"
  244.     return self.tag || " " || self.name || "(" || (__self1 := self.fields).__methods.String(__self1.__state) || ")"
  245.   end
  246. record declaration__state(__state,__methods,name,fields,tag)
  247. record declaration__methods(read,write,String,name)
  248. global declaration__oprec
  249. procedure declaration(name,fields,tag)
  250. local self,clone
  251. initial {
  252.   if /declaration__oprec then declarationinitialize()
  253.   }
  254.   self := declaration__state(&null,declaration__oprec,name,fields,tag)
  255.   self.__state := self
  256.   declarationinitially(self)
  257.   return idol_object(self,declaration__oprec)
  258. end
  259.  
  260. procedure declarationinitialize()
  261.   initial declaration__oprec := declaration__methods(declaration_read,declaration_write,declaration_String,declaration_name)
  262. end
  263. procedure declarationinitially(self)
  264. #line 90 "idol.iol"
  265.   if \self.name then (__self1 := self).__methods.read(__self1.__state,self.name)
  266. end
  267. procedure declaration_name(self)
  268.   return .(self.name)
  269. end
  270.  
  271. procedure vardecl_write(self,f)
  272. #line 98 "idol.iol"
  273.     write(f,self.s)
  274.   end
  275. record vardecl__state(__state,__methods,s)
  276. record vardecl__methods(write)
  277. global vardecl__oprec
  278. procedure vardecl(s)
  279. local self,clone
  280. initial {
  281.   if /vardecl__oprec then vardeclinitialize()
  282.   }
  283.   self := vardecl__state(&null,vardecl__oprec,s)
  284.   self.__state := self
  285.   return idol_object(self,vardecl__oprec)
  286. end
  287.  
  288. procedure vardeclinitialize()
  289.   initial vardecl__oprec := vardecl__methods(vardecl_write)
  290. end
  291. procedure constant_expand(self,s)
  292. #line 107 "idol.iol"
  293.     i := 1
  294.  
  295.  
  296.  
  297.  
  298.     while ((i <- find(k <- (__self1 := self).__methods.foreach(__self1.__state),s,i)) & ((i=1) | any(nonalpha,s[i-1])) & 
  299.       ((*s = i+*k-1) | any(nonalpha,s[i+*k])) &
  300.           notquote(s[1:i])) do {
  301.     val := \ (self.t[k]) | stop("internal error in expand")
  302.     s[i +: *k] := val
  303.  
  304.     }
  305.     return s
  306.   end
  307. procedure constant_foreach(self)
  308. #line 122 "idol.iol"
  309.     suspend key(self.t)
  310.   end
  311. procedure constant_eval(self,s)
  312. #line 125 "idol.iol"
  313.     if s2 := \ self.t[s] then return s2
  314.   end
  315. procedure constant_parse(self,s)
  316. #line 128 "idol.iol"
  317.     s ? {
  318.     k := trim(tab(find(":="))) | fail
  319.     move(2)
  320.     tab(many(white))
  321.     val := tab(0) | fail
  322.     (*val > 0) | fail
  323.     self.t [ k ] := val
  324.     }
  325.     return
  326.   end
  327. procedure constant_append(self,cd)
  328. #line 139 "idol.iol"
  329.     every s := (__self1 := cd).__methods.parse(__self1.__state)do (__self2 := self).__methods.parse(__self2.__state,s)
  330.   end
  331. record constant__state(__state,__methods,t)
  332. record constant__methods(expand,foreach,eval,parse,append)
  333. global constant__oprec
  334. procedure constant(t)
  335. local self,clone
  336. initial {
  337.   if /constant__oprec then constantinitialize()
  338.   }
  339.   self := constant__state(&null,constant__oprec,t)
  340.   self.__state := self
  341.   constantinitially(self)
  342.   return idol_object(self,constant__oprec)
  343. end
  344.  
  345. procedure constantinitialize()
  346.   initial constant__oprec := constant__methods(constant_expand,constant_foreach,constant_eval,constant_parse,constant_append)
  347. end
  348. procedure constantinitially(self)
  349. #line 142 "idol.iol"
  350.   self.t := table()
  351. end
  352. procedure constdcl_parse(self)
  353. #line 151 "idol.iol"
  354.     self.s ? {
  355.     tab(find("const")+6)
  356.     tab(many(white))
  357.     while s2 := trim(tab(find(","))) do {
  358.         suspend s2
  359.         move(1)
  360.         tab(many(white))
  361.     }
  362.     suspend trim(tab(0))
  363.     }
  364.   end
  365. record constdcl__state(__state,__methods,s)
  366. record constdcl__methods(parse,write,vardecl)
  367. global constdcl__oprec, vardecl__oprec
  368. procedure constdcl(s)
  369. local self,clone
  370. initial {
  371.   if /constdcl__oprec then constdclinitialize()
  372.   if /vardecl__oprec then vardeclinitialize()
  373.   constdcl__oprec.vardecl := vardecl__oprec
  374.   }
  375.   self := constdcl__state(&null,constdcl__oprec,s)
  376.   self.__state := self
  377.   return idol_object(self,constdcl__oprec)
  378. end
  379.  
  380. procedure constdclinitialize()
  381.   initial constdcl__oprec := constdcl__methods(constdcl_parse,vardecl_write)
  382. end
  383. procedure body_read(self)
  384. #line 170 "idol.iol"
  385.     self.fn    := fName
  386.     self.ln    := fLine
  387.     self.text  := []
  388.     while line := readln() do {
  389.       put(self.text, line)
  390.       line ? {
  391.       tab(many(white))
  392.       if ="end" & &pos > *line then return
  393.       else if =("local"|"static"|"initial") & any(nonalpha) then {
  394.           self.ln +:= 1
  395.           pull(self.text)
  396.           / (self.vars) := []
  397.           put(self.vars, line)
  398.       }
  399.       }
  400.     }
  401.     halt("body/read: eof inside a procedure/method definition")
  402.   end
  403. procedure body_write(self,f)
  404. #line 189 "idol.iol"
  405.     if \self.vars then every write(f,!self.vars)
  406.     if \compatible then write(f,"  \\self := self.__state")
  407.     if \self.ln then
  408.     write(f,"#line ",self.ln + ((*\self.vars)|0)," \"",self.fn,"\"")
  409.     every write(f,(__self1 := self).__methods.foreach(__self1.__state)) 
  410.   end
  411. procedure body_delete(self)
  412. #line 196 "idol.iol"
  413.     return pull(self.text)
  414.   end
  415. procedure body_size(self)
  416. #line 199 "idol.iol"
  417.     return (*\ (self.text)) | 0
  418.   end
  419. procedure body_foreach(self)
  420. #line 202 "idol.iol"
  421.     if t := \self.text then suspend !self.text
  422.   end
  423. record body__state(__state,__methods,fn,ln,vars,text)
  424. record body__methods(read,write,delete,size,foreach)
  425. global body__oprec
  426. procedure body(fn,ln,vars,text)
  427. local self,clone
  428. initial {
  429.   if /body__oprec then bodyinitialize()
  430.   }
  431.   self := body__state(&null,body__oprec,fn,ln,vars,text)
  432.   self.__state := self
  433.   return idol_object(self,body__oprec)
  434. end
  435.  
  436. procedure bodyinitialize()
  437.   initial body__oprec := body__methods(body_read,body_write,body_delete,body_size,body_foreach)
  438. end
  439. procedure class_read(self,line,phase)
  440. #line 214 "idol.iol"
  441.     (__self1 := self).__methods.declaration.read(__self1.__state,line)
  442.     self.supers := idTaque(":")
  443.     (__self1 := self.supers).__methods.parse(__self1.__state,line[find(":",line)+1:find("(",line)] | "")
  444.     self.methods:= taque()
  445.     self.text   := body()
  446.     while line  := readln("wrap") do {
  447.       line ? {
  448.     tab(many(white))
  449.     if ="initially" then {
  450.         (__self1 := self.text).__methods.read(__self1.__state)
  451.         if phase=2 then return
  452.         (__self1 := self.text).__methods.delete(__self1.__state)
  453.  
  454.         return
  455.     } else if ="method" then {
  456.         decl := method(self.name)
  457.         (__self1 := decl).__methods.read(__self1.__state,line,phase)
  458.         (__self1 := self.methods).__methods.insert(__self1.__state,decl,(__self2 := decl).__methods.name(__self2.__state))
  459.     } else if ="end" then {
  460.  
  461.         return
  462.     } else if ="procedure" then {
  463.         decl := method("")
  464.         (__self1 := decl).__methods.read(__self1.__state,line,phase)
  465.         /self.glob := []
  466.         put(self.glob,decl)
  467.     } else if ="global" then {
  468.         /self.glob := []
  469.         put(self.glob,vardecl(line))
  470.     } else if ="record" then {
  471.         /self.glob := []
  472.         put(self.glob,declaration(line))
  473.     } else if upto(nonwhite) then {
  474.         halt("class/read expected declaration on: ",line)
  475.     }
  476.       }
  477.     }
  478.     halt("class/read syntax error: eof inside a class definition")
  479.   end
  480. procedure class_has_initially(self)
  481. #line 258 "idol.iol"
  482.     return (__self1 := self.text).__methods.size(__self1.__state) > 0 
  483.   end
  484. procedure class_ispublic(self,fieldname)
  485. #line 261 "idol.iol"
  486.     if (__self1 := self.fields).__methods.ispublic(__self1.__state,fieldname) then return fieldname
  487.   end
  488. procedure class_foreachmethod(self)
  489. #line 264 "idol.iol"
  490.     suspend (__self1 := self.methods).__methods.foreach(__self1.__state) 
  491.   end
  492. procedure class_foreachsuper(self)
  493. #line 267 "idol.iol"
  494.     suspend (__self1 := self.supers).__methods.foreach(__self1.__state) 
  495.   end
  496. procedure class_foreachfield(self)
  497. #line 270 "idol.iol"
  498.     suspend (__self1 := self.fields).__methods.foreach(__self1.__state) 
  499.   end
  500. procedure class_isvarg(self,s)
  501. #line 273 "idol.iol"
  502.     if (__self1 := self.fields).__methods.isvarg(__self1.__state,s) then return s
  503.   end
  504. procedure class_transitive_closure(self)
  505. #line 276 "idol.iol"
  506.     count := (__self1 := self.supers).__methods.size(__self1.__state) 
  507.     while count > 0 do {
  508.     added := taque()
  509.     every sc := (__self1 := self.supers).__methods.foreach(__self1.__state) do { 
  510.       if /(super := (__self1 := classes).__methods.lookup(__self1.__state,sc)) then
  511.         halt("class/transitive_closure: couldn't find superclass ",sc)
  512.       every supersuper := (__self1 := super).__methods.foreachsuper(__self1.__state) do {
  513.         if / (__self1 := self.supers).__methods.lookup(__self1.__state,supersuper) &
  514.          /(__self1 := added).__methods.lookup(__self1.__state,supersuper) then {
  515.           (__self1 := added).__methods.insert(__self1.__state,supersuper)
  516.         }
  517.       }
  518.     }
  519.     count := (__self1 := added).__methods.size(__self1.__state) 
  520.     every (__self1 := self.supers).__methods.insert(__self1.__state,(__self2 := added).__methods.foreach(__self2.__state)) 
  521.     }
  522.   end
  523. procedure class_writedecl(self,f,s)
  524. #line 298 "idol.iol"
  525.     writes(f, s," ",self.name)
  526.     if s=="class" & ( *(supers := (__self1 := self.supers).__methods.String(__self1.__state)) > 0 ) then
  527.         writes(f," : ",supers)
  528.     writes(f,"(")
  529.     rv := (__self1 := self.fields).__methods.String(__self1.__state,s)
  530.     if *rv > 0 then rv ||:= ","
  531.     if s~=="class" & *(\self.ifields)>0 then    {
  532.       every l := !self.ifields do rv ||:= l.ident || ","
  533.       if /(superclass := (__self1 := classes).__methods.lookup(__self1.__state,l.class)) then
  534.       halt("class/resolve: couldn't find superclass ",sc)
  535.       if (__self1 := superclass).__methods.isvarg(__self1.__state,l.ident) then rv := rv[1:-1]||"[],"
  536.     }
  537.     writes(f,rv[1:-1])
  538.     write(f,,")")
  539.   end
  540. procedure class_writespec(self,f)
  541. #line 314 "idol.iol"
  542.     f := envopen(filename(self.name),"w")
  543.     (__self1 := self).__methods.writedecl(__self1.__state,f,"class")
  544.     every (__self2 := ((__self1 := self.methods).__methods.foreach(__self1.__state))).__methods.writedecl(__self2.__state,f,"method") 
  545.     if (__self1 := self).__methods.has_initially(__self1.__state) then write(f,"initially")
  546.     write(f,"end")
  547.     close(f)
  548.   end
  549. procedure class_writemethods(self)
  550. #line 327 "idol.iol"
  551.     f:= envopen(filename(self.name,".icn"),"w")
  552.     every (__self2 := ((__self1 := self.methods).__methods.foreach(__self1.__state))).__methods.write(__self2.__state,f,self.name) 
  553.  
  554.     if \self.glob & *self.glob>0 then {
  555.     write(f,"#\n# globals declared within the class\n#")
  556.     every i := 1 to *self.glob do (__self1 := (self.glob[i])).__methods.write(__self1.__state,f,"")
  557.     }
  558.     close(f)
  559.   end
  560. procedure class_write(self)
  561. #line 341 "idol.iol"
  562.     f:= envopen(filename(self.name,".icn"),"a")
  563.  
  564.  
  565.  
  566.     if /self.ifields then (__self1 := self).__methods.resolve(__self1.__state)
  567.  
  568.  
  569.  
  570.  
  571.     writes(f,"record ",self.name,"__state(__state,__methods")
  572.     rv := ","
  573.     rv ||:= (__self1 := self.fields).__methods.idTaque.String(__self1.__state)
  574.     if rv[-1] ~== "," then rv ||:= ","
  575.     every s := (!self.ifields).ident do rv ||:= s || ","
  576.     write(f,rv[1:-1],")")
  577.  
  578.  
  579.  
  580.  
  581.     writes(f,"record ",self.name,"__methods(")
  582.     rv := ""
  583.  
  584.     every s := (((__self2 := ((__self1 := self.methods).__methods.foreach(__self1.__state))).__methods.name(__self2.__state))    | 
  585.         (__self1 := self.fields).__methods.foreachpublic(__self1.__state)    |
  586.         (!self.imethods).ident        |
  587.         (__self1 := self.supers).__methods.foreach(__self1.__state)) 
  588.     do rv ||:= s || ","
  589.  
  590.     if *rv>0 then rv[-1] := ""
  591.     write(f,rv,")")
  592.  
  593.  
  594.  
  595.  
  596.  
  597.     writes(f,"global ",self.name,"__oprec")
  598.     every writes(f,", ", (__self1 := self.supers).__methods.foreach(__self1.__state),"__oprec") 
  599.     write(f)
  600.  
  601.  
  602.  
  603.  
  604.  
  605.     (__self1 := self).__methods.writedecl(__self1.__state,f,"procedure")
  606.     write(f,"local self,clone")
  607.  
  608.  
  609.  
  610.  
  611.     write(f,"initial {\n",
  612.         "  if /",self.name,"__oprec then ",self.name,"initialize()")
  613.     if (__self1 := self.supers).__methods.size(__self1.__state) > 0 then 
  614.     every (super <- (__self1 := self.supers).__methods.foreach(__self1.__state)) ~== self.name do 
  615.         write(f,"  if /",super,"__oprec then ",super,"initialize()\n",
  616.             "  ",self.name,"__oprec.",super," := ", super,"__oprec")
  617.     write(f,"  }")
  618.  
  619.  
  620.  
  621.  
  622.     writes(f,"  self := ",self.name,"__state(&null,",self.name,"__oprec")
  623.     every writes(f,",",(__self1 := self.fields).__methods.foreach(__self1.__state)) 
  624.     if \self.ifields then every writes(f,",",(!self.ifields).ident)
  625.     write(f,")\n  self.__state := self")
  626.  
  627.  
  628.  
  629.  
  630.     if (__self1 := self.text).__methods.size(__self1.__state) > 0 then write(f,"  ",self.name,"initially(self)") 
  631.  
  632.  
  633.  
  634.  
  635.     if (__self1 := self.supers).__methods.size(__self1.__state) > 0 then { 
  636.     every (super <- (__self1 := self.supers).__methods.foreach(__self1.__state)) ~== self.name do { 
  637.         if (__self2 := ((__self1 := classes).__methods.lookup(__self1.__state,super))).__methods.has_initially(__self2.__state) then {
  638.         if /madeclone := 1 then {
  639.             write(f,"  clone := ",self.name,"__state()\n",
  640.             "  clone.__state := clone\n",
  641.             "  clone.__methods := ",self.name,"__oprec")
  642.         }
  643.         write(f,"  # inherited initialization from class ",super)
  644.         write(f,"    every i := 2 to *self do clone[i] := self[i]\n",
  645.             "    ",super,"initially(clone)")
  646.         every l := !self.ifields do {
  647.             if l.class == super then
  648.             write(f,"    self.",l.ident," := clone.",l.ident)
  649.         }
  650.         }
  651.     }
  652.     }
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.     write(f,"  return idol_object(self,",self.name,"__oprec)\n",
  660.         "end\n")
  661.  
  662.  
  663.  
  664.  
  665.     write(f,"procedure ",self.name,"initialize()")
  666.     writes(f,"  initial ",self.name,"__oprec := ",self.name,"__methods")
  667.     rv := "("
  668.     every s := (__self2 := ((__self1 := self.methods).__methods.foreach(__self1.__state))).__methods.name(__self2.__state) do { 
  669.       if *rv>1 then rv ||:= ","
  670.       rv ||:= self.name||"_"||s
  671.     }
  672.     every me := (__self1 := self.fields).__methods.foreachpublic(__self1.__state) do {
  673.       if *rv>1 then rv ||:= ","
  674.       rv ||:= self.name||"_"||me
  675.     }
  676.     every l := !self.imethods do {
  677.       if *rv>1 then rv ||:= ","
  678.       rv ||:= l.class||"_"||l.ident
  679.     }
  680.     write(f,rv,")\n","end")
  681.  
  682.  
  683.  
  684.     if (__self1 := self).__methods.has_initially(__self1.__state) then {
  685.     write(f,"procedure ",self.name,"initially(self)")
  686.     (__self1 := self.text).__methods.write(__self1.__state,f)
  687.     write(f,"end")
  688.     }
  689.  
  690.  
  691.  
  692.  
  693.     every me := (__self1 := self.fields).__methods.foreachpublic(__self1.__state) do {
  694.       write(f,"procedure ",self.name,"_",me,"(self)")
  695.       if \strict then {
  696.     write(f,"  if type(self.",me,") == ",
  697.         "(\"list\"|\"table\"|\"set\"|\"record\") then\n",
  698.         "    runerr(501,\"idol: scalar type expected\")")
  699.     }
  700.       write(f,"  return .(self.",me,")")
  701.       write(f,"end")
  702.       write(f)
  703.     }
  704.  
  705.     close(f)
  706.  
  707.   end
  708. procedure class_resolve(self)
  709. #line 492 "idol.iol"
  710.  
  711.  
  712.  
  713.     self.imethods := []
  714.     self.ifields := []
  715.     ipublics := []
  716.     addedfields := table()
  717.     addedmethods := table()
  718.     every sc := (__self1 := self.supers).__methods.foreach(__self1.__state) do { 
  719.     if /(superclass := (__self1 := classes).__methods.lookup(__self1.__state,sc)) then
  720.         halt("class/resolve: couldn't find superclass ",sc)
  721.     every superclassfield := (__self1 := superclass).__methods.foreachfield(__self1.__state) do {
  722.         if /(__self1 := self.fields).__methods.lookup(__self1.__state,superclassfield) &
  723.            /addedfields[superclassfield] then {
  724.         addedfields[superclassfield] := superclassfield
  725.         put ( self.ifields , classident(sc,superclassfield) )
  726.         if (__self1 := superclass).__methods.ispublic(__self1.__state,superclassfield) then
  727.             put( ipublics, classident(sc,superclassfield) )
  728.         } else if \strict then {
  729.         warn("class/resolve: '",sc,"' field '",superclassfield,
  730.              "' is redeclared in subclass ",self.name)
  731.         }
  732.     }
  733.     every superclassmethod := (__self2 := ((__self1 := superclass).__methods.foreachmethod(__self1.__state))).__methods.name(__self2.__state) do {
  734.         if /(__self1 := self.methods).__methods.lookup(__self1.__state,superclassmethod) &
  735.            /addedmethods[superclassmethod] then {
  736.         addedmethods[superclassmethod] := superclassmethod
  737.         put ( self.imethods, classident(sc,superclassmethod) )
  738.         }
  739.     }
  740.     every public := (!ipublics) do {
  741.         if public.class == sc then
  742.         put (self.imethods, classident(sc,public.ident))
  743.     }
  744.     }
  745.   end
  746. #
  747. # globals declared within the class
  748. #
  749. record classident(class,ident)
  750. record class__state(__state,__methods,supers,methods,text,imethods,ifields,glob,name,fields,tag)
  751. record class__methods(read,has_initially,ispublic,foreachmethod,foreachsuper,foreachfield,isvarg,transitive_closure,writedecl,writespec,writemethods,write,resolve,String,name,declaration)
  752. global class__oprec, declaration__oprec
  753. procedure class(supers,methods,text,imethods,ifields,glob,name,fields,tag)
  754. local self,clone
  755. initial {
  756.   if /class__oprec then classinitialize()
  757.   if /declaration__oprec then declarationinitialize()
  758.   class__oprec.declaration := declaration__oprec
  759.   }
  760.   self := class__state(&null,class__oprec,supers,methods,text,imethods,ifields,glob,name,fields,tag)
  761.   self.__state := self
  762.   clone := class__state()
  763.   clone.__state := clone
  764.   clone.__methods := class__oprec
  765.   # inherited initialization from class declaration
  766.     every i := 2 to *self do clone[i] := self[i]
  767.     declarationinitially(clone)
  768.     self.name := clone.name
  769.     self.fields := clone.fields
  770.     self.tag := clone.tag
  771.   return idol_object(self,class__oprec)
  772. end
  773.  
  774. procedure classinitialize()
  775.   initial class__oprec := class__methods(class_read,class_has_initially,class_ispublic,class_foreachmethod,class_foreachsuper,class_foreachfield,class_isvarg,class_transitive_closure,class_writedecl,class_writespec,class_writemethods,class_write,class_resolve,declaration_String,declaration_name)
  776. end
  777. procedure method_read(self,line,phase)
  778. #line 535 "idol.iol"
  779.     (__self1 := self).__methods.declaration.read(__self1.__state,line)
  780.     self.text := body()
  781.     if phase = 1 then
  782.       (__self1 := self.text).__methods.read(__self1.__state)
  783.   end
  784. procedure method_writedecl(self,f,s)
  785. #line 541 "idol.iol"
  786.     decl := (__self1 := self).__methods.String(__self1.__state)
  787.     if s == "method" then decl[1:upto(white,decl)] := "method"
  788.     else {
  789.     decl[1:upto(white,decl)] := "procedure"
  790.     if *(self.class)>0 then {
  791.         decl[upto(white,decl)] ||:= self.class||"_"
  792.         i := find("(",decl)
  793.         decl[i] ||:= "self" || (((decl[i+1] ~== ")"), ",") | "")
  794.     }
  795.     }
  796.     write(f,decl)
  797.   end
  798. procedure method_write(self,f)
  799. #line 554 "idol.iol"
  800.     if self.name ~== "initially" then
  801.     (__self1 := self).__methods.writedecl(__self1.__state,f,"procedure")
  802.     (__self1 := self.text).__methods.write(__self1.__state,f)
  803.     self.text := &null
  804.   end
  805. record method__state(__state,__methods,class,text,name,fields,tag)
  806. record method__methods(read,writedecl,write,String,name,declaration)
  807. global method__oprec, declaration__oprec
  808. procedure method(class,text,name,fields,tag)
  809. local self,clone
  810. initial {
  811.   if /method__oprec then methodinitialize()
  812.   if /declaration__oprec then declarationinitialize()
  813.   method__oprec.declaration := declaration__oprec
  814.   }
  815.   self := method__state(&null,method__oprec,class,text,name,fields,tag)
  816.   self.__state := self
  817.   clone := method__state()
  818.   clone.__state := clone
  819.   clone.__methods := method__oprec
  820.   # inherited initialization from class declaration
  821.     every i := 2 to *self do clone[i] := self[i]
  822.     declarationinitially(clone)
  823.     self.name := clone.name
  824.     self.fields := clone.fields
  825.     self.tag := clone.tag
  826.   return idol_object(self,method__oprec)
  827. end
  828.  
  829. procedure methodinitialize()
  830.   initial method__oprec := method__methods(method_read,method_writedecl,method_write,declaration_String,declaration_name)
  831. end
  832. procedure Table_size(self)
  833. #line 566 "idol.iol"
  834.     return (* \ self.t) | 0
  835.   end
  836. procedure Table_insert(self,x,key)
  837. #line 569 "idol.iol"
  838.     /self.t := table()
  839.     /key := x
  840.     if / (self.t[key]) := x then return
  841.   end
  842. procedure Table_lookup(self,key)
  843. #line 574 "idol.iol"
  844.     if t := \self.t then return t[key]
  845.     return
  846.   end
  847. procedure Table_foreach(self)
  848. #line 578 "idol.iol"
  849.     if t := \self.t then every suspend !self.t
  850.   end
  851. record Table__state(__state,__methods,t)
  852. record Table__methods(size,insert,lookup,foreach)
  853. global Table__oprec
  854. procedure Table(t)
  855. local self,clone
  856. initial {
  857.   if /Table__oprec then Tableinitialize()
  858.   }
  859.   self := Table__state(&null,Table__oprec,t)
  860.   self.__state := self
  861.   return idol_object(self,Table__oprec)
  862. end
  863.  
  864. procedure Tableinitialize()
  865.   initial Table__oprec := Table__methods(Table_size,Table_insert,Table_lookup,Table_foreach)
  866. end
  867. procedure taque_insert(self,x,key)
  868. #line 589 "idol.iol"
  869.     /self.l := []
  870.     if (__self1 := self).__methods.Table.insert(__self1.__state,x,key) then put(self.l,x)
  871.   end
  872. procedure taque_foreach(self)
  873. #line 593 "idol.iol"
  874.     if l := \self.l then every suspend !self.l
  875.   end
  876. procedure taque_insert_t(self,x,key)
  877. #line 596 "idol.iol"
  878.     (__self1 := self).__methods.Table.insert(__self1.__state,x,key)
  879.   end
  880. procedure taque_foreach_t(self)
  881. #line 599 "idol.iol"
  882.     suspend (__self1 := self).__methods.Table.foreach(__self1.__state)
  883.   end
  884. record taque__state(__state,__methods,l,t)
  885. record taque__methods(insert,foreach,insert_t,foreach_t,size,lookup,Table)
  886. global taque__oprec, Table__oprec
  887. procedure taque(l,t)
  888. local self,clone
  889. initial {
  890.   if /taque__oprec then taqueinitialize()
  891.   if /Table__oprec then Tableinitialize()
  892.   taque__oprec.Table := Table__oprec
  893.   }
  894.   self := taque__state(&null,taque__oprec,l,t)
  895.   self.__state := self
  896.   return idol_object(self,taque__oprec)
  897. end
  898.  
  899. procedure taqueinitialize()
  900.   initial taque__oprec := taque__methods(taque_insert,taque_foreach,taque_insert_t,taque_foreach_t,Table_size,Table_lookup)
  901. end
  902. procedure idTaque_parse(self,s)
  903. #line 609 "idol.iol"
  904.     s ? {
  905.       tab(many(white))
  906.       while name := tab(find(self.punc)) do {
  907.     (__self1 := self).__methods.insert(__self1.__state,trim(name))
  908.     move(1)
  909.     tab(many(white))
  910.       }
  911.       if any(nonwhite) then (__self1 := self).__methods.insert(__self1.__state,trim(tab(0)))
  912.     }
  913.     return
  914.   end
  915. procedure idTaque_String(self)
  916. #line 621 "idol.iol"
  917.     if /self.l then return ""
  918.     out := ""
  919.     every id := !self.l do out ||:= id||self.punc
  920.     return out[1:-1]
  921.   end
  922. record idTaque__state(__state,__methods,punc,l,t)
  923. record idTaque__methods(parse,String,insert,foreach,insert_t,foreach_t,size,lookup,taque,Table)
  924. global idTaque__oprec, taque__oprec, Table__oprec
  925. procedure idTaque(punc,l,t)
  926. local self,clone
  927. initial {
  928.   if /idTaque__oprec then idTaqueinitialize()
  929.   if /taque__oprec then taqueinitialize()
  930.   idTaque__oprec.taque := taque__oprec
  931.   if /Table__oprec then Tableinitialize()
  932.   idTaque__oprec.Table := Table__oprec
  933.   }
  934.   self := idTaque__state(&null,idTaque__oprec,punc,l,t)
  935.   self.__state := self
  936.   return idol_object(self,idTaque__oprec)
  937. end
  938.  
  939. procedure idTaqueinitialize()
  940.   initial idTaque__oprec := idTaque__methods(idTaque_parse,idTaque_String,taque_insert,taque_foreach,taque_insert_t,taque_foreach_t,Table_size,Table_lookup)
  941. end
  942. procedure argList_insert(self,s)
  943. #line 633 "idol.iol"
  944.     if \self.varg then halt("variable arg must be final")
  945.     if i := find("[",s) then {
  946.       if not (j := find("]",s)) then halt("variable arg expected ]")
  947.       s[i : j+1] := ""
  948.       self.varg := s := trim(s)
  949.     }
  950.     (__self1 := self).__methods.idTaque.insert(__self1.__state,s)
  951.   end
  952. procedure argList_isvarg(self,s)
  953. #line 642 "idol.iol"
  954.     if s == \self.varg then return s
  955.   end
  956. procedure argList_String(self)
  957. #line 645 "idol.iol"
  958.     return (__self1 := self).__methods.idTaque.String(__self1.__state) || ((\self.varg & "[]") | "")
  959.   end
  960. record argList__state(__state,__methods,varg,punc,l,t)
  961. record argList__methods(insert,isvarg,String,varg,parse,foreach,insert_t,foreach_t,size,lookup,idTaque,taque,Table)
  962. global argList__oprec, idTaque__oprec, taque__oprec, Table__oprec
  963. procedure argList(varg,punc,l,t)
  964. local self,clone
  965. initial {
  966.   if /argList__oprec then argListinitialize()
  967.   if /idTaque__oprec then idTaqueinitialize()
  968.   argList__oprec.idTaque := idTaque__oprec
  969.   if /taque__oprec then taqueinitialize()
  970.   argList__oprec.taque := taque__oprec
  971.   if /Table__oprec then Tableinitialize()
  972.   argList__oprec.Table := Table__oprec
  973.   }
  974.   self := argList__state(&null,argList__oprec,varg,punc,l,t)
  975.   self.__state := self
  976.   argListinitially(self)
  977.   return idol_object(self,argList__oprec)
  978. end
  979.  
  980. procedure argListinitialize()
  981.   initial argList__oprec := argList__methods(argList_insert,argList_isvarg,argList_String,argList_varg,idTaque_parse,taque_foreach,taque_insert_t,taque_foreach_t,Table_size,Table_lookup)
  982. end
  983. procedure argListinitially(self)
  984. #line 648 "idol.iol"
  985.   self.punc := ","
  986. end
  987. procedure argList_varg(self)
  988.   return .(self.varg)
  989. end
  990.  
  991. procedure classFields_String(self,s)
  992. #line 656 "idol.iol"
  993.     if *(rv := (__self1 := self).__methods.argList.String(__self1.__state)) = 0 then return ""
  994.     if /s | (s ~== "class") then return rv
  995.     if (__self1 := self).__methods.ispublic(__self1.__state,self.l[1]) then rv := "public "||rv
  996.     every field:=(__self1 := self).__methods.foreachpublic(__self1.__state) do rv[find(","||field,rv)] ||:= "public "
  997.     return rv
  998.   end
  999. procedure classFields_foreachpublic(self)
  1000. #line 663 "idol.iol"
  1001.     if \self.publics then every suspend !self.publics
  1002.   end
  1003. procedure classFields_ispublic(self,s)
  1004. #line 666 "idol.iol"
  1005.     if \self.publics then every suspend !self.publics == s
  1006.   end
  1007. procedure classFields_insert(self,s)
  1008. #line 669 "idol.iol"
  1009.     s ? {
  1010.       if ="public" & tab(many(white)) then {
  1011.     s := tab(0)
  1012.     /self.publics := []
  1013.     put(self.publics,s)
  1014.       }
  1015.     }
  1016.     (__self1 := self).__methods.argList.insert(__self1.__state,s)
  1017.   end
  1018. record classFields__state(__state,__methods,publics,varg,punc,l,t)
  1019. record classFields__methods(String,foreachpublic,ispublic,insert,isvarg,varg,parse,foreach,insert_t,foreach_t,size,lookup,argList,idTaque,taque,Table)
  1020. global classFields__oprec, argList__oprec, idTaque__oprec, taque__oprec, Table__oprec
  1021. procedure classFields(publics,varg,punc,l,t)
  1022. local self,clone
  1023. initial {
  1024.   if /classFields__oprec then classFieldsinitialize()
  1025.   if /argList__oprec then argListinitialize()
  1026.   classFields__oprec.argList := argList__oprec
  1027.   if /idTaque__oprec then idTaqueinitialize()
  1028.   classFields__oprec.idTaque := idTaque__oprec
  1029.   if /taque__oprec then taqueinitialize()
  1030.   classFields__oprec.taque := taque__oprec
  1031.   if /Table__oprec then Tableinitialize()
  1032.   classFields__oprec.Table := Table__oprec
  1033.   }
  1034.   self := classFields__state(&null,classFields__oprec,publics,varg,punc,l,t)
  1035.   self.__state := self
  1036.   classFieldsinitially(self)
  1037.   clone := classFields__state()
  1038.   clone.__state := clone
  1039.   clone.__methods := classFields__oprec
  1040.   # inherited initialization from class argList
  1041.     every i := 2 to *self do clone[i] := self[i]
  1042.     argListinitially(clone)
  1043.     self.varg := clone.varg
  1044.   return idol_object(self,classFields__oprec)
  1045. end
  1046.  
  1047. procedure classFieldsinitialize()
  1048.   initial classFields__oprec := classFields__methods(classFields_String,classFields_foreachpublic,classFields_ispublic,classFields_insert,argList_isvarg,argList_varg,idTaque_parse,taque_foreach,taque_insert_t,taque_foreach_t,Table_size,Table_lookup)
  1049. end
  1050. procedure classFieldsinitially(self)
  1051. #line 679 "idol.iol"
  1052.   self.punc := ","
  1053. end
  1054. #
  1055. # Idol: Icon-derived object language, version 8.0
  1056. #
  1057. # SYNOPSIS:
  1058. #
  1059. #   idol -install
  1060. #   idol prog[.iol] ... [-x args ]
  1061. #   prog
  1062. #
  1063. # FILES:
  1064. #
  1065. #   ./prog.iol                       : source file
  1066. #   ./prog.icn                     : Icon code for non-classes in prog.iol
  1067. #   ./idolcode.env/i_object.*      : Icon code for the universal object type
  1068. #   ./idolcode.env/classname.icn   : Icon files are generated for each class
  1069. #   ./idolcode.env/classname.u[12] : translated class files
  1070. #   ./idolcode.env/classname       : class specification/interface
  1071. #
  1072. # SEE ALSO:
  1073. #
  1074. #   "Programming in Idol: An Object Primer"
  1075. #   (U of Arizona Dept of CS Technical Report #90-10)
  1076. #   serves as user's guide and reference manual for Idol
  1077. #
  1078. ### Global variables
  1079. #
  1080. # FILES  : fin = input (.iol) file, fout = output (.icn) file
  1081. # CSETS  : alpha = identifier characters, nonalpha = everything else
  1082. #          alphadot = identifiers + '.'
  1083. #          white = whitespace, nonwhite = everything else
  1084. # TAQUES : classes in this module
  1085. # FLAGS  : comp if we should try to make an executable from args[1]
  1086. #          strict if we should generate paranoic encapsulation protection
  1087. #          loud if Idol should generate extra console messages
  1088. #          exec if we should run the result after translation
  1089. # LISTS  : links = names of external icon code to link to
  1090. #          imports = names of external classes to import
  1091. #          compiles = names of classes which need to be compiled
  1092. #
  1093. global fin,fout,fName,fLine,alpha,alphadot,white,nonwhite,nonalpha
  1094. global classes,comp,exec,strict,links,imports,loud,compiles,compatible,ct
  1095. global icontopt,tempenv
  1096.  
  1097. #
  1098. # initialize global variables
  1099. #
  1100. procedure initialize()
  1101.   loud     := 1
  1102.   comp     := 0
  1103.   alpha    := &ucase ++ &lcase ++ '_' ++ &digits
  1104.   nonalpha := &cset -- alpha
  1105.   alphadot := alpha ++ '.'
  1106.   white    := ' \t\f'
  1107.   nonwhite := &cset -- white
  1108.   classes  := taque()
  1109.   links    := []
  1110.   imports  := []
  1111.   compiles := []
  1112.   sysinitialize()
  1113. end
  1114.  
  1115. procedure main(args)
  1116.     initialize()
  1117.     if *args = 0 then write("usage: idol files...")
  1118.     else {
  1119.       if (!args ~== "-version") &
  1120.       not tryenvopen(filename("i_object",".u1")) then { 
  1121.           tempenv := 0
  1122.           install(args)
  1123.       }
  1124.       every i := 1 to *args do {
  1125.     if \exec then next            # after -x, args are for execution
  1126.     if args[i][1] == "-" then {
  1127.       case map(args[i]) of {
  1128.         "-c"   : {
  1129.         sysok := &null
  1130.         if comp = 0 then comp := -1        # don't make exe
  1131.         }
  1132.         "-ic"     : compatible := 1
  1133.         "-quiet"  : loud := &null
  1134.         "-strict" : strict := 1
  1135.         "-s"      : sysok := &null
  1136.         "-t"      : comp := -2                      # don't translate
  1137.         "-version": return write("Idol version 8.0 of 10/6/90") & 0
  1138.         "-x"      : exec := i
  1139.         default   : icontopt ||:= args[i] || " "
  1140.       }
  1141.         }
  1142.         else {
  1143.       \tempenv +:= 1
  1144.       if args[i] := fileroot(args[i],".cl") then {
  1145.           push(imports,args[i])
  1146.       }
  1147.       else if args[i] := fileroot(args[i],".icn") then {
  1148.           push(links,args[i])
  1149.           icont(" -c "||args[i])
  1150.       }
  1151.       else if args[i] := fileroot(args[i],".u1") then {
  1152.           push(links,args[i])
  1153.       }
  1154.       else if (args[i] := fileroot(args[i],".iol")) |
  1155.           tryopen(filename(args[i],".iol"),"r") then {
  1156.           /exe := i
  1157.           args[i] := fileroot(args[i],".iol")
  1158.           /fout := sysopen(filename(args[i],".icn"),"w")
  1159.           readinput(filename(args[i],".iol"),1)
  1160.           } else {
  1161.                   #
  1162.               # look for an appropriate .icn, .u1 or class file
  1163.               #
  1164.           if tryopen(filename(args[i],".icn"),"r") then {
  1165.               push(links,args[i])
  1166.               icont(" -c "||args[i])
  1167.           }
  1168.           else if tryopen(filename(args[i],".u1")) then {
  1169.               push(links,args[i])
  1170.           }
  1171.           else if tryenvopen(args[i]) then {
  1172.               push(imports,args[i])
  1173.           }
  1174.           }
  1175.       }
  1176.       }
  1177.       if gencode() then {
  1178.       close(\fout)
  1179.       if comp = 1 & (not makeexe(args,exe)) then
  1180.           stop("Idol exits after errors creating executable")
  1181.       } else {
  1182.       close(\fout)
  1183.       stop("Idol exits after errors translating")
  1184.       }
  1185.     }
  1186.     #
  1187.     # if we built an executable without separate compilation AND
  1188.     # there's no IDOLENV class environment AND
  1189.     # we had to install an environment then remove the environment
  1190.     #
  1191.     if (comp = 1) & (\tempenv < 2) & not getenv("IDOLENV") then uninstall()
  1192. end
  1193.  
  1194. #
  1195. # tell whether the character following s is within a quote or not
  1196. #
  1197. procedure notquote(s)
  1198.   outs := ""
  1199.   #
  1200.   # eliminate escaped quotes.
  1201.   # this is a bug for people who write code like \"hello"...
  1202.   s ? {
  1203.     while outs ||:= tab(find("\\")+1) do move(1)
  1204.     outs ||:= tab(0)
  1205.   }
  1206.   # see if every quote has a matching endquote
  1207.   outs ? {
  1208.     while s := tab(find("\""|"'")+1) do {
  1209.     if not tab(find(s[-1])+1) then fail
  1210.     }
  1211.   }
  1212.   return
  1213. end
  1214.  
  1215. #
  1216. # A contemplated addition: shorthand $.foo for self.foo ?
  1217. #
  1218. #procedure selfdot(line)
  1219. #  i := 1
  1220. #  while ((i := find("$.",line,i)) & notquote(line[1:i])) do line[i]:="self"
  1221. #end
  1222.  
  1223. #
  1224. # error/warning/message handling
  1225. #
  1226. procedure halt(args[])
  1227.   errsrc()
  1228.   every writes(&errout,!args)
  1229.   stop()
  1230. end
  1231.  
  1232. procedure warn(args[])
  1233.   errsrc()
  1234.   every writes(&errout,!args)
  1235.   write(&errout)
  1236. end
  1237.  
  1238. procedure errsrc()
  1239.   writes(&errout,"\"",\fName,"\", line ",\fLine,": Idol/")
  1240. end
  1241. #
  1242. # System-independent, but system related routines
  1243. #
  1244. procedure tryopen(file,mode)
  1245.   if f := open(file,mode) then return close(f)
  1246. end
  1247. procedure tryenvopen(file,mode)
  1248.   return tryopen(envpath(file),mode)
  1249. end
  1250. procedure sysopen(file,mode)
  1251.   if not (f := open(file,mode)) then
  1252.       halt("Couldn't open file ",file," for mode ",mode)
  1253.   return f
  1254. end
  1255. procedure envopen(file,mode)
  1256.   return sysopen(envpath(file),mode)
  1257. end
  1258. procedure writelink(s)
  1259.   write(fout,"link \"",s,"\"")
  1260. end
  1261. procedure icont(argstr,prefix)
  1262. static s
  1263. initial { s := (getenv("ICONT")|"icont") }
  1264.   return mysystem((\prefix|"") ||s||icontopt||argstr)
  1265. end
  1266.