So after reading Programming in Scala and a few other books, I tried my hand at making a Universal Turing Machine Simulator. I tried my best to make it as idiomatic, functional (as in the paradigm, not usability) and simple(?) as possible.
Notes about formatting and scope of review:
This was run through the Idea 2016.1 formatter for Scala set on default.
The TuringMain
object, is, as usual, not really up for review, however, any logic or organization comments will be appreciated.
Usage:
The project is hosted here, grab the latest release from there to run it. The documentation is hosted here. Basically, this code really overuses Vector
s instead of List
s, so it requires Scala 2.8 and newer. I develop on Scala 2.11.8 with IntelliJ Idea 2016.1.2 and JDK 1.8_u40. The release .jar
has the Scala runtime bundled into it so it can be run normally like any other JAR file.
For lack of time, the launcher takes positional parameters rather than named ones. This describes the parameters and their positions, but it basically goes as:
-
The input file path
-
The tape size
-
The number of steps for which to run the program. Leave it negative to run it till it halts.
-
The number of milliseconds to pause before starting the next step. Leave this negative to pause for user input before every step.
The Turing Machine code files are simple text files, no extension is enforced.
There are some special characters usable in these files, and they are as follows:
Allowed characters with special meaning:
-
Lines starting with
DirectiveChar
(#
) - Directives indicating acceptable halting commands, other than the default halt command -
Lines starting with
CommentChar
(;
) - Discarded as comments. Well, it is a Turing Machine Code program after all, so the assembler style is employed -
Lines having a
CommentChar
(;
) in the middle - Only the part to the Left is processed, rest is discarded as an inline comment -
Line starting with
InitialStateChar
(~
) - The initial command indicator -
Line starting with
FillerChar
(@
) - The tape initializer. This String is split by whitespace after trimming the indicator character to get filler Strings, which are repeated in order to fill up the tape. Without such a line, the tape is initialized to logical blanks, represented by null -
Empty Lines - Ignored and discarded
A particular operation for the Turing Machine is denoted as follows:
<current state> <next state> <current value> <next value> <direction>
Two wildcards are allowed for anything except the direction of tape head movement:
-
!
- indicates a null value or the halting command, internally represented asnull
. -
*
- indicates a match-all wildcard character, no separate internal representation
<direction>
indicates the direction of tape head movement.
Left by 1 cell is indicated by anything starting with "L"
or "l"
or a negative integer.
Right by 1 cell is indicated by anything starting with "R"
or "r"
or a positive integer.
Neither of the above is no movement.
Hence follows the code: