rubocop-brainfuck 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2c47468ec001e54ece8acd69b00e41b7c97d7d1d
4
+ data.tar.gz: d3b3e21429e96996f76f3c3ef9b5f541994696c8
5
+ SHA512:
6
+ metadata.gz: 709f2f279a74fb85717a234730bc0e93bd3071892595076a96a314502593c3848133e85f0a826463602495709b65e5d7fe93b9207d2b190110741dc4af6553cc
7
+ data.tar.gz: abdbc597c86e8667faeb6f1776e57f4b7e92881f05961a817eda1818a44ff812441b8ce60d88efc6af2ed1ad93ee3352fd80a2630a66d654e649ee9926471a15
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rubocop-brainfuck.gemspec
4
+ gemspec
@@ -0,0 +1,36 @@
1
+ # Rubocop::Brainfuck
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rubocop/brainfuck`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'rubocop-brainfuck'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install rubocop-brainfuck
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Masataka Kuwabara/rubocop-brainfuck.
36
+
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rubocop/brainfuck"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,2 @@
1
+ Brainfuck/Interpreter:
2
+ Enabled: true
@@ -0,0 +1,20 @@
1
+ require 'rubocop'
2
+
3
+ module RuboCop
4
+ Runner::MAX_ITERATIONS = Float::INFINITY
5
+
6
+ module Brainfuck
7
+ PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
8
+ CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
9
+ CONFIG = YAML.safe_load(CONFIG_DEFAULT.read).freeze
10
+
11
+ private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
12
+ end
13
+ end
14
+
15
+ require "rubocop/brainfuck/version"
16
+ require "rubocop/brainfuck/inject"
17
+
18
+ RuboCop::Brainfuck::Inject.defaults!
19
+
20
+ require 'rubocop/cop/brainfuck/interpreter'
@@ -0,0 +1,38 @@
1
+ # The MIT License (MIT)
2
+ # =====================
3
+ #
4
+ # Copyright (c) 2014 Ian MacLeod <ian@nevir.net>
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
7
+ # this software and associated documentation files (the "Software"), to deal in
8
+ # the Software without restriction, including without limitation the rights to
9
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10
+ # of the Software, and to permit persons to whom the Software is furnished to do
11
+ # so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in all
14
+ # copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
23
+ module RuboCop
24
+ module Brainfuck
25
+ # Because RuboCop doesn't yet support plugins, we have to monkey patch in a
26
+ # bit of our configuration.
27
+ module Inject
28
+ def self.defaults!
29
+ path = CONFIG_DEFAULT.to_s
30
+ hash = ConfigLoader.send(:load_yaml_configuration, path)
31
+ config = Config.new(hash, path)
32
+ puts "configuration from #{path}" if ConfigLoader.debug?
33
+ config = ConfigLoader.merge_with_default(config, path)
34
+ ConfigLoader.instance_variable_set(:@default_configuration, config)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ module Rubocop
2
+ module Brainfuck
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Brainfuck
6
+ # This cop check brainfuck program.
7
+ class Interpreter < Cop
8
+ MSG = 'Interpreting the brainfuck code...'.freeze
9
+
10
+ def_node_matcher :program?, <<-PATTERN
11
+ (class _ (const {nil cbase} :BrainFuck) $_body)
12
+ PATTERN
13
+
14
+ def_node_search :pc, '(casgn nil :PC $int)'
15
+ def_node_search :code, '(casgn nil :Code ${str dstr})'
16
+ def_node_search :memory, '(casgn nil :Memory $array)'
17
+ def_node_search :stdout, '(casgn nil :Stdout $str)'
18
+ def_node_search :stdin, '(casgn nil :Stdin $str)'
19
+ def_node_search :pointer, '(casgn nil :Pointer $int)'
20
+
21
+ def_node_matcher :int_value, '(int $_)'
22
+
23
+ def on_class(node)
24
+ body = program?(node)
25
+ return unless body
26
+
27
+ pc = int_value(pc(body).first)
28
+ code = code_value(code(body).first)
29
+ return if code.size <= pc
30
+
31
+ add_offense(node, :expression)
32
+ end
33
+
34
+ private
35
+
36
+ def autocorrect(node)
37
+ body = program?(node)
38
+
39
+ pc = pc(body).first
40
+ pc_value = int_value(pc)
41
+ code = code_value(code(body).first)
42
+ memory = memory(body).first
43
+ memory_value = to_array(memory)
44
+ stdout = stdout(body).first
45
+ stdin = stdin(body).first
46
+ pointer = pointer(body).first
47
+ pointer_value = int_value(pointer)
48
+
49
+ lambda do |corrector|
50
+ case code[pc_value]
51
+ when '>'
52
+ corrector.replace(
53
+ pointer.loc.expression,
54
+ (int_value(pointer) + 1).to_s
55
+ )
56
+ when '<'
57
+ corrector.replace(
58
+ pointer.loc.expression,
59
+ (int_value(pointer) - 1).to_s
60
+ )
61
+ when '+'
62
+ v = memory_value[pointer_value] || 0
63
+ memory_value[pointer_value] = v == 255 ? 0 : v + 1
64
+ corrector.replace(
65
+ memory.loc.expression,
66
+ memory_value.inspect
67
+ )
68
+ when '-'
69
+ v = memory_value[pointer_value] || 0
70
+ memory_value[pointer_value] = v == 0 ? 255 : v - 1
71
+ corrector.replace(
72
+ memory.loc.expression,
73
+ memory_value.inspect
74
+ )
75
+ when '.'
76
+ str = stdout.str_content + (memory_value[pointer_value] || 0).chr
77
+ corrector.replace(
78
+ stdout.loc.expression,
79
+ str.inspect
80
+ )
81
+ when ','
82
+ char = stdin.str_content.ord rescue 0
83
+ memory_value[pointer_value] = char
84
+ corrector.replace(
85
+ memory.loc.expression,
86
+ memory_value.inspect
87
+ )
88
+ corrector.replace(
89
+ stdin.loc.expression,
90
+ String(stdin.str_content[1..-1]).inspect
91
+ )
92
+ when '['
93
+ v = memory_value[pointer_value] || 0
94
+ if v == 0
95
+ level = 1
96
+ idx = code.chars[(pc_value+1)..-1].index do |code|
97
+ level += 1 if code == '['
98
+ level -= 1 if code == ']'
99
+ level == 0
100
+ end
101
+ pc_value = idx + pc_value + 1
102
+ end
103
+ when ']'
104
+ level = 1
105
+ idx = code.chars[0...pc_value].rindex do |code|
106
+ level += 1 if code == ']'
107
+ level -= 1 if code == '['
108
+ level == 0
109
+ end
110
+ pc_value = idx - 1
111
+ end
112
+
113
+ jump(corrector, pc, pc_value+1)
114
+ end
115
+ end
116
+
117
+ def code_value(node)
118
+ v =
119
+ case node.type
120
+ when :str
121
+ node.str_content
122
+ when :dstr
123
+ node.children.map(&:str_content).join
124
+ else
125
+ raise
126
+ end
127
+ v.chars.select{|c| %w{> < + - . , [ ]}.include?(c)}.join
128
+ end
129
+
130
+ def to_array(node)
131
+ node.children.map{|n| int_value(n)}
132
+ end
133
+
134
+ def jump(corrector, pc, v)
135
+ corrector.replace(
136
+ pc.loc.expression,
137
+ v.to_s
138
+ )
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rubocop/brainfuck/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rubocop-brainfuck"
8
+ spec.version = Rubocop::Brainfuck::VERSION
9
+ spec.authors = ["Masataka Kuwabara"]
10
+ spec.email = ["kuwabara@pocke.me"]
11
+
12
+ spec.summary = %q{A Brainfuck interpreter implementation on RuboCop}
13
+ spec.description = %q{A Brainfuck interpreter implementation on RuboCop}
14
+ spec.homepage = "https://github.com/pocke/rubocop-brainfuck"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_runtime_dependency 'rubocop', '>= 0.42.0'
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.14"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "rspec"
28
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubocop-brainfuck
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Masataka Kuwabara
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-03-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rubocop
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.42.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.42.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.14'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: A Brainfuck interpreter implementation on RuboCop
70
+ email:
71
+ - kuwabara@pocke.me
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - Gemfile
79
+ - README.md
80
+ - Rakefile
81
+ - bin/console
82
+ - bin/setup
83
+ - config/default.yml
84
+ - lib/rubocop/brainfuck.rb
85
+ - lib/rubocop/brainfuck/inject.rb
86
+ - lib/rubocop/brainfuck/version.rb
87
+ - lib/rubocop/cop/brainfuck/interpreter.rb
88
+ - rubocop-brainfuck.gemspec
89
+ homepage: https://github.com/pocke/rubocop-brainfuck
90
+ licenses: []
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.6.8
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: A Brainfuck interpreter implementation on RuboCop
112
+ test_files: []