rasel 1.1.3 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e383f8b5e25f0d283eeeb1eebf5bbe1572206494
4
- data.tar.gz: 4b53daac9f618a7be7188ba657703d88d62fbf1e
3
+ metadata.gz: 8b3b17070c0c2dd2bf982193c8becb0d2f079971
4
+ data.tar.gz: 053577514bcbe505c5c6bd1766ec0ddf52ae9974
5
5
  SHA512:
6
- metadata.gz: 5740ece90b2d4f2aafad4031a7f26dfc1d1d68338aaf9bfd8189bed6925e3421dbb47e10ce8aa2cd3e756117f04e0708afaec7e7dd3472fa3b4278e67eb98925
7
- data.tar.gz: 8ee6156d49f97c57682d97bab8762f70c69539259cdaf413289949d3b548afbfaad123b43b3a2bef7d6ffccb8fa4c2d2cf3b1533be28296b36e323d71808a88e
6
+ metadata.gz: bfe946adc630d7fe4c91c9d10f4407c3903dba8255d1c5531681ab387f8117bab5f084a59d9b010873d6e24d1936fe91030488963b43b3520d00367b289cd3f2
7
+ data.tar.gz: 5c86eb71eecd98797bfefd987400d25c7f91bce3270b3f3ee5588c42f4c80813d5b605e84cf8aa7af5cb5c72abb35792ab2cc278dfdad5a109209a0a1f297eae
data/bin/rasel-annotated CHANGED
@@ -3,4 +3,4 @@ Signal.trap(:INT){ abort "\n(interrupted by SIGINT)" }
3
3
 
4
4
  require_relative "../lib/rasel"
5
5
  require "json"
6
- exit RASEL(JSON.load(ARGF.read), STDOUT).exitcode
6
+ exit RASEL::run_annotated(JSON.load(ARGF.read), STDOUT).exitcode
data/bin/rasel-ide CHANGED
@@ -266,7 +266,7 @@ post "/run" do
266
266
  begin
267
267
  require "timeout"
268
268
  result = Timeout.timeout(2) do
269
- RASEL \
269
+ RASEL::run_annotated \
270
270
  JSON.load(File.read ARGV.first),
271
271
  StringIO.new,
272
272
  StringIO.new.tap{ |_| JSON.load(params.fetch "stdin").bytes.reverse_each &_.method(:ungetbyte) }
data/lib/rasel.rb CHANGED
@@ -2,6 +2,103 @@ Encoding::default_internal = Encoding::default_external = "ASCII-8BIT"
2
2
  END { RubyProf::FlatPrinter.new(RubyProf.stop).print STDERR, min_percent: 1 } if ENV["PROFILE"]
3
3
 
4
4
  module RASEL
5
+ ResultStruct = Struct.new :stdout, :stack, :exitcode
6
+
7
+ def self.run source, stdout = StringIO.new, stdin = STDIN
8
+ stack = []
9
+ pop = ->{ stack.pop || 0 }
10
+ error = Proc.new{ return RASEL::ResultStruct.new stdout, stack, 255 }
11
+
12
+ lines = source.tap{ |_| raise ArgumentError.new "empty source" if _.empty? }.gsub(/ +$/,"").split(?\n)
13
+ code = lines.map{ |_| _.ljust(lines.map(&:size).max).bytes }
14
+
15
+ dx, dy = 1, 0
16
+ x, y = -1, 0
17
+
18
+ # debugging and profiling (currently not maintained)
19
+ history = {}
20
+ debug_history = ENV.key? "DEBUG_HISTORY"
21
+ move = lambda do
22
+ y = (y + dy) % code.size
23
+ x = (x + dx) % code[y].size
24
+ next unless debug_history && (code[y][x] == 32 || code[y][x][0] == 32)
25
+ history[[x, y]] ||= 0
26
+ history[[x, y]] += 1
27
+ end
28
+ time = Time.now
29
+ thread = Thread.new do
30
+ loop do
31
+ unless Time.now < time + 1
32
+ time += 1
33
+ p history.sort_by(&:last).last(10)
34
+ end
35
+ sleep 0.1
36
+ end
37
+ end if debug_history
38
+ if ENV["PROFILE"]
39
+ require "ruby-prof"
40
+ RubyProf.start
41
+ end
42
+
43
+ reverse = ->{ dy, dx = -dy, -dx }
44
+ stringmode = false
45
+ debug = ENV.key? "DEBUG"
46
+ loop do
47
+ move[]
48
+ byte = code[y][x]
49
+ char = byte.chr
50
+ STDERR.puts [char, stringmode, (stack.last Integer ENV["DEBUG"] rescue stack)].inspect if debug
51
+
52
+ next stack.push byte if stringmode && char != ?"
53
+ return RASEL::ResultStruct.new stdout, stack, (
54
+ t = pop[]
55
+ 1 != t.denominator || t < 0 || t > 255 ? 255 : t.to_i
56
+ ) if char == ?@
57
+ case char
58
+ when ?\s
59
+
60
+ when ?0..?9 ; stack.push byte - 48
61
+ when ?A..?Z ; stack.push byte - 55
62
+ when ?" ; stringmode ^= true
63
+ when ?# ; move[]
64
+ when ?$ ; pop[]
65
+ when ?: ; stack.concat [pop[]] * 2
66
+ when ?- ; stack.push -(pop[] - pop[])
67
+ when ?/ ; b, a = pop[], pop[]; stack.push b.zero? ? 0 : Rational(a) / b
68
+ when ?% ; b, a = pop[], pop[]; stack.push b.zero? ? 0 : Rational(a) % b
69
+ when ?v ; dx, dy = 0, 1
70
+ when ?> ; dx, dy = 1, 0
71
+ when ?^ ; dx, dy = 0, -1
72
+ when ?< ; dx, dy = -1, 0
73
+ when ?? ; move[] if pop[] > 0
74
+ when ?\\
75
+ t = pop[]
76
+ error.call if 1 != t.denominator
77
+ stack.unshift 0 until stack.size > t
78
+ stack[-t-1], stack[-1] = stack[-1], stack[-t-1] unless 0 > t
79
+ when ?. ; stdout.print "#{_ = pop[]; 1 != _.denominator ? _.to_f : _.to_i} "
80
+ when ?, ; stdout.print "#{_ = pop[]; 1 != _.denominator ? error.call : _ < 0 || _ > 255 ? error.call : _.to_i.chr}"
81
+ when ?~ ; if _ = stdin.getbyte then stack.push _; move[] end
82
+ when ?&
83
+ getc = ->{ stdin.getc or throw nil }
84
+ catch nil do
85
+ nil until (?0..?9).include? c = getc[]
86
+ while (?0..?9).include? cc = stdin.getc ; c << cc end
87
+ stdin.ungetbyte cc if cc
88
+ stack.push c.to_i
89
+ move[]
90
+ end
91
+ when ?j
92
+ t = pop[]
93
+ error.call if 1 != t.denominator
94
+ y = (y + dy * t.to_i) % code.size
95
+ x = (x + dx * t.to_i) % code[y].size
96
+
97
+ else ; error.call
98
+ end
99
+ end
100
+ end
101
+
5
102
  require "delegate"
6
103
  class StackItem < DelegateClass Rational
7
104
  attr_reader :annotation
@@ -10,29 +107,13 @@ module RASEL
10
107
  @annotation = annotation || (n.annotation if n.respond_to? :annotation)
11
108
  end
12
109
  end
110
+ def self.run_annotated source, stdout = StringIO.new, stdin = STDIN
111
+ stack = []
112
+ pop = ->{ stack.pop || 0 }
113
+ error = Proc.new{ return ResultStruct.new stdout, stack, 255 }
13
114
 
14
- ResultStruct = Struct.new :stdout, :stack, :exitcode
15
-
16
- def self.write_pretty_json where, what
17
- File.write where, "[\n " + (
18
- what.map(&JSON.method(:dump)).join ",\n "
19
- ) + "\n]\n"
20
- end
21
- end
22
-
23
- def RASEL source, stdout = StringIO.new, stdin = STDIN
24
- stack = []
25
- pop = ->{ stack.pop || 0 }
26
- error = Proc.new{ return RASEL::ResultStruct.new stdout, stack, 255 }
27
-
28
- case source
29
- when String
30
- lines = source.tap{ |_| raise ArgumentError.new "empty source" if _.empty? }.gsub(/ +$/,"").split(?\n)
31
- code = lines.map{ |_| _.ljust(lines.map(&:size).max).bytes }
32
- when Array
33
- annotate = true
34
115
  code = Array.new(source.map{|y,|y}.max+1){ Array.new(source.map{|_,x,|x}.max+1){ " ".ord } }
35
- source.each{ |y, x, c, a| code[y][x] = [c.ord, a] }
116
+ source.each{ |y, x, c, a| code[y][x] = [c.ord, a] unless c.empty? }
36
117
  stdout.instance_eval do
37
118
  pos = self.pos
38
119
  old_puts = method :puts
@@ -40,7 +121,7 @@ def RASEL source, stdout = StringIO.new, stdin = STDIN
40
121
  define_singleton_method :puts do |str, reason|
41
122
  next if prev == dump = JSON.dump([reason, str])
42
123
  old_puts.call prev = dump
43
- if 200_000 < stdout.pos - pos
124
+ if 500_000 < stdout.pos - pos
44
125
  old_puts.call JSON.dump [:abort, "printed size"]
45
126
  error.call
46
127
  end
@@ -49,99 +130,87 @@ def RASEL source, stdout = StringIO.new, stdin = STDIN
49
130
  puts str, :print
50
131
  end
51
132
  end
52
- else
53
- raise ArgumentError.new "unsupported source class: #{source.class}"
54
- end
55
- dx, dy = 1, 0
56
- x, y = -1, 0
57
-
58
- # debugging and profiling (currently not maintained)
59
- history = {}
60
- debug_history = ENV.key? "DEBUG_HISTORY"
61
- move = lambda do
62
- y = (y + dy) % code.size
63
- x = (x + dx) % code[y].size
64
- next unless debug_history && (code[y][x] == 32 || code[y][x][0] == 32)
65
- history[[x, y]] ||= 0
66
- history[[x, y]] += 1
67
- end
68
- time = Time.now
69
- thread = Thread.new do
133
+
134
+ dx, dy = 1, 0
135
+ x, y = -1, 0
136
+
137
+ move = lambda do
138
+ y = (y + dy) % code.size
139
+ x = (x + dx) % code[y].size
140
+ end
141
+ time = Time.now
142
+
143
+ reverse = ->{ dy, dx = -dy, -dx }
144
+ stringmode = false
70
145
  loop do
71
- unless Time.now < time + 1
72
- time += 1
73
- p history.sort_by(&:last).last(10)
146
+ if 1 < Time.now - time
147
+ stdout.puts "timeout", :abort
148
+ error.call
74
149
  end
75
- sleep 0.1
76
- end
77
- end if debug_history
78
- if ENV["PROFILE"]
79
- require "ruby-prof"
80
- RubyProf.start
81
- end
150
+ stdout.puts stack.map{ |_| _.respond_to?(:annotation) && _.annotation ? [_, _.annotation] : _ }, :loop
82
151
 
83
- reverse = ->{ dy, dx = -dy, -dx }
84
- stringmode = false
85
- debug = ENV.key? "DEBUG"
86
- loop do
87
- if annotate && 1 < Time.now - time
88
- stdout.puts "timeout", :abort
89
- error.call
90
- end
91
- stdout.puts stack.map{ |_| _.respond_to?(:annotation) && _.annotation ? [_, _.annotation] : _ }, :loop if annotate
92
-
93
- move[]
94
- byte, annotation = code[y][x]
95
- char = byte.chr
96
- STDERR.puts [char, stringmode, (stack.last Integer ENV["DEBUG"] rescue stack)].inspect if debug
97
-
98
- next stack.push byte if stringmode && char != ?"
99
- return RASEL::ResultStruct.new stdout, stack, (
100
- t = pop[]
101
- 1 != t.denominator || t < 0 || t > 255 ? 255 : t.to_i
102
- ) if char == ?@
103
- case char
104
- when ?\s
105
-
106
- when ?0..?9 ; stack.push RASEL::StackItem.new byte - 48, annotation
107
- when ?A..?Z ; stack.push RASEL::StackItem.new byte - 55, annotation
108
- when ?" ; stringmode ^= true
109
- when ?# ; move[]
110
- when ?$ ; pop[]
111
- when ?: ; popped = pop[]; stack.push popped; stack.push RASEL::StackItem.new popped, annotation
112
- when ?- ; stack.push RASEL::StackItem.new -(pop[] - pop[]), annotation
113
- when ?/ ; b, a = pop[], pop[]; stack.push RASEL::StackItem.new b.zero? ? 0 : Rational(a) / b, annotation
114
- when ?% ; b, a = pop[], pop[]; stack.push RASEL::StackItem.new b.zero? ? 0 : Rational(a) % b, annotation
115
- when ?v ; dx, dy = 0, 1
116
- when ?> ; dx, dy = 1, 0
117
- when ?^ ; dx, dy = 0, -1
118
- when ?< ; dx, dy = -1, 0
119
- when ?? ; move[] if pop[] > 0
120
- when ?\\
121
- t = pop[]
122
- error.call if 1 != t.denominator
123
- stack.unshift 0 until stack.size > t
124
- stack[-t-1], stack[-1] = RASEL::StackItem.new(stack[-1], annotation), stack[-t-1] unless 0 > t
125
- # TODO: annotate prints
126
- when ?. ; stdout.print "#{_ = pop[]; 1 != _.denominator ? _.to_f : _.to_i} "
127
- when ?, ; stdout.print "#{_ = pop[]; 1 != _.denominator ? error.call : _ < 0 || _ > 255 ? error.call : _.to_i.chr}"
128
- when ?~ ; if _ = stdin.getbyte then stack.push RASEL::StackItem.new _, annotation; move[] end
129
- when ?&
130
- getc = ->{ stdin.getc or throw nil }
131
- catch nil do
132
- nil until (?0..?9).include? c = getc[]
133
- while (?0..?9).include? cc = stdin.getc ; c << cc end
134
- stdin.ungetbyte cc if cc
135
- stack.push RASEL::StackItem.new c.to_i, annotation
136
- move[]
137
- end
138
- when ?j
152
+ move[]
153
+ byte, annotation = code[y][x]
154
+ char = byte.chr
155
+
156
+ next stack.push StackItem.new byte, annotation if stringmode && char != ?"
157
+ return ResultStruct.new stdout, stack, (
139
158
  t = pop[]
140
- error.call if 1 != t.denominator
141
- y = (y + dy * t.to_i) % code.size
142
- x = (x + dx * t.to_i) % code[y].size
159
+ 1 != t.denominator || t < 0 || t > 255 ? 255 : t.to_i
160
+ ) if char == ?@
161
+ case char
162
+ when ?\s
163
+
164
+ when ?0..?9 ; stack.push StackItem.new byte - 48, annotation
165
+ when ?A..?Z ; stack.push StackItem.new byte - 55, annotation
166
+ when ?" ; stringmode ^= true
167
+ when ?# ; move[]
168
+ when ?$ ; pop[]
169
+ when ?: ; popped = pop[]; stack.push popped; stack.push StackItem.new popped, annotation
170
+ when ?- ; stack.push StackItem.new -(pop[] - pop[]), annotation
171
+ when ?/ ; b, a = pop[], pop[]; stack.push StackItem.new b.zero? ? 0 : Rational(a) / b, annotation
172
+ when ?% ; b, a = pop[], pop[]; stack.push StackItem.new b.zero? ? 0 : Rational(a) % b, annotation
173
+ when ?v ; dx, dy = 0, 1
174
+ when ?> ; dx, dy = 1, 0
175
+ when ?^ ; dx, dy = 0, -1
176
+ when ?< ; dx, dy = -1, 0
177
+ when ?? ; move[] if pop[] > 0
178
+ when ?\\
179
+ t = pop[]
180
+ error.call if 1 != t.denominator
181
+ stack.unshift 0 until stack.size > t
182
+ stack[-t-1], stack[-1] = StackItem.new(stack[-1], annotation), stack[-t-1] unless 0 > t
183
+ # TODO: annotate prints
184
+ when ?. ; stdout.print "#{_ = pop[]; 1 != _.denominator ? _.to_f : _.to_i} "
185
+ when ?, ; stdout.print "#{_ = pop[]; 1 != _.denominator ? error.call : _ < 0 || _ > 255 ? error.call : _.to_i.chr}"
186
+ when ?~ ; if _ = stdin.getbyte then stack.push StackItem.new _, annotation; move[] end
187
+ when ?&
188
+ getc = ->{ stdin.getc or throw nil }
189
+ catch nil do
190
+ nil until (?0..?9).include? c = getc[]
191
+ while (?0..?9).include? cc = stdin.getc ; c << cc end
192
+ stdin.ungetbyte cc if cc
193
+ stack.push StackItem.new c.to_i, annotation
194
+ move[]
195
+ end
196
+ when ?j
197
+ t = pop[]
198
+ error.call if 1 != t.denominator
199
+ y = (y + dy * t.to_i) % code.size
200
+ x = (x + dx * t.to_i) % code[y].size
143
201
 
144
- else ; error.call
202
+ else ; error.call
203
+ end
145
204
  end
146
205
  end
206
+
207
+ def self.write_pretty_json where, what
208
+ File.write where, "[\n " + (
209
+ what.map(&JSON.method(:dump)).join ",\n "
210
+ ) + "\n]\n"
211
+ end
212
+ end
213
+
214
+ def RASEL *args
215
+ RASEL::run *args
147
216
  end
data/rasel.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "rasel"
3
- spec.version = "1.1.3"
3
+ spec.version = "1.1.4"
4
4
  spec.summary = "Random Access Stack Esoteric Language"
5
5
 
6
6
  spec.author = "Victor Maslov aka Nakilon"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rasel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Maslov aka Nakilon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-01 00:00:00.000000000 Z
11
+ date: 2021-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: webrick