[270] | 1 | // Porting from
|
---|
| 2 | // https://github.com/jeanlazarou/blockly2ruby
|
---|
| 3 | // Copyright (c) 2014 Jean Lazarou
|
---|
| 4 | // MIT Lisence
|
---|
| 5 | using System;
|
---|
| 6 | using Bridge;
|
---|
| 7 | using System.Collections.Generic;
|
---|
| 8 |
|
---|
| 9 | namespace WebMrbc
|
---|
| 10 | {
|
---|
| 11 | partial class Ruby
|
---|
| 12 | {
|
---|
| 13 | public node controls_repeat(ControlsRepeatBlock block)
|
---|
| 14 | {
|
---|
| 15 | // Repeat n times (internal number).
|
---|
| 16 | var times = block.getFieldValue("TIMES");
|
---|
| 17 | var repeats = new int_node(this, times == null ? 0 : Script.ParseInt(times, 10));
|
---|
| 18 | var branch = statementToCode(block, "DO");
|
---|
| 19 | return new call_node(this, repeats, intern("times"), new node[0], new block_node(this, new node[0], branch, false));
|
---|
| 20 | }
|
---|
| 21 |
|
---|
| 22 | public node controls_repeat_ext(ControlsRepeatExtBlock block)
|
---|
| 23 | {
|
---|
| 24 | // Repeat n times (external number).
|
---|
| 25 | var repeats = valueToCode(block, "TIMES");
|
---|
| 26 | if (repeats == null) repeats = new int_node(this, 0);
|
---|
| 27 | if (repeats is int_node) {
|
---|
| 28 | }
|
---|
| 29 | else {
|
---|
| 30 | repeats = new call_node(this, repeats, intern("to_i"));
|
---|
| 31 | }
|
---|
| 32 | var branch = statementToCode(block, "DO");
|
---|
| 33 | return new call_node(this, repeats, intern("times"), new node[0], new block_node(this, new node[0], branch, false));
|
---|
| 34 | }
|
---|
| 35 |
|
---|
| 36 | public node controls_whileUntil(ControlsWhileUntilBlock block)
|
---|
| 37 | {
|
---|
| 38 | // Do while/until loop.
|
---|
| 39 | var until = block.getFieldValue("MODE") == "UNTIL";
|
---|
| 40 | var argument0 = valueToCode(block, "BOOL");
|
---|
| 41 | if (argument0 == null) argument0 = new false_node(this);
|
---|
| 42 | var branch = statementToCode(block, "DO");
|
---|
| 43 | if (until)
|
---|
| 44 | return new until_node(this, argument0, branch);
|
---|
| 45 | else
|
---|
| 46 | return new while_node(this, argument0, branch);
|
---|
| 47 | }
|
---|
| 48 |
|
---|
| 49 | public node controls_for(ControlsForBlock block)
|
---|
| 50 | {
|
---|
| 51 | // For loop.
|
---|
| 52 | var lv = local_switch();
|
---|
| 53 |
|
---|
| 54 | var loopVar = local_add_f(block.getFieldValue("VAR"));
|
---|
| 55 | var fromVal = valueToCode(block, "FROM");
|
---|
| 56 | if (fromVal == null) fromVal = new int_node(this, 0);
|
---|
| 57 | var toVal = valueToCode(block, "TO");
|
---|
| 58 | if (toVal == null) toVal = new int_node(this, 0);
|
---|
| 59 | var increment = valueToCode(block, "BY");
|
---|
| 60 | var branch = statementToCode(block, "DO");
|
---|
| 61 |
|
---|
| 62 | if (fromVal is int_node && toVal is int_node &&
|
---|
| 63 | (increment == null || increment is int_node)) {
|
---|
| 64 |
|
---|
| 65 | if (increment == null) increment = new int_node(this, 1);
|
---|
| 66 |
|
---|
| 67 | // All parameters are simple numbers.
|
---|
| 68 | }
|
---|
| 69 | else {
|
---|
| 70 | fromVal = new call_node(this, fromVal, intern("to_f"));
|
---|
| 71 | toVal = new call_node(this, toVal, intern("to_f"));
|
---|
| 72 | if (increment == null)
|
---|
| 73 | increment = new float_node(this, 1);
|
---|
| 74 | else
|
---|
| 75 | increment = new call_node(this, increment, intern("to_f"));
|
---|
| 76 | }
|
---|
| 77 |
|
---|
| 78 | local_resume(lv);
|
---|
| 79 |
|
---|
| 80 | var arg = new hash_node(this, new hash_node.kv_t[] {
|
---|
| 81 | new hash_node.kv_t(new sym_node(this, intern("from")), fromVal),
|
---|
| 82 | new hash_node.kv_t(new sym_node(this, intern("to")), toVal),
|
---|
| 83 | new hash_node.kv_t(new sym_node(this, intern("by")), increment),
|
---|
| 84 | });
|
---|
| 85 | var exec = new block_node(this, new node[] { new arg_node(this, loopVar) }, branch, false);
|
---|
| 86 | return new fcall_node(this, intern("for_loop"), new node[] { arg }, exec);
|
---|
| 87 | }
|
---|
| 88 |
|
---|
| 89 | public node controls_forEach(ControlsForEachBlock block)
|
---|
| 90 | {
|
---|
| 91 | // For each loop.
|
---|
| 92 | var lv = local_switch();
|
---|
| 93 |
|
---|
| 94 | var loopVar = local_add_f(block.getFieldValue("VAR"));
|
---|
| 95 | var argument0 = valueToCode(block, "LIST");
|
---|
| 96 | if (argument0 == null) argument0 = new array_node(this, new node[0]);
|
---|
| 97 | var branch = statementToCode(block, "DO");
|
---|
| 98 |
|
---|
| 99 | local_resume(lv);
|
---|
| 100 |
|
---|
| 101 | var exec = new block_node(this, new node[] { new arg_node(this, loopVar) }, branch, false);
|
---|
| 102 | return new call_node(this, argument0, intern("each"), new node[0], exec);
|
---|
| 103 | }
|
---|
| 104 |
|
---|
| 105 | public node controls_flow_statements(ControlsFlowStatementsBlock block)
|
---|
| 106 | {
|
---|
| 107 | // Flow statements: continue, break.
|
---|
| 108 | switch (block.getFieldValue("FLOW")) {
|
---|
| 109 | case "BREAK":
|
---|
| 110 | return new break_node(this, null);
|
---|
| 111 | case "CONTINUE":
|
---|
| 112 | return new next_node(this, null);
|
---|
| 113 | }
|
---|
| 114 | throw new Exception("Unknown flow statement.");
|
---|
| 115 | }
|
---|
| 116 | }
|
---|
| 117 | }
|
---|