rpxem 0.0.2 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c58c71a092aa80e4df9b4f619c9c452067e687a06ced3bc5e5791cecb3a2667f
4
+ data.tar.gz: 372a4a2e91c31414dd4f2b1b112b071430639dbf7428d89f7d1314e8b0ac03a9
5
+ SHA512:
6
+ metadata.gz: 65cb700a60db4f36fd91ee5b3c225d3d875360d471ceb743b4adb232a8a8a9959eaaf27123cb0fe603bd9c77f97f92ca4a1c0a2bf4c849ab4d7afba54b156ac6
7
+ data.tar.gz: 52deace08db6bd44366c50c1c0eebacc8f023a8d95648273c5b5bc2604e6ef73c322dc4a2874aae76aa09ef88801b4e2889e47583ced9d268d81ccc687c95822
@@ -0,0 +1,15 @@
1
+ name: Run RSpec
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ branches: [master]
8
+
9
+ jobs:
10
+ run_rspec:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+ - run: bundle install -j4
15
+ - run: bundle exec rspec
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0
4
+ - 2.1
5
+ - 2.2
6
+ - 2.3
7
+ - 2.4
8
+ - 2.5
9
+ - 2.6
10
+ - 2.7
11
+ - 3.0
12
+ cache:
13
+ directories: vendor/bundle
14
+ before_install:
15
+ - gem install bundler || true
data/MIT-LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 wktk
1
+ Copyright (c) 2012, 2018 wktk
2
2
 
3
3
  MIT License
4
4
 
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # RPxem
2
2
 
3
- [![Build Status](https://travis-ci.org/wktk/rpxem.png)](https://travis-ci.org/wktk/rpxem)
3
+ [![Build Status](https://travis-ci.org/wktk/rpxem.svg?branch=master)](https://travis-ci.org/wktk/rpxem)
4
4
 
5
- RPxem is a Ruby implementation of [Pxem], a esoteric programming language that
5
+ RPxem is a Ruby implementation of [Pxem], an esoteric programming language that
6
6
  enables you to create programs in 0-byte files.
7
- [Pxem]: http://cfs.maxn.jp/neta/pxem.php
7
+
8
+ [Pxem]: https://web.archive.org/web/20120605223423/http://cfs.maxn.jp/neta/pxem.php
8
9
 
9
10
  ## Installation
10
11
 
@@ -71,5 +72,12 @@ Hello, world!
71
72
 
72
73
  ## License
73
74
 
74
- Copyright (c) 2012 wktk. This software is distributed under the
75
- MIT License. See `MIT-LICENSE.txt` for details.
75
+ Copyright (c) 2012, 2018 wktk.
76
+ This software is distributed under the MIT License.
77
+ See `MIT-LICENSE.txt` for details.
78
+
79
+
80
+ ## See also
81
+
82
+ - Original resource: https://web.archive.org/web/20120605223423/http://cfs.maxn.jp/neta/pxem.php
83
+ - Esolang wiki: https://esolangs.org/wiki/Pxem
data/Rakefile CHANGED
@@ -1,12 +1,6 @@
1
- #!/usr/bin/env rake
2
1
  require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
- task :default => [:spec]
5
- begin
6
- require 'rspec/core/rake_task'
7
- RSpec::Core::RakeTask.new(:spec) do |spec|
8
- spec.pattern = 'spec/**/*_spec.rb'
9
- spec.rspec_opts = ['-cfs']
10
- end
11
- rescue LoadError => e
12
- end
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/rpxem CHANGED
@@ -1,14 +1,14 @@
1
- #!/usr/bin/env ruby
2
-
3
- if (!ARGV[0] || /^-/ =~ ARGV[0] && !File.exist?(ARGV[0]))
4
- require 'rpxem/version'
5
- puts "RPxem (#{RPxem::VERSION}) https://github.com/wtkt/rpxem"
6
- puts 'Usage: rpxem path-to-pxem-file.pxe'
7
- puts 'Report bugs to <https://github.com/wktk/rpxem/issues>.'
8
- elsif (!File.exist?(ARGV[0]) || !source = open(ARGV[0]).read)
9
- puts "Can't load file: #{ARGV[0]}"
10
- puts "Try `rpxem --help' for more infomation."
11
- else
12
- require 'rpxem'
13
- RPxem.run(File::basename(ARGV[0]), source)
14
- end
1
+ #!/usr/bin/env ruby
2
+
3
+ if (!ARGV[0] || /^-/ =~ ARGV[0] && !File.exist?(ARGV[0]))
4
+ require 'rpxem/version'
5
+ puts "RPxem (#{RPxem::VERSION}) https://github.com/wktk/rpxem"
6
+ puts 'Usage: rpxem path-to-pxem-file.pxe'
7
+ puts 'Report bugs to <https://github.com/wktk/rpxem/issues>.'
8
+ elsif (!File.exist?(ARGV[0]) || !source = open(ARGV[0]).read)
9
+ puts "Can't load file: #{ARGV[0]}"
10
+ puts "Try `rpxem --help' for more infomation."
11
+ else
12
+ require 'rpxem'
13
+ RPxem.run(File::basename(ARGV[0]), source)
14
+ end
data/lib/rpxem.rb CHANGED
@@ -1,20 +1,20 @@
1
- require 'rpxem/interpreter'
2
- require 'rpxem/version'
3
-
4
- module RPxem
5
- class << self
6
- def new(options={})
7
- RPxem::Interpreter.new(options)
8
- end
9
-
10
- private
11
- def method_missing(name, *args, &block)
12
- return super unless new.respond_to?(name)
13
- new.__send__(name, *args, &block)
14
- end
15
-
16
- def respond_to?(name)
17
- new.respond_to?(name) || super(name)
18
- end
19
- end
20
- end
1
+ require 'rpxem/interpreter'
2
+ require 'rpxem/version'
3
+
4
+ module RPxem
5
+ class << self
6
+ def new(options={})
7
+ RPxem::Interpreter.new(options)
8
+ end
9
+
10
+ private
11
+ def method_missing(name, *args, &block)
12
+ return super unless new.respond_to?(name)
13
+ new.__send__(name, *args, &block)
14
+ end
15
+
16
+ def respond_to?(name)
17
+ new.respond_to?(name) || super(name)
18
+ end
19
+ end
20
+ end
@@ -1,232 +1,229 @@
1
- require 'rpxem/stack'
2
- require 'rpxem/version'
3
- require 'scanf'
4
-
5
- module RPxem
6
- class Interpreter
7
- attr_accessor :mapping
8
- attr_reader :stack, :temp
9
-
10
- def initialize(mapping={})
11
- @mapping = default_mapping().merge(mapping)
12
- end
13
-
14
- # Open and execute a Pxem file
15
- def open(file, stack=RPxem::Stack.new, temp=nil)
16
- run(File.basename(file), File.open(file).read, stack, temp)
17
- end
18
-
19
- # Execute a Pxem code
20
- def run(filename, source='', stack=RPxem::Stack.new, temp=nil)
21
- @filename, @source, @stack, @temp = filename.each_byte.to_a, source, stack, temp
22
- buffer, @cursor, length = RPxem::Stack.new, 0, @filename.length
23
-
24
- while (@cursor < length)
25
- char = @filename[@cursor]
26
- @cursor += 1
27
- if (@cursor < length && 46 == char && name = @mapping[@filename[@cursor].chr.downcase])
28
- @stack.push(*buffer)
29
- buffer = RPxem::Stack.new
30
- __send__(name)
31
- @cursor += 1
32
- else
33
- buffer.unshift(char)
34
- end
35
- end
36
-
37
- return @stack
38
- end
39
-
40
- def default_mapping
41
- {
42
- # I/O
43
- 'p' => 'output_all',
44
- 'o' => 'output',
45
- 'n' => 'output_num',
46
- 'i' => 'input',
47
- '_' => 'input_num',
48
-
49
- # Stack
50
- 'c' => 'copy',
51
- 's' => 'throw_away',
52
- 'v' => 'reverse',
53
-
54
- # File contents
55
- 'f' => 'read_file',
56
- 'e' => 'emurate',
57
-
58
- # Rand
59
- 'r' => 'rand',
60
-
61
- # Loop
62
- 'w' => 'w',
63
- 'x' => 'x',
64
- 'y' => 'y',
65
- 'z' => 'z',
66
- 'a' => 'a',
67
-
68
- # Temporary area
69
- 't' => 'to_temp',
70
- 'm' => 'from_temp',
71
-
72
- # Do nothing
73
- 'd' => 'void',
74
-
75
- # Math
76
- '+' => 'addition',
77
- '-' => 'subtraction',
78
- '!' => 'multiplication',
79
- '$' => 'quotient',
80
- '%' => 'surplus',
81
- }
82
- end
83
-
84
- private
85
-
86
- # .p:
87
- def output_all
88
- while output; end
89
- end
90
-
91
- # .o:
92
- def output
93
- putc @stack.pop unless @stack.empty?
94
- end
95
-
96
- # .n:
97
- def output_num
98
- print @stack.pop
99
- end
100
-
101
- # .i:
102
- def input
103
- @stack.push(*STDIN.getc.ord)
104
- end
105
-
106
- # ._:
107
- def input_num
108
- @stack.push(*scanf('%d'))
109
- end
110
-
111
- # .c:
112
- def copy
113
- @stack.push(@stack.last)
114
- end
115
-
116
- # .s:
117
- def throw_away
118
- @stack.pop
119
- end
120
-
121
- # .v:
122
- def reverse
123
- @stack.reverse!
124
- end
125
-
126
- # .f:
127
- def read_file
128
- @stack.push(*@source.each_byte.to_a.reverse)
129
- end
130
-
131
- # .e:
132
- def emurate
133
- @stack.push(*clone.run(@source, @source, @stack.clone))
134
- end
135
-
136
- # .r:
137
- def rand
138
- @stack.push((super * @stack.pop).to_i)
139
- end
140
-
141
- # .w:
142
- def w
143
- jump if (!@stack.empty? && 0 == @stack.pop)
144
- end
145
-
146
- # .x:
147
- def x
148
- jump if (2 <= @stack.size && @stack.pop >= @stack.pop)
149
- end
150
-
151
- # .y:
152
- def y
153
- jump if (2 <= @stack.size && @stack.pop <= @stack.pop)
154
- end
155
-
156
- # .z:
157
- def z
158
- jump if (2 <= @stack.size && @stack.pop == @stack.pop)
159
- end
160
-
161
- # Jump forward to correspondent .a
162
- def jump
163
- count = 1
164
- while (count.nonzero?)
165
- @cursor += 1
166
- if (46 == @filename[@cursor])
167
- if (['w','x','y','z'].include? @filename[@cursor+1].chr.downcase)
168
- count += 1
169
- elsif ('a' == @filename[@cursor+1].chr.downcase)
170
- count -= 1
171
- end
172
- end
173
- end
174
- @cursor += 1
175
- end
176
-
177
- # .a:
178
- def a
179
- @cursor -= 2
180
- count = -1
181
- while (count.nonzero?)
182
- if (46 == @filename[@cursor])
183
- if (['w','x','y','z'].include? @filename[@cursor+1].chr.downcase)
184
- count += 1
185
- elsif ('a' == @filename[@cursor+1].chr.downcase)
186
- count -= 1
187
- end
188
- end
189
- @cursor -= 1
190
- end
191
- end
192
-
193
- # .t:
194
- def to_temp
195
- @temp = @stack.pop
196
- end
197
-
198
- # .m:
199
- def from_temp
200
- @stack.push(@temp) if @temp
201
- end
202
-
203
- # .d:
204
- def void
205
- end
206
-
207
- # .+:
208
- def addition
209
- @stack.push(@stack.pop + @stack.pop) if 2 <= @stack.size
210
- end
211
-
212
- # .-:
213
- def subtraction
214
- @stack.push((@stack.pop - @stack.pop).abs) if 2 <= @stack.size
215
- end
216
-
217
- # .!:
218
- def multiplication
219
- @stack.push(@stack.pop * @stack.pop) if 2 <= @stack.size
220
- end
221
-
222
- # .$:
223
- def quotient
224
- @stack.push((f=@stack.pop)>(s=@stack.pop)? f/s : s/f) if 2 <= @stack.size
225
- end
226
-
227
- # .%:
228
- def surplus
229
- @stack.push((f=@stack.pop)>(s=@stack.pop)? f%s : s%f) if 2 <= @stack.size
230
- end
231
- end
232
- end
1
+ require 'rpxem/stack'
2
+ require 'scanf'
3
+
4
+ module RPxem
5
+ class Interpreter
6
+ attr_accessor :mapping
7
+ attr_reader :stack, :temp
8
+
9
+ def initialize(mapping={})
10
+ @mapping = default_mapping().merge(mapping)
11
+ end
12
+
13
+ # Open and execute a Pxem file
14
+ def open(file, stack=RPxem::Stack.new, temp=nil)
15
+ run(File.basename(file), File.open(file).read, stack, temp)
16
+ end
17
+
18
+ # Execute a Pxem code
19
+ def run(filename, source='', stack=RPxem::Stack.new, temp=nil)
20
+ @filename, @source, @stack, @temp = filename.each_byte.to_a, source, stack, temp
21
+ buffer, @cursor, length = RPxem::Stack.new, 0, @filename.length
22
+
23
+ while (@cursor < length)
24
+ char = @filename[@cursor]
25
+ @cursor += 1
26
+ if (@cursor < length && 46 == char && name = @mapping[@filename[@cursor].chr.downcase])
27
+ @stack.push(*buffer)
28
+ buffer = RPxem::Stack.new
29
+ break if name == 'terminate'
30
+ __send__(name)
31
+ @cursor += 1
32
+ else
33
+ buffer.unshift(char)
34
+ end
35
+ end
36
+
37
+ return @stack
38
+ end
39
+
40
+ def default_mapping
41
+ {
42
+ # I/O
43
+ 'p' => 'output_all',
44
+ 'o' => 'output',
45
+ 'n' => 'output_num',
46
+ 'i' => 'input',
47
+ '_' => 'input_num',
48
+
49
+ # Stack
50
+ 'c' => 'copy',
51
+ 's' => 'throw_away',
52
+ 'v' => 'reverse',
53
+
54
+ # File contents
55
+ 'f' => 'read_file',
56
+ 'e' => 'emurate',
57
+
58
+ # Rand
59
+ 'r' => 'rand',
60
+
61
+ # Loop
62
+ 'w' => 'w',
63
+ 'x' => 'x',
64
+ 'y' => 'y',
65
+ 'z' => 'z',
66
+ 'a' => 'a',
67
+
68
+ # Temporary area
69
+ 't' => 'to_temp',
70
+ 'm' => 'from_temp',
71
+
72
+ # Terminate execution
73
+ 'd' => 'terminate',
74
+
75
+ # Math
76
+ '+' => 'addition',
77
+ '-' => 'subtraction',
78
+ '!' => 'multiplication',
79
+ '$' => 'quotient',
80
+ '%' => 'surplus',
81
+ }
82
+ end
83
+
84
+ private
85
+
86
+ # .p:
87
+ def output_all
88
+ while output; end
89
+ end
90
+
91
+ # .o:
92
+ def output
93
+ putc @stack.pop unless @stack.empty?
94
+ end
95
+
96
+ # .n:
97
+ def output_num
98
+ print @stack.pop
99
+ end
100
+
101
+ # .i:
102
+ def input
103
+ stdin = STDIN.getc
104
+ @stack.push(stdin ? stdin.ord : -1)
105
+ end
106
+
107
+ # ._:
108
+ def input_num
109
+ @stack.push(*scanf('%d'))
110
+ end
111
+
112
+ # .c:
113
+ def copy
114
+ @stack.push(@stack.last) unless @stack.empty?
115
+ end
116
+
117
+ # .s:
118
+ def throw_away
119
+ @stack.pop
120
+ end
121
+
122
+ # .v:
123
+ def reverse
124
+ @stack.reverse!
125
+ end
126
+
127
+ # .f:
128
+ def read_file
129
+ @stack.push(*@source.each_byte.to_a.reverse)
130
+ end
131
+
132
+ # .e:
133
+ def emurate
134
+ @stack.push(*clone.run(@source, @source, @stack.clone))
135
+ end
136
+
137
+ # .r:
138
+ def rand
139
+ @stack.push((super * @stack.pop).to_i)
140
+ end
141
+
142
+ # .w:
143
+ def w
144
+ jump if (!@stack.empty? && 0 == @stack.pop)
145
+ end
146
+
147
+ # .x:
148
+ def x
149
+ jump if (2 <= @stack.size && @stack.pop >= @stack.pop)
150
+ end
151
+
152
+ # .y:
153
+ def y
154
+ jump if (2 <= @stack.size && @stack.pop <= @stack.pop)
155
+ end
156
+
157
+ # .z:
158
+ def z
159
+ jump if (2 <= @stack.size && @stack.pop == @stack.pop)
160
+ end
161
+
162
+ # Jump forward to correspondent .a
163
+ def jump
164
+ count = 1
165
+ while (count.nonzero?)
166
+ @cursor += 1
167
+ if (46 == @filename[@cursor])
168
+ if (['w','x','y','z'].include? @filename[@cursor+1].chr.downcase)
169
+ count += 1
170
+ elsif ('a' == @filename[@cursor+1].chr.downcase)
171
+ count -= 1
172
+ end
173
+ end
174
+ end
175
+ @cursor += 1
176
+ end
177
+
178
+ # .a:
179
+ def a
180
+ @cursor -= 2
181
+ count = -1
182
+ while (count.nonzero?)
183
+ if (46 == @filename[@cursor])
184
+ if (['w','x','y','z'].include? @filename[@cursor+1].chr.downcase)
185
+ count += 1
186
+ elsif ('a' == @filename[@cursor+1].chr.downcase)
187
+ count -= 1
188
+ end
189
+ end
190
+ @cursor -= 1
191
+ end
192
+ end
193
+
194
+ # .t:
195
+ def to_temp
196
+ @temp = @stack.pop
197
+ end
198
+
199
+ # .m:
200
+ def from_temp
201
+ @stack.push(@temp) if @temp
202
+ end
203
+
204
+ # .+:
205
+ def addition
206
+ @stack.push(@stack.pop + @stack.pop) if 2 <= @stack.size
207
+ end
208
+
209
+ # .-:
210
+ def subtraction
211
+ @stack.push((@stack.pop - @stack.pop).abs) if 2 <= @stack.size
212
+ end
213
+
214
+ # .!:
215
+ def multiplication
216
+ @stack.push(@stack.pop * @stack.pop) if 2 <= @stack.size
217
+ end
218
+
219
+ # .$:
220
+ def quotient
221
+ @stack.push((f=@stack.pop)>(s=@stack.pop)? f/s : s/f) if 2 <= @stack.size
222
+ end
223
+
224
+ # .%:
225
+ def surplus
226
+ @stack.push((f=@stack.pop)>(s=@stack.pop)? f%s : s%f) if 2 <= @stack.size
227
+ end
228
+ end
229
+ end