Example #1
0
        private static void CompileMemoryFunction(int level, bool debug, Node node, NanCodeWriter wr, Scope parameterNames)
        {
            // Check for special increment mode
            if (node.Text == "set" && Optimisations.IsSmallIncrement(node, out var incr, out var target))
            {
                wr.Increment(incr, target);
                return;
            }

            // Pivot the node's children into 1st child, with the rest as 1st child's children
            var child = new Node(false, node.SourceLocation)
            {
                Text = node.Children.First.Value.Text
            };
            var paramCount = node.Children.Count - 1;

            for (int i = paramCount; i > 0; i--)
            {
                child.AddLast(node.Children.ElementAt(i));
            }

            wr.Merge(Compile(child, level + 1, debug, parameterNames, null, Context.MemoryAccess));

            if (debug)
            {
                wr.Comment("// Memory function : " + node.Text);
            }

            wr.Memory(node.Text[0], child.Text, paramCount);
        }
Example #2
0
        private static bool CompileConditionOrLoop(int level, bool debug, Node node, NanCodeWriter wr, Scope parameterNames)
        {
            bool returns = false;

            if (node.Children.Count < 1)
            {
                throw new ArgumentException(node.Text + " required parameter(s)");
            }

            bool isLoop    = node.Text == "while";
            var  context   = isLoop ? Context.Loop : Context.Condition;
            var  condition = new Node(false, -2);

            condition.AddLast(node.Children.ElementAt(0));
            condition.Text = "()";

            var topOfBlock = wr.Position() - 1;


            var body = new Node(false, -2);

            for (int i = 1; i < node.Children.Count; i++)
            {
                body.AddLast(node.Children.ElementAt(i));
            }

            body.Text = "()";
            var compiledBody = Compile(body, level + 1, debug, parameterNames, null, context);

            returns |= compiledBody.ReturnsValues;
            var opCodeCount = compiledBody.OpCodeCount();

            if (isLoop)
            {
                opCodeCount++;         // also skip the end unconditional jump
            }
            if (debug)
            {
                wr.Comment("// Compare condition for : " + node.Text + ", If false, skip " + compiledBody.OpCodeCount() + " element(s)");
            }

            if (Optimisations.IsSimpleComparion(condition, opCodeCount))
            {
                // output just the arguments
                var argNodes      = Optimisations.ReadSimpleComparison(condition, out var cmpOp, out var argCount);
                var conditionArgs = Compile(argNodes, level + 1, debug, parameterNames, null, context);
                wr.Merge(conditionArgs);
                wr.CompoundCompareJump(cmpOp, argCount, (ushort)opCodeCount);
            }
            else
            {
                var conditionCode = Compile(condition, level + 1, debug, parameterNames, null, context);

                if (debug)
                {
                    wr.Comment("// Condition for : " + node.Text);
                }

                wr.Merge(conditionCode);
                wr.CompareJump(opCodeCount);
            }

            wr.Merge(compiledBody);

            if (debug)
            {
                wr.Comment("// End : " + node.Text);
            }
            if (isLoop)
            {
                var distance = wr.Position() - topOfBlock;
                wr.UnconditionalJump((uint)distance);
            }
            return(returns);
        }