home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1991-12-30 | 39.3 KB | 1,266 lines
global fin,fout,fName,fLine,alpha,alphadot,white,nonwhite,nonalpha global classes,comp,exec,strict,links,imports,loud,compiles,compatible,ct procedure gencode() #line 11 "idol.iol" if \loud then write("Class import/export:") every cl := (__self1 := classes).__methods.foreach_t(__self1.__state) do (__self2 := cl).__methods.writespec(__self2.__state) repeat { added := 0 every super:= ((__self2 := ((__self1 := classes).__methods.foreach_t(__self1.__state))).__methods.foreachsuper(__self2.__state) | !imports) do{ if /(__self1 := classes).__methods.lookup(__self1.__state,super) then { added := 1 fname := filename(super) readinput(envpath(fname),2) if /(__self1 := classes).__methods.lookup(__self1.__state,super) then halt("can't import class '",super,"'") writesublink(fname) } } if added = 0 then break } every (__self2 := ((__self1 := classes).__methods.foreach_t(__self1.__state))).__methods.transitive_closure(__self2.__state) if \loud then write("Generating code:") writesublink("i_object") every s := !links do writelink(s) write(fout) every out := (__self1 := classes).__methods.foreach(__self1.__state) do { name := filename((__self1 := out).__methods.name(__self1.__state)) (__self1 := out).__methods.write(__self1.__state) put(compiles,name) writesublink(name) } if *compiles>0 then return cdicont(compiles) else return end procedure readinput(name,phase,ct2) #line 686 "idol.iol" if \loud then write("\t",name) fName := name fLine := 0 fin := sysopen(name,"r") ct := \ct2 | constant() while line := readln("wrap") do { line ? { tab(many(white)) if ="class" then { decl := class() (__self1 := decl).__methods.read(__self1.__state,line,phase) if phase=1 then { (__self1 := decl).__methods.writemethods(__self1.__state) (__self1 := classes).__methods.insert(__self1.__state,decl,(__self2 := decl).__methods.name(__self2.__state)) } else (__self1 := classes).__methods.insert_t(__self1.__state,decl,(__self2 := decl).__methods.name(__self2.__state)) } else if ="procedure" then { if comp = 0 then comp := 1 decl := method("") (__self1 := decl).__methods.read(__self1.__state,line,phase) (__self1 := decl).__methods.write(__self1.__state,fout,"") } else if ="record" then { if comp = 0 then comp := 1 decl := declaration(line) (__self1 := decl).__methods.write(__self1.__state,fout,"") } else if ="global" then { if comp = 0 then comp := 1 decl := vardecl(line) (__self1 := decl).__methods.write(__self1.__state,fout,"") } else if ="const" then { (__self1 := ct).__methods.append(__self1.__state,constdcl(line) ) } else if ="method" then { halt("readinput: method outside class") } else if ="#include" then { savedFName := fName savedFLine := fLine savedFIn := fin tab(many(white)) readinput(tab(if ="\"" then find("\"") else many(nonwhite)), phase,ct) fName := savedFName fLine := savedFLine fin := savedFIn } } } close(fin) end procedure readln(wrap) #line 745 "idol.iol" count := 0 prefix := "" while /finished do { if not (line := read(fin)) then fail fLine +:= 1 if match("#include",line) then return line line[ 1(x<-find("#",line),notquote(line[1:x])) : 0] := "" line := trim(line,white) x := 1 while ((x := find("$",line,x)) & notquote(line[1:x])) do { z := line[x+1:0] ||" " case line[x+1] of { "(": line[x+:2] := "{" ")": line[x+:2] := "}" "<": line[x+:2] := "[" ">": line[x+:2] := "]" "!"|"*"|"@"|"?": { z ? { move(1) tab(many(white)) if not (id := tab(many(alphadot))) then { if not match("(") then halt("readln can't parse ",line) if not (id := tab(&pos<bal())) then halt("readln: cant bal ",&subject) } Op := case line[x+1] of { "@": "activate" "*": "size" "!": "foreach" "?": "random" } count +:= 1 line[x:0] := "(__self"||count||" := "||id||").__methods."|| Op||"(__self"||count||".__state)"||tab(0) } } "[": { z ? { if not (middle := tab((&pos<bal(&cset,'[',']'))-1)[2:0]) then halt("readln: can't bal([) ",&subject) tail := tab(0)|"" line := line[1:x]||"$index("||middle||")"||(tab(0)|"") } } default: { reverse(line[1:x])||" " ? { tab(many(white)) if not (id := reverse(tab(many(alphadot)))) then { if not match(")") then halt("readln: can't parse") if not (id := reverse(tab(&pos<bal(&cset,')','(')))) then halt("readln: can't bal ",&subject) } objlen := &pos-1 } count +:= 1 front := "(__self"||count||" := "||id||").__methods." back := "__self"||count||".__state" z ? { ="$" tab(many(white)) if not (methodname := tab(many(alphadot))) then halt("readln: expected a method name after $") tab(many(white)) methodname ||:= "(" if ="(" then { tab(many(white)) afterlp := &subject[&pos] } else { afterlp := ")" back ||:= ")" } methlen := &pos-1 } if line[x+1] == "$" then { c := if afterlp[1] ~== ")" then "" else "[]" methodname[-1] := "!(" back := "["||back||"]|||" } else { c := if (\afterlp)[1] == ")" then "" else "," } line[x-objlen : (((*line>=(x+methlen+1))|0)\1)] := front || methodname || back || c } } } if /wrap | (prefix==line=="") then finished := line else { prefix ||:= line || " " prefix ? { if ((*prefix = bal()) & (not find(",",prefix[-2]))) then finished := prefix[1:-1] } } } return (__self1 := ct).__methods.expand(__self1.__state,finished) end record idol_object(__state,__methods) procedure declaration_read(self,decl) #line 63 "idol.iol" decl ? ( (tab(many(white)) | "") , (self.tag := =("procedure"|"class"|"method"|"record")) , (tab(many(white)) | "") , (self.name := tab(many(alpha))) , (tab(find("(")+1)), (tab(many(white)) | "") , ((__self1 := (self.fields := classFields())).__methods.parse(__self1.__state,tab(find(")")))) ) | halt("declaration/read can't parse decl ",decl) end procedure declaration_write(self,f) #line 81 "idol.iol" write(f,(__self1 := self).__methods.String(__self1.__state)) end procedure declaration_String(self) #line 87 "idol.iol" return self.tag || " " || self.name || "(" || (__self1 := self.fields).__methods.String(__self1.__state) || ")" end record declaration__state(__state,__methods,name,fields,tag) record declaration__methods(read,write,String,name) global declaration__oprec procedure declaration(name,fields,tag) local self,clone initial { if /declaration__oprec then declarationinitialize() } self := declaration__state(&null,declaration__oprec,name,fields,tag) self.__state := self declarationinitially(self) return idol_object(self,declaration__oprec) end procedure declarationinitialize() initial declaration__oprec := declaration__methods(declaration_read,declaration_write,declaration_String,declaration_name) end procedure declarationinitially(self) #line 90 "idol.iol" if \self.name then (__self1 := self).__methods.read(__self1.__state,self.name) end procedure declaration_name(self) return .(self.name) end procedure vardecl_write(self,f) #line 98 "idol.iol" write(f,self.s) end record vardecl__state(__state,__methods,s) record vardecl__methods(write) global vardecl__oprec procedure vardecl(s) local self,clone initial { if /vardecl__oprec then vardeclinitialize() } self := vardecl__state(&null,vardecl__oprec,s) self.__state := self return idol_object(self,vardecl__oprec) end procedure vardeclinitialize() initial vardecl__oprec := vardecl__methods(vardecl_write) end procedure constant_expand(self,s) #line 107 "idol.iol" i := 1 while ((i <- find(k <- (__self1 := self).__methods.foreach(__self1.__state),s,i)) & ((i=1) | any(nonalpha,s[i-1])) & ((*s = i+*k-1) | any(nonalpha,s[i+*k])) & notquote(s[1:i])) do { val := \ (self.t[k]) | stop("internal error in expand") s[i +: *k] := val } return s end procedure constant_foreach(self) #line 122 "idol.iol" suspend key(self.t) end procedure constant_eval(self,s) #line 125 "idol.iol" if s2 := \ self.t[s] then return s2 end procedure constant_parse(self,s) #line 128 "idol.iol" s ? { k := trim(tab(find(":="))) | fail move(2) tab(many(white)) val := tab(0) | fail (*val > 0) | fail self.t [ k ] := val } return end procedure constant_append(self,cd) #line 139 "idol.iol" every s := (__self1 := cd).__methods.parse(__self1.__state)do (__self2 := self).__methods.parse(__self2.__state,s) end record constant__state(__state,__methods,t) record constant__methods(expand,foreach,eval,parse,append) global constant__oprec procedure constant(t) local self,clone initial { if /constant__oprec then constantinitialize() } self := constant__state(&null,constant__oprec,t) self.__state := self constantinitially(self) return idol_object(self,constant__oprec) end procedure constantinitialize() initial constant__oprec := constant__methods(constant_expand,constant_foreach,constant_eval,constant_parse,constant_append) end procedure constantinitially(self) #line 142 "idol.iol" self.t := table() end procedure constdcl_parse(self) #line 151 "idol.iol" self.s ? { tab(find("const")+6) tab(many(white)) while s2 := trim(tab(find(","))) do { suspend s2 move(1) tab(many(white)) } suspend trim(tab(0)) } end record constdcl__state(__state,__methods,s) record constdcl__methods(parse,write,vardecl) global constdcl__oprec, vardecl__oprec procedure constdcl(s) local self,clone initial { if /constdcl__oprec then constdclinitialize() if /vardecl__oprec then vardeclinitialize() constdcl__oprec.vardecl := vardecl__oprec } self := constdcl__state(&null,constdcl__oprec,s) self.__state := self return idol_object(self,constdcl__oprec) end procedure constdclinitialize() initial constdcl__oprec := constdcl__methods(constdcl_parse,vardecl_write) end procedure body_read(self) #line 170 "idol.iol" self.fn := fName self.ln := fLine self.text := [] while line := readln() do { put(self.text, line) line ? { tab(many(white)) if ="end" & &pos > *line then return else if =("local"|"static"|"initial") & any(nonalpha) then { self.ln +:= 1 pull(self.text) / (self.vars) := [] put(self.vars, line) } } } halt("body/read: eof inside a procedure/method definition") end procedure body_write(self,f) #line 189 "idol.iol" if \self.vars then every write(f,!self.vars) if \compatible then write(f," \\self := self.__state") if \self.ln then write(f,"#line ",self.ln + ((*\self.vars)|0)," \"",self.fn,"\"") every write(f,(__self1 := self).__methods.foreach(__self1.__state)) end procedure body_delete(self) #line 196 "idol.iol" return pull(self.text) end procedure body_size(self) #line 199 "idol.iol" return (*\ (self.text)) | 0 end procedure body_foreach(self) #line 202 "idol.iol" if t := \self.text then suspend !self.text end record body__state(__state,__methods,fn,ln,vars,text) record body__methods(read,write,delete,size,foreach) global body__oprec procedure body(fn,ln,vars,text) local self,clone initial { if /body__oprec then bodyinitialize() } self := body__state(&null,body__oprec,fn,ln,vars,text) self.__state := self return idol_object(self,body__oprec) end procedure bodyinitialize() initial body__oprec := body__methods(body_read,body_write,body_delete,body_size,body_foreach) end procedure class_read(self,line,phase) #line 214 "idol.iol" (__self1 := self).__methods.declaration.read(__self1.__state,line) self.supers := idTaque(":") (__self1 := self.supers).__methods.parse(__self1.__state,line[find(":",line)+1:find("(",line)] | "") self.methods:= taque() self.text := body() while line := readln("wrap") do { line ? { tab(many(white)) if ="initially" then { (__self1 := self.text).__methods.read(__self1.__state) if phase=2 then return (__self1 := self.text).__methods.delete(__self1.__state) return } else if ="method" then { decl := method(self.name) (__self1 := decl).__methods.read(__self1.__state,line,phase) (__self1 := self.methods).__methods.insert(__self1.__state,decl,(__self2 := decl).__methods.name(__self2.__state)) } else if ="end" then { return } else if ="procedure" then { decl := method("") (__self1 := decl).__methods.read(__self1.__state,line,phase) /self.glob := [] put(self.glob,decl) } else if ="global" then { /self.glob := [] put(self.glob,vardecl(line)) } else if ="record" then { /self.glob := [] put(self.glob,declaration(line)) } else if upto(nonwhite) then { halt("class/read expected declaration on: ",line) } } } halt("class/read syntax error: eof inside a class definition") end procedure class_has_initially(self) #line 258 "idol.iol" return (__self1 := self.text).__methods.size(__self1.__state) > 0 end procedure class_ispublic(self,fieldname) #line 261 "idol.iol" if (__self1 := self.fields).__methods.ispublic(__self1.__state,fieldname) then return fieldname end procedure class_foreachmethod(self) #line 264 "idol.iol" suspend (__self1 := self.methods).__methods.foreach(__self1.__state) end procedure class_foreachsuper(self) #line 267 "idol.iol" suspend (__self1 := self.supers).__methods.foreach(__self1.__state) end procedure class_foreachfield(self) #line 270 "idol.iol" suspend (__self1 := self.fields).__methods.foreach(__self1.__state) end procedure class_isvarg(self,s) #line 273 "idol.iol" if (__self1 := self.fields).__methods.isvarg(__self1.__state,s) then return s end procedure class_transitive_closure(self) #line 276 "idol.iol" count := (__self1 := self.supers).__methods.size(__self1.__state) while count > 0 do { added := taque() every sc := (__self1 := self.supers).__methods.foreach(__self1.__state) do { if /(super := (__self1 := classes).__methods.lookup(__self1.__state,sc)) then halt("class/transitive_closure: couldn't find superclass ",sc) every supersuper := (__self1 := super).__methods.foreachsuper(__self1.__state) do { if / (__self1 := self.supers).__methods.lookup(__self1.__state,supersuper) & /(__self1 := added).__methods.lookup(__self1.__state,supersuper) then { (__self1 := added).__methods.insert(__self1.__state,supersuper) } } } count := (__self1 := added).__methods.size(__self1.__state) every (__self1 := self.supers).__methods.insert(__self1.__state,(__self2 := added).__methods.foreach(__self2.__state)) } end procedure class_writedecl(self,f,s) #line 298 "idol.iol" writes(f, s," ",self.name) if s=="class" & ( *(supers := (__self1 := self.supers).__methods.String(__self1.__state)) > 0 ) then writes(f," : ",supers) writes(f,"(") rv := (__self1 := self.fields).__methods.String(__self1.__state,s) if *rv > 0 then rv ||:= "," if s~=="class" & *(\self.ifields)>0 then { every l := !self.ifields do rv ||:= l.ident || "," if /(superclass := (__self1 := classes).__methods.lookup(__self1.__state,l.class)) then halt("class/resolve: couldn't find superclass ",sc) if (__self1 := superclass).__methods.isvarg(__self1.__state,l.ident) then rv := rv[1:-1]||"[]," } writes(f,rv[1:-1]) write(f,,")") end procedure class_writespec(self,f) #line 314 "idol.iol" f := envopen(filename(self.name),"w") (__self1 := self).__methods.writedecl(__self1.__state,f,"class") every (__self2 := ((__self1 := self.methods).__methods.foreach(__self1.__state))).__methods.writedecl(__self2.__state,f,"method") if (__self1 := self).__methods.has_initially(__self1.__state) then write(f,"initially") write(f,"end") close(f) end procedure class_writemethods(self) #line 327 "idol.iol" f:= envopen(filename(self.name,".icn"),"w") every (__self2 := ((__self1 := self.methods).__methods.foreach(__self1.__state))).__methods.write(__self2.__state,f,self.name) if \self.glob & *self.glob>0 then { write(f,"#\n# globals declared within the class\n#") every i := 1 to *self.glob do (__self1 := (self.glob[i])).__methods.write(__self1.__state,f,"") } close(f) end procedure class_write(self) #line 341 "idol.iol" f:= envopen(filename(self.name,".icn"),"a") if /self.ifields then (__self1 := self).__methods.resolve(__self1.__state) writes(f,"record ",self.name,"__state(__state,__methods") rv := "," rv ||:= (__self1 := self.fields).__methods.idTaque.String(__self1.__state) if rv[-1] ~== "," then rv ||:= "," every s := (!self.ifields).ident do rv ||:= s || "," write(f,rv[1:-1],")") writes(f,"record ",self.name,"__methods(") rv := "" every s := (((__self2 := ((__self1 := self.methods).__methods.foreach(__self1.__state))).__methods.name(__self2.__state)) | (__self1 := self.fields).__methods.foreachpublic(__self1.__state) | (!self.imethods).ident | (__self1 := self.supers).__methods.foreach(__self1.__state)) do rv ||:= s || "," if *rv>0 then rv[-1] := "" write(f,rv,")") writes(f,"global ",self.name,"__oprec") every writes(f,", ", (__self1 := self.supers).__methods.foreach(__self1.__state),"__oprec") write(f) (__self1 := self).__methods.writedecl(__self1.__state,f,"procedure") write(f,"local self,clone") write(f,"initial {\n", " if /",self.name,"__oprec then ",self.name,"initialize()") if (__self1 := self.supers).__methods.size(__self1.__state) > 0 then every (super <- (__self1 := self.supers).__methods.foreach(__self1.__state)) ~== self.name do write(f," if /",super,"__oprec then ",super,"initialize()\n", " ",self.name,"__oprec.",super," := ", super,"__oprec") write(f," }") writes(f," self := ",self.name,"__state(&null,",self.name,"__oprec") every writes(f,",",(__self1 := self.fields).__methods.foreach(__self1.__state)) if \self.ifields then every writes(f,",",(!self.ifields).ident) write(f,")\n self.__state := self") if (__self1 := self.text).__methods.size(__self1.__state) > 0 then write(f," ",self.name,"initially(self)") if (__self1 := self.supers).__methods.size(__self1.__state) > 0 then { every (super <- (__self1 := self.supers).__methods.foreach(__self1.__state)) ~== self.name do { if (__self2 := ((__self1 := classes).__methods.lookup(__self1.__state,super))).__methods.has_initially(__self2.__state) then { if /madeclone := 1 then { write(f," clone := ",self.name,"__state()\n", " clone.__state := clone\n", " clone.__methods := ",self.name,"__oprec") } write(f," # inherited initialization from class ",super) write(f," every i := 2 to *self do clone[i] := self[i]\n", " ",super,"initially(clone)") every l := !self.ifields do { if l.class == super then write(f," self.",l.ident," := clone.",l.ident) } } } } write(f," return idol_object(self,",self.name,"__oprec)\n", "end\n") write(f,"procedure ",self.name,"initialize()") writes(f," initial ",self.name,"__oprec := ",self.name,"__methods") rv := "(" every s := (__self2 := ((__self1 := self.methods).__methods.foreach(__self1.__state))).__methods.name(__self2.__state) do { if *rv>1 then rv ||:= "," rv ||:= self.name||"_"||s } every me := (__self1 := self.fields).__methods.foreachpublic(__self1.__state) do { if *rv>1 then rv ||:= "," rv ||:= self.name||"_"||me } every l := !self.imethods do { if *rv>1 then rv ||:= "," rv ||:= l.class||"_"||l.ident } write(f,rv,")\n","end") if (__self1 := self).__methods.has_initially(__self1.__state) then { write(f,"procedure ",self.name,"initially(self)") (__self1 := self.text).__methods.write(__self1.__state,f) write(f,"end") } every me := (__self1 := self.fields).__methods.foreachpublic(__self1.__state) do { write(f,"procedure ",self.name,"_",me,"(self)") if \strict then { write(f," if type(self.",me,") == ", "(\"list\"|\"table\"|\"set\"|\"record\") then\n", " runerr(501,\"idol: scalar type expected\")") } write(f," return .(self.",me,")") write(f,"end") write(f) } close(f) end procedure class_resolve(self) #line 492 "idol.iol" self.imethods := [] self.ifields := [] ipublics := [] addedfields := table() addedmethods := table() every sc := (__self1 := self.supers).__methods.foreach(__self1.__state) do { if /(superclass := (__self1 := classes).__methods.lookup(__self1.__state,sc)) then halt("class/resolve: couldn't find superclass ",sc) every superclassfield := (__self1 := superclass).__methods.foreachfield(__self1.__state) do { if /(__self1 := self.fields).__methods.lookup(__self1.__state,superclassfield) & /addedfields[superclassfield] then { addedfields[superclassfield] := superclassfield put ( self.ifields , classident(sc,superclassfield) ) if (__self1 := superclass).__methods.ispublic(__self1.__state,superclassfield) then put( ipublics, classident(sc,superclassfield) ) } else if \strict then { warn("class/resolve: '",sc,"' field '",superclassfield, "' is redeclared in subclass ",self.name) } } every superclassmethod := (__self2 := ((__self1 := superclass).__methods.foreachmethod(__self1.__state))).__methods.name(__self2.__state) do { if /(__self1 := self.methods).__methods.lookup(__self1.__state,superclassmethod) & /addedmethods[superclassmethod] then { addedmethods[superclassmethod] := superclassmethod put ( self.imethods, classident(sc,superclassmethod) ) } } every public := (!ipublics) do { if public.class == sc then put (self.imethods, classident(sc,public.ident)) } } end # # globals declared within the class # record classident(class,ident) record class__state(__state,__methods,supers,methods,text,imethods,ifields,glob,name,fields,tag) record class__methods(read,has_initially,ispublic,foreachmethod,foreachsuper,foreachfield,isvarg,transitive_closure,writedecl,writespec,writemethods,write,resolve,String,name,declaration) global class__oprec, declaration__oprec procedure class(supers,methods,text,imethods,ifields,glob,name,fields,tag) local self,clone initial { if /class__oprec then classinitialize() if /declaration__oprec then declarationinitialize() class__oprec.declaration := declaration__oprec } self := class__state(&null,class__oprec,supers,methods,text,imethods,ifields,glob,name,fields,tag) self.__state := self clone := class__state() clone.__state := clone clone.__methods := class__oprec # inherited initialization from class declaration every i := 2 to *self do clone[i] := self[i] declarationinitially(clone) self.name := clone.name self.fields := clone.fields self.tag := clone.tag return idol_object(self,class__oprec) end procedure classinitialize() 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) end procedure method_read(self,line,phase) #line 535 "idol.iol" (__self1 := self).__methods.declaration.read(__self1.__state,line) self.text := body() if phase = 1 then (__self1 := self.text).__methods.read(__self1.__state) end procedure method_writedecl(self,f,s) #line 541 "idol.iol" decl := (__self1 := self).__methods.String(__self1.__state) if s == "method" then decl[1:upto(white,decl)] := "method" else { decl[1:upto(white,decl)] := "procedure" if *(self.class)>0 then { decl[upto(white,decl)] ||:= self.class||"_" i := find("(",decl) decl[i] ||:= "self" || (((decl[i+1] ~== ")"), ",") | "") } } write(f,decl) end procedure method_write(self,f) #line 554 "idol.iol" if self.name ~== "initially" then (__self1 := self).__methods.writedecl(__self1.__state,f,"procedure") (__self1 := self.text).__methods.write(__self1.__state,f) self.text := &null end record method__state(__state,__methods,class,text,name,fields,tag) record method__methods(read,writedecl,write,String,name,declaration) global method__oprec, declaration__oprec procedure method(class,text,name,fields,tag) local self,clone initial { if /method__oprec then methodinitialize() if /declaration__oprec then declarationinitialize() method__oprec.declaration := declaration__oprec } self := method__state(&null,method__oprec,class,text,name,fields,tag) self.__state := self clone := method__state() clone.__state := clone clone.__methods := method__oprec # inherited initialization from class declaration every i := 2 to *self do clone[i] := self[i] declarationinitially(clone) self.name := clone.name self.fields := clone.fields self.tag := clone.tag return idol_object(self,method__oprec) end procedure methodinitialize() initial method__oprec := method__methods(method_read,method_writedecl,method_write,declaration_String,declaration_name) end procedure Table_size(self) #line 566 "idol.iol" return (* \ self.t) | 0 end procedure Table_insert(self,x,key) #line 569 "idol.iol" /self.t := table() /key := x if / (self.t[key]) := x then return end procedure Table_lookup(self,key) #line 574 "idol.iol" if t := \self.t then return t[key] return end procedure Table_foreach(self) #line 578 "idol.iol" if t := \self.t then every suspend !self.t end record Table__state(__state,__methods,t) record Table__methods(size,insert,lookup,foreach) global Table__oprec procedure Table(t) local self,clone initial { if /Table__oprec then Tableinitialize() } self := Table__state(&null,Table__oprec,t) self.__state := self return idol_object(self,Table__oprec) end procedure Tableinitialize() initial Table__oprec := Table__methods(Table_size,Table_insert,Table_lookup,Table_foreach) end procedure taque_insert(self,x,key) #line 589 "idol.iol" /self.l := [] if (__self1 := self).__methods.Table.insert(__self1.__state,x,key) then put(self.l,x) end procedure taque_foreach(self) #line 593 "idol.iol" if l := \self.l then every suspend !self.l end procedure taque_insert_t(self,x,key) #line 596 "idol.iol" (__self1 := self).__methods.Table.insert(__self1.__state,x,key) end procedure taque_foreach_t(self) #line 599 "idol.iol" suspend (__self1 := self).__methods.Table.foreach(__self1.__state) end record taque__state(__state,__methods,l,t) record taque__methods(insert,foreach,insert_t,foreach_t,size,lookup,Table) global taque__oprec, Table__oprec procedure taque(l,t) local self,clone initial { if /taque__oprec then taqueinitialize() if /Table__oprec then Tableinitialize() taque__oprec.Table := Table__oprec } self := taque__state(&null,taque__oprec,l,t) self.__state := self return idol_object(self,taque__oprec) end procedure taqueinitialize() initial taque__oprec := taque__methods(taque_insert,taque_foreach,taque_insert_t,taque_foreach_t,Table_size,Table_lookup) end procedure idTaque_parse(self,s) #line 609 "idol.iol" s ? { tab(many(white)) while name := tab(find(self.punc)) do { (__self1 := self).__methods.insert(__self1.__state,trim(name)) move(1) tab(many(white)) } if any(nonwhite) then (__self1 := self).__methods.insert(__self1.__state,trim(tab(0))) } return end procedure idTaque_String(self) #line 621 "idol.iol" if /self.l then return "" out := "" every id := !self.l do out ||:= id||self.punc return out[1:-1] end record idTaque__state(__state,__methods,punc,l,t) record idTaque__methods(parse,String,insert,foreach,insert_t,foreach_t,size,lookup,taque,Table) global idTaque__oprec, taque__oprec, Table__oprec procedure idTaque(punc,l,t) local self,clone initial { if /idTaque__oprec then idTaqueinitialize() if /taque__oprec then taqueinitialize() idTaque__oprec.taque := taque__oprec if /Table__oprec then Tableinitialize() idTaque__oprec.Table := Table__oprec } self := idTaque__state(&null,idTaque__oprec,punc,l,t) self.__state := self return idol_object(self,idTaque__oprec) end procedure idTaqueinitialize() initial idTaque__oprec := idTaque__methods(idTaque_parse,idTaque_String,taque_insert,taque_foreach,taque_insert_t,taque_foreach_t,Table_size,Table_lookup) end procedure argList_insert(self,s) #line 633 "idol.iol" if \self.varg then halt("variable arg must be final") if i := find("[",s) then { if not (j := find("]",s)) then halt("variable arg expected ]") s[i : j+1] := "" self.varg := s := trim(s) } (__self1 := self).__methods.idTaque.insert(__self1.__state,s) end procedure argList_isvarg(self,s) #line 642 "idol.iol" if s == \self.varg then return s end procedure argList_String(self) #line 645 "idol.iol" return (__self1 := self).__methods.idTaque.String(__self1.__state) || ((\self.varg & "[]") | "") end record argList__state(__state,__methods,varg,punc,l,t) record argList__methods(insert,isvarg,String,varg,parse,foreach,insert_t,foreach_t,size,lookup,idTaque,taque,Table) global argList__oprec, idTaque__oprec, taque__oprec, Table__oprec procedure argList(varg,punc,l,t) local self,clone initial { if /argList__oprec then argListinitialize() if /idTaque__oprec then idTaqueinitialize() argList__oprec.idTaque := idTaque__oprec if /taque__oprec then taqueinitialize() argList__oprec.taque := taque__oprec if /Table__oprec then Tableinitialize() argList__oprec.Table := Table__oprec } self := argList__state(&null,argList__oprec,varg,punc,l,t) self.__state := self argListinitially(self) return idol_object(self,argList__oprec) end procedure argListinitialize() 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) end procedure argListinitially(self) #line 648 "idol.iol" self.punc := "," end procedure argList_varg(self) return .(self.varg) end procedure classFields_String(self,s) #line 656 "idol.iol" if *(rv := (__self1 := self).__methods.argList.String(__self1.__state)) = 0 then return "" if /s | (s ~== "class") then return rv if (__self1 := self).__methods.ispublic(__self1.__state,self.l[1]) then rv := "public "||rv every field:=(__self1 := self).__methods.foreachpublic(__self1.__state) do rv[find(","||field,rv)] ||:= "public " return rv end procedure classFields_foreachpublic(self) #line 663 "idol.iol" if \self.publics then every suspend !self.publics end procedure classFields_ispublic(self,s) #line 666 "idol.iol" if \self.publics then every suspend !self.publics == s end procedure classFields_insert(self,s) #line 669 "idol.iol" s ? { if ="public" & tab(many(white)) then { s := tab(0) /self.publics := [] put(self.publics,s) } } (__self1 := self).__methods.argList.insert(__self1.__state,s) end record classFields__state(__state,__methods,publics,varg,punc,l,t) record classFields__methods(String,foreachpublic,ispublic,insert,isvarg,varg,parse,foreach,insert_t,foreach_t,size,lookup,argList,idTaque,taque,Table) global classFields__oprec, argList__oprec, idTaque__oprec, taque__oprec, Table__oprec procedure classFields(publics,varg,punc,l,t) local self,clone initial { if /classFields__oprec then classFieldsinitialize() if /argList__oprec then argListinitialize() classFields__oprec.argList := argList__oprec if /idTaque__oprec then idTaqueinitialize() classFields__oprec.idTaque := idTaque__oprec if /taque__oprec then taqueinitialize() classFields__oprec.taque := taque__oprec if /Table__oprec then Tableinitialize() classFields__oprec.Table := Table__oprec } self := classFields__state(&null,classFields__oprec,publics,varg,punc,l,t) self.__state := self classFieldsinitially(self) clone := classFields__state() clone.__state := clone clone.__methods := classFields__oprec # inherited initialization from class argList every i := 2 to *self do clone[i] := self[i] argListinitially(clone) self.varg := clone.varg return idol_object(self,classFields__oprec) end procedure classFieldsinitialize() 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) end procedure classFieldsinitially(self) #line 679 "idol.iol" self.punc := "," end # # 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 getenv("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 := (getenv("ICONT")|"icont") } return mysystem((\prefix|"") ||s||icontopt||argstr) end