\documentclass{article} \usepackage{open-axiom} \begin{document} \title{src/algebra files.spad} \author{Stephen M. Watt, Victor Miller, Barry Trager, Gabriel Dos~Reis} \maketitle \begin{abstract} \end{abstract} \tableofcontents \eject \section{A domain for IO mode} <>= )abbrev domain IOMODE IOMode ++ Author: Gabriel Dos Reis ++ Date Created: September 30, 2008 ++ Date Last Updated: September 30, 2008 ++ Basic Operations: inputIOMode, outputIoMode, bothWayIOMode ++ Description: ++ This domain provides constants to describe directions of ++ IO conduits (file, etc) mode of operations. IOMode(): Public == Private where Public == SetCategory with input: % ++ \spad{input} indicates that an IO conduit is for input. output: % ++ \spad{output} indicates that an IO conduit is for output bothWays: % ++ \spad{bothWays} indicates that an IO conduit is for both input and output. closed: % ++ \spad{closed} indicates that the IO conduit has been closed. Private == add input == _$InputIOMode$Foreign(Builtin) output == _$OutputIOMode$Foreign(Builtin) bothWays == _$BothWaysIOMode$Foreign(Builtin) closed == _$ClosedIOMode$Foreign(Builtin) x = y == %peq(x,y)$Foreign(Builtin) coerce m == m = input => outputForm 'input m = output => outputForm 'output m = closed => outputForm 'closed outputForm 'bothWays @ \section{category FILECAT FileCategory} <>= )abbrev category FILECAT FileCategory ++ Author: Stephen M. Watt, Victor Miller ++ Date Created: ++ Date Last Updated: June 4, 1991 ++ Basic Operations: ++ Related Domains: File ++ Also See: ++ AMS Classifications: ++ Keywords: ++ Examples: ++ References: ++ Description: ++ This category provides an interface to operate on files in the ++ computer's file system. The precise method of naming files ++ is determined by the Name parameter. The type of the contents ++ of the file is determined by S. FileCategory(Name, S): Category == FCdefinition where Name: SetCategory S: SetCategory IOMode ==> String -- Union("input", "output", "closed") FCdefinition == SetCategory with open: Name -> % ++ open(s) returns the file s open for input. open: (Name, IOMode) -> % ++ open(s,mode) returns a file s open for operation in the ++ indicated mode: "input" or "output". reopen!: (%, IOMode) -> % ++ reopen!(f,mode) returns a file f reopened for operation in the ++ indicated mode: "input" or "output". ++ \spad{reopen!(f,"input")} will reopen the file f for input. close!: % -> % ++ close!(f) returns the file f closed to input and output. name: % -> Name ++ name(f) returns the external name of the file f. iomode: % -> IOMode ++ iomode(f) returns the status of the file f. The input/output ++ status of f may be "input", "output" or "closed" mode. read!: % -> S ++ read!(f) extracts a value from file f. The state of f is ++ modified so a subsequent call to \spadfun{read!} will return ++ the next element. write!: (%,S) -> S ++ write!(f,s) puts the value s into the file f. ++ The state of f is modified so subsequents call to \spad{write!} ++ will append one after another. @ \section{domain FILE File} <>= )abbrev domain FILE File ++ Author: Stephen M. Watt, Victor Miller ++ Date Created: 1984 ++ Date Last Updated: June 4, 1991 ++ Basic Operations: ++ Related Domains: ++ Also See: ++ AMS Classifications: ++ Keywords: ++ Examples: ++ References: ++ Description: ++ This domain provides a basic model of files to save arbitrary values. ++ The operations provide sequential access to the contents. File(S:SetCategory): FileCategory(FileName, S) with readIfCan!: % -> Union(S, "failed") ++ readIfCan!(f) returns a value from the file f, if possible. ++ If f is not open for reading, or if f is at the end of file ++ then \spad{"failed"} is the result. == add FileState ==> SExpression IOMode ==> String Rep:=Record(fileName: FileName, _ fileState: FileState, _ fileIOmode: IOMode) defstream(fn: FileName, mode: IOMode): FileState == mode = "input" => not readable? fn => error ["File is not readable", fn] MAKE_-INSTREAM(fn::String)$Lisp mode = "output" => not writable? fn => error ["File is not writable", fn] MAKE_-OUTSTREAM(fn::String)$Lisp error ["IO mode must be input or output", mode] f1 = f2 == f1.fileName = f2.fileName coerce(f: %): OutputForm == f.fileName::OutputForm open fname == open(fname, "input") open(fname, mode) == fstream := defstream(fname, mode) [fname, fstream, mode] reopen!(f, mode) == fname := f.fileName f.fileState := defstream(fname, mode) f.fileIOmode:= mode f close! f == SHUT(f.fileState)$Lisp f.fileIOmode := "closed" f name f == f.fileName iomode f == f.fileIOmode read! f == f.fileIOmode ~= "input" => error "File not in read state" x: Maybe S := readExpr(f.fileState)$Foreign(Builtin) x case nothing => error "End of file" x@S readIfCan! f == f.fileIOmode ~= "input" => error "File not in read state" x: Maybe S := readExpr(f.fileState)$Foreign(Builtin) x case nothing => "failed" x@S write!(f, x) == f.fileIOmode ~= "output" => error "File not in write state" z := PRINT_-FULL(x, f.fileState)$Lisp %writeNewline(f.fileState)$Foreign(Builtin) x @ \section{domain TEXTFILE TextFile} <>= )abbrev domain TEXTFILE TextFile ++ Author: Stephen M. Watt ++ Date Created: 1985 ++ Date Last Updated: June 4, 1991 ++ Basic Operations: writeLine! readLine! readLineIfCan! readIfCan! endOfFile? ++ Related Constructors: ++ Also See: ++ AMS Classifications: ++ Keywords: ++ References: ++ Description: ++ This domain provides an implementation of text files. Text is stored ++ in these files using the native character set of the computer. TextFile: Cat == Def where StreamName ==> Union(FileName, "console") Cat == FileCategory(FileName, String) with writeLine!: (%, String) -> String ++ writeLine!(f,s) writes the contents of the string s ++ and finishes the current line in the file f. ++ The value of s is returned. writeLine!: % -> String ++ writeLine!(f) finishes the current line in the file f. ++ An empty string is returned. The call \spad{writeLine!(f)} is ++ equivalent to \spad{writeLine!(f,"")}. readLine!: % -> String ++ readLine!(f) returns a string of the contents of a line from ++ the file f. readLineIfCan!: % -> Union(String, "failed") ++ readLineIfCan!(f) returns a string of the contents of a line from ++ file f, if possible. If f is not readable or if it is ++ positioned at the end of file, then \spad{"failed"} is returned. readIfCan!: % -> Union(String, "failed") ++ readIfCan!(f) returns a string of the contents of a line from ++ file f, if possible. If f is not readable or if it is ++ positioned at the end of file, then \spad{"failed"} is returned. endOfFile?: % -> Boolean ++ endOfFile?(f) tests whether the file f is positioned after the ++ end of all text. If the file is open for output, then ++ this test is always true. Def == File(String) add FileState ==> SExpression Rep := Record(fileName: FileName, _ fileState: FileState, _ fileIOmode: String) read! f == readLine! f readIfCan! f == readLineIfCan! f readLine! f == f.fileIOmode ~= "input" => error "File not in read state" s: Maybe String := readLine(f.fileState)$Foreign(Builtin) s case String => s error "End of file" readLineIfCan! f == f.fileIOmode ~= "input" => error "File not in read state" s: Maybe String := readLine(f.fileState)$Foreign(Builtin) s case String => s@String "failed" write!(f, x) == f.fileIOmode ~= "output" => error "File not in write state" %writeString(x, f.fileState)$Foreign(Builtin) x writeLine! f == f.fileIOmode ~= "output" => error "File not in write state" %writeNewline(f.fileState)$Foreign(Builtin) "" writeLine!(f, x) == f.fileIOmode ~= "output" => error "File not in write state" %writeLine(x,f.fileState)$Foreign(Builtin) x endOfFile? f == f.fileIOmode = "output" => false eof?(f.fileState)$Lisp @ \section{domain KAFILE KeyedAccessFile} <>= )abbrev domain KAFILE KeyedAccessFile ++ Author: Stephen M. Watt ++ Date Created: 1985 ++ Date Last Updated: June 4, 1991 ++ Basic Operations: ++ Related Domains: ++ Also See: ++ AMS Classifications: ++ Keywords: ++ Examples: ++ References: ++ Description: ++ This domain allows a random access file to be viewed both as a table ++ and as a file object. KeyedAccessFile(Entry): KAFcategory == KAFcapsule where Name ==> FileName Key ==> String Entry : SetCategory KAFcategory == Join(FileCategory(Name, Record(key: Key, entry: Entry)), TableAggregate(Key, Entry)) with pack!: % -> % ++ pack!(f) reorganizes the file f on disk to recover ++ unused space. KAFcapsule == add CLASS ==> 131 -- an arbitrary no. greater than 127 FileState ==> SExpression IOMode ==> String Cons:= Record(car: SExpression, cdr: SExpression) Rep := Record(fileName: Name, _ fileState: FileState, _ fileIOmode: IOMode) defstream(fn: Name, mode: IOMode): FileState == mode = "input" => not readable? fn => error ["File is not readable", fn] RDEFINSTREAM(fn::String)$Lisp mode = "output" => not writable? fn => error ["File is not writable", fn] RDEFOUTSTREAM(fn::String)$Lisp error ["IO mode must be input or output", mode] ---- From Set ---- f1 = f2 == f1.fileName = f2.fileName coerce(f: %): OutputForm == f.fileName::OutputForm ---- From FileCategory ---- open fname == open(fname, "either") open(fname, mode) == mode = "either" => exists? fname => open(fname, "input") writable? fname => reopen!(open(fname, "output"), "input") error "File does not exist and cannot be created" [fname, defstream(fname, mode), mode] reopen!(f, mode) == close! f if mode ~= "closed" then f.fileState := defstream(f.fileName, mode) f.fileIOmode := mode f close! f == if f.fileIOmode ~= "closed" then RSHUT(f.fileState)$Lisp f.fileIOmode := "closed" f read! f == f.fileIOmode ~= "input" => error ["File not in read state",f] ks: List Symbol := RKEYIDS(f.fileName)$Lisp null ks => error ["Attempt to read empty file", f] ix := random(#ks)$Integer k: String := string(ks.ix) [k, SPADRREAD(k, f.fileState)$Lisp] write!(f, pr) == f.fileIOmode ~= "output" => error ["File not in write state",f] SPADRWRITE(pr.key, pr.entry, f.fileState)$Lisp pr name f == f.fileName iomode f == f.fileIOmode ---- From TableAggregate ---- empty() == fn := new("", "kaf", "sdata")$Name open fn keys f == close! f l: List SExpression := RKEYIDS(f.fileName)$Lisp [PNAME(n)$Lisp for n in l] # f == # keys f elt(f,k) == reopen!(f, "input") SPADRREAD(k, f.fileState)$Lisp setelt(f,k,e) == -- Leaves f in a safe, closed state. For speed use "write". reopen!(f, "output") try write!(f, [k,e]) finally close! f e search(k,f) == not member?(k, keys f) => "failed" -- can't trap RREAD error reopen!(f, "input") (SPADRREAD(k, f.fileState)$Lisp)@Entry remove!(k:String,f:%) == result := search(k,f) result case "failed" => result close! f RDROPITEMS(NAMESTRING(f.fileName)$Lisp, LIST(k)$Lisp)$Lisp result pack! f == close! f RPACKFILE(f.fileName)$Lisp f @ \section{domain LIB Library} <>= )abbrev domain LIB Library ++ Author: Stephen M. Watt ++ Date Created: 1985 ++ Date Last Updated: June 4, 1991 ++ Basic Operations: ++ Related Domains: KeyedAccessFile ++ Also See: ++ AMS Classifications: ++ Keywords: ++ Examples: ++ References: ++ Description: ++ This domain provides a simple way to save values in files. Library(): Join(TableAggregate(String, Any),Eltable(Symbol,Any)) with library: FileName -> % ++ library(ln) creates a new library file. pack!: % -> % ++ pack!(f) reorganizes the file f on disk to recover ++ unused space. setelt : (%, Symbol, Any) -> Any ++ \spad{lib.k := v} saves the value \spad{v} in the library ++ \spad{lib}. It can later be extracted using the key \spad{k}. == KeyedAccessFile(Any) add library f == per open f elt(f:%,v:Symbol) == elt(rep f, string v) setelt(f:%, v:Symbol, val:Any) == setelt(rep f, string v, val) @ \section{License} <>= --Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. --All rights reserved. -- --Redistribution and use in source and binary forms, with or without --modification, are permitted provided that the following conditions are --met: -- -- - Redistributions of source code must retain the above copyright -- notice, this list of conditions and the following disclaimer. -- -- - Redistributions in binary form must reproduce the above copyright -- notice, this list of conditions and the following disclaimer in -- the documentation and/or other materials provided with the -- distribution. -- -- - Neither the name of The Numerical ALgorithms Group Ltd. nor the -- names of its contributors may be used to endorse or promote products -- derived from this software without specific prior written permission. -- --THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS --IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER --OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, --EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, --PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR --PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING --NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS --SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @ <<*>>= <> <> <> <> <> <> <> @ \eject \begin{thebibliography}{99} \bibitem{1} nothing \end{thebibliography} \end{document}