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.
- checksums.yaml +7 -0
- data/.rubocop.yml +25 -0
- data/.vscode/launch.json +21 -0
- data/CHANGELOG.md +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +271 -0
- data/Rakefile +16 -0
- data/img_to_script.gemspec +41 -0
- data/lib/img_to_script/abs_token_type.rb +33 -0
- data/lib/img_to_script/abstract_token/abs_func.rb +19 -0
- data/lib/img_to_script/abstract_token/abstract_token.rb +23 -0
- data/lib/img_to_script/abstract_token/assign_value.rb +20 -0
- data/lib/img_to_script/abstract_token/clear_screen.rb +16 -0
- data/lib/img_to_script/abstract_token/data_read.rb +19 -0
- data/lib/img_to_script/abstract_token/data_store.rb +19 -0
- data/lib/img_to_script/abstract_token/draw_chunk_by_hex_value.rb +19 -0
- data/lib/img_to_script/abstract_token/draw_line_by_abs_coords.rb +22 -0
- data/lib/img_to_script/abstract_token/draw_pixel_by_abs_coords.rb +20 -0
- data/lib/img_to_script/abstract_token/go_to.rb +19 -0
- data/lib/img_to_script/abstract_token/if_condition.rb +20 -0
- data/lib/img_to_script/abstract_token/loop_begin.rb +21 -0
- data/lib/img_to_script/abstract_token/loop_end.rb +19 -0
- data/lib/img_to_script/abstract_token/math_add.rb +20 -0
- data/lib/img_to_script/abstract_token/math_greater_than.rb +20 -0
- data/lib/img_to_script/abstract_token/math_mult.rb +20 -0
- data/lib/img_to_script/abstract_token/math_sub.rb +20 -0
- data/lib/img_to_script/abstract_token/move_point_to_abs_coords.rb +20 -0
- data/lib/img_to_script/abstract_token/parentheses.rb +19 -0
- data/lib/img_to_script/abstract_token/program_begin.rb +16 -0
- data/lib/img_to_script/abstract_token/program_end.rb +16 -0
- data/lib/img_to_script/abstract_token/remark.rb +19 -0
- data/lib/img_to_script/abstract_token/sign_func.rb +19 -0
- data/lib/img_to_script/abstract_token/wait.rb +19 -0
- data/lib/img_to_script/abstract_token.rb +8 -0
- data/lib/img_to_script/container.rb +26 -0
- data/lib/img_to_script/current_line_placeholder.rb +40 -0
- data/lib/img_to_script/formatter.rb +34 -0
- data/lib/img_to_script/generators/generator.rb +134 -0
- data/lib/img_to_script/generators/hex_mask/default.rb +24 -0
- data/lib/img_to_script/generators/hex_mask/enhanced.rb +220 -0
- data/lib/img_to_script/generators/hex_mask/hex_mask.rb +100 -0
- data/lib/img_to_script/generators/hex_mask.rb +13 -0
- data/lib/img_to_script/generators/run_length_encoding/horizontal.rb +78 -0
- data/lib/img_to_script/generators/run_length_encoding/run_length_encoding.rb +304 -0
- data/lib/img_to_script/generators/run_length_encoding/vertical.rb +79 -0
- data/lib/img_to_script/generators/run_length_encoding.rb +10 -0
- data/lib/img_to_script/generators/segmental/data_read_draw/data_read_draw.rb +70 -0
- data/lib/img_to_script/generators/segmental/data_read_draw/horizontal.rb +54 -0
- data/lib/img_to_script/generators/segmental/data_read_draw/vertical.rb +54 -0
- data/lib/img_to_script/generators/segmental/data_read_draw.rb +18 -0
- data/lib/img_to_script/generators/segmental/direct_draw/direct_draw.rb +62 -0
- data/lib/img_to_script/generators/segmental/direct_draw/horizontal.rb +16 -0
- data/lib/img_to_script/generators/segmental/direct_draw/vertical.rb +16 -0
- data/lib/img_to_script/generators/segmental/direct_draw.rb +12 -0
- data/lib/img_to_script/generators/segmental/horizontal_mixin.rb +32 -0
- data/lib/img_to_script/generators/segmental/segmental.rb +101 -0
- data/lib/img_to_script/generators/segmental/vertical_mixin.rb +38 -0
- data/lib/img_to_script/generators/segmental.rb +10 -0
- data/lib/img_to_script/generators.rb +27 -0
- data/lib/img_to_script/import.rb +5 -0
- data/lib/img_to_script/language_token.rb +8 -0
- data/lib/img_to_script/languages/mk90_basic/formatters/formatter.rb +49 -0
- data/lib/img_to_script/languages/mk90_basic/formatters/minificator.rb +316 -0
- data/lib/img_to_script/languages/mk90_basic/formatters/sliceable_tokens_mixin.rb +15 -0
- data/lib/img_to_script/languages/mk90_basic/formatters.rb +13 -0
- data/lib/img_to_script/languages/mk90_basic/mk90_basic_token.rb +59 -0
- data/lib/img_to_script/languages/mk90_basic/translators/mixin.rb +205 -0
- data/lib/img_to_script/languages/mk90_basic/translators/mk90_basic_10.rb +27 -0
- data/lib/img_to_script/languages/mk90_basic/translators/mk90_basic_20.rb +27 -0
- data/lib/img_to_script/languages/mk90_basic/translators/translator.rb +205 -0
- data/lib/img_to_script/languages/mk90_basic/translators.rb +13 -0
- data/lib/img_to_script/languages/mk90_basic.rb +17 -0
- data/lib/img_to_script/languages.rb +10 -0
- data/lib/img_to_script/task.rb +26 -0
- data/lib/img_to_script/translator.rb +31 -0
- data/lib/img_to_script/version.rb +5 -0
- data/lib/img_to_script.rb +19 -0
- data/sig/img_to_script.rbs +4 -0
- 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,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
|