img_to_script 1.0.0

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.
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