esolang 0.1.2

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: 48161d9cd63a90d101a9f5936464c053d2295b9ef7b500c95ad3cb2ff3049dc7
4
+ data.tar.gz: 4c570f8ff4b1de1c7c115572e1d3ab06a8d84015936a82ecfdcd98396b7fea24
5
+ SHA512:
6
+ metadata.gz: 8777ec08eac7ae40588d31fb178b9ebee874f12fd9847eba36c52132312e9c96db43113e970fa0632be4c70bac9569b0d4bd6c5d96cd33093f1a5b3812e21bf9
7
+ data.tar.gz: e9033263c0ea899c52be1a33c968c2b3ca667bf3f6a35b14f70a6cb7e457b7a0e95e018b6cda2beed83b198f743adf735bde5bd0cb6742d367d2adbf10eead89
data/lib/esolang.rb ADDED
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/interpreters/boolfuck_interpreter.rb'
4
+ require_relative '../lib/interpreters/smallfuck_interpreter.rb'
5
+ require_relative '../lib/interpreters/paintfuck_interpreter.rb'
6
+ require_relative '../lib/interpreters/brainfuck_interpreter.rb'
7
+ require_relative '../lib/interpreters/ook_interpreter.rb'
8
+
9
+ require_relative '../lib/refinements/refinements.rb'
10
+
11
+ # The Esolang module provides methods to interpret esoteric programming languages.
12
+ #
13
+ # To use it you need to:
14
+ #
15
+ # ```ruby
16
+ # using Esolang::Refinements
17
+ # ```
18
+ module Esolang
19
+ # Interprets Boolfuck code.
20
+ #
21
+ # @param code [String] The Boolfuck code to interpret.
22
+ # @param input [String] The input for the Boolfuck program (optional).
23
+ # @return [String] The result of the Boolfuck interpretation.
24
+ def self.boolfuck(code, input = '')
25
+ Interpreters::Boolfuck.new(code, input).run
26
+ end
27
+
28
+ # Interprets Smallfuck code.
29
+ #
30
+ # @param code [String] The Smallfuck code to interpret.
31
+ # @param tape [String] The initial tape state for the Smallfuck program.
32
+ # @return [String] The result of the Smallfuck interpretation.
33
+ def self.smallfuck(code, tape)
34
+ Interpreters::Smallfuck.new(code, tape).run
35
+ end
36
+
37
+ # Interprets Paintfuck code.
38
+ #
39
+ # @param code [String] The Paintfuck code to interpret.
40
+ # @param iterations [Integer] The number of iterations for the Paintfuck program.
41
+ # @param width [Integer] The width of the Paintfuck canvas.
42
+ # @param height [Integer] The height of the Paintfuck canvas.
43
+ # @return [String] The result of the Paintfuck interpretation.
44
+ def self.paintfuck(code, iterations, width, height)
45
+ Interpreters::Paintfuck.new(code, iterations, width, height).run
46
+ end
47
+
48
+ # Interprets Brainfuck code.
49
+ #
50
+ # @param code [String] The Brainfuck code to interpret.
51
+ # @param input [String] The input for the Brainfuck program (optional).
52
+ # @return [String] The result of the Brainfuck interpretation.
53
+ def self.brainfuck(code, input = '')
54
+ Interpreters::Brainfuck.new(code, input).run
55
+ end
56
+
57
+ # Interprets Ook! code.
58
+ #
59
+ # @param code [String] The Ook! code to interpret.
60
+ # @param input [String] The input for the Ook! program (optional).
61
+ # @return [String] The result of the Ook! interpretation.
62
+ def self.ook(code, input = '')
63
+ Interpreters::Ook.new(code, input).run
64
+ end
65
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esolang
4
+ module Interpreters
5
+ # The BaseInterpreter class provides a common interface and basic functionality for
6
+ # interpreting esoteric programming languages.
7
+ class BaseInterpreter
8
+ # Initializes a new instance of the BaseInterpreter class.
9
+ #
10
+ # @param code [String] The code to interpret.
11
+ def initialize(code)
12
+ @code = code.chars
13
+ @code_pointer = 0
14
+ @loop_map = create_loop_map
15
+ @tape_pointer = 0
16
+ end
17
+
18
+ # Executes the interpretation of the code. Subclasses must implement this method.
19
+ #
20
+ # @abstract Subclasses must implement the run method.
21
+ # @raise [NotImplementedError] Raised if the method is not implemented by subclasses.
22
+ def run
23
+ raise NotImplementedError, 'Subclasses must implement the run method'
24
+ end
25
+
26
+ private
27
+
28
+ # Moves the tape pointer to the right.
29
+ def move_right
30
+ @tape_pointer += 1
31
+ end
32
+
33
+ # Moves the tape pointer to the left.
34
+ def move_left
35
+ @tape_pointer -= 1
36
+ end
37
+
38
+ # Reads input and writes it to the tape.
39
+ def input_to_tape
40
+ @input.empty? ? current_bit(0) : current_bit(@input.shift)
41
+ end
42
+
43
+ # Reads the tape and appends the current bit to the output array.
44
+ def tape_to_output_array
45
+ @output << current_bit
46
+ end
47
+
48
+ # Creates a map of loop indices for efficient loop navigation.
49
+ def create_loop_map
50
+ map = {}
51
+ stack = []
52
+
53
+ @code.each_with_index do |command, index|
54
+ case command
55
+ when '[' then stack << index
56
+ when ']'
57
+ if stack.empty?
58
+ raise StandardError, "Invalid code: No matching '[' for ']' at index #{index}"
59
+ else
60
+ map[stack.pop] = index
61
+ end
62
+ end
63
+ end
64
+
65
+ raise StandardError, "Invalid code: No matching ']' for '[' at index #{stack.last}" unless stack.empty?
66
+
67
+ map
68
+ end
69
+
70
+ # Jumps to the matching ']' if the current bit is zero.
71
+ def loop_begin
72
+ return unless current_bit.zero?
73
+
74
+ @code_pointer = @loop_map[@code_pointer]
75
+ end
76
+
77
+ # Jumps back to the matching '[' if the current bit is non-zero.
78
+ def loop_end
79
+ return if current_bit.zero?
80
+
81
+ @code_pointer = @loop_map.key(@code_pointer)
82
+ end
83
+
84
+ # Flips the current bit.
85
+ def flip
86
+ current_bit(current_bit ^ 1)
87
+ end
88
+
89
+ # Retrieves the value of the current bit. Subclasses must implement this method.
90
+ #
91
+ # @abstract Subclasses must implement the current_bit method.
92
+ # @raise [NotImplementedError] Raised if the method is not implemented by subclasses.
93
+ def current_bit
94
+ raise NotImplementedError, 'Subclasses must implement the current_bit method'
95
+ end
96
+
97
+ # Checks if the interpreter is still running (code execution is not completed).
98
+ def running?
99
+ @code_pointer < @code.length
100
+ end
101
+
102
+ # Retrieves the current command in the code.
103
+ def command
104
+ @code[@code_pointer]
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_interpreter'
4
+
5
+ module Esolang
6
+ module Interpreters
7
+ # The Boolfuck class represents an interpreter for the Boolfuck esoteric programming language.
8
+ class Boolfuck < BaseInterpreter
9
+ # Initializes a new instance of the Boolfuck interpreter.
10
+ #
11
+ # @param code [String] The Boolfuck code to interpret.
12
+ # @param input [String] The input for the Boolfuck program (optional).
13
+ def initialize(code, input = '')
14
+ super(code.gsub(/[^,\.;<>\+\[\]]/, ''))
15
+ @input = chars_to_bits(input)
16
+ @output = []
17
+ @tape = Hash.new(0)
18
+ end
19
+
20
+ # Executes the interpretation of the Boolfuck code.
21
+ #
22
+ # @return [String] The result of the Boolfuck interpretation.
23
+ def run
24
+ while running? do
25
+ case command
26
+ when ',' then input_to_tape
27
+ when ';' then tape_to_output_array
28
+ when '>' then move_right
29
+ when '<' then move_left
30
+ when '+' then flip
31
+ when '[' then loop_begin
32
+ when ']' then loop_end
33
+ end
34
+
35
+ @code_pointer += 1
36
+ end
37
+
38
+ translate_output_bits_to_chars
39
+ end
40
+
41
+ private
42
+
43
+ # Converts characters to bits (0 or 1).
44
+ #
45
+ # @param chars [String] The characters to convert.
46
+ # @return [Array<Integer>] The array of bits.
47
+ def chars_to_bits(chars)
48
+ chars.chars.map { |char| [char.ord].pack("C*").unpack("b*")[0] }.join.chars.map(&:to_i)
49
+ end
50
+
51
+ # Retrieves or updates the value of the current bit on the tape.
52
+ #
53
+ # @param new_value [Integer] The new value for the current bit (optional).
54
+ # @return [Integer] The value of the current bit.
55
+ def current_bit(new_value = nil)
56
+ @tape[@tape_pointer] = new_value unless new_value.nil?
57
+
58
+ @tape[@tape_pointer]
59
+ end
60
+
61
+ # Translates the bits in the output array to characters.
62
+ #
63
+ # @return [String] The translated characters.
64
+ def translate_output_bits_to_chars
65
+ zeros_count_to_fill = (@output.length % 8).zero? ? 0 : 8 - (@output.length % 8)
66
+
67
+ @output.fill(0, @output.length, zeros_count_to_fill).each_slice(8).map do |byte|
68
+ byte.join.reverse.to_i(2).chr
69
+ end.join
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_interpreter'
4
+
5
+ module Esolang
6
+ module Interpreters
7
+ # The Brainfuck class represents an interpreter for the Brainfuck esoteric programming language.
8
+ class Brainfuck < BaseInterpreter
9
+ # Initializes a new instance of the Brainfuck interpreter.
10
+ #
11
+ # @param code [String] The Brainfuck code to interpret.
12
+ # @param input [String] The input for the Brainfuck program (optional).
13
+ def initialize(code, input = '')
14
+ # Added ? to valid chars for compatibility with Ook! But don't parse ? in Brainfuck
15
+ super(code.gsub(/[^\?,\.<>\+-\[\]]/, ''))
16
+ @input = chars_to_bytes(input)
17
+ @output = []
18
+ @tape = Hash.new(0)
19
+ end
20
+
21
+ # Executes the interpretation of the Brainfuck code.
22
+ #
23
+ # @return [String] The result of the Brainfuck interpretation.
24
+ def run
25
+ while running? do
26
+ case command
27
+ when ',' then input_to_tape
28
+ when '.' then tape_to_output_array
29
+ when '>' then move_right
30
+ when '<' then move_left
31
+ when '+' then increment
32
+ when '-' then decrement
33
+ when '[' then loop_begin
34
+ when ']' then loop_end
35
+ end
36
+
37
+ @code_pointer += 1
38
+ end
39
+
40
+ translate_output_bytes_to_chars
41
+ end
42
+
43
+ private
44
+
45
+ # Increments the value of the current bit on the tape.
46
+ def increment
47
+ current_bit((current_bit + 1) % 256)
48
+ end
49
+
50
+ # Decrements the value of the current bit on the tape.
51
+ def decrement
52
+ current_bit((current_bit - 1) % 256)
53
+ end
54
+
55
+ # Converts characters to byte values.
56
+ #
57
+ # @param chars [String] The characters to convert.
58
+ # @return [Array<Integer>] The array of byte values.
59
+ def chars_to_bytes(chars)
60
+ chars.chars.map { |char| char.ord }
61
+ end
62
+
63
+ # Retrieves or updates the value of the current bit on the tape.
64
+ #
65
+ # @param new_value [Integer] The new value for the current bit (optional).
66
+ # @return [Integer] The value of the current bit.
67
+ def current_bit(new_value = nil)
68
+ @tape[@tape_pointer] = new_value unless new_value.nil?
69
+
70
+ @tape[@tape_pointer]
71
+ end
72
+
73
+ # Translates the byte values in the output array to characters.
74
+ #
75
+ # @return [String] The translated characters.
76
+ def translate_output_bytes_to_chars
77
+ @output.map { |char| char.chr }.join
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'brainfuck_interpreter'
4
+
5
+ module Esolang
6
+ module Interpreters
7
+ # The Ook class represents an interpreter for the Ook! esoteric programming language,
8
+ # which is translated to Brainfuck for execution.
9
+ class Ook < Brainfuck
10
+ # Initializes a new instance of the Ook interpreter.
11
+ #
12
+ # @param code [String] The Ook code to interpret.
13
+ # @param input [String] The input for the Ook program (optional).
14
+ def initialize(code, input = '')
15
+ super(translate_to_brainfuck(code), input)
16
+ @input = input
17
+ end
18
+
19
+ # Executes the interpretation of the Ook code.
20
+ #
21
+ # @return [String] The result of the Ook interpretation.
22
+ def run
23
+ while running? do
24
+ case command
25
+ when ',' then input_to_tape
26
+ when '.' then tape_to_output_array
27
+ when '>' then move_right
28
+ when '<' then move_left
29
+ when '+' then increment
30
+ when '-' then decrement
31
+ when '[' then loop_begin
32
+ when ']' then loop_end
33
+ when '?' then banana
34
+ end
35
+
36
+ @code_pointer += 1
37
+ end
38
+
39
+ translate_output_bytes_to_chars
40
+ end
41
+
42
+ private
43
+
44
+ # Translates Ook! code to Brainfuck code.
45
+ #
46
+ # @param code [String] The Ook code to translate.
47
+ # @return [String] The translated Brainfuck code.
48
+ def translate_to_brainfuck(code)
49
+ code.gsub(/[^\.\!\?]/, '').chars.each_slice(2).map do |command|
50
+ case command.join
51
+ when ".?" then ">"
52
+ when "?." then "<"
53
+ when ".." then "+"
54
+ when "!!" then "-"
55
+ when "!." then "."
56
+ when ".!" then ","
57
+ when "!?" then "["
58
+ when "?!" then "]"
59
+ when "??" then "?"
60
+ end
61
+ end.join
62
+ end
63
+
64
+ # Prints a message indicating that the memory pointer got a banana.
65
+ def banana
66
+ puts "The memory pointer got a banana"
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_interpreter'
4
+
5
+ module Esolang
6
+ module Interpreters
7
+ # The Paintfuck class represents an interpreter for the Paintfuck esoteric programming language.
8
+ class Paintfuck < BaseInterpreter
9
+ # Initializes a new instance of the Paintfuck interpreter.
10
+ #
11
+ # @param code [String] The Paintfuck code to interpret.
12
+ # @param iterations [Integer] The number of iterations for the Paintfuck program.
13
+ # @param width [Integer] The width of the Paintfuck canvas.
14
+ # @param height [Integer] The height of the Paintfuck canvas.
15
+ def initialize(code, iterations, width, height)
16
+ super(code.gsub(/[^nesw\*\[\]]/, ''))
17
+ @iterations = iterations
18
+ @width = width
19
+ @height = height
20
+ @data_grid = generate_zero_grid
21
+ @grid_pointer = [0, 0]
22
+ end
23
+
24
+ # Executes the interpretation of the Paintfuck code.
25
+ #
26
+ # @return [String] The result of the Paintfuck interpretation.
27
+ def run
28
+ while running? do
29
+ case command
30
+ when 'n' then move_up
31
+ when 'e' then move_right
32
+ when 's' then move_down
33
+ when 'w' then move_left
34
+ when '*' then flip
35
+ when '[' then loop_begin
36
+ when ']' then loop_end
37
+ end
38
+
39
+ @code_pointer += 1
40
+ @iterations -= 1
41
+ end
42
+
43
+ output
44
+ end
45
+
46
+ private
47
+
48
+ # Moves the grid pointer up.
49
+ def move_up
50
+ @grid_pointer[0] = (@grid_pointer.first - 1 + @height) % @height
51
+ end
52
+
53
+ # Moves the grid pointer down.
54
+ def move_down
55
+ @grid_pointer[0] = (@grid_pointer.first + 1 + @height) % @height
56
+ end
57
+
58
+ # Moves the grid pointer right.
59
+ def move_right
60
+ @grid_pointer[1] = (@grid_pointer.last + 1 + @width) % @width
61
+ end
62
+
63
+ # Moves the grid pointer left.
64
+ def move_left
65
+ @grid_pointer[1] = (@grid_pointer.last - 1 + @width) % @width
66
+ end
67
+
68
+ # Retrieves or updates the value of the current bit on the Paintfuck canvas.
69
+ #
70
+ # @param new_value [Integer] The new value for the current bit (optional).
71
+ # @return [Integer] The value of the current bit.
72
+ def current_bit(new_value = nil)
73
+ @data_grid[@grid_pointer.first][@grid_pointer.last] = new_value unless new_value.nil?
74
+
75
+ @data_grid[@grid_pointer.first][@grid_pointer.last]
76
+ end
77
+
78
+ # Retrieves the output of the Paintfuck program.
79
+ #
80
+ # @return [String] The Paintfuck canvas as a string.
81
+ def output
82
+ @data_grid
83
+ .map { |row| row.join }
84
+ .join("\r\n")
85
+ end
86
+
87
+ # Generates a canvas grid filled with zeros.
88
+ #
89
+ # @return [Array<Array<Integer>>] The zero-filled grid.
90
+ def generate_zero_grid
91
+ (1..@height).map { [0] * @width }
92
+ end
93
+
94
+ # Checks if the interpreter is still running (code execution is not completed).
95
+ #
96
+ # @return [Boolean] Returns true if the interpreter is still running, otherwise false.
97
+ def running?
98
+ @iterations.positive? && super
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_interpreter'
4
+
5
+ module Esolang
6
+ module Interpreters
7
+ # The Smallfuck class represents an interpreter for the Smallfuck esoteric programming language.
8
+ class Smallfuck < BaseInterpreter
9
+ # Initializes a new instance of the Smallfuck interpreter.
10
+ #
11
+ # @param code [String] The Smallfuck code to interpret.
12
+ # @param tape [String] The initial tape state for the Smallfuck program.
13
+ def initialize(code, tape)
14
+ super(code.gsub(/[^<>\*\[\]]/, ''))
15
+ @tape = tape.chars.map(&:to_i)
16
+ end
17
+
18
+ # Executes the interpretation of the Smallfuck code.
19
+ #
20
+ # @return [String] The result of the Smallfuck interpretation.
21
+ def run
22
+ while running? do
23
+ case command
24
+ when '>' then move_right
25
+ when '<' then move_left
26
+ when '*' then flip
27
+ when '[' then loop_begin
28
+ when ']' then loop_end
29
+ end
30
+ @code_pointer += 1
31
+ end
32
+ @tape.join
33
+ end
34
+
35
+ private
36
+
37
+ # Checks if the interpreter is still running (code execution is not completed).
38
+ #
39
+ # @return [Boolean] Returns true if the interpreter is still running, otherwise false.
40
+ def running?
41
+ @tape_pointer < @tape.length &&
42
+ @tape_pointer >= 0 &&
43
+ super
44
+ end
45
+
46
+ # Retrieves or updates the value of the current bit on the tape.
47
+ #
48
+ # @param new_value [Integer] The new value for the current bit (optional).
49
+ # @return [Integer] The value of the current bit.
50
+ def current_bit(new_value = nil)
51
+ @tape[@tape_pointer] = new_value unless new_value.nil?
52
+
53
+ @tape[@tape_pointer]
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esolang
4
+ # The Refinements module provides refinements for String class to enable
5
+ # direct interpretation of esoteric programming languages.
6
+ #
7
+ # To use these refinements, you need to include them using the `using` keyword:
8
+ #
9
+ # ```ruby
10
+ # require 'esolang'
11
+ # ```
12
+ module Refinements
13
+ # Refines the String class to provide a convenient method for interpreting Boolfuck code.
14
+ refine String do
15
+ # Interprets Boolfuck code directly on a String.
16
+ #
17
+ # @param input [String] The input for the Boolfuck program (optional).
18
+ # @return [String] The result of the Boolfuck interpretation.
19
+ def boolfuck(input = '')
20
+ Esolang::Interpreters::Boolfuck.new(self, input).run
21
+ end
22
+
23
+ # Interprets Smallfuck code directly on a String.
24
+ #
25
+ # @param tape [String] The initial tape state for the Smallfuck program.
26
+ # @return [String] The result of the Smallfuck interpretation.
27
+ def smallfuck(tape)
28
+ Esolang::Interpreters::Smallfuck.new(self, tape).run
29
+ end
30
+
31
+ # Interprets Paintfuck code directly on a String.
32
+ #
33
+ # @param iterations [Integer] The number of iterations for the Paintfuck program.
34
+ # @param width [Integer] The width of the Paintfuck canvas.
35
+ # @param height [Integer] The height of the Paintfuck canvas.
36
+ # @return [String] The result of the Paintfuck interpretation.
37
+ def paintfuck(iterations, width, height)
38
+ Esolang::Interpreters::Paintfuck.new(self, iterations, width, height).run
39
+ end
40
+
41
+ # Interprets Brainfuck code directly on a String.
42
+ #
43
+ # @param input [String] The input for the Brainfuck program (optional).
44
+ # @return [String] The result of the Brainfuck interpretation.
45
+ def brainfuck(input = '')
46
+ Esolang::Interpreters::Brainfuck.new(self, input).run
47
+ end
48
+
49
+ # Interprets Ook! code directly on a String.
50
+ #
51
+ # @param input [String] The input for the Ook! program (optional).
52
+ # @return [String] The result of the Ook! interpretation.
53
+ def ook(input = '')
54
+ Esolang::Interpreters::Ook.new(self, input).run
55
+ end
56
+ end
57
+ end
58
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: esolang
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Kipp
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-01-22 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: |-
14
+ A gem for working with esoteric programming languages.
15
+ Usage: require 'esolang'; using Esolang::Refinements
16
+ Adds string refinements, usage: e.g. 'code_string'.boolfuck('user_input'). Alternative usage: e.g. Esolang.boolfuck(code, input)
17
+ email:
18
+ - daniel.kipp@gmail.com
19
+ executables: []
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - lib/esolang.rb
24
+ - lib/interpreters/base_interpreter.rb
25
+ - lib/interpreters/boolfuck_interpreter.rb
26
+ - lib/interpreters/brainfuck_interpreter.rb
27
+ - lib/interpreters/ook_interpreter.rb
28
+ - lib/interpreters/paintfuck_interpreter.rb
29
+ - lib/interpreters/smallfuck_interpreter.rb
30
+ - lib/refinements/refinements.rb
31
+ homepage:
32
+ licenses:
33
+ - MIT
34
+ metadata: {}
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubygems_version: 3.3.7
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: Interpreter gem for different Esolangs
54
+ test_files: []