OK. Here they all are. > > Sounds good. You have not attached fileIO.sml. Can you re-transmit your > > mail with this also attached so that I may just forward your original > > mail to the course mailing group? > > > > cheers, > > > > Subhashis Banerjee > > Professor > > Dept. Computer Science and Engineering > > Indian Institute of Technology, New Delhi 110016, INDIA > > > > Office: +91 11 26591288 > > Fax: +91 11 26581060, +91 11 26582283 > > Email: suban@cse.iitd.ernet.in > > URL: http://www.cse.iitd.ernet.in/~suban > > > > > > On 24/10/10 12:38 PM, sak@cse.iitd.ernet.in wrote: >> >> Dear Subhashis, >> >> >> >> After going through Abelson's notes, I have come to the conclusion that >> >> what CSL102 students would want to know in Standard ML is text-file I/O >> >> and conducting an online conversation. >> >> >> >> Here are 3 files attached to this mail: >> >> >> >> 1. stdio.sml: This captures the Pascal-like readln and writeln functions >> >> in SML and is defined as a structure "Stdio" which may >> >> be opened before use >> >> 2. readEvalLoop.sml: This uses the Stdio structure to run a simple >> >> example >> >> "read-eval-output-loop" using Stdio. It takes two >> >> functions as parameters >> >> eval: string -> string: which processes an input line and yields >> >> a >> >> response output string. >> >> cond: string -> bool: which decides whether to terminate the >> >> conversation >> >> 3. fileIO.sml: which gives various functions to read from text files. I >> >> have not modularized it because I didn't have the time. >> >> But >> >> it gives various functions for reading text files which >> >> takes >> >> a string parameter (the filename) and yields appropriate >> >> outputs. >> >> getclist: string -> char list: It takes a filename and yields a >> >> list >> >> of characters in the file >> >> (including >> >> newline characters) >> >> getclistNN: string -> char list: Same as above except that >> >> newline >> >> characters are removed. >> >> lick: string -> string list: Reads a text file an produces a >> >> list of >> >> lines (terminated by newline >> >> character) >> >> readLines: string -> string list: same as lick without newline >> >> characters >> >> >> >> I hope these are sufficient to program a conversation in SML. >> >> >> >> > > fileIO.sml (* Partly from the SML Basis LIbrary -- Gansner and Reppy *) (* get a list of characters from a file *) fun getclist (filename:string) = let val f = TextIO.getInstream(TextIO.openIn filename) fun loop (clist, f) = case TextIO.StreamIO.input1 f of SOME (c, f') => loop (c::clist, f') | NONE => (TextIO.StreamIO.closeIn; clist) in rev(loop ([], f)) end (* get list of chars except newline characters *) fun getclistNoNewline (filename:string) = let val f = TextIO.getInstream(TextIO.openIn filename) fun loopNoNewline (clist, f) = case TextIO.StreamIO.input1 f of SOME (#"\n", f') => loopNoNewline (clist, f') | SOME (c, f') => loopNoNewline (c::clist, f') | NONE => (TextIO.StreamIO.closeIn; clist) in rev(loopNoNewline ([], f)) end val getclistNN = getclistNoNewline (* Get the contents of an entire text file as a string *) fun slurp (filename:string) = let val f = TextIO.getInstream(TextIO.openIn filename) val (s, _) = TextIO.StreamIO.inputAll f in TextIO.StreamIO.closeIn; s end val readAll = slurp; (* Reading a chunk of characters at a time and outputting a list of strings *) fun bite (filename:string) = let val f = TextIO.getInstream(TextIO.openIn filename) fun loop (accum: string list, f) = case TextIO.StreamIO.input f of ("", f') => (TextIO.StreamIO.closeIn f'; accum) | (chunk, f') => loop (chunk::accum, f') (* esac *) in rev(loop ([], f)) end (* Reading by lines list of strings *) fun lick (filename:string) = let val f = TextIO.getInstream(TextIO.openIn filename) fun loop (accum: string list, f) = case TextIO.StreamIO.inputLine f of SOME(chunk, f') => loop (chunk::accum, f') | NONE => (TextIO.StreamIO.closeIn f; accum) (* esac *) in rev(loop ([], f)) end val readLines = chomp o lick (* The perl function chomp *) fun chomp1 s = let val charlist = rev (explode s) fun nibble [] = [] | nibble (#"\n"::l) = l | nibble l = l in implode (rev (nibble charlist)) end fun chomp (L: string list) = map chomp1 L; stdio.sml (* tty IO -- simulating Pascal's readln and writeln *) signature STDIO = sig val readln : unit -> string val writeln : string -> unit val write : string -> unit end structure Stdio : STDIO = struct fun chomp1 s = (* to remove newline character on reading *) let val charlist = rev (explode s) fun nibble [] = [] | nibble (#"\n"::l) = l | nibble l = l in implode (rev (nibble charlist)) end fun readln () = (case TextIO.inputLine(TextIO.stdIn) of SOME s => chomp1(s) | NONE => "" ) fun writeln (s) = print (s^"\n") val write = print end (* struct Stdio *) readEvalLoop.sml (* Let's try out "stdio.sml" with the standard read-eval-write loop for interactive systems. *) use "stdio.sml"; open Stdio; fun readEvalLoop (eval, cond) = let (* Need to delay the input till after the prompt "**" is output *) val inps = fn x:string => readln (); in ( (* prompt user to type something *) write ("** "); (* user prompt *) let val str = (inps "") (* read user input *) in if cond (str) then writeln ("End of conversation") else ( writeln (eval str); readEvalLoop (eval, cond)) end ) end; fun cond (s) = (s = "."); fun eval s = implode ((map Char.toUpper) (explode s)); (writeln ("\n\n\"**\" is the user prompt for input; To end type \".\" on a line by itself"); readEvalLoop (eval, cond));