############################################################################ # # File: exprfile.icn # # Subject: Procedures to produce programs on the fly # # Author: Ralph E. Griswold # # Date: August 5, 1997 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # exprfile(exp, link, ...) # produces a pipe to a program that writes all the # results generated by exp. The trailing arguments # name link files needed for the expression. # # exprfile() closes any previous pipe it opened # and deletes its temporary file. Therefore, # exprfile() cannot be used for multiple expression # pipes. # # If the expression fails to compile, the global # expr_error is set to 1; otherwise 0. # # exec_expr(expr_list, links[]) # generates the results of executing the expression # contained in the lists expr_list with the specified # links. # # plst2pstr(L) converts the list of Icon programs lines in L to a # string with separating newlines. # # pstr2plst(s) converts the string of Icon program lines (separated # by newlines) to a list of lines. # # ucode(file) produces a ucode file from the Icon program in file. # ############################################################################ # # Requires: system(), pipes, /tmp # ############################################################################ # # Links: io # ############################################################################ link io global expr_error procedure exprfile(exp, links[]) #: pipe for Icon expression local output static name, input expr_error := &null remove(\name) # remove former executable close(\input) # and close last pipe output := tempfile("expr", ".icn", "/tmp") image(output) ? { ="file(" name := tab(find(".icn")) } write(output, "invocable all") every write(output, "link ", image(!links)) write(output, "procedure main(args)") write(output, " every write(", exp, ")") write(output, "end") close(output) if system("icont -o " || name || " -s " || name || " >/dev/null 2>/dev/null") ~= 0 then { expr_error := 1 remove(name || ".icn") fail } remove(name || ".icn") # remove source code file # Return a pipe for the executable. Error messages are discarded. return input := open(name || " 2>/dev/null", "p") end procedure exec_expr(expr_list, links[]) #: execute expression in lists suspend !(exprfile ! push(links, plst2pstr(expr_list))) end procedure plst2pstr(L) #: convert program list to string local result result := "" every result ||:= !L || "\n" return result end procedure pstr2plst(s) #: convert program string to list local result result := [] s ? { while put(result, tab(upto('\n'))) do move(1) if not pos(0) then put(result, tab(0)) } return result end procedure ucode(file) #: create ucode file if system("icont -s -c " || file) ~= 0 then fail return end