syntax_tree-bf 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ddb9a72bfa7b2fd5f6960214c364bf2dea81ecd90f4512187280fca93a0e086c
4
+ data.tar.gz: b6c92797a50f0a94b160aa5d4e2ccccd81472a0b770a79c2c7e7bccad47c166c
5
+ SHA512:
6
+ metadata.gz: 30f416c5e87cdafd9f088655ab4f0eac4bdaa99ce8bc0a10cc492435fb7b03fbca87c0e461147c94d7a9004bface66c21d0927441cb8bf1e98b8be8775428ed5
7
+ data.tar.gz: e3f09df44d161a2212ab2e6075e0f2b77457fdf4e2b3988886b126287a93c9ea76b82133659a87a32439bd038e52c89b4a8b978a6d5672b92cbf20a9fddb203f
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "bundler"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "daily"
@@ -0,0 +1,34 @@
1
+ name: Main
2
+ on:
3
+ - push
4
+ - pull_request_target
5
+ jobs:
6
+ ci:
7
+ name: CI
8
+ runs-on: ubuntu-latest
9
+ env:
10
+ CI: true
11
+ steps:
12
+ - uses: actions/checkout@master
13
+ - uses: ruby/setup-ruby@v1
14
+ with:
15
+ bundler-cache: true
16
+ ruby-version: '3.1'
17
+ - name: Test
18
+ run: |
19
+ bundle exec rake test
20
+ bundle exec rake stree:check
21
+ automerge:
22
+ name: AutoMerge
23
+ needs: ci
24
+ runs-on: ubuntu-latest
25
+ if: github.event_name == 'pull_request_target' && github.actor == 'dependabot[bot]'
26
+ steps:
27
+ - uses: actions/github-script@v3
28
+ with:
29
+ script: |
30
+ github.pulls.merge({
31
+ owner: context.payload.repository.owner.login,
32
+ repo: context.payload.repository.name,
33
+ pull_number: context.payload.pull_request.number
34
+ })
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ test.bf
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2022-05-26
10
+
11
+ ### Added
12
+
13
+ - 🎉 Initial release! 🎉
14
+
15
+ [unreleased]: https://github.com/ruby-syntax-tree/syntax_tree-bf/compare/v0.1.0...HEAD
16
+ [0.1.0]: https://github.com/ruby-syntax-tree/syntax_tree-bf/compare/30c324...v0.1.0
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ syntax_tree-bf (0.1.0)
5
+ prettier_print
6
+ syntax_tree (>= 2.0.1)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ docile (1.4.0)
12
+ minitest (5.15.0)
13
+ prettier_print (0.1.0)
14
+ rake (13.0.6)
15
+ simplecov (0.21.2)
16
+ docile (~> 1.1)
17
+ simplecov-html (~> 0.11)
18
+ simplecov_json_formatter (~> 0.1)
19
+ simplecov-html (0.12.3)
20
+ simplecov_json_formatter (0.1.4)
21
+ syntax_tree (2.7.1)
22
+ prettier_print
23
+
24
+ PLATFORMS
25
+ x86_64-darwin-21
26
+ x86_64-linux
27
+
28
+ DEPENDENCIES
29
+ bundler
30
+ minitest
31
+ rake
32
+ simplecov
33
+ syntax_tree-bf!
34
+
35
+ BUNDLED WITH
36
+ 2.3.6
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022-present Kevin Newton
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # SyntaxTree::Bf
2
+
3
+ [![Build Status](https://github.com/ruby-syntax-tree/syntax_tree-bf/actions/workflows/main.yml/badge.svg)](https://github.com/ruby-syntax-tree/syntax_tree-bf/actions/workflows/main.yml)
4
+ [![Gem Version](https://img.shields.io/gem/v/syntax_tree-bf.svg)](https://rubygems.org/gems/syntax_tree-bf)
5
+
6
+ [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree) support for Brainf***.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem "syntax_tree-bf"
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle install
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install syntax_tree-bf
23
+
24
+ ## Usage
25
+
26
+ From code:
27
+
28
+ ```ruby
29
+ require "syntax_tree/bf"
30
+
31
+ pp SyntaxTree::Bf.parse(source) # print out the AST
32
+ puts SyntaxTree::Bf.format(source) # format the AST
33
+ ```
34
+
35
+ From the CLI:
36
+
37
+ ```sh
38
+ $ stree ast --plugins=bf file.bf
39
+ (root
40
+ (increment),
41
+ ...
42
+ (increment),
43
+ (loop
44
+ (shift_right),
45
+ ...
46
+ (decrement)
47
+ ),
48
+ (shift_right),
49
+ ...
50
+ (output)
51
+ )
52
+ ```
53
+
54
+ or
55
+
56
+ ```sh
57
+ $ stree format --plugins=bf file.bf
58
+ ++++++++[
59
+ >++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-
60
+ ]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
61
+ ```
62
+
63
+ or
64
+
65
+ ```sh
66
+ $ stree write --plugins=bf file.bf
67
+ file.bf 1ms
68
+ ```
69
+
70
+ ## Contributing
71
+
72
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ruby-syntax-tree/syntax_tree-bf.
73
+
74
+ ## License
75
+
76
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+ require "syntax_tree/rake_tasks"
6
+
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.libs << "test"
9
+ t.libs << "lib"
10
+ t.test_files = FileList["test/**/*_test.rb"]
11
+ end
12
+
13
+ source_files = FileList["{lib,test}/**/*.rb"]
14
+ SyntaxTree::Rake::CheckTask.new { |t| t.source_files = source_files }
15
+ SyntaxTree::Rake::WriteTask.new { |t| t.source_files = source_files }
16
+
17
+ task default: :test
data/exe/bf ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.expand_path("../lib", __dir__))
4
+ require "syntax_tree/bf"
5
+
6
+ SyntaxTree::Bf::Evaluate.run(ARGF.read)
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SyntaxTree
4
+ module Bf
5
+ module Evaluate
6
+ # Takes a bf syntax tree and compiles it down to a simple bytecode. The
7
+ # instructions almost entirely map to the tree nodes except:
8
+ #
9
+ # * Root - replaced by its contents
10
+ # * Loop - replaced by a jmz (jump if zero) and a jmp (unconditional jump)
11
+ #
12
+ class Compiler < Visitor
13
+ attr_reader :insns
14
+
15
+ def initialize
16
+ @insns = []
17
+ end
18
+
19
+ def visit_root(node)
20
+ super
21
+ end
22
+
23
+ def visit_loop(node)
24
+ index = insns.length
25
+ insns << [:jmz, -1]
26
+
27
+ super
28
+
29
+ insns << [:jmp, index]
30
+ insns[index][1] = insns.length
31
+ end
32
+
33
+ def visit_increment(node)
34
+ insns << [:inc]
35
+ end
36
+
37
+ def visit_decrement(node)
38
+ insns << [:dec]
39
+ end
40
+
41
+ def visit_shift_right(node)
42
+ insns << [:shr]
43
+ end
44
+
45
+ def visit_shift_left(node)
46
+ insns << [:shl]
47
+ end
48
+
49
+ def visit_input(node)
50
+ insns << [:inp]
51
+ end
52
+
53
+ def visit_output(node)
54
+ insns << [:out]
55
+ end
56
+ end
57
+
58
+ # This is the virtual machine that runs the set of instructions that the
59
+ # compiler outputs. Its state is kept on an infinite tape of memory, which
60
+ # is paired with a cursor.
61
+ class Machine
62
+ attr_reader :insns, :stdin, :stdout
63
+
64
+ def initialize(insns, stdin: STDIN, stdout: STDOUT)
65
+ @insns = insns
66
+ @stdin = stdin
67
+ @stdout = stdout
68
+ end
69
+
70
+ def run
71
+ pc = 0
72
+
73
+ tape = Hash.new { 0 }
74
+ cursor = 0
75
+
76
+ while pc < insns.length
77
+ insn = insns[pc]
78
+ pc += 1
79
+
80
+ case insn
81
+ in [:inc]
82
+ tape[cursor] += 1
83
+ in [:dec]
84
+ tape[cursor] -= 1
85
+ in [:shr]
86
+ cursor += 1
87
+ in [:shl]
88
+ cursor -= 1
89
+ in [:inp]
90
+ tape[cursor] = stdin.getc.ord
91
+ in [:out]
92
+ stdout.putc(tape[cursor].chr)
93
+ in [:jmz, offset]
94
+ pc = offset if tape[cursor] == 0
95
+ in [:jmp, offset]
96
+ pc = offset
97
+ end
98
+ end
99
+
100
+ tape
101
+ end
102
+ end
103
+
104
+ def self.run(source, stdin: STDIN, stdout: STDOUT)
105
+ node = Parser.new(source).parse
106
+ compiler = Compiler.new
107
+
108
+ compiler.visit(node)
109
+ Machine.new(compiler.insns, stdin: stdin, stdout: stdout).run
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SyntaxTree
4
+ module Bf
5
+ class Format < Visitor
6
+ attr_reader :q
7
+
8
+ def initialize(q)
9
+ @q = q
10
+ end
11
+
12
+ def visit_root(node)
13
+ super
14
+ q.breakable(force: true)
15
+ end
16
+
17
+ def visit_loop(node)
18
+ q.group do
19
+ q.text("[")
20
+ q.nest(2) do
21
+ q.breakable("")
22
+ super
23
+ end
24
+ q.breakable("")
25
+ q.text("]")
26
+ end
27
+ end
28
+
29
+ def visit_increment(node)
30
+ q.text("+")
31
+ end
32
+
33
+ def visit_decrement(node)
34
+ q.text("-")
35
+ end
36
+
37
+ def visit_shift_right(node)
38
+ q.text(">")
39
+ end
40
+
41
+ def visit_shift_left(node)
42
+ q.text("<")
43
+ end
44
+
45
+ def visit_input(node)
46
+ q.text(",")
47
+ end
48
+
49
+ def visit_output(node)
50
+ q.text(".")
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,201 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SyntaxTree
4
+ module Bf
5
+ class Node
6
+ def format(q)
7
+ Format.new(q).visit(self)
8
+ end
9
+
10
+ def pretty_print(q)
11
+ PrettyPrint.new(q).visit(self)
12
+ end
13
+ end
14
+
15
+ # The root node of the syntax tree.
16
+ class Root < Node
17
+ attr_reader :nodes, :location
18
+
19
+ def initialize(nodes:, location:)
20
+ @nodes = nodes
21
+ @location = location
22
+ end
23
+
24
+ def accept(visitor)
25
+ visitor.visit_root(self)
26
+ end
27
+
28
+ def child_nodes
29
+ nodes
30
+ end
31
+
32
+ alias deconstruct child_nodes
33
+
34
+ def deconstruct_keys(keys)
35
+ { nodes: nodes, location: location }
36
+ end
37
+ end
38
+
39
+ # [ ... ]
40
+ class Loop < Node
41
+ attr_reader :nodes, :location
42
+
43
+ def initialize(nodes:, location:)
44
+ @nodes = nodes
45
+ @location = location
46
+ end
47
+
48
+ def accept(visitor)
49
+ visitor.visit_loop(self)
50
+ end
51
+
52
+ def child_nodes
53
+ nodes
54
+ end
55
+
56
+ alias deconstruct child_nodes
57
+
58
+ def deconstruct_keys(keys)
59
+ { nodes: nodes, location: location }
60
+ end
61
+ end
62
+
63
+ # +
64
+ class Increment < Node
65
+ attr_reader :location
66
+
67
+ def initialize(location:)
68
+ @location = location
69
+ end
70
+
71
+ def accept(visitor)
72
+ visitor.visit_increment(self)
73
+ end
74
+
75
+ def child_nodes
76
+ []
77
+ end
78
+
79
+ alias deconstruct child_nodes
80
+
81
+ def deconstruct_keys(keys)
82
+ { value: "+", location: location }
83
+ end
84
+ end
85
+
86
+ # -
87
+ class Decrement < Node
88
+ attr_reader :location
89
+
90
+ def initialize(location:)
91
+ @location = location
92
+ end
93
+
94
+ def accept(visitor)
95
+ visitor.visit_decrement(self)
96
+ end
97
+
98
+ def child_nodes
99
+ []
100
+ end
101
+
102
+ alias deconstruct child_nodes
103
+
104
+ def deconstruct_keys(keys)
105
+ { value: "-", location: location }
106
+ end
107
+ end
108
+
109
+ # >
110
+ class ShiftRight < Node
111
+ attr_reader :location
112
+
113
+ def initialize(location:)
114
+ @location = location
115
+ end
116
+
117
+ def accept(visitor)
118
+ visitor.visit_shift_right(self)
119
+ end
120
+
121
+ def child_nodes
122
+ []
123
+ end
124
+
125
+ alias deconstruct child_nodes
126
+
127
+ def deconstruct_keys(keys)
128
+ { value: ">", location: location }
129
+ end
130
+ end
131
+
132
+ # <
133
+ class ShiftLeft < Node
134
+ attr_reader :location
135
+
136
+ def initialize(location:)
137
+ @location = location
138
+ end
139
+
140
+ def accept(visitor)
141
+ visitor.visit_shift_left(self)
142
+ end
143
+
144
+ def child_nodes
145
+ []
146
+ end
147
+
148
+ alias deconstruct child_nodes
149
+
150
+ def deconstruct_keys(keys)
151
+ { value: "<", location: location }
152
+ end
153
+ end
154
+
155
+ # ,
156
+ class Input < Node
157
+ attr_reader :location
158
+
159
+ def initialize(location:)
160
+ @location = location
161
+ end
162
+
163
+ def accept(visitor)
164
+ visitor.visit_input(self)
165
+ end
166
+
167
+ def child_nodes
168
+ []
169
+ end
170
+
171
+ alias deconstruct child_nodes
172
+
173
+ def deconstruct_keys(keys)
174
+ { value: ",", location: location }
175
+ end
176
+ end
177
+
178
+ # .
179
+ class Output < Node
180
+ attr_reader :location
181
+
182
+ def initialize(location:)
183
+ @location = location
184
+ end
185
+
186
+ def accept(visitor)
187
+ visitor.visit_output(self)
188
+ end
189
+
190
+ def child_nodes
191
+ []
192
+ end
193
+
194
+ alias deconstruct child_nodes
195
+
196
+ def deconstruct_keys(keys)
197
+ { value: ".", location: location }
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SyntaxTree
4
+ module Bf
5
+ # Parses the given source code into a syntax tree.
6
+ class Parser
7
+ class Error < StandardError
8
+ end
9
+
10
+ attr_reader :source
11
+
12
+ def initialize(source)
13
+ @source = source
14
+ end
15
+
16
+ def parse
17
+ Root.new(nodes: parse_segment(source, 0), location: 0...source.length)
18
+ end
19
+
20
+ private
21
+
22
+ def parse_segment(segment, offset)
23
+ index = 0
24
+ nodes = []
25
+
26
+ while index < segment.length
27
+ location = offset + index
28
+
29
+ case segment[index]
30
+ when "+"
31
+ nodes << Increment.new(location: location...(location + 1))
32
+ index += 1
33
+ when "-"
34
+ nodes << Decrement.new(location: location...(location + 1))
35
+ index += 1
36
+ when ">"
37
+ nodes << ShiftRight.new(location: location...(location + 1))
38
+ index += 1
39
+ when "<"
40
+ nodes << ShiftLeft.new(location: location...(location + 1))
41
+ index += 1
42
+ when "."
43
+ nodes << Output.new(location: location...(location + 1))
44
+ index += 1
45
+ when ","
46
+ nodes << Input.new(location: location...(location + 1))
47
+ index += 1
48
+ when "["
49
+ matched = 1
50
+ end_index = index + 1
51
+
52
+ while matched != 0 && end_index < segment.length
53
+ case segment[end_index]
54
+ when "["
55
+ matched += 1
56
+ when "]"
57
+ matched -= 1
58
+ end
59
+
60
+ end_index += 1
61
+ end
62
+
63
+ raise Error, "Unmatched start loop" if matched != 0
64
+
65
+ content = segment[(index + 1)...(end_index - 1)]
66
+ nodes << Loop.new(
67
+ nodes: parse_segment(content, offset + index + 1),
68
+ location: location...(offset + end_index)
69
+ )
70
+
71
+ index = end_index
72
+ when "]"
73
+ raise Error, "Unmatched end loop"
74
+ else
75
+ index += 1
76
+ end
77
+ end
78
+
79
+ nodes
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SyntaxTree
4
+ module Bf
5
+ class PrettyPrint < Visitor
6
+ attr_reader :q
7
+
8
+ def initialize(q)
9
+ @q = q
10
+ end
11
+
12
+ def visit_root(node)
13
+ visit_node("root", node)
14
+ end
15
+
16
+ def visit_loop(node)
17
+ visit_node("loop", node)
18
+ end
19
+
20
+ def visit_increment(node)
21
+ visit_node("increment", node)
22
+ end
23
+
24
+ def visit_decrement(node)
25
+ visit_node("decrement", node)
26
+ end
27
+
28
+ def visit_shift_right(node)
29
+ visit_node("shift_right", node)
30
+ end
31
+
32
+ def visit_shift_left(node)
33
+ visit_node("shift_left", node)
34
+ end
35
+
36
+ def visit_input(node)
37
+ visit_node("input", node)
38
+ end
39
+
40
+ def visit_output(node)
41
+ visit_node("output", node)
42
+ end
43
+
44
+ private
45
+
46
+ def visit_node(name, node)
47
+ q.group do
48
+ q.text("(")
49
+ q.text(name)
50
+
51
+ if node.child_nodes.any?
52
+ q.nest(2) do
53
+ q.breakable
54
+ q.seplist(node.child_nodes) { |child_node| visit(child_node) }
55
+ end
56
+
57
+ q.breakable("")
58
+ end
59
+
60
+ q.text(")")
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SyntaxTree
4
+ module Bf
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SyntaxTree
4
+ module Bf
5
+ class Visitor
6
+ def visit(node)
7
+ node.accept(self)
8
+ end
9
+
10
+ def visit_all(nodes)
11
+ nodes.map { |node| visit(node) }
12
+ end
13
+
14
+ def visit_child_nodes(node)
15
+ visit_all(node.child_nodes)
16
+ end
17
+
18
+ # Visit a Root node.
19
+ alias visit_root visit_child_nodes
20
+
21
+ # Visit a Loop node.
22
+ alias visit_loop visit_child_nodes
23
+
24
+ # Visit an Increment node.
25
+ alias visit_increment visit_child_nodes
26
+
27
+ # Visit a Decrement node.
28
+ alias visit_decrement visit_child_nodes
29
+
30
+ # Visit a ShiftRight node.
31
+ alias visit_shift_right visit_child_nodes
32
+
33
+ # Visit a ShiftLeft node.
34
+ alias visit_shift_left visit_child_nodes
35
+
36
+ # Visit an Input node.
37
+ alias visit_input visit_child_nodes
38
+
39
+ # Visit an Output node.
40
+ alias visit_output visit_child_nodes
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "prettier_print"
4
+ require "syntax_tree"
5
+
6
+ require_relative "bf/nodes"
7
+ require_relative "bf/parser"
8
+ require_relative "bf/visitor"
9
+
10
+ require_relative "bf/evaluate"
11
+ require_relative "bf/format"
12
+ require_relative "bf/pretty_print"
13
+
14
+ module SyntaxTree
15
+ module Bf
16
+ def self.format(source, maxwidth = 80)
17
+ PrettierPrint.format(+"", maxwidth) { |q| parse(source).format(q) }
18
+ end
19
+
20
+ def self.parse(source)
21
+ Parser.new(source).parse
22
+ end
23
+
24
+ def self.read(source)
25
+ File.read(source)
26
+ end
27
+ end
28
+
29
+ register_handler(".bf", Bf)
30
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/syntax_tree/bf/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "syntax_tree-bf"
7
+ spec.version = SyntaxTree::Bf::VERSION
8
+ spec.authors = ["Kevin Newton"]
9
+ spec.email = ["kddnewton@gmail.com"]
10
+
11
+ spec.summary = "Syntax Tree support for Brainf***"
12
+ spec.homepage = "https://github.com/ruby-syntax-tree/syntax_tree-bf"
13
+ spec.license = "MIT"
14
+ spec.metadata = { "rubygems_mfa_required" => "true" }
15
+
16
+ spec.files = Dir.chdir(__dir__) do
17
+ `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ end
21
+
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = %w[lib]
25
+
26
+ spec.add_dependency "prettier_print"
27
+ spec.add_dependency "syntax_tree", ">= 2.0.1"
28
+
29
+ spec.add_development_dependency "bundler"
30
+ spec.add_development_dependency "minitest"
31
+ spec.add_development_dependency "rake"
32
+ spec.add_development_dependency "simplecov"
33
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: syntax_tree-bf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kevin Newton
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-05-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: prettier_print
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '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'
27
+ - !ruby/object:Gem::Dependency
28
+ name: syntax_tree
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 2.0.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
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
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description:
98
+ email:
99
+ - kddnewton@gmail.com
100
+ executables:
101
+ - bf
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".github/dependabot.yml"
106
+ - ".github/workflows/main.yml"
107
+ - ".gitignore"
108
+ - CHANGELOG.md
109
+ - Gemfile
110
+ - Gemfile.lock
111
+ - LICENSE
112
+ - README.md
113
+ - Rakefile
114
+ - exe/bf
115
+ - lib/syntax_tree/bf.rb
116
+ - lib/syntax_tree/bf/evaluate.rb
117
+ - lib/syntax_tree/bf/format.rb
118
+ - lib/syntax_tree/bf/nodes.rb
119
+ - lib/syntax_tree/bf/parser.rb
120
+ - lib/syntax_tree/bf/pretty_print.rb
121
+ - lib/syntax_tree/bf/version.rb
122
+ - lib/syntax_tree/bf/visitor.rb
123
+ - syntax_tree-bf.gemspec
124
+ homepage: https://github.com/ruby-syntax-tree/syntax_tree-bf
125
+ licenses:
126
+ - MIT
127
+ metadata:
128
+ rubygems_mfa_required: 'true'
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubygems_version: 3.3.3
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Syntax Tree support for Brainf***
148
+ test_files: []