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
@@ -0,0 +1,316 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module Languages
5
+ module MK90Basic
6
+ module Formatters
7
+ #
8
+ # The aim of the minificator is to make the output as compact as
9
+ # possible, and so to save space at the MPO-10 cart.
10
+ #
11
+ # The minificator:
12
+ # 1. doesn't put spaces (as MK90's BASIC lexer ignores them);
13
+ # 2. adds as many characters to a line as possible.
14
+ # This minimizes the number of CR+LF sequences.
15
+ #
16
+ class Minificator < Formatter
17
+ SEP_BETWEEN_STATEMENTS = ":"
18
+
19
+ private
20
+
21
+ #
22
+ # Append a token to the BASIC script.
23
+ #
24
+ def _append_token(token)
25
+ @token = token
26
+ @placeholders_idx = _get_placeholders_idx
27
+
28
+ _format_token_arguments
29
+
30
+ if @token.sliceable
31
+ _process_sliceable_token
32
+ else
33
+ _process_non_sliceable_token
34
+ end
35
+ end
36
+
37
+ #
38
+ # Process a token with a statement that can be splitted and
39
+ # continued on a next line.
40
+ #
41
+ def _process_sliceable_token
42
+ @current_arg_idx = 0
43
+
44
+ _append_arg until @current_arg_idx == @args.length
45
+ end
46
+
47
+ #
48
+ # Append an argument of the sliceable statement.
49
+ #
50
+ def _append_arg
51
+ @current_arg = @args[@current_arg_idx].to_s
52
+
53
+ if @current_arg_idx.zero?
54
+ # The first argument should be handled differently (since a
55
+ # keyword should be prepended first).
56
+ _append_arg_with_keyword
57
+ else
58
+ # The rest arguments are processed in a batch.
59
+ _append_rest_sliceable_args
60
+ end
61
+
62
+ @current_arg_idx += 1
63
+ end
64
+
65
+ #
66
+ # Append the keyword of a sliceable statement, when attach an
67
+ # argument to it.
68
+ #
69
+ # There are two situations when this happens:
70
+ # 1. the argument is the first in the arguments array;
71
+ # 2. the statement was splitted and should be continued on a new line.
72
+ #
73
+ def _append_arg_with_keyword
74
+ statement = "#{@token.keyword}#{@current_arg}"
75
+
76
+ if @token.require_nl
77
+ # Statement explicitly demands to be on a new line
78
+ _append_to_new_line(statement)
79
+ return
80
+ end
81
+
82
+ if _calc_sliceable_statement_keyword_length <= @max_chars_per_line
83
+ # There is enough space in the current BASIC line to add a new keyword + the next arg. pair.
84
+ _append_to_current_line(statement)
85
+ else
86
+ # There is not enough space in the current BASIC line, create a new one.
87
+ _append_to_new_line(statement)
88
+ end
89
+ end
90
+
91
+ def _append_rest_sliceable_args
92
+ if _calc_current_line_plus_argument_length <= @max_chars_per_line
93
+ # There is enough space in the current BASIC line to add another argument.
94
+ _append_new_argument_to_current_line
95
+ else
96
+ # There is not enough space in the current BASIC line, create a new one.
97
+ _append_arg_with_keyword
98
+ end
99
+ end
100
+
101
+ #
102
+ # Append current argument of the sliceable statement to a current line.
103
+ #
104
+ def _append_new_argument_to_current_line
105
+ @script[-1] += @token.separator + @current_arg.to_s
106
+ end
107
+
108
+ #
109
+ # Length of a current line with a current argument of the sliceable
110
+ # statement.
111
+ #
112
+ # @return [Integer]
113
+ #
114
+ def _calc_current_line_plus_argument_length
115
+ _get_current_line_content.length +
116
+ @current_arg.length +
117
+ @token.separator.length
118
+ end
119
+
120
+ #
121
+ # Process a token with a statement that cannot be splitted, i.e. it
122
+ # should be lined up within a single BASIC line.
123
+ #
124
+ def _process_non_sliceable_token
125
+ _evaluate_placeholders
126
+
127
+ if @token.require_nl
128
+ # Statement explicitly demands to be on a new line.
129
+ _append_to_new_line(_non_sliceable_statement)
130
+ else
131
+ # Statement potentially can be added to a current line.
132
+ _try_to_append_non_sliceble_to_current_line
133
+ end
134
+ end
135
+
136
+ #
137
+ # Try to append a non-sliceable statement to a current line.
138
+ #
139
+ # There are situations when it can't be done:
140
+ # 1. current line is empty (that means it is not numbered yet).
141
+ # 2. there's no enough space in the current line to append the
142
+ # statement.
143
+ #
144
+ def _try_to_append_non_sliceble_to_current_line
145
+ if _get_current_line_content.empty?
146
+ _append_to_new_line(_non_sliceable_statement)
147
+ return
148
+ end
149
+
150
+ if _calc_non_sliceable_statement_length <= @max_chars_per_line
151
+ _append_to_current_line(_non_sliceable_statement)
152
+ else
153
+ _append_to_new_line(_non_sliceable_statement)
154
+ end
155
+ end
156
+
157
+ #
158
+ # Return current BASIC line, i.e. the last element of the @script
159
+ # array.
160
+ #
161
+ # @return [String]
162
+ #
163
+ def _get_current_line_content
164
+ @script[-1] || ""
165
+ end
166
+
167
+ #
168
+ # Return a formatted non-sliceable statement.
169
+ #
170
+ # @return [String]
171
+ #
172
+ def _non_sliceable_statement
173
+ @token.keyword + @args.join(@token.separator)
174
+ end
175
+
176
+ def _update_line_num
177
+ @n_line += @line_step
178
+
179
+ # Since line number has been changed, it is required to
180
+ # re-evaluate placeholders with the updated value.
181
+ _evaluate_placeholders
182
+ end
183
+
184
+ #
185
+ # Append statement to the current BASIC line.
186
+ #
187
+ # @param [String] statement
188
+ # Statement to append in a String formatted form, e.g.: "ABS(X+L)"
189
+ #
190
+ def _append_to_current_line(statement)
191
+ @script[-1] += "#{SEP_BETWEEN_STATEMENTS}#{statement}"
192
+ end
193
+
194
+ #
195
+ # Append statement to a new BASIC line.
196
+ #
197
+ # @param [String] statement
198
+ # Statement to append in a String formatted form, e.g.: "ABS(X+L)"
199
+ #
200
+ def _append_to_new_line(statement)
201
+ # Since a new line is about to be created, the line number should
202
+ # be updated first.
203
+ _update_line_num
204
+
205
+ new_line = "#{_select_line_label}#{statement}"
206
+ @script << new_line
207
+ end
208
+
209
+ #
210
+ # @return [String]
211
+ #
212
+ def _select_line_label
213
+ @number_lines ? @n_line.to_s : ""
214
+ end
215
+
216
+ #
217
+ # Full length of a non-sliceable statement.
218
+ #
219
+ # @return [Integer]
220
+ #
221
+ def _calc_non_sliceable_statement_length
222
+ _get_current_line_content.length +
223
+ _non_sliceable_statement.length +
224
+ SEP_BETWEEN_STATEMENTS.length
225
+ end
226
+
227
+ #
228
+ # Keyword + first argument length.
229
+ #
230
+ # @return [Integer]
231
+ #
232
+ def _calc_sliceable_statement_keyword_length
233
+ _get_current_line_content.length +
234
+ @token.keyword.length +
235
+ @current_arg.length +
236
+ SEP_BETWEEN_STATEMENTS.length
237
+ end
238
+
239
+ #
240
+ # Evaluate current line number placeholders in the token's arguments.
241
+ #
242
+ def _evaluate_placeholders
243
+ @placeholders_idx.each do |i|
244
+ e = @token.args[i]
245
+ @args[i] = @n_line + e.shift * @line_step
246
+ end
247
+ end
248
+
249
+ #
250
+ # For an argument what is a token (i.e. a nested token): pass the
251
+ # argument to a new instance of the minificator, and append the
252
+ # argument in a formatted form (a String).
253
+ #
254
+ # For the arguments of other types: append as is.
255
+ #
256
+ def _format_token_arguments
257
+ @args = []
258
+ @token.args.each do |arg|
259
+ if arg.is_a?(MK90Basic::MK90BasicToken)
260
+ @args.append(_format_nested_token(arg))
261
+ else
262
+ @args.append(arg)
263
+ end
264
+ end
265
+ end
266
+
267
+ #
268
+ # Format a nested token.
269
+ #
270
+ # @return [String]
271
+ #
272
+ def _format_nested_token(token)
273
+ arr = _minificator.format(
274
+ Array(token)
275
+ )
276
+
277
+ case arr.length
278
+ when 0
279
+ # @todo: warn: minificator returned an empty arr!
280
+ ""
281
+ when 1
282
+ # ok!
283
+ arr.first
284
+ else
285
+ # @todo: warn: statement doesn't fit to a single line!
286
+ arr.first
287
+ end
288
+ end
289
+
290
+ #
291
+ # Return a minificator instance to format a nested token.
292
+ #
293
+ # @return [Minificator]
294
+ # A new Minificator instance.
295
+ #
296
+ def _minificator
297
+ Minificator.new.configure do |config|
298
+ config.number_lines = false
299
+ end
300
+ end
301
+
302
+ #
303
+ # Return array of indexes of the placeholders.
304
+ #
305
+ # @return [Array<Integer>]
306
+ #
307
+ def _get_placeholders_idx
308
+ @token.args.each_index.select do |i|
309
+ @token.args[i].is_a?(CurrentLinePlaceholder)
310
+ end
311
+ end
312
+ end
313
+ end
314
+ end
315
+ end
316
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module Languages
5
+ module MK90Basic
6
+ module Formatters
7
+ #
8
+ # Methods related to the sliceable statements.
9
+ #
10
+ module SliceableTokensMixin
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module Languages
5
+ module MK90Basic
6
+ #
7
+ # Namespace for the MK90 BASIC formatters.
8
+ #
9
+ module Formatters
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module Languages
5
+ module MK90Basic
6
+ #
7
+ # Designed to be used with the MK90 BASIC translator & formatter.
8
+ #
9
+ class MK90BasicToken < LanguageToken
10
+ attr_accessor :keyword, :args, :separator, :require_nl, :sliceable
11
+
12
+ #
13
+ # Initialize a new BASIC token.
14
+ #
15
+ # @param [String] keyword
16
+ # Statement keyword (e.g.: "PRINT", "FOR", "CLS").
17
+ #
18
+ # @param [Array<Numeric, String>] args
19
+ # Statement arguments (e.g.: %i[10 20 30 40]).
20
+ #
21
+ # @param [String] separator
22
+ # Separator between arguments. Commonly a comma or
23
+ # an 'empty' string (no separation between arguments).
24
+ #
25
+ # @param [Boolean] require_nl
26
+ # Defines if the statement should be placed on a new line.
27
+ #
28
+ # @param [Boolean] sliceable
29
+ # Defines if the statement allows to 'slice' its arguments,
30
+ # to move some of them on a new line if the expression doesn't
31
+ # fit into a current line. Examples:
32
+ #
33
+ # sliceable = true:
34
+ # | <- max. characters per line limit
35
+ # 10 DATA 1, [omitted...], 8, 9, 10, 11
36
+ # => |
37
+ # 10 DATA 1, [omitted...], 8
38
+ # 20 DATA 9, 10, 11 |
39
+ #
40
+ # sliceable = false:
41
+ # |
42
+ # 10 [omitted...]:PRINT"HELLO, WORLD!"
43
+ # => |
44
+ # 10 [omitted...] |
45
+ # 20 PRINT"HELLO, WORLD!" |
46
+ #
47
+ def initialize(keyword:, args:, separator:, require_nl:, sliceable:)
48
+ @keyword = keyword
49
+ @args = args
50
+ @separator = separator
51
+ @require_nl = require_nl
52
+ @sliceable = sliceable
53
+
54
+ super()
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,205 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module Languages
5
+ module MK90Basic
6
+ module Translators
7
+ # rubocop:disable Metrics/ModuleLength
8
+
9
+ #
10
+ # Shared by both MK90 BAIC v.1.0 & v.2.0.
11
+ #
12
+ module Mixin
13
+ def _abs_func(token)
14
+ _function(token, "ABS")
15
+ end
16
+
17
+ def _clear_screen(token)
18
+ _single_keyword(token, "CLS")
19
+ end
20
+
21
+ def _program_end(token)
22
+ _single_keyword(token, "END")
23
+ end
24
+
25
+ def _data_store(token)
26
+ MK90BasicToken.new(
27
+ keyword: "DATA",
28
+ args: token.data,
29
+ separator: ",",
30
+ require_nl: token.require_nl,
31
+ sliceable: true
32
+ )
33
+ end
34
+
35
+ def _data_read(token)
36
+ MK90BasicToken.new(
37
+ keyword: "READ",
38
+ args: _translate_arguments(token.var_list),
39
+ separator: ",",
40
+ require_nl: token.require_nl,
41
+ sliceable: false
42
+ )
43
+ end
44
+
45
+ def _draw_line_by_abs_coords(token)
46
+ MK90BasicToken.new(
47
+ keyword: "DRAWD",
48
+ args: _translate_arguments([
49
+ token.x0,
50
+ token.y0,
51
+ token.x1,
52
+ token.y1
53
+ ]),
54
+ separator: ",",
55
+ require_nl: token.require_nl,
56
+ sliceable: false
57
+ )
58
+ end
59
+
60
+ def _draw_pixel_by_abs_coords(token)
61
+ MK90BasicToken.new(
62
+ keyword: "DRAWH",
63
+ args: _translate_arguments([
64
+ token.x,
65
+ token.y
66
+ ]),
67
+ separator: ",",
68
+ require_nl: token.require_nl,
69
+ sliceable: false
70
+ )
71
+ end
72
+
73
+ def _draw_chunk_by_hex_value(token)
74
+ MK90BasicToken.new(
75
+ keyword: "DRAWM",
76
+ args: token.hex_values,
77
+ separator: "",
78
+ require_nl: token.require_nl,
79
+ sliceable: true
80
+ )
81
+ end
82
+
83
+ def _math_add(token)
84
+ _math_operation(token, "+")
85
+ end
86
+
87
+ def _math_greater_than(token)
88
+ _math_operation(token, ">")
89
+ end
90
+
91
+ def _math_sub(token)
92
+ _math_operation(token, "-")
93
+ end
94
+
95
+ def _math_mult(token)
96
+ _math_operation(token, "*")
97
+ end
98
+
99
+ def _move_point_to_abs_coords(token)
100
+ MK90BasicToken.new(
101
+ keyword: "DRAWO",
102
+ args: _translate_arguments([
103
+ token.x,
104
+ token.y
105
+ ]),
106
+ separator: ",",
107
+ require_nl: token.require_nl,
108
+ sliceable: false
109
+ )
110
+ end
111
+
112
+ def _go_to(token)
113
+ MK90BasicToken.new(
114
+ keyword: "GOTO",
115
+ args: _translate_arguments([
116
+ token.line
117
+ ]),
118
+ separator: "",
119
+ require_nl: token.require_nl,
120
+ sliceable: false
121
+ )
122
+ end
123
+
124
+ def _loop_begin(token)
125
+ MK90BasicToken.new(
126
+ keyword: "FOR",
127
+ args: _translate_arguments([
128
+ token.var_name,
129
+ "=",
130
+ token.start_value,
131
+ "TO",
132
+ token.end_value
133
+ ]),
134
+ separator: "",
135
+ require_nl: token.require_nl,
136
+ sliceable: false
137
+ )
138
+ end
139
+
140
+ def _sign_func(token)
141
+ _function(token, "SGN")
142
+ end
143
+
144
+ def _parentheses(token)
145
+ _function(token, "")
146
+ end
147
+
148
+ def _loop_end(token)
149
+ MK90BasicToken.new(
150
+ keyword: "NEXT",
151
+ args: _translate_arguments(
152
+ [
153
+ token.var_name
154
+ ]
155
+ ),
156
+ separator: "",
157
+ require_nl: token.require_nl,
158
+ sliceable: false
159
+ )
160
+ end
161
+
162
+ def _if_condition(token)
163
+ MK90BasicToken.new(
164
+ keyword: "IF",
165
+ args: _translate_arguments([
166
+ token.expression,
167
+ "THEN",
168
+ token.consequent
169
+ ]),
170
+ separator: "",
171
+ require_nl: token.require_nl,
172
+ sliceable: false
173
+ )
174
+ end
175
+
176
+ def _wait(token)
177
+ MK90BasicToken.new(
178
+ keyword: "WAIT",
179
+ args: _translate_arguments([
180
+ token.time
181
+ ]),
182
+ separator: "",
183
+ require_nl: token.require_nl,
184
+ sliceable: false
185
+ )
186
+ end
187
+
188
+ def _remark(token)
189
+ MK90BasicToken.new(
190
+ keyword: "REM",
191
+ args: [
192
+ token.text
193
+ ],
194
+ separator: "",
195
+ require_nl: token.require_nl,
196
+ sliceable: false
197
+ )
198
+ end
199
+ end
200
+
201
+ # rubocop:enable Metrics/ModuleLength
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module Languages
5
+ module MK90Basic
6
+ module Translators
7
+ #
8
+ # Translates abstract tokens to the MK90 BASIC v.1.0 statements.
9
+ #
10
+ class MK90Basic10 < Translator
11
+ private
12
+
13
+ # MK90 BASIC v1.0 - requires the "LET" keyword
14
+ def _assign_value(token)
15
+ MK90BasicToken.new(
16
+ keyword: "LET",
17
+ args: _translate_arguments([token.left, "=", token.right]),
18
+ separator: "",
19
+ require_nl: token.require_nl,
20
+ sliceable: false
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImgToScript
4
+ module Languages
5
+ module MK90Basic
6
+ module Translators
7
+ #
8
+ # Translates abstract tokens to the MK90 BASIC v.2.0 statements.
9
+ #
10
+ class MK90Basic20 < Translator
11
+ private
12
+
13
+ # MK90 BASIC v2.0 - doesn't require the "LET" keyword
14
+ def _assign_value(token)
15
+ MK90BasicToken.new(
16
+ keyword: "",
17
+ args: _translate_arguments([token.left, "=", token.right]),
18
+ separator: "",
19
+ require_nl: token.require_nl,
20
+ sliceable: false
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end