############################################################################ # # File: eventgen.icn # # Subject: Procedures for meta-variant code generation # # Author: Ralph E. Griswold # # Date: May 23, 1996 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # This program is designed to be linked with the output of the meta-variant # translator. # # It is designed to insert event-reporting code in Icon programs. # ############################################################################ # # Bug: The invocable declaration is not handled properly. "invocable all" # will get by, but some other forms produce syntax errors. The # problem is in the meta-variant translator itself, not in this # program. # ############################################################################ # # Links: strings # ############################################################################ global procname link strings # main() calls tp(), which is produced by the meta-variant # translation. procedure main() write("$define MAssign 1") write("$define MValue 2") write("procedure noop()") write("end") Mp() end procedure Alt(e1, e2) # e1 | e2 return cat("(", e1, "|", e2, ")") end procedure Apply(e1, e2) # e1 ! e2 return cat("(", e1, "!", e2, ")") end procedure Arg(e) return e end procedure Asgnop(op, e1, e2) # e1 op e2 return cat("2(event(MAssign, ", image(e1) , "), ", e1, " ", op, " ", e2, ", event(MValue, ", e1, "))") end procedure Augscan(e1, e2) # e1 ?:= e2 return cat("(", e1, " ?:= ", e2, ")") end procedure Bamper(e1, e2) # e1 & e2 return cat("(", e1, " & ", e2, ")") end procedure Binop(op, e1, e2) # e1 op e2 return cat("(", e1, " ", op, " ", e2, ")") end procedure Body(s[]) # procedure body if procname == "main" then write(" if &source === &main then event := noop") every write(!s) return end procedure Break(e) # break e return cat("break ", e) end procedure Case(e, clist) # case e of { caselist } return cat("case ", e, " of {", clist, "}") end procedure Cclause(e1, e2) # e1 : e2 return cat(e1, " : ", e2, "\n") end procedure Clist(e1, e2) # e1 ; e2 in case list return cat(e1, ";", e2) end procedure Clit(e) # 's' # return cat("'", e, "'") return image(e) end procedure Compound(es[]) # { e1; e2; ... } local result if *es = 0 then return "{}\n" result := "{\n" every result ||:= !es || "\n" return cat(result, "}\n") end procedure Create(e) # create e return cat("create ", e) end procedure Default(e) # default: e return cat("default: ", e) end procedure End() # end write("end") return end procedure Every(e) # every e return cat("every ", e) end procedure EveryDo(e1, e2) # every e1 do e2 return cat("every ", e1, " do ", e2) end procedure Fail() # fail return "fail" end procedure Field(e1, e2) # e . f return cat("(", e1, ".", e2, ")") end procedure Global(vs[]) # global v1, v2, ... local result result := "" every result ||:= !vs || ", " write("global ", result[1:-2]) return end procedure If(e1, e2) # if e1 then e2 return cat("if ", e1, " then ", e2) end procedure IfElse(e1, e2, e3) # if e1 then e2 else e3 return cat("if ", e1, " then ", e2, " else ", e3) end procedure Ilit(e) # i return e end procedure Initial(s) # initial e write("initial ", s) return end procedure Invocable(es[]) # invocable ... (problem) if \es then write("invocable all") else write("invocable ", es) return end procedure Invoke(e0, es[]) # e0(e1, e2, ...) local result if *es = 0 then return cat(e0, "()") result := "" every result ||:= !es || ", " return cat(e0, "(", result[1:-2], ")") end procedure Key(s) # &s return cat("&", s) end procedure Limit(e1, e2) # e1 \ e2 return cat("(", e1, "\\", e2, ")") end procedure Link(vs[]) # link "v1, v2, ..." local result result := "" every result ||:= !vs || ", " write("link ", result[1:-2]) return end procedure List(es[]) # [e1, e2, ... ] local result if *es = 0 then return "[]" result := "" every result ||:= !es || ", " return cat("[", result[1:-2], "]") end procedure Local(vs[]) # local v1, v2, ... local result result := "" every result ||:= !vs || ", " write("local ", result[1:-2]) return end procedure Next() # next return "next" end procedure Not(e) # not e return cat("not(", e, ")") end procedure Null() # &null return "" end procedure Paren(es[]) # (e1, e2, ... ) local result if *es = 0 then return "()" result := "" every result ||:= !es || ", " return cat("(", result[1:-2], ")") end procedure Pdco(e0, es[]) # e0{e1, e2, ... } local result if *es = 0 then return cat(e0, "{}") result := "" every result ||:= !es || ", " return cat(e0, "{", result[1:-2], "}") end procedure Proc(s, es[]) # procedure s(v1, v2, ...) local result, e if *es = 0 then write("procedure ", s, "()") result := "" every e := !es do if \e == "[]" then result[-2:0] := e || ", " else result ||:= (\e | "") || ", " write("procedure ", s, "(", result[1:-2], ")") procname := s # needed later return end procedure Record(s, es[]) # record s(v1, v2, ...) local result, field if *es = 0 then write("record ", s, "()") result := "" every field := !es do result ||:= (\field | "") || ", " write("record ", s, "(", result[1:-2], ")") return end procedure Repeat(e) # repeat e return cat("repeat ", e) end procedure Return(e) # return e return cat("return ", e) end procedure Rlit(e) return e end procedure Scan(e1, e2) # e1 ? e2 return cat("(", e1 , " ? ", e2, ")") end procedure Section(op, e1, e2, e3) # e1[e2 op e3] return cat(e1, "[", e2, op, e3, "]") end procedure Slit(s) # "s" return image(s) end procedure Static(ev[]) # static v1, v2, .. local result result := "" every result ||:= !ev || ", " write("static ", result[1:-2]) return end procedure Subscript(e1, e2) # e1[e2] return cat(e1, "[", e2, "]") end procedure Suspend(e) # suspend e return cat("suspend ", e) end procedure SuspendDo(e1, e2) # suspend e1 do e2 return cat("suspend ", e1, " do ", e2) end procedure To(e1, e2) # e1 to e2 return cat("(", e1, " to ", e2, ")") end procedure ToBy(e1, e2, e3) # e1 to e2 by e3 return cat("(", e1, " to ", e2, " by ", e3, ")") end procedure Repalt(e) # |e return cat("(|", e, ")") end procedure Unop(op, e) # op e return cat("(", op, e, ")") end procedure Until(e) # until e return cat("until ", e) end procedure UntilDo(e1, e2) # until e1 do e2 return cat("until ", e1, " do ", e2) end procedure Var(s) # v return s end procedure While(e) # while e return cat("while ", e) end procedure WhileDo(e1, e2) # while e1 do e2 return cat("while ", e1, " do ", e2) end