source: EcnlProtoTool/trunk/webapp/webmrbc/Ruby/Text.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: 8.2 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 text(TextBlock block)
14 {
15 // Text value.
16 return new_str_node(block.getFieldValue("TEXT"));
17 }
18
19 public node text_join(TextJoinBlock block)
20 {
21 // Create a string made up of any number of elements of any type.
22 if (block.itemCount_ == 0) {
23 return new str_node(this, "");
24 }
25 else if (block.itemCount_ == 1) {
26 var argument0 = valueToCode(block, "ADD0");
27 if (argument0 == null) argument0 = new str_node(this, "");
28 return new call_node(this, argument0, intern("to_s"));
29 }
30 else {
31 var argument0 = valueToCode(block, "ADD0");
32 if (argument0 == null)
33 argument0 = new str_node(this, "");
34 else
35 argument0 = new call_node(this, argument0, intern("to_s"));
36 for (var n = 1; n < block.itemCount_; n++) {
37 var argument1 = valueToCode(block, "ADD" + n);
38 if (argument1 == null)
39 argument1 = new str_node(this, "");
40 else
41 argument1 = new call_node(this, argument1, intern("to_s"));
42 argument0 = new call_node(this, argument0, intern("+"), argument1);
43 }
44 return argument0;
45 }
46 }
47
48 public node text_append(TextAppendBlock block)
49 {
50 // Append to a variable in place.
51 var varName = get_var_name(block.getFieldValue("VAR"));
52 var argument0 = valueToCode(block, "TEXT");
53 if (argument0 == null)
54 argument0 = new str_node(this, "");
55 else
56 argument0 = new call_node(this, argument0, intern("to_s"));
57 var code = new call_node(this, new_var_node(varName), intern("to_s"));
58 code = new call_node(this, code, intern("+"), argument0);
59 return new asgn_node(this, new_var_node(varName), code);
60 }
61
62 public node text_length(TextLengthBlock block)
63 {
64 // String length.
65 var argument0 = valueToCode(block, "VALUE");
66 if (argument0 == null) argument0 = new str_node(this, "");
67 return new call_node(this, argument0, intern("size"));
68 }
69
70 public node text_isEmpty(TextIsEmptyBlock block)
71 {
72 // Is the string null?
73 var argument0 = valueToCode(block, "VALUE");
74 if (argument0 == null) argument0 = new str_node(this, "");
75 return new call_node(this, argument0, intern("empty?"));
76 }
77
78 public node text_indexOf(TextIndexOfBlock block)
79 {
80 // Search the text for a substring.
81 // Should we allow for non-case sensitive???
82 var finder = block.getFieldValue("END") == "FIRST" ? "find_first" : "find_last";
83 var search = valueToCode(block, "FIND");
84 if (search == null) search = new str_node(this, "");
85 var text = valueToCode(block, "VALUE");
86 if (text == null) text = new str_node(this, "");
87 return new call_node(this, text, intern(finder), new node[] { search }, null);
88 }
89
90 public node text_charAt(TextCharAtBlock block)
91 {
92 // Get letter at index.
93 // Note: Until January 2013 this block did not have the WHERE input.
94 var where = block.getFieldValue("WHERE");
95 if (String.IsNullOrEmpty(where)) where = "FROM_START";
96 var at = valueToCode(block, "AT");
97 if (at == null) at = new int_node(this, 1);
98 var text = valueToCode(block, "VALUE");
99 if (text == null) text = new str_node(this, "");
100
101 // Blockly uses one-based indicies.
102 if (at is int_node) {
103 // If the index is a naked number, decrement it right now.
104 at = new int_node(this, (int)(((int_node)at).to_i() - 1));
105 }
106 else {
107 // If the index is dynamic, decrement it in code.
108 at = new call_node(this, at, intern("to_i"));
109 at = new call_node(this, at, intern("-"), new int_node(this, 1));
110 }
111
112 switch (where) {
113 case "FIRST":
114 return new call_node(this, text, intern("[]"), new node[] { new int_node(this, 0) }, null);
115 case "LAST":
116 return new call_node(this, text, intern("[]"), new node[] { new int_node(this, -1) }, null);
117 case "FROM_START":
118 return new fcall_node(this, intern("text_get_from_start"), new node[] { text, at }, null);
119 case "FROM_END":
120 return new fcall_node(this, intern("text_get_from_end"), new node[] { text, at }, null);
121 case "RANDOM":
122 return new fcall_node(this, intern("text_random_letter"), new node[] { text }, null);
123 }
124 throw new Exception("Unhandled option (text_charAt).");
125 }
126
127 public node text_getSubstring(TextGetSubstringBlock block)
128 {
129 // Get substring.
130 var text = valueToCode(block, "STRING");
131 if (text == null) text = new str_node(this, "");
132 var where1 = block.getFieldValue("WHERE1");
133 var where2 = block.getFieldValue("WHERE2");
134 var at1 = valueToCode(block, "AT1");
135 if (at1 == null) at1 = new int_node(this, 1);
136 var at2 = valueToCode(block, "AT2");
137 if (at2 == null) at2 = new int_node(this, 1);
138 if (where1 == "FIRST" || (where1 == "FROM_START" && at1 is int_node && ((int_node)at1).to_i() == 1)) {
139 at1 = new int_node(this, 0);
140 }
141 else if (where1 == "FROM_START") {
142 // Blockly uses one-based indicies.
143 if (at1 is int_node) {
144 // If the index is a naked number, decrement it right now.
145 at1 = new int_node(this, (int)(((int_node)at1).to_i() - 1));
146 }
147 else {
148 // If the index is dynamic, decrement it in code.
149 at1 = new call_node(this, at1, intern("to_i"));
150 at1 = new call_node(this, at1, intern("-"), new int_node(this, 1));
151 }
152 }
153 else if (where1 == "FROM_END") {
154 if (at1 is int_node) {
155 at1 = new int_node(this, (int)(-((int_node)at1).to_i()));
156 }
157 else {
158 at1 = new call_node(this, at1, intern("-@"), (node)null);
159 at1 = new call_node(this, at1, intern("to_i"));
160 }
161 }
162 if (where2 == "LAST" || (where2 == "FROM_END" && at2 is int_node && ((int_node)at2).to_i() == 1)) {
163 at2 = new int_node(this, -1);
164 }
165 else if (where2 == "FROM_START") {
166 if (at2 is int_node) {
167 at2 = new int_node(this, (int)(((int_node)at2).to_i() - 1));
168 }
169 else {
170 at2 = new call_node(this, at2, intern("to_i"));
171 at2 = new call_node(this, at2, intern("-"), new int_node(this, 1));
172 }
173 }
174 else if (where2 == "FROM_END") {
175 if (at2 is int_node) {
176 at2 = new int_node(this, (int)(-((int_node)at2).to_i()));
177 }
178 else {
179 at2 = new call_node(this, at2, intern("-@"), (node)null);
180 at2 = new call_node(this, at2, intern("to_i"));
181 }
182 }
183 var code = new dot2_node(this, at1, at2);
184 return new call_node(this, text, intern("[]"), new node[] { code }, null);
185 }
186
187 public node text_changeCase(TextChangeCaseBlock block)
188 {
189 // Change capitalization.
190 var OPERATORS = new Dictionary<string, string>() {
191 { "UPPERCASE", "upcase" },
192 { "LOWERCASE", "downcase"},
193 { "TITLECASE", null }
194 };
195 node code;
196 var @operator = OPERATORS[block.getFieldValue("CASE")];
197 if (!String.IsNullOrEmpty(@operator)) {
198 @operator = OPERATORS[block.getFieldValue("CASE")];
199 var argument0 = valueToCode(block, "TEXT");
200 if (argument0 == null) argument0 = new str_node(this, "");
201 code = new call_node(this, argument0, intern(@operator));
202 }
203 else {
204 // Title case is not a native Ruby function. Define one.
205 var argument0 = valueToCode(block, "TEXT");
206 if (argument0 == null) argument0 = new str_node(this, "");
207 code = new fcall_node(this, intern("text_to_title_case"), new node[] { argument0 }, null);
208 }
209 return code;
210 }
211
212 public node text_trim(TextTrimBlock block)
213 {
214 // Trim spaces.
215 var OPERATORS = new Dictionary<string, string>() {
216 { "LEFT", ".lstrip" },
217 { "RIGHT", ".rstrip"},
218 { "BOTH", ".strip" }
219 };
220 var @operator = OPERATORS[block.getFieldValue("MODE")];
221 var argument0 = valueToCode(block, "TEXT");
222 if (argument0 == null) argument0 = new str_node(this, "");
223 return new call_node(this, argument0, intern(@operator));
224 }
225
226 public node text_print(TextPrintBlock block)
227 {
228 // Print statement.
229 var argument0 = valueToCode(block, "TEXT");
230 if (argument0 == null) argument0 = new str_node(this, "");
231 return new fcall_node(this, intern("blockly_puts"), new node[] { argument0 }, null);
232 }
233
234 public node text_prompt(TextPromptBlock block)
235 {
236 // Prompt function.
237 var msg = new str_node(this, block.getFieldValue("TEXT"));
238 node code = new fcall_node(this, intern("text_prompt"), new node[] { msg }, null);
239 var toNumber = block.getFieldValue("TYPE") == "NUMBER";
240 if (toNumber) {
241 code = new call_node(this, code, intern("to_f"));
242 }
243 return code;
244 }
245 }
246}
Note: See TracBrowser for help on using the repository browser.