public node procedures_ifreturn(ProceduresIfreturnBlock block) { // Conditionally return value from a procedure. var condition = valueToCode(block, "CONDITION"); if (condition == null) { condition = new false_node(this); } node code = null; if (block.hasReturnValue_) { var value = valueToCode(block, "VALUE"); if (value == null) { value = new nil_node(this); } code = new return_node(this, value); } else { code = new return_node(this, null); } return(new if_node(this, condition, code, null, false)); }
public node controls_if(ControlsIfBlock block) { // If/elseif/else condition. node code = null; if (block.elseCount_ != 0) { code = statementToCode(block, "ELSE"); if (code == null) { code = new nil_node(this); } } for (var n = block.elseifCount_; n >= 0; n--) { var argument = valueToCode(block, "IF" + n); if (argument == null) { argument = new false_node(this); } var branch = statementToCode(block, "DO" + n); code = new if_node(this, argument, branch, code, false); } return(code); }
public node lists_create_with(ListsCreateWithBlock block) { // Create a list with any number of elements of any type. var p = new JsArray <node>(block.itemCount_); for (var n = 0; n < block.itemCount_; n++) { var i = valueToCode(block, "ADD" + n); if (i == null) { i = new nil_node(this); } p.Push(i); } return(new array_node(this, p)); }
public node procedures_callnoreturn(ProceduresCallnoreturnBlock block) { // Call a procedure with no return value. var funcName = intern(block.getFieldValue("NAME")); var args = new JsArray <node>(); for (var x = 0; x < block.arguments_.Length; x++) { args.Push(valueToCode(block, "ARG" + x)); if (args[x] == null) { args[x] = new nil_node(this); } } return(new fcall_node(this, funcName, args, null)); }
public node lists_repeat(ListsRepeatBlock block) { // Create a list with one element repeated. var argument0 = valueToCode(block, "ITEM"); if (argument0 == null) { argument0 = new nil_node(this); } var argument1 = valueToCode(block, "NUM"); if (argument1 == null) { argument1 = new int_node(this, 0); } var a = new array_node(this, new JsArray <node>() { argument0 }); return(new call_node(this, a, intern("*"), argument1)); }
public node logic_ternary(LogicTernaryBlock block) { // Ternary operator. var value_if = valueToCode(block, "IF"); if (value_if == null) { value_if = new false_node(this); } var value_then = valueToCode(block, "THEN"); if (value_then == null) { value_then = new nil_node(this); } var value_else = valueToCode(block, "ELSE"); if (value_else == null) { value_else = new nil_node(this); } return(new if_node(this, value_if, value_then, value_else, true)); }
public node lists_setIndex(ListsSetIndexBlock block) { // Set element at index. var list = valueToCode(block, "LIST"); if (list == null) { list = new array_node(this, new JsArray <node>()); } var mode = block.getFieldValue("MODE"); if (String.IsNullOrEmpty(mode)) { mode = "GET"; } var where = block.getFieldValue("WHERE"); if (String.IsNullOrEmpty(where)) { where = "FROM_START"; } var at = valueToCode(block, "AT"); if (at == null) { at = new int_node(this, 1); } var value = valueToCode(block, "TO"); if (value == null) { value = new nil_node(this); } if (where == "FIRST") { if (mode == "SET") { return(new asgn_node(this, new call_node(this, list, intern("[]"), new JsArray <node>() { new int_node(this, 0) }, null), value)); } else if (mode == "INSERT") { return(new call_node(this, list, intern("unshift"), new JsArray <node>() { value }, null)); } } else if (where == "LAST") { if (mode == "SET") { return(new asgn_node(this, new call_node(this, list, intern("[]"), new JsArray <node>() { new int_node(this, -1) }, null), value)); } else if (mode == "INSERT") { return(new call_node(this, list, intern("push"), new JsArray <node>() { value }, null)); } } else if (where == "FROM_START") { // Blockly uses one-based indicies. if (at is int_node) { // If the index is a naked number, decrement it right now. at = new int_node(this, (int)(((int_node)at).to_i() - 1)); } else { // If the index is dynamic, decrement it in code. at = new begin_node(this, new call_node(this, at, intern("-"), new int_node(this, 1)), true); at = new call_node(this, at, intern("to_i")); } if (mode == "SET") { return(new asgn_node(this, new call_node(this, list, intern("[]"), new JsArray <node>() { at }, null), value)); } else if (mode == "INSERT") { return(new call_node(this, list, intern("insert"), new JsArray <node>() { at, value }, null)); } } else if (where == "FROM_END") { if (mode == "SET") { // Blockly uses one-based indicies. if (at is int_node) { // If the index is a naked number, decrement it right now. } else { // If the index is dynamic, decrement it in code. at = new call_node(this, at, intern("to_i")); } return(new asgn_node(this, new call_node(this, list, intern("[]"), new JsArray <node>() { at }, null), value)); } else if (mode == "INSERT") { // Blockly uses one-based indicies. if (at is int_node) { // If the index is a naked number, decrement it right now. at = new int_node(this, (int)(((int_node)at).to_i() + 1)); } else { // If the index is dynamic, decrement it in code. at = new begin_node(this, new call_node(this, at, intern("+"), new int_node(this, 1)), true); at = new call_node(this, at, intern("to_i")); } at = new call_node(this, at, intern("-@"), (node)null); return(new call_node(this, list, intern("insert"), new JsArray <node>() { at, value }, null)); } } else if (where == "RANDOM") { if (mode == "SET") { return(new fcall_node(this, intern("lists_set_random_item"), new JsArray <node>() { list, value }, null)); } else if (mode == "INSERT") { return(new fcall_node(this, intern("lists_insert_random_item"), new JsArray <node>() { list, value }, null)); } } throw new Exception("Unhandled combination (lists_setIndex)."); }