esolang 0.1.2

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: 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: []