Skip to content

Commit dbfc341

Browse files
authored
Merge pull request #176 from /issues/175
error occurs 'if !($global == 1); end' (closes #175)
2 parents 9b643a7 + 68834b3 commit dbfc341

File tree

3 files changed

+398
-126
lines changed

3 files changed

+398
-126
lines changed

src/lib/ruby-to-blocks-converter/operators.js

Lines changed: 135 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -12,97 +12,28 @@ const OperatorsConverter = {
1212
switch (name) {
1313
case 'rand':
1414
if (args.length === 1 && this._isBlock(args[0]) && args[0].opcode === 'ruby_range') {
15-
block = this._changeBlock(args[0], 'operator_random', 'value');
15+
return this._changeBlock(args[0], 'operator_random', 'value');
1616
}
1717
break;
1818
}
19-
} else if (!this._isVariableBlock(receiver)) {
19+
}
20+
21+
if (!this._isVariableBlock(receiver)) {
2022
switch (name) {
21-
case '+':
22-
case '-':
23-
case '*':
24-
case '/':
25-
case '%':
26-
if (args.length === 1) {
27-
if (this._isNumberOrBlock(receiver) && this._isNumberOrBlock(args[0])) {
28-
let opcode;
29-
if (name === '+') {
30-
opcode = 'operator_add';
31-
} else if (name === '-') {
32-
opcode = 'operator_subtract';
33-
} else if (name === '*') {
34-
opcode = 'operator_multiply';
35-
} else if (name === '/') {
36-
opcode = 'operator_divide';
37-
} else {
38-
opcode = 'operator_mod';
39-
}
40-
block = this._createBlock(opcode, 'value');
41-
this._addNumberInput(block, 'NUM1', 'math_number', receiver, '');
42-
this._addNumberInput(block, 'NUM2', 'math_number', args[0], '');
43-
} else if (name === '+' &&
44-
(this._isStringOrBlock(receiver) || this._isStringOrBlock(args[0]))) {
45-
block = this._createBlock('operator_join', 'value');
46-
this._addTextInput(
47-
block,
48-
'STRING1',
49-
this._isNumber(receiver) ? receiver.toString() : receiver,
50-
'apple'
51-
);
52-
this._addTextInput(
53-
block,
54-
'STRING2',
55-
this._isNumber(args[0]) ? args[0].toString() : args[0],
56-
'banana'
57-
);
58-
}
59-
}
60-
break;
61-
case '>':
62-
case '<':
63-
case '==':
64-
if (args.length === 1) {
65-
let opcode;
66-
if (name === '>') {
67-
opcode = 'operator_gt';
68-
} else if (name === '<') {
69-
opcode = 'operator_lt';
70-
} else {
71-
opcode = 'operator_equals';
72-
}
73-
block = this._createBlock(opcode, 'value_boolean');
74-
this._addTextInput(
75-
block, 'OPERAND1', this._isNumber(receiver) ? receiver.toString() : receiver, ''
76-
);
77-
this._addTextInput(
78-
block, 'OPERAND2', this._isNumber(args[0]) ? args[0].toString() : args[0], '50'
79-
);
80-
}
81-
break;
82-
case '!':
83-
if (args.length === 0 && this._isFalseOrBooleanBlock(receiver)) {
84-
block = this._createBlock('operator_not', 'value_boolean');
85-
if (!this._isFalse(receiver)) {
86-
this._addInput(
87-
block,
88-
'OPERAND',
89-
this._createTextBlock(this._isNumber(receiver) ? receiver.toString() : receiver)
90-
);
91-
}
92-
}
93-
break;
9423
case '[]':
9524
if (this._isStringOrBlock(receiver) &&
9625
args.length === 1 && this._isNumberOrBlock(args[0])) {
9726
block = this._createBlock('operator_letter_of', 'value');
9827
this._addTextInput(block, 'STRING', receiver, 'apple');
9928
this._addNumberInput(block, 'LETTER', 'math_number', args[0], 1);
29+
return block;
10030
}
10131
break;
10232
case 'length':
10333
if (args.length === 0 && this._isStringOrBlock(receiver)) {
10434
block = this._createBlock('operator_length', 'value');
10535
this._addTextInput(block, 'STRING', receiver, 'apple');
36+
return block;
10637
}
10738
break;
10839
case 'include?':
@@ -111,41 +42,123 @@ const OperatorsConverter = {
11142
block = this._createBlock('operator_contains', 'value');
11243
this._addTextInput(block, 'STRING1', receiver, 'apple');
11344
this._addTextInput(block, 'STRING2', args[0], 'a');
45+
return block;
11446
}
11547
break;
116-
case 'round':
117-
if (args.length === 0 && this._isNumberOrBlock(receiver)) {
118-
block = this._createBlock('operator_round', 'value');
119-
this._addNumberInput(block, 'NUM', 'math_number', receiver, '');
48+
}
49+
}
50+
51+
switch (name) {
52+
case '+':
53+
case '-':
54+
case '*':
55+
case '/':
56+
case '%':
57+
if (args.length === 1) {
58+
if (this._isNumberOrBlock(receiver) && this._isNumberOrBlock(args[0])) {
59+
let opcode;
60+
if (name === '+') {
61+
opcode = 'operator_add';
62+
} else if (name === '-') {
63+
opcode = 'operator_subtract';
64+
} else if (name === '*') {
65+
opcode = 'operator_multiply';
66+
} else if (name === '/') {
67+
opcode = 'operator_divide';
68+
} else {
69+
opcode = 'operator_mod';
70+
}
71+
block = this._createBlock(opcode, 'value');
72+
this._addNumberInput(block, 'NUM1', 'math_number', receiver, '');
73+
this._addNumberInput(block, 'NUM2', 'math_number', args[0], '');
74+
return block;
75+
} else if (name === '+' &&
76+
(this._isStringOrBlock(receiver) || this._isStringOrBlock(args[0]))) {
77+
block = this._createBlock('operator_join', 'value');
78+
this._addTextInput(
79+
block,
80+
'STRING1',
81+
this._isNumber(receiver) ? receiver.toString() : receiver,
82+
'apple'
83+
);
84+
this._addTextInput(
85+
block,
86+
'STRING2',
87+
this._isNumber(args[0]) ? args[0].toString() : args[0],
88+
'banana'
89+
);
90+
return block;
12091
}
121-
break;
122-
case 'abs':
123-
case 'floor':
124-
case 'ceil': {
125-
let operator;
126-
switch (name) {
127-
case 'ceil':
128-
operator = 'ceiling';
129-
break;
130-
default:
131-
operator = name;
92+
}
93+
break;
94+
case '>':
95+
case '<':
96+
case '==':
97+
if (args.length === 1) {
98+
let opcode;
99+
if (name === '>') {
100+
opcode = 'operator_gt';
101+
} else if (name === '<') {
102+
opcode = 'operator_lt';
103+
} else {
104+
opcode = 'operator_equals';
132105
}
133-
if (args.length === 0 && this._isNumberOrBlock(receiver)) {
134-
block = this._createBlock('operator_mathop', 'value');
135-
this._addField(block, 'OPERATOR', operator);
136-
this._addNumberInput(block, 'NUM', 'math_number', receiver, '');
106+
block = this._createBlock(opcode, 'value_boolean');
107+
this._addTextInput(
108+
block, 'OPERAND1', this._isNumber(receiver) ? receiver.toString() : receiver, ''
109+
);
110+
this._addTextInput(
111+
block, 'OPERAND2', this._isNumber(args[0]) ? args[0].toString() : args[0], '50'
112+
);
113+
return block;
114+
}
115+
break;
116+
case '!':
117+
if (args.length === 0 && this._isFalseOrBooleanBlock(receiver)) {
118+
block = this._createBlock('operator_not', 'value_boolean');
119+
if (!this._isFalse(receiver)) {
120+
this._addInput(
121+
block,
122+
'OPERAND',
123+
this._createTextBlock(this._isNumber(receiver) ? receiver.toString() : receiver)
124+
);
137125
}
138-
break;
126+
return block;
127+
}
128+
break;
129+
case 'round':
130+
if (args.length === 0 && this._isNumberOrBlock(receiver)) {
131+
block = this._createBlock('operator_round', 'value');
132+
this._addNumberInput(block, 'NUM', 'math_number', receiver, '');
133+
return block;
139134
}
140-
case 'sqrt':
141-
case 'sin':
142-
case 'cos':
143-
case 'tan':
144-
case 'asin':
145-
case 'acos':
146-
case 'atan':
147-
case 'log':
148-
case 'log10': {
135+
break;
136+
case 'abs':
137+
case 'floor':
138+
case 'ceil':
139+
if (args.length === 0 && this._isNumberOrBlock(receiver)) {
140+
let operator = name;
141+
if (name === 'ceil') {
142+
operator = 'ceiling';
143+
}
144+
block = this._createBlock('operator_mathop', 'value');
145+
this._addField(block, 'OPERATOR', operator);
146+
this._addNumberInput(block, 'NUM', 'math_number', receiver, '');
147+
return block;
148+
}
149+
break;
150+
case 'sqrt':
151+
case 'sin':
152+
case 'cos':
153+
case 'tan':
154+
case 'asin':
155+
case 'acos':
156+
case 'atan':
157+
case 'log':
158+
case 'log10':
159+
if (args.length === 1 &&
160+
this._isConst(receiver) && receiver.toString() === '::Math' &&
161+
this._isNumberOrBlock(args[0])) {
149162
let operator;
150163
switch (name) {
151164
case 'log':
@@ -157,34 +170,31 @@ const OperatorsConverter = {
157170
default:
158171
operator = name;
159172
}
160-
if (args.length === 1 &&
161-
this._isConst(receiver) && receiver.toString() === '::Math' &&
162-
this._isNumberOrBlock(args[0])) {
173+
block = this._createBlock('operator_mathop', 'value');
174+
this._addField(block, 'OPERATOR', operator);
175+
this._addNumberInput(block, 'NUM', 'math_number', args[0], '');
176+
return block;
177+
}
178+
break;
179+
case '**':
180+
if (args.length === 1 && this._isNumberOrBlock(args[0])) {
181+
let operator;
182+
if (this._isConst(receiver) && receiver.toString() === '::Math::E') {
183+
operator = 'e ^';
184+
} else if (receiver.type === 'int' && receiver.value === 10) {
185+
operator = '10 ^';
186+
}
187+
if (operator) {
163188
block = this._createBlock('operator_mathop', 'value');
164189
this._addField(block, 'OPERATOR', operator);
165190
this._addNumberInput(block, 'NUM', 'math_number', args[0], '');
191+
return block;
166192
}
167-
break;
168-
}
169-
case '**':
170-
if (args.length === 1 && this._isNumberOrBlock(args[0])) {
171-
let operator;
172-
if (this._isConst(receiver) && receiver.toString() === '::Math::E') {
173-
operator = 'e ^';
174-
} else if (receiver.type === 'int' && receiver.value === 10) {
175-
operator = '10 ^';
176-
}
177-
if (operator) {
178-
block = this._createBlock('operator_mathop', 'value');
179-
this._addField(block, 'OPERATOR', operator);
180-
this._addNumberInput(block, 'NUM', 'math_number', args[0], '');
181-
}
182-
}
183-
break;
184193
}
194+
break;
185195
}
186196

187-
return block;
197+
return null;
188198
},
189199

190200
// eslint-disable-next-line no-unused-vars

test/unit/lib/ruby-to-blocks-converter/index.test.js

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import RubyToBlocksConverter from '../../../../src/lib/ruby-to-blocks-converter';
22
import {
33
convertAndExpectToEqualBlocks,
4-
rubyToExpected
4+
rubyToExpected,
5+
expectedInfo
56
} from '../../../helpers/expect-to-equal-blocks';
67

78
describe('RubyToBlocksConverter', () => {
@@ -195,6 +196,58 @@ describe('RubyToBlocksConverter', () => {
195196
expect(converter.errors[0].row).toEqual(2);
196197
expect(res).toBeFalsy();
197198
});
199+
200+
test('==, <, > and variable', () => {
201+
code = `
202+
if !($global == 21)
203+
bounce_if_on_edge
204+
end
205+
`;
206+
expected = [
207+
{
208+
opcode: 'control_if',
209+
inputs: [
210+
{
211+
name: 'CONDITION',
212+
block: {
213+
opcode: 'operator_not',
214+
inputs: [
215+
{
216+
name: 'OPERAND',
217+
block: {
218+
opcode: 'operator_equals',
219+
inputs: [
220+
{
221+
name: 'OPERAND1',
222+
block: {
223+
opcode: 'data_variable',
224+
fields: [
225+
{
226+
name: 'VARIABLE',
227+
variable: '$global'
228+
}
229+
]
230+
},
231+
shadow: expectedInfo.makeText('')
232+
},
233+
{
234+
name: 'OPERAND2',
235+
block: expectedInfo.makeText('21')
236+
}
237+
]
238+
}
239+
}
240+
]
241+
}
242+
}
243+
],
244+
branches: [
245+
rubyToExpected(converter, target, 'bounce_if_on_edge')[0]
246+
]
247+
}
248+
];
249+
convertAndExpectToEqualBlocks(converter, target, code, expected);
250+
});
198251
});
199252
});
200253
});

0 commit comments

Comments
 (0)