source: EcnlProtoTool/trunk/webapp/webmrbc/Ruby/Lists.cs@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csharp
File size: 10.3 KB
Line 
1// Porting from
2// https://github.com/jeanlazarou/blockly2ruby
3// Copyright (c) 2014 Jean Lazarou
4// MIT Lisence
5using System;
6using Bridge;
7using System.Collections.Generic;
8
9namespace WebMrbc
10{
11 partial class Ruby
12 {
13 public node lists_create_empty(ListsCreateEmptyBlock block)
14 {
15 // Create an empty list.
16 var p = new node[0];
17 return new array_node(this, p);
18 }
19
20 public node lists_create_with(ListsCreateWithBlock block)
21 {
22 // Create a list with any number of elements of any type.
23 var p = new node[block.itemCount_];
24 for (var n = 0; n < block.itemCount_; n++) {
25 var i = valueToCode(block, "ADD" + n);
26 if (i == null)
27 i = new nil_node(this);
28 p.Push(i);
29 }
30 return new array_node(this, p);
31 }
32
33 public node lists_repeat(ListsRepeatBlock block)
34 {
35 // Create a list with one element repeated.
36 var argument0 = valueToCode(block, "ITEM");
37 if (argument0 == null) argument0 = new nil_node(this);
38 var argument1 = valueToCode(block, "NUM");
39 if (argument1 == null) argument1 = new int_node(this, 0);
40 var a = new array_node(this, new node[] { argument0 });
41 return new call_node(this, a, intern("*"), argument1);
42 }
43
44 public node lists_length(ListsLengthBlock block)
45 {
46 // List length.
47 var argument0 = valueToCode(block, "VALUE");
48 if (argument0 == null) argument0 = new array_node(this, new node[0]);
49 return new call_node(this, argument0, intern("length"));
50 }
51
52 public node lists_isEmpty(ListsIsEmptyBlock block)
53 {
54 // Is the list empty?
55 var argument0 = valueToCode(block, "VALUE");
56 if (argument0 == null) argument0 = new array_node(this, new node[0]);
57 return new call_node(this, argument0, intern("empty?"));
58 }
59
60 public node lists_indexOf(ListsIndexOfBlock block)
61 {
62 // Find an item in the list.
63 var search = valueToCode(block, "FIND");
64 if (search == null) search = new str_node(this, "");
65 var list = valueToCode(block, "VALUE");
66 if (list == null) list = new array_node(this, new node[0]);
67 var finder = block.getFieldValue("END") == "FIRST" ? "find_first" : "find_last";
68 var p = new node[] {
69 search
70 };
71 return new call_node(this, list, intern("finder"), p, null);
72 }
73
74 public node lists_getIndex(ListsGetIndexBlock block)
75 {
76 // Get element at index.
77 var mode = block.getFieldValue("MODE");
78 if (String.IsNullOrEmpty(mode)) mode = "GET";
79 var where = block.getFieldValue("WHERE");
80 if (String.IsNullOrEmpty(where)) where = "FROM_START";
81 var at = valueToCode(block, "AT");
82 if (at == null) at = new int_node(this, 1);
83 var list = valueToCode(block, "VALUE");
84 if (list == null) list = new array_node(this, new node[0]);
85
86 if (where == "FIRST") {
87 if (mode == "GET") {
88 return new call_node(this, list, intern("first"));
89 }
90 else {
91 if (mode == "GET_REMOVE") {
92 return new call_node(this, list, intern("shift"));
93 }
94 else if (mode == "REMOVE") {
95 return new call_node(this, list, intern("shift"));
96 }
97 }
98 }
99 else if (where == "LAST") {
100 if (mode == "GET") {
101 return new call_node(this, list, intern("last"));
102 }
103 else {
104 var code = list + ".pop";
105 if (mode == "GET_REMOVE") {
106 return new call_node(this, list, intern("pop"));
107 }
108 else if (mode == "REMOVE") {
109 return new call_node(this, list, intern("pop"));
110 }
111 }
112 }
113 else if (where == "FROM_START") {
114 // Blockly uses one-based indicies.
115 if (at is int_node) {
116 // If the index is a naked number, decrement it right now.
117 at = new int_node(this, (int)(((int_node)at).to_i() - 1));
118 }
119 else {
120 // If the index is dynamic, decrement it in code.
121 at = new begin_node(this, new call_node(this, at, intern("-"), new int_node(this, 1)), true);
122 at = new call_node(this, at, intern("to_i"));
123 }
124 if (mode == "GET") {
125 return new call_node(this, list, intern("[]"), new node[] { at }, null);
126 }
127 else if (mode == "GET_REMOVE") {
128 return new call_node(this, list, intern("delete_at"), new node[] { at }, null);
129 }
130 else if (mode == "REMOVE") {
131 return new call_node(this, list, intern("delete_at"), new node[] { at }, null);
132 }
133 }
134 else if (where == "FROM_END") {
135 at = new call_node(this, at, intern("-@"), (node)null);
136 if (mode == "GET") {
137 return new call_node(this, list, intern("[]"), new node[] { at }, null);
138 }
139 else if (mode == "GET_REMOVE") {
140 return new call_node(this, list, intern("delete_at"), new node[] { at }, null);
141 }
142 else if (mode == "REMOVE") {
143 return new call_node(this, list, intern("delete_at"), new node[] { at }, null);
144 }
145 }
146 else if (where == "RANDOM") {
147 if (mode == "GET") {
148 return new fcall_node(this, intern("lists_random_item"), new node[] { list }, null);
149 }
150 else {
151 if (mode == "GET_REMOVE") {
152 return new fcall_node(this, intern("lists_remove_random_item"), new node[] { list }, null);
153 }
154 else if (mode == "REMOVE") {
155 return new fcall_node(this, intern("lists_remove_random_item"), new node[] { list }, null);
156 }
157 }
158 }
159 throw new Exception("Unhandled combination (lists_getIndex).");
160 }
161
162 public node lists_setIndex(ListsSetIndexBlock block)
163 {
164 // Set element at index.
165 var list = valueToCode(block, "LIST");
166 if (list == null) list = new array_node(this, new node[0]);
167 var mode = block.getFieldValue("MODE");
168 if (String.IsNullOrEmpty(mode)) mode = "GET";
169 var where = block.getFieldValue("WHERE");
170 if (String.IsNullOrEmpty(where)) where = "FROM_START";
171 var at = valueToCode(block, "AT");
172 if (at == null) at = new int_node(this, 1);
173 var value = valueToCode(block, "TO");
174 if (value == null) value = new nil_node(this);
175
176 if (where == "FIRST") {
177 if (mode == "SET") {
178 return new asgn_node(this, new call_node(this, list, intern("[]"), new node[] { new int_node(this, 0) }, null), value);
179 }
180 else if (mode == "INSERT") {
181 return new call_node(this, list, intern("unshift"), new node[] { value }, null);
182 }
183 }
184 else if (where == "LAST") {
185 if (mode == "SET") {
186 return new asgn_node(this, new call_node(this, list, intern("[]"), new node[] { new int_node(this, -1) }, null), value);
187 }
188 else if (mode == "INSERT") {
189 return new call_node(this, list, intern("push"), new node[] { value }, null);
190 }
191 }
192 else if (where == "FROM_START") {
193 // Blockly uses one-based indicies.
194 if (at is int_node) {
195 // If the index is a naked number, decrement it right now.
196 at = new int_node(this, (int)(((int_node)at).to_i() - 1));
197 }
198 else {
199 // If the index is dynamic, decrement it in code.
200 at = new begin_node(this, new call_node(this, at, intern("-"), new int_node(this, 1)), true);
201 at = new call_node(this, at, intern("to_i"));
202 }
203 if (mode == "SET") {
204 return new asgn_node(this, new call_node(this, list, intern("[]"), new node[] { at }, null), value);
205 }
206 else if (mode == "INSERT") {
207 return new call_node(this, list, intern("insert"), new node[] { at, value }, null);
208 }
209 }
210 else if (where == "FROM_END") {
211 if (mode == "SET") {
212 // Blockly uses one-based indicies.
213 if (at is int_node) {
214 // If the index is a naked number, decrement it right now.
215 }
216 else {
217 // If the index is dynamic, decrement it in code.
218 at = new call_node(this, at, intern("to_i"));
219 }
220 return new asgn_node(this, new call_node(this, list, intern("[]"), new node[] { at }, null), value);
221 }
222 else if (mode == "INSERT") {
223 // Blockly uses one-based indicies.
224 if (at is int_node) {
225 // If the index is a naked number, decrement it right now.
226 at = new int_node(this, (int)(((int_node)at).to_i() + 1));
227 }
228 else {
229 // If the index is dynamic, decrement it in code.
230 at = new begin_node(this, new call_node(this, at, intern("+"), new int_node(this, 1)), true);
231 at = new call_node(this, at, intern("to_i"));
232 }
233
234 at = new call_node(this, at, intern("-@"), (node)null);
235 return new call_node(this, list, intern("insert"), new node[] { at, value }, null);
236 }
237 }
238 else if (where == "RANDOM") {
239 if (mode == "SET") {
240 return new fcall_node(this, intern("lists_set_random_item"), new node[] { list, value }, null);
241 }
242 else if (mode == "INSERT") {
243 return new fcall_node(this, intern("lists_insert_random_item"), new node[] { list, value }, null);
244 }
245 }
246 throw new Exception("Unhandled combination (lists_setIndex).");
247 }
248
249 public node lists_getSublist(ListsGetSublistBlock block)
250 {
251 // Get sublist.
252 var list = valueToCode(block, "LIST");
253 if (list == null) list = new array_node(this, new node[0]);
254 var where1 = block.getFieldValue("WHERE1");
255 var where2 = block.getFieldValue("WHERE2");
256 var at1 = valueToCode(block, "AT1");
257 if (at1 == null) at1 = new int_node(this, 1);
258 var at2 = valueToCode(block, "AT2");
259 if (at2 == null) at2 = new int_node(this, 1);
260 if (where1 == "FIRST" || (where1 == "FROM_START" && at1 is int_node && ((int_node)at1).to_i() == 1)) {
261 at1 = new int_node(this, 0);
262 }
263 else if (where1 == "FROM_START") {
264 // Blockly uses one-based indicies.
265 if (at1 is int_node) {
266 at1 = new int_node(this, (int)(((int_node)at1).to_i() - 1));
267 }
268 else {
269 at1 = new call_node(this, at1, intern("to_i"));
270 at1 = new call_node(this, at1, intern("-"), new int_node(this, 1));
271 }
272 }
273 else if (where1 == "FROM_END") {
274 if (at1 is int_node) {
275 at1 = new int_node(this, (int)(-((int_node)at1).to_i()));
276 }
277 else {
278 at1 = new call_node(this, at1, intern("-@"), (node)null);
279 at1 = new call_node(this, at1, intern("to_i"));
280 }
281 }
282 if (where2 == "LAST" || (where2 == "FROM_END" && at2 is int_node && ((int_node)at2).to_i() == 1)) {
283 at2 = new int_node(this, -1);
284 }
285 else if (where2 == "FROM_START") {
286 if (at2 is int_node) {
287 at2 = new int_node(this, (int)(((int_node)at2).to_i() - 1));
288 }
289 else {
290 at2 = new call_node(this, at2, intern("to_i"));
291 at2 = new call_node(this, at2, intern("-"), new int_node(this, 1));
292 }
293 }
294 else if (where2 == "FROM_END") {
295 if (at2 is int_node) {
296 at2 = new int_node(this, (int)(-((int_node)at2).to_i()));
297 }
298 else {
299 at2 = new call_node(this, at2, intern("-@"), (node)null);
300 at2 = new call_node(this, at2, intern("to_i"));
301 }
302 }
303 return new fcall_node(this, intern("lists_sublist"), new node[] { list, at1, at2 }, null);
304 }
305 }
306}
Note: See TracBrowser for help on using the repository browser.