img_to_script 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +25 -0
  3. data/.vscode/launch.json +21 -0
  4. data/CHANGELOG.md +7 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +271 -0
  7. data/Rakefile +16 -0
  8. data/img_to_script.gemspec +41 -0
  9. data/lib/img_to_script/abs_token_type.rb +33 -0
  10. data/lib/img_to_script/abstract_token/abs_func.rb +19 -0
  11. data/lib/img_to_script/abstract_token/abstract_token.rb +23 -0
  12. data/lib/img_to_script/abstract_token/assign_value.rb +20 -0
  13. data/lib/img_to_script/abstract_token/clear_screen.rb +16 -0
  14. data/lib/img_to_script/abstract_token/data_read.rb +19 -0
  15. data/lib/img_to_script/abstract_token/data_store.rb +19 -0
  16. data/lib/img_to_script/abstract_token/draw_chunk_by_hex_value.rb +19 -0
  17. data/lib/img_to_script/abstract_token/draw_line_by_abs_coords.rb +22 -0
  18. data/lib/img_to_script/abstract_token/draw_pixel_by_abs_coords.rb +20 -0
  19. data/lib/img_to_script/abstract_token/go_to.rb +19 -0
  20. data/lib/img_to_script/abstract_token/if_condition.rb +20 -0
  21. data/lib/img_to_script/abstract_token/loop_begin.rb +21 -0
  22. data/lib/img_to_script/abstract_token/loop_end.rb +19 -0
  23. data/lib/img_to_script/abstract_token/math_add.rb +20 -0
  24. data/lib/img_to_script/abstract_token/math_greater_than.rb +20 -0
  25. data/lib/img_to_script/abstract_token/math_mult.rb +20 -0
  26. data/lib/img_to_script/abstract_token/math_sub.rb +20 -0
  27. data/lib/img_to_script/abstract_token/move_point_to_abs_coords.rb +20 -0
  28. data/lib/img_to_script/abstract_token/parentheses.rb +19 -0
  29. data/lib/img_to_script/abstract_token/program_begin.rb +16 -0
  30. data/lib/img_to_script/abstract_token/program_end.rb +16 -0
  31. data/lib/img_to_script/abstract_token/remark.rb +19 -0
  32. data/lib/img_to_script/abstract_token/sign_func.rb +19 -0
  33. data/lib/img_to_script/abstract_token/wait.rb +19 -0
  34. data/lib/img_to_script/abstract_token.rb +8 -0
  35. data/lib/img_to_script/container.rb +26 -0
  36. data/lib/img_to_script/current_line_placeholder.rb +40 -0
  37. data/lib/img_to_script/formatter.rb +34 -0
  38. data/lib/img_to_script/generators/generator.rb +134 -0
  39. data/lib/img_to_script/generators/hex_mask/default.rb +24 -0
  40. data/lib/img_to_script/generators/hex_mask/enhanced.rb +220 -0
  41. data/lib/img_to_script/generators/hex_mask/hex_mask.rb +100 -0
  42. data/lib/img_to_script/generators/hex_mask.rb +13 -0
  43. data/lib/img_to_script/generators/run_length_encoding/horizontal.rb +78 -0
  44. data/lib/img_to_script/generators/run_length_encoding/run_length_encoding.rb +304 -0
  45. data/lib/img_to_script/generators/run_length_encoding/vertical.rb +79 -0
  46. data/lib/img_to_script/generators/run_length_encoding.rb +10 -0
  47. data/lib/img_to_script/generators/segmental/data_read_draw/data_read_draw.rb +70 -0
  48. data/lib/img_to_script/generators/segmental/data_read_draw/horizontal.rb +54 -0
  49. data/lib/img_to_script/generators/segmental/data_read_draw/vertical.rb +54 -0
  50. data/lib/img_to_script/generators/segmental/data_read_draw.rb +18 -0
  51. data/lib/img_to_script/generators/segmental/direct_draw/direct_draw.rb +62 -0
  52. data/lib/img_to_script/generators/segmental/direct_draw/horizontal.rb +16 -0
  53. data/lib/img_to_script/generators/segmental/direct_draw/vertical.rb +16 -0
  54. data/lib/img_to_script/generators/segmental/direct_draw.rb +12 -0
  55. data/lib/img_to_script/generators/segmental/horizontal_mixin.rb +32 -0
  56. data/lib/img_to_script/generators/segmental/segmental.rb +101 -0
  57. data/lib/img_to_script/generators/segmental/vertical_mixin.rb +38 -0
  58. data/lib/img_to_script/generators/segmental.rb +10 -0
  59. data/lib/img_to_script/generators.rb +27 -0
  60. data/lib/img_to_script/import.rb +5 -0
  61. data/lib/img_to_script/language_token.rb +8 -0
  62. data/lib/img_to_script/languages/mk90_basic/formatters/formatter.rb +49 -0
  63. data/lib/img_to_script/languages/mk90_basic/formatters/minificator.rb +316 -0
  64. data/lib/img_to_script/languages/mk90_basic/formatters/sliceable_tokens_mixin.rb +15 -0
  65. data/lib/img_to_script/languages/mk90_basic/formatters.rb +13 -0
  66. data/lib/img_to_script/languages/mk90_basic/mk90_basic_token.rb +59 -0
  67. data/lib/img_to_script/languages/mk90_basic/translators/mixin.rb +205 -0
  68. data/lib/img_to_script/languages/mk90_basic/translators/mk90_basic_10.rb +27 -0
  69. data/lib/img_to_script/languages/mk90_basic/translators/mk90_basic_20.rb +27 -0
  70. data/lib/img_to_script/languages/mk90_basic/translators/translator.rb +205 -0
  71. data/lib/img_to_script/languages/mk90_basic/translators.rb +13 -0
  72. data/lib/img_to_script/languages/mk90_basic.rb +17 -0
  73. data/lib/img_to_script/languages.rb +10 -0
  74. data/lib/img_to_script/task.rb +26 -0
  75. data/lib/img_to_script/translator.rb +31 -0
  76. data/lib/img_to_script/version.rb +5 -0
  77. data/lib/img_to_script.rb +19 -0
  78. data/sig/img_to_script.rbs +4 -0
  79. metadata +204 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 98fc645a04ddc50a2633b04a8d82d5ba61514d478215908e64b19a66499120fc
4
+ data.tar.gz: 7a40da06bfb2c9b7fba74bfc2cc6b201b92ea672c27203da20096f0ecb05d347
5
+ SHA512:
6
+ metadata.gz: aba04a011f62d58441ccd402077de347788629c9eb41975de644674bb389726f367f3f92e167d9680b176561442089088d100f6e9c2c97724926329492f455fa
7
+ data.tar.gz: 87f2c883e748c07836d2f0b4d24961a34784b7a8932b2682855e929c3c4f8df05e466171a69058937dac744d634e8a40ea834efdda172bac88fe6493373ff4cb
data/.rubocop.yml ADDED
@@ -0,0 +1,25 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.0
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: double_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: double_quotes
11
+
12
+ Layout/LineLength:
13
+ Max: 120
14
+
15
+ Metrics/MethodLength:
16
+ Max: 15
17
+
18
+ Naming/MethodParameterName:
19
+ AllowedNames:
20
+ - x
21
+ - y
22
+ - x0
23
+ - x1
24
+ - y0
25
+ - y1
@@ -0,0 +1,21 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "type": "rdbg",
9
+ "name": "Debug current file with rdbg",
10
+ "request": "launch",
11
+ "script": "${file}",
12
+ "args": [],
13
+ "askParameters": true
14
+ },
15
+ {
16
+ "type": "rdbg",
17
+ "name": "Attach with rdbg",
18
+ "request": "attach"
19
+ }
20
+ ]
21
+ }
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ ## [1.0.0] - 2023-12-11
2
+
3
+ - API change.
4
+
5
+ ## [0.1.0] - 2023-11-26
6
+
7
+ - Initial release.
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 8bit-m8
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,271 @@
1
+ # ImgToScript
2
+
3
+ ## Introduction
4
+
5
+ **img_to_script** is a Ruby gem (a library) that converts images to executable scripts that plot the binary version of the image using the simple commands e.g. “draw a line”, “draw a dot”, etc..
6
+
7
+ The gem was initially developed to convert binary images to the executable scripts for the build-in BASIC interpreter of the Soviet vintage portable computer **Elektronika MK90**. Yet it is possible to expand the gem to support other similar hardware and script languages (e.g. the build-in TI-BASIC of the Z80-based TI calculators).
8
+
9
+ ![Elektronika MK90 renders an image with the build-in BASIC interpreter](/data/lain-mk90.jpg)
10
+
11
+ *Vintage Elektronika MK90 renders an image with the build-in BASIC interpreter. The program was generated by the **img_to_script** gem.*
12
+
13
+ The gem was designed as a library, i.e. it neither provide a user interface, nor validates the input data. It only provides an API, the rest should be handled by the external software. To make a converter you’ll need to build an application around the **img_to_script** gem and provide a user interface, e.g. a command-line interface or a web interface.
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ ```ruby
20
+ gem "img_to_script"
21
+ ```
22
+
23
+ And then execute:
24
+
25
+ $ bundle install
26
+
27
+ Or install it yourself as:
28
+
29
+ $ gem install img_to_script
30
+
31
+ ## Modules
32
+
33
+ Three steps are required to complete the conversion. The gem has a dedicated module (a namespace) for each step:
34
+
35
+ - **Generator** reads the image data and creates an array of the abstract tokens. Each token represents a simple command to the interpreter, e.g.: “draw a line”, “draw a dot”, “assign a value to a variable”, “start a loop”, etc..
36
+
37
+ - **Translator** is a mediator between a generator and a formatter. It translates abstract tokens to the specific statements of the target programming language. Translator chooses keywords, separators and handles other syntax issues.
38
+
39
+ - **Formatter** takes input from the translator and formats it into the executable script (a target language code). It can serve a function of a prettier or a minificator. Another common formatter’s task is to track down and to label BASIC line numbers.
40
+
41
+ ## Usage
42
+
43
+ ### API
44
+
45
+ ```ruby
46
+ ImgToScript::Task.new(
47
+ generator: generator,
48
+ translator: translator,
49
+ formatter: formatter
50
+ ).run(
51
+ image: image,
52
+ scr_width: scr_width,
53
+ scr_height: scr_height
54
+ )
55
+ ```
56
+
57
+ todo...
58
+
59
+ #### Returns
60
+ Array\<String\>
61
+
62
+ ### Example
63
+
64
+ 1. Require the gem:
65
+
66
+ ```ruby
67
+ require "img_to_script"
68
+ ```
69
+
70
+ 2. Read an image using the `rmagick/bin_magick` gem:
71
+
72
+ ```ruby
73
+ require "rmagick/bin_magick"
74
+
75
+ image = Magick::BinMagick::Image.from_file("my_file.png").to_binary!
76
+ ```
77
+
78
+ 3. Create a generator instance. You can also provide options via a configuration block, e.g.:
79
+
80
+ ```ruby
81
+ generator = ImgToScript::Generators::RunLengthEncoding::Horizontal.new.configure do |config|
82
+ config.x_offset = -10
83
+ config.y_offset = 15
84
+ # etc.
85
+ end
86
+ ```
87
+
88
+ 4. Create a translator instance, e.g.:
89
+
90
+ ```ruby
91
+ translator = ImgToScript::Languages::MK90Basic::Translators::MK90Basic10.new
92
+ ```
93
+
94
+ 5. Create a formatter instance. You can also provide options via a configuration block, e.g.:
95
+
96
+ ```ruby
97
+ formatter = ImgToScript::Languages::MK90Basic::Formatters::Minificator.new.configure do |config|
98
+ config.line_offset = 10
99
+ config.line_step = 5
100
+ config.max_chars_per_line = 60
101
+ # etc.
102
+ end
103
+ ```
104
+
105
+ 6. Create a task instance and pass created instances as the task’s dependencies:
106
+
107
+ ```ruby
108
+ task = ImgToScript::Task.new(
109
+ generator: generator,
110
+ translator: translator,
111
+ formatter: formatter
112
+ )
113
+ ```
114
+
115
+ Note that you can also provide your own custom objects as long as they respond to the required public interface.
116
+
117
+ In case of the Elektronika MK90 BASIC **only** you can omit any dependency (i.e. skip any step from the 3rd to the 5th), since these are optional arguments. Then a default object with a default configuration will be used.
118
+
119
+ You can also re-configure any dependency of an existing task object, e.g.:
120
+
121
+ ```ruby
122
+ task.formatter.configure do |config|
123
+ # your config...
124
+ end
125
+ ```
126
+
127
+ 7. Run conversion to get a script. You need to provide the image and the target device resolution:
128
+
129
+ ```ruby
130
+ script = task.run(
131
+ image: image,
132
+ scr_width: 120,
133
+ scr_height: 64
134
+ )
135
+ ```
136
+
137
+ ## Build-in classes
138
+
139
+ ### Generators
140
+
141
+ - **ImgToScript::Generators::Generator**
142
+
143
+ Base class all generators inherit from.
144
+
145
+ **Public interface**: #generate(image:, scr_width:, scr_height:)
146
+
147
+ **Configuration options**:
148
+
149
+ - x_offset, default: X_OFFSET (0)
150
+
151
+ Offset the X point on the screen.
152
+
153
+ - y_offset, default: Y_OFFSET (0)
154
+
155
+ Offset the Y point on the screen.
156
+
157
+ - clear_screen, default: CLEAR_SCREEN (true)
158
+
159
+ Add a statement to clear the screen at the begin of the script.
160
+
161
+ - pause_program, default: PAUSE_PROGRAM (true)
162
+
163
+ Add a statement to pause the program at the end of the script.
164
+
165
+ - program_begin_lbl, default: PRORGAM_BEGIN_LBL (false)
166
+
167
+ Add a statement that marks the begin of the program.
168
+
169
+ - program_end_lbl, default: PROGRAM_END_LBL (false)
170
+
171
+ Add a statement that marks the end of the program.
172
+
173
+ - **ImgToScript::Generators::HexMask::Default**
174
+
175
+ Specific for the Elektronika MK90 BASIC.
176
+
177
+ MK90's BASIC has a balanced build-in method to encode and render images. The Elektronika MK90's manual refers to it as the *hex-mask rendering* method. Each 8x1 px block of a binary image is being represented as a hex value (e.g. '00' for a tile of the 8 white pixels in a row, 'FF' for a tile of the 8 black pixels in a row, etc.). Then these hex values are being passed as arguments to the DRAM/M BASIC statement that renders the image according to the provided data.
178
+
179
+ Due to the logic of the DRAM/M operator, only vertical scan lines are supported.
180
+
181
+ - **ImgToScript::Generators::HexMask::Enhanced**
182
+
183
+ Specific for the Elektronika MK90 BASIC.
184
+
185
+ Hex-mask encoding with modifications what make output BASIC code more compact.
186
+
187
+ Due to the logic of the DRAM/M operator, only vertical scan lines are supported.
188
+
189
+ - **ImgToScript::Generators::RunLengthEncoding::Horizontal**
190
+
191
+ RLE, horizontal scan lines.
192
+
193
+ - **ImgToScript::Generators::RunLengthEncoding::Vertical**
194
+
195
+ RLE, vertical scan lines.
196
+
197
+ - **ImgToScript::Generators::Segmental::DirectDraw::Horizontal**
198
+
199
+ Directly plot segments, horizontal scan lines.
200
+
201
+ - **ImgToScript::Generators::Segmental::DirectDraw::Vertical**
202
+
203
+ Directly plot segments, vertical scan lines.
204
+
205
+ - **ImgToScript::Generators::Segmental::DataReadDraw::Horizontal**
206
+
207
+ Store and read segments' coordinates, when use them to plot segments. Horizontal scan lines.
208
+
209
+ - **ImgToScript::Generators::Segmental::DataReadDraw::Vertical**
210
+
211
+ Store and read segments' coordinates, when use them to plot segments. Vertical scan lines.
212
+
213
+ ### Elektronika MK90 BASIC
214
+
215
+ #### Translators
216
+
217
+ - **ImgToScript::Languages::MK90Basic::Translators::Translator**
218
+
219
+ Base class all MK90 translators inherit from.
220
+
221
+ **Public interface**: #translate(abstract_tokens, **kwargs)
222
+
223
+ - **ImgToScript::Languages::MK90Basic::Translators::MK90Basic10**
224
+
225
+ Translates abstract tokens to the MK90 BASIC v1.0 statements.
226
+
227
+ - **ImgToScript::Languages::MK90Basic::Translators::MK90Basic20**
228
+
229
+ Translates abstract tokens to the MK90 BASIC v2.0 statements.
230
+
231
+ #### Formatters
232
+
233
+ - **ImgToScript::Languages::MK90Basic::Formatters::Formatter**
234
+
235
+ Base class all MK90 formatters inherit from.
236
+
237
+ **Public interface**: #format(tokens)
238
+
239
+ **Configuration options**:
240
+
241
+ - line_offset, default: LINE_OFFSET (1)
242
+
243
+ First BASIC line number.
244
+
245
+ - line_step, default: LINE_STEP (1)
246
+
247
+ Step between two neighbor BASIC lines.
248
+
249
+ - max_chars_per_line, default: MAX_CHARS_PER_LINE (80)
250
+
251
+ Note: MK90 BASIC doesn’t support more than 80 characters per line.
252
+
253
+ - number_lines, default: true
254
+
255
+ - **ImgToScript::Languages::MK90Basic::Formatters::Minificator**
256
+
257
+ The aim of the minificator is to make the output script as compact as possible, and so to save space at the MPO-10 cart.
258
+
259
+ ## Development
260
+
261
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
262
+
263
+ 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 the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
264
+
265
+ ## Contributing
266
+
267
+ Bug reports and pull requests are welcome on GitHub at https://github.com/8bit-mate/img_to_script.rb.
268
+
269
+ ## License
270
+
271
+ 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,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/**/test_*.rb"]
10
+ end
11
+
12
+ require "rubocop/rake_task"
13
+
14
+ RuboCop::RakeTask.new
15
+
16
+ task default: %i[test rubocop]
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/img_to_script/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "img_to_script"
7
+ spec.version = ImgToScript::VERSION
8
+ spec.authors = ["8bit-mate"]
9
+ spec.email = ["you@example.com"]
10
+
11
+ spec.summary = "Converts images to executable scripts."
12
+ spec.homepage = "https://github.com/8bit-mate/img_to_script.rb"
13
+ spec.license = "MIT"
14
+ spec.required_ruby_version = ">= 3.0.0"
15
+
16
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
17
+
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = spec.homepage
20
+ spec.metadata["changelog_uri"] = spec.homepage
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
+ spec.files = Dir.chdir(__dir__) do
25
+ `git ls-files -z`.split("\x0").reject do |f|
26
+ (File.expand_path(f) == __FILE__) ||
27
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
28
+ end
29
+ end
30
+ spec.files -= ["data/lain-mk90.jpg"]
31
+
32
+ spec.bindir = "exe"
33
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
34
+ spec.require_paths = ["lib"]
35
+
36
+ spec.add_dependency "dry-system", "~> 1.0", ">= 1.0.1"
37
+ spec.add_dependency "run_length_encoding_rb", "~> 1.0", ">= 1.0.0"
38
+ spec.add_dependency "zeitwerk", "~> 2.6", ">= 2.6.12"
39
+
40
+ spec.add_development_dependency "rmagick-bin_magick", "~> 0.2", ">= 0.2.0"
41
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ #
5
+ # Defines abstract tokens types.
6
+ #
7
+ module AbsTokenType
8
+ ABS_FUNC = :abs_func
9
+ ASSIGN_VALUE = :assign_value
10
+ CLEAR_SCREEN = :clear_screen
11
+ DATA_READ = :data_read
12
+ DATA_STORE = :data_store
13
+ DRAW_CHUNK_BY_HEX_VALUE = :draw_chunk_by_hex_value
14
+ DRAW_LINE_BY_ABS_COORDS = :draw_line_by_abs_coords
15
+ DRAW_PIXEL_BY_ABS_COORDS = :draw_pixel_by_abs_coords
16
+ GO_TO = :go_to
17
+ IF_CONDITION = :if_condition
18
+ LOOP_BEGIN = :loop_begin
19
+ LOOP_END = :loop_end
20
+ MATH_ADD = :math_add
21
+ MATH_GREATER_THAN = :math_greater_than
22
+ MATH_MULT = :math_mult
23
+ MATH_SUB = :math_sub
24
+ MOVE_POINT_TO_ABS_COORDS = :move_point_to_abs_coords
25
+ PARENTHESES = :parentheses
26
+ PROGRAM_BEGIN = :program_begin_lbl
27
+ PROGRAM_END_LBL = :program_end_lbl
28
+ REMARK = :remark
29
+ SIGN_FUNC = :sign_func
30
+ SIGN_GREATER_THAN = :sign_greater_than
31
+ WAIT = :wait
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module AbstractToken
5
+ #
6
+ # Absolute value (modulus).
7
+ #
8
+ class AbsFunc < AbstractToken
9
+ attr_reader :expression
10
+
11
+ def initialize(expression:, **)
12
+ @type = AbsTokenType::ABS_FUNC
13
+ @expression = expression
14
+
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module AbstractToken
5
+ #
6
+ # Stores single command in an abstract representation.
7
+ #
8
+ class AbstractToken
9
+ attr_reader :type, :require_nl
10
+
11
+ #
12
+ # Init. a new abstract token.
13
+ #
14
+ # @option [Boolean] require_nl (false)
15
+ # If 'true', the formatter will put the statement, that is
16
+ # assotiated with the token, on a new line.
17
+ #
18
+ def initialize(require_nl: false, **)
19
+ @require_nl = require_nl
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module AbstractToken
5
+ #
6
+ # Assign value to a variable.
7
+ #
8
+ class AssignValue < AbstractToken
9
+ attr_reader :left, :right
10
+
11
+ def initialize(left:, right:, **)
12
+ @type = AbsTokenType::ASSIGN_VALUE
13
+ @left = left
14
+ @right = right
15
+
16
+ super
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module AbstractToken
5
+ #
6
+ # Clear screen.
7
+ #
8
+ class ClearScreen < AbstractToken
9
+ def initialize(**)
10
+ @type = AbsTokenType::CLEAR_SCREEN
11
+
12
+ super
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module AbstractToken
5
+ #
6
+ # Read value(s) from an array of constants.
7
+ #
8
+ class DataRead < AbstractToken
9
+ attr_reader :var_list
10
+
11
+ def initialize(var_list:, **)
12
+ @type = AbsTokenType::DATA_READ
13
+ @var_list = Array(var_list)
14
+
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module AbstractToken
5
+ #
6
+ # Store array of contants.
7
+ #
8
+ class DataStore < AbstractToken
9
+ attr_reader :data
10
+
11
+ def initialize(data:, **)
12
+ @type = AbsTokenType::DATA_STORE
13
+ @data = Array(data)
14
+
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module AbstractToken
5
+ #
6
+ # Draw 8x1 px block of pixels encoded by a hex value.
7
+ #
8
+ class DrawChunkByHexValue < AbstractToken
9
+ attr_reader :hex_values
10
+
11
+ def initialize(hex_values:, **)
12
+ @type = AbsTokenType::DRAW_CHUNK_BY_HEX_VALUE
13
+ @hex_values = Array(hex_values)
14
+
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module AbstractToken
5
+ #
6
+ # Draw a line by absolute coordinates.
7
+ #
8
+ class DrawLineByAbsCoords < AbstractToken
9
+ attr_reader :x0, :y0, :x1, :y1
10
+
11
+ def initialize(x0:, y0:, x1:, y1:, **)
12
+ @type = AbsTokenType::DRAW_LINE_BY_ABS_COORDS
13
+ @x0 = x0
14
+ @y0 = y0
15
+ @x1 = x1
16
+ @y1 = y1
17
+
18
+ super
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module AbstractToken
5
+ #
6
+ # Draw a pixel by absolute coordinates.
7
+ #
8
+ class DrawPixelByAbsCoords < AbstractToken
9
+ attr_reader :x, :y
10
+
11
+ def initialize(x:, y:, **)
12
+ @type = AbsTokenType::DRAW_PIXEL_BY_ABS_COORDS
13
+ @x = x
14
+ @y = y
15
+
16
+ super
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module AbstractToken
5
+ #
6
+ # Go to BASIC line.
7
+ #
8
+ class GoTo < AbstractToken
9
+ attr_reader :line
10
+
11
+ def initialize(line:, **)
12
+ @type = AbsTokenType::GO_TO
13
+ @line = line
14
+
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module AbstractToken
5
+ #
6
+ # If condition.
7
+ #
8
+ class IfCondition < AbstractToken
9
+ attr_reader :expression, :consequent
10
+
11
+ def initialize(expression:, consequent:, **)
12
+ @type = AbsTokenType::IF_CONDITION
13
+ @expression = expression
14
+ @consequent = consequent
15
+
16
+ super
17
+ end
18
+ end
19
+ end
20
+ end