ruby-tm 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. checksums.yaml +7 -0
  2. data/bin/tm +125 -0
  3. data/changelog.md +4 -0
  4. data/license.txt +24 -0
  5. data/readme.md +26 -0
  6. metadata +49 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 51f98ccf552ffb389a6276c8987d6e21e7498280
4
+ data.tar.gz: 3b3a5f48e600a0041953d4aa66e93d2e86f010dd
5
+ SHA512:
6
+ metadata.gz: 14b740031a4db14ec6af7798494ab170b268de904395005a918b28fbd2825fbf524ecaa057f8f2b33c377e35f60f776c720e924363c1792b3df0c2773692990a
7
+ data.tar.gz: 29b617cf848f0570a9533b6ab8acf653aa4767d2930f88c9e38a5f7d03acc406bc37c3f9f8a9a9bb61c018a978d7ff459cef7b3ffacae5af3891a33e9833a5e8
data/bin/tm ADDED
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ VERBOSE = (!ARGV[2].nil? && ARGV[2].include?("v"))
4
+
5
+ class Tape
6
+ def initialize(str=nil)
7
+ @tape = (str.nil? ? "" : str.dup)
8
+ @position = 0
9
+ end
10
+
11
+ def left
12
+ if @position == 0
13
+ @tape.insert(@position, "_")
14
+ else
15
+ @position -= 1
16
+ end
17
+ end
18
+
19
+ def right
20
+ ensure_current_position_exists
21
+ @position += 1
22
+ end
23
+
24
+ def read
25
+ ensure_current_position_exists
26
+ @tape[@position, 1]
27
+ end
28
+
29
+ def write(val)
30
+ ensure_current_position_exists
31
+ @tape[@position] = val
32
+ end
33
+
34
+ def to_s
35
+ @tape.sub(/^_+/, '').sub(/_.*/, '')
36
+ end
37
+
38
+ private
39
+
40
+ def ensure_current_position_exists
41
+ if @position == @tape.length
42
+ @tape << "_"
43
+ end
44
+ end
45
+ end
46
+
47
+ class Transition
48
+ def initialize(new_state, new_char, dir)
49
+ @new_state = new_state.to_sym
50
+ @new_char = new_char
51
+ @dir = dir
52
+ end
53
+
54
+ def apply
55
+ print "#{@new_state} -> " if VERBOSE
56
+ yield @new_char, @dir
57
+ return @new_state
58
+ end
59
+ end
60
+
61
+ class Instructions
62
+ attr_accessor :initial_state
63
+
64
+ def initialize(filename)
65
+ re = Regexp.compile('\s* (\w+) \s+ (\w) \s+ (\w+) \s+ (\w) \s+ ([RL])',
66
+ Regexp::EXTENDED)
67
+ @instructions = Hash.new { |hash, key| hash[key] = Hash.new }
68
+
69
+ File.open(filename) do |file|
70
+ file.each_line do |line|
71
+ if data = re.match(line) then
72
+ st = data[1].to_sym
73
+ ch = data[2]
74
+ @instructions[st][ch] = Transition.new(*data[3 .. 5])
75
+
76
+ if self.initial_state.nil?
77
+ self.initial_state = st
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ def get_transition(state, char)
85
+ if @instructions.has_key?(state) && @instructions[state].has_key?(char)
86
+ return @instructions[state][char]
87
+ else
88
+ return nil
89
+ end
90
+ end
91
+
92
+ def run(tape, state = self.initial_state)
93
+ raise("Invalid tape") unless
94
+ tape.respond_to?(:left) &&
95
+ tape.respond_to?(:right) &&
96
+ tape.respond_to?(:read) &&
97
+ tape.respond_to?(:write)
98
+
99
+ while t = get_transition(state, tape.read)
100
+ state = t.apply do |ch, dir|
101
+ tape.write(ch)
102
+ case dir
103
+ when 'L'
104
+ tape.left
105
+ when 'R'
106
+ tape.right
107
+ else
108
+ raise "Invalid direction"
109
+ end
110
+ puts tape if VERBOSE
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ if __FILE__ == $0
117
+ if ARGV.empty?
118
+ abort("usage: tm <input_file> <input_tape> [-v]\nUse -v or generally any string containing v as the 3rd parameter for verbose mode.\n\nexample: tm reverse.tm something\ngnihtemos")
119
+ end
120
+ ins = Instructions.new(ARGV[0])
121
+ tape = Tape.new(ARGV[1])
122
+ ins.run(tape)
123
+
124
+ puts tape
125
+ end
@@ -0,0 +1,4 @@
1
+ ### 0.0.1
2
+ (released 20/11/2013)
3
+
4
+ - first version, publish to github and rubygems
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org/>
@@ -0,0 +1,26 @@
1
+ # Ruby Turing Machine
2
+
3
+ ## Description
4
+
5
+ This is a turing machine interpreter packaged as a command line tool. I cobbled it together by finding a large part of the code readily-implemented in just the way I wanted it on the web and then adding some additional parameters and options.
6
+
7
+ ## Installation
8
+
9
+ `gem install ruby-tm`
10
+
11
+ ## Usage
12
+
13
+ Run `tm` in a terminal for the basic help.
14
+
15
+ You will need to supply a text file with the turing machine instructions that you want to add to the machine. These have to be of the following structure:
16
+
17
+ `CURR_STATE READ_VAL NEW_STATE WRITE_VAL DIRECTION`
18
+
19
+ Example: `read_first b append_b _ L`
20
+ Interpretation: if we're on the `read_first` label and the value under the tape head is on the `b` letter, change the label to the `append_b` label, write `blank` under the tape head and move the tape head to the Left.
21
+
22
+ `tm` will read the supplied file and parse any lines that match the aforementioned structure and ignore everything else. It will then proceed to run the instructions on the provided starting tape, and will output the resulting tape at the end.
23
+
24
+ ## Credit where credit is due
25
+
26
+ The code for the interpreter is based off of a certain Marcelo's [subimission](https://www.ruby-forum.com/attachment/1899/turing.rb) to quiz [#162](https://www.ruby-forum.com/topic/152512#673087) of the "Ruby Quiz 2". I found it while searching for a ready-made turing machine command line interpreter. Marcelo submitted it as a guest account and as such I could not contact him for permission to repackage his code as the present RubyGem package, so I decided to do so anyway. Since I found most of the code freely on the internet, I have kept it unlicensed under the public domain.
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-tm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Theodor Văraru
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-20 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: This is a turing machine interpreter packaged as a command line tool.
14
+ email:
15
+ - theo@tvararu.ro
16
+ executables:
17
+ - tm
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - license.txt
22
+ - readme.md
23
+ - changelog.md
24
+ - bin/tm
25
+ homepage: http://github.com/tvararu/ruby-tm
26
+ licenses:
27
+ - license.txt
28
+ metadata: {}
29
+ post_install_message:
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubyforge_project:
45
+ rubygems_version: 2.0.3
46
+ signing_key:
47
+ specification_version: 4
48
+ summary: Command line turing machine interpreter.
49
+ test_files: []