############################################################################ # # File: lindcomp.icn # # Subject: Program to compile 0L-systems # # Author: Ralph E. Griswold # # Date: August 13, 1995 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # This program converts a 0L-system to an Icon program, which when # executed, produces the corresponding drawing. # ############################################################################ # # See also: linden.icn # ############################################################################ global procs procedure main() local line, sym, new, keyword, value, axiom, gener, angle, length local replace procs := table() # table of procedures to generate gener := 4 # defaults length := 5 angle := 90.0 while line := read() do line ? { if sym := tab(find("->")) then { move(2) replace := tab(0) procs[sym] := replace } else if keyword := tab(find(":")) then { move(1) value := tab(0) case keyword of { "axiom": axiom := value "gener": gener := integer(value) | stop("*** invalid generation specification") "angle": angle := real(value) | stop("*** invalid angle: ", line) "length": length := integer(value) | stop("*** invalid length: ", line) "name": &null # ignore name default: stop("*** invalid keyword: ", line) } } else stop("*** invalid specification: ", line) } # Write heading and main procedure write("link turtle") write() write("$define Generations ", gener) write("$define Angle ", angle) write("$define Length ", length) write() write("procedure main()") gencode(axiom, "Generations") write("end") write() # Produce drawing procedures. every sym := key(procs) do genproc(sym, procs[sym]) end procedure gencode(replace, arg) local sym every sym := !replace do { case sym of { "+": write(" TRight(Angle) # +") "-": write(" TLeft(Angle) # -") "[": write(" TSave() # [") "]": write(" TRestore() # ]") default: if \procs[sym] then write(" ", sym, "(", arg, ") # ", sym) } } return end procedure genproc(name, replace) write("procedure ", name, "(gener)") write(" if gener > 0 then {") gencode(replace, "gener - 1") write(" }") case name of { "F": write(" else TDraw(Length) # F") "f": write(" else TSkip(Length) # f") } write(" return") write("end") write() return end