Example #1
0
        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));
        }
Example #2
0
        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);
        }
Example #3
0
        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));
        }
Example #4
0
        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));
        }
Example #5
0
        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));
        }
Example #6
0
        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));
        }
Example #7
0
        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).");
        }