home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1997-04-25 | 6.5 KB | 212 lines | [TEXT/3PRM] |
- implementation module tmfile
-
-
- import StdInt, StdBool, StdChar, StdString, StdFile, StdArray, StdClass
- from deltaSystem import DirSeparator
- from tm import Turing, State, Tape, Transition, Head
-
-
- :: *Disk :== Files
-
- DummyTuring :== {transitions=[],tape=DummyTape,state=""}
- DummyTape :== {content="",head=0}
- DummyTrans :== {start="",sigma=' ',end="",move=' '}
-
-
-
- // Write a Turing Machine to a file.
- WriteTuringToFile :: Turing !String !Disk -> (!Bool,!Disk)
- WriteTuringToFile turing fname disk
- # (success,file,disk) = fopen fname FWriteText disk
- | not success = (False,disk)
- # file = WritePartsToFile turing file
- (_,disk) = fclose file disk
- | otherwise = (True, disk)
- where
- WritePartsToFile :: !Turing !*File -> *File
- WritePartsToFile {transitions,tape} file
- # file = WriteTransitionsToFile transitions file
- file = WriteTapeToFile tape file
- = file
- where
- WriteTransitionsToFile :: ![Transition] !*File -> *File
- WriteTransitionsToFile [trans:rest] file
- # file = WriteTransitionToFile trans file
- file = WriteTransitionsToFile rest file
- = file
- where
- WriteTransitionToFile :: !Transition !*File -> *File
- WriteTransitionToFile {start,sigma,end,move} file
- # file = fwrites (String4 start) file
- file = fwritec ' ' file
- file = fwritec sigma file
- file = fwrites " -> " file
- file = fwrites (String4 end) file
- file = fwritec ' ' file
- file = fwritec move file
- file = fwritec '\n' file
- = file
- where
- String4 :: !String -> String
- String4 str
- | len>=4 = str%(0,3)
- | otherwise = str+++" "%(0,3-len)
- where
- len = size str
- WriteTransitionsToFile _ file
- = fwrites "\nTape:\n" file
-
- WriteTapeToFile :: !Tape !*File -> *File
- WriteTapeToFile {content} file
- = fwrites (LimitContents content) file
- where
- LimitContents :: !String -> String
- LimitContents cont
- | first>last = "##"
- | fgood && lgood = cont % (first-1, last+1)
- | lgood = cont % (0, last+1)
- | fgood = cont % (first-1, lmin1)
- | otherwise = cont
- where
- first = FirstNonEmpty 0 lmin1 cont
- last = LastNonEmpty lmin1 cont
- fgood = first>0
- lgood = last<lmin1
- lmin1 = size cont-1
-
- FirstNonEmpty :: !Int !Int String -> Int
- FirstNonEmpty i len str
- | i>len || str.[i]<>'#' = i
- | otherwise = FirstNonEmpty (i+1) len str
-
- LastNonEmpty :: !Int String -> Int
- LastNonEmpty i str
- | i<0 || str.[i]<>'#' = i
- | otherwise = LastNonEmpty (i-1) str
-
-
-
- // Read a Turing Machine from a file
- ReadTuring :: !String !Disk -> (!Int,!Turing,!Disk)
- ReadTuring filename disk
- # (success,file,disk) = fopen filename FReadText disk
- | not success = (-2,DummyTuring,disk)
- # (linenr,turing,file)= ReadTuringFile file
- (_,disk) = fclose file disk
- | otherwise = (linenr,turing,disk)
- where
- ReadTuringFile :: !*File -> (!Int,!Turing,!*File)
- ReadTuringFile file
- # (linenr,trs,file) = ReadTransitions 1 file
- | linenr<>0 = (linenr, DummyTuring, file)
- # (cont,file) = ReadTape file
- | otherwise = (linenr, {transitions=trs,tape={content=cont,head=size cont-1},state="S"},file)
- where
- ReadTape :: !*File -> (!String,!*File)
- ReadTape file
- # (line,file) = freadline file
- | line=="" = ("##",file)
- # first = line.[0]
- | first<>'|' && first<>'\n' = (ParseTape 0 (size line) line,file)
- | otherwise = ReadTape file
- where
- ParseTape :: !Int !Int !String -> String
- ParseTape i l s
- | i>=l = s
- | c==' ' || c=='|' || c=='\n' = s%(0,i-1)
- | otherwise = ParseTape (i+1) l s
- where
- c = s.[i]
-
- ReadTransitions :: Int !*File -> (!Int,![Transition],!*File)
- ReadTransitions linenr file
- | sfend file = (-1,[],file)
- # (line,file) = freadline file
- (error,tape,comment,trans) = ParseLine line
- | error = (linenr,[],file)
- | tape = (0,[],file)
- # (lnr,rest,file) = ReadTransitions (linenr+1) file
- | comment = (lnr,rest,file)
- | otherwise = (lnr,[trans:rest],file)
- where
- ParseLine :: !String -> (!Bool,!Bool,!Bool,!Transition)
- ParseLine s
- | s%(0,3)=="Tape" = (False,True, False,DummyTrans)
- | first=='|' || first=='\n' = (False,False,True, DummyTrans)
- | otherwise = (error,False,False,trans)
- where
- (error,trans) = ParseTransition s
- first = s.[0]
-
- ParseTransition :: !String -> (!Bool,!Transition)
- ParseTransition s
- # i = SkipLayout 0 len s
- (error,start,i) = ParseState i i len s
- | error = (True, DummyTrans)
- # (error,i) = DemandLayout i i len s
- | error = (True, DummyTrans)
- # (error,sigma,i) = ParseHead i len s
- | error = (True, DummyTrans)
- # (error,i) = DemandLayout i i len s
- | error = (True, DummyTrans)
- # (error,end,i) = ParseState i i len s
- | error = (True, DummyTrans)
- # (error,i) = DemandLayout i i len s
- | error = (True, DummyTrans)
- # (error,move,i) = ParseHead i len s
- | error = (True, DummyTrans)
- | otherwise = (False,{start=start,sigma=sigma,end=end,move=move})
- where
- len = size s
-
- ParseState :: Int !Int !Int String -> (!Bool,!State,!Int)
- ParseState b i l s
- | i>=l || i-b>4 || (is_layout && i==b) = (True,"",0)
- | is_layout && i>b = (False, s%(b,i-1),i)
- | otherwise = ParseState b (i+1) l s
- where
- is_layout = IsLayoutChar i s
-
- ParseHead :: !Int !Int String -> (!Bool,!Char,!Int)
- ParseHead i l s
- | i>=l || IsLayoutChar i s = (True,' ',0)
- | otherwise = (False,s.[i],i+1)
-
- DemandLayout :: Int !Int !Int String -> (!Bool,!Int)
- DemandLayout b i l s
- | i>=l || (is_no_layout && i==b) = (True ,0)
- | is_no_layout && i>b = (False,i)
- | otherwise = DemandLayout b (i+1) l s
- where
- is_no_layout = not (IsLayoutChar i s)
-
- SkipLayout :: !Int !Int String -> Int
- SkipLayout i l s
- | i>=l = i-1
- | IsLayoutChar i s = SkipLayout (i+1) l s
- | otherwise = i
-
- IsLayoutChar :: !Int !String -> Bool
- IsLayoutChar i s
- = c==' ' || c=='(' || c==')' || c=='-' || c=='>' ||
- c==',' || c=='.' || c=='[' || c==']' || c=='{' ||
- c=='}' || c==' ' || c==':'
- where
- c = s.[i]
-
-
- // Given a pathname, return the filename (remove the path).
- RemovePath :: !String -> String
- RemovePath s
- | found = s%(position+1,length_min_1)
- | otherwise = s
- where
- (found,position) = LastColon s length_min_1
- length_min_1 = size s-1
-
- LastColon :: String !Int -> (!Bool,!Int)
- LastColon s i
- | i<=0 = (False,0)
- | DirSeparator==s.[i] = (True,i)
- | otherwise = LastColon s (i-1)
-