/// <summary>
        /// Constructs a Code Node with asm commands representing a heap top modification on a given offset.
        /// </summary>
        /// <param name="parent">Parent Code Node</param>
        /// <param name="offset">How much we can change heap top</param>
        /// <param name="useAsReg">It this true, 'offset' would be considered as register number and
        /// instead of constant heap top change, execution-time change commands would be generated</param>
        /// <param name="decrease">If 'useAsReg' is true, defines whether we allocating heap memory or deallocating ('decrease = true' means allocation)</param>
        /// <returns></returns>
        protected CodeNode GetHeapTopChangeNode(CodeNode?parent, int offset, bool useAsReg = false, bool decrease = true)
        {
            CodeNode heapTopNode = new CodeNode("Heap top change by " + (useAsReg ? (decrease ? ("-R" + offset) : ("+R" + offset)) : offset.ToString()) + " bytes", parent)
                                   .Add(GenerateLDC(0, 27))
                                   .Add(GenerateLD(27, 27));

            if (useAsReg)
            {
                if (decrease)
                {
                    heapTopNode.Add(GenerateSUB(offset, 27)); // When we load the heap
                }
                else
                {
                    heapTopNode.Add(GenerateADD(offset, 27)); // When we free the heap
                }
            }
            else
            {
                heapTopNode.Add(GenerateLDA(27, 27, offset));
            }
            heapTopNode
            .Add(GenerateLDC(0, SB))
            .Add(GenerateST(27, SB))
            .Add(GenerateLDC(4, SB));     // Tricky trick
            return(heapTopNode);
        }
        /// <summary>
        /// Constructs a Code Node that has generated binary code of loading a given variable address (on the stack) to the given register.
        /// </summary>
        /// <param name="parent">Parent Code Node.</param>
        /// <param name="varName">Variable name which address is to be loaded into register.</param>
        /// <param name="reg">Register to load to given variable address.</param>
        /// <param name="ctx">Current context.</param>
        /// <returns>Constructed Code Node that represents binary code that loads given variable address to the given register.</returns>
        protected CodeNode GetLoadVariableAddressNode(CodeNode?parent, string varName, byte reg, Context?ctx)
        {
            CodeNode loadVarNode = new CodeNode("Load variable address \'" + varName + "\' into R" + reg.ToString(), parent);

            if (ctx.IsVarGlobal(varName))
            {
                loadVarNode
                .Add(GenerateLDA(SB, 27, ctx.GetStaticOffset(varName)))
                .Add(GenerateMOV(27, reg));
            }
            else
            {
                int blockOffset = ctx.GetVarDeclarationBlockOffset(varName);
                loadVarNode.Add(GenerateMOV(FP, 27));
                for (int i = 0; i < blockOffset; i++)
                {
                    loadVarNode
                    .Add(GenerateLDA(27, 27, -4))
                    .Add(GenerateLD(27, 27));
                }
                loadVarNode
                .Add(GenerateLDA(27, 27, ctx.GetFrameOffset(varName)))
                .Add(GenerateMOV(27, reg));
            }

            return(loadVarNode);
        }
        void Language(StructuredReport report)
        {
            CodeNode language = new CodeNode(new CodedEntry("121049", "DCM", "Language of Content Item and Descendants"));

            language.Value = new CodedEntry("en", "RFC3066", "English");
            report.Root.Add(language, RelationshipType.HasConceptModifier);

            CodeNode country = new CodeNode(new CodedEntry("121046", "DCM", "Country of Language"));

            country.Value = new CodedEntry("US", "ISO3166_1", "UNITED STATES");
            language.Add(country, RelationshipType.HasConceptModifier);
        }
        public override CodeNode Construct(AASTNode aastNode, CodeNode?parent)
        {
            Generator g        = Program.currentCompiler.generator;
            CodeNode  exprNode = new CodeNode(aastNode, parent);

            // 1) Store result of the left operand in FR0
            CodeNode firstOpNode = base.Construct((AASTNode)aastNode.Children[0], exprNode);
            byte     fr0         = firstOpNode.ByteToReturn;

            exprNode.Children.AddLast(firstOpNode);
            exprNode.ByteToReturn = fr0;

            if (aastNode.Children.Count > 1)
            {
                exprNode.OperandByte = fr0; // Update operand register

                // 2) Store result of the right operand in FR0/FR1
                CodeNode secondOpNode = base.Construct((AASTNode)aastNode.Children[2], exprNode);
                byte     fr1          = secondOpNode.ByteToReturn;
                exprNode.Children.AddLast(secondOpNode);

                // 3) Generate a code of the operation itself using these two register
                //    and put an extra byte indicating the register with the result
                //    (this byte is being removed upper in the call stack)
                string   op            = aastNode.Children[1].Token.Value;
                CodeNode operationNode = new CodeNode("Operation \'" + op + "\'", exprNode);
                switch (op)
                {
                // ATTENTION: What about command "format"? I use 32 everywhere. ANSWER: it's okay.
                case "+":
                {
                    // FR0 += FR1; FR0  # In this case order does not matter
                    operationNode.Add(GenerateADD(fr1, fr0));
                    exprNode.ByteToReturn = fr0;
                    break;
                }

                case "-":
                {
                    // FR0 -= FR1; FR0
                    operationNode.Add(GenerateSUB(fr1, fr0));
                    exprNode.ByteToReturn = fr0;
                    break;
                }

                case ">=":
                {
                    // FR2 := 1;
                    // FR3 := <lsr>;
                    // <lsr>
                    // FR0 >= FR0;
                    // FR1 -= FR2;
                    // if FR1 goto FR3;
                    // fr0
                    CodeNode fr2Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr2Node);
                    byte     fr2     = fr2Node.ByteToReturn;
                    CodeNode fr3Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr3Node);
                    byte     fr3      = fr3Node.ByteToReturn;
                    CodeNode lsrNode1 = new CodeNode("LSR cmds 1", operationNode)
                                        .Add(GenerateLDC(1, fr2));
                    CodeNode lsrNode2 = new CodeNode("LSR cmds 2", operationNode)
                                        .Add(GenerateLSR(fr0, fr0))
                                        .Add(GenerateSUB(fr2, fr1))
                                        .Add(GenerateCBR(fr1, fr3));

                    CodeNode lsrLabelDecl = new CodeNode("Label declaration", operationNode).Add(new byte[8]);
                    lsrLabelDecl.ByteToReturn = fr3;
                    CodeNode lsrLabel = new CodeNode("Label", operationNode);
                    lsrLabel.LabelDecl = lsrLabelDecl;

                    operationNode.Children.AddLast(lsrNode1);
                    operationNode.Children.AddLast(lsrLabelDecl);
                    operationNode.Children.AddLast(lsrLabel);
                    operationNode.Children.AddLast(lsrNode2);

                    exprNode.ByteToReturn = fr0;
                    g.FreeReg(fr2);
                    g.FreeReg(fr3);
                    break;
                }

                case "<=":
                {
                    // FR2 := 1;
                    // FR3 := <lsr>;
                    // <lsr>
                    // FR0 >= FR0;
                    // FR1 -= FR2;
                    // if FR1 goto FR3;
                    // fr0
                    CodeNode fr2Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr2Node);
                    byte     fr2     = fr2Node.ByteToReturn;
                    CodeNode fr3Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr3Node);
                    byte     fr3      = fr3Node.ByteToReturn;
                    CodeNode lslNode1 = new CodeNode("LSL cmds 1", operationNode)
                                        .Add(GenerateLDC(1, fr2));
                    CodeNode lslNode2 = new CodeNode("LSL cmds 2", operationNode)
                                        .Add(GenerateLSL(fr0, fr0))
                                        .Add(GenerateSUB(fr2, fr1))
                                        .Add(GenerateCBR(fr1, fr3));
                    CodeNode lslLabelDecl = new CodeNode("Label declaration", operationNode).Add(new byte[8]);
                    lslLabelDecl.ByteToReturn = fr3;
                    CodeNode lslLabel = new CodeNode("Label", operationNode);
                    lslLabel.LabelDecl = lslLabelDecl;

                    operationNode.Children.AddLast(lslNode1);
                    operationNode.Children.AddLast(lslLabelDecl);
                    operationNode.Children.AddLast(lslLabel);
                    operationNode.Children.AddLast(lslNode2);

                    exprNode.ByteToReturn = fr0;
                    g.FreeReg(fr2);
                    g.FreeReg(fr3);
                    break;
                }

                case "&":
                {
                    // FR0 &= FR1; FR0
                    operationNode.Add(GenerateAND(fr1, fr0));
                    exprNode.ByteToReturn = fr0;
                    break;
                }

                case "|":
                {
                    // FR0 |= FR1; FR0
                    operationNode.Add(GenerateOR(fr1, fr0));
                    exprNode.ByteToReturn = fr0;
                    break;
                }

                case "^":
                {
                    // FR0 ^= FR1; FR0
                    operationNode.Add(GenerateXOR(fr1, fr0));
                    exprNode.ByteToReturn = fr0;
                    break;
                }

                case "?":
                {
                    // FR0 ?= FR1; FR0
                    operationNode.Add(GenerateCND(fr1, fr0));
                    exprNode.ByteToReturn = fr0;
                    break;
                }

                case "=":
                case "/=":
                case ">":
                case "<":
                {
                    int      mask    = op.Equals("=") ? 4 : op.Equals("/=") ? 3 : op.Equals(">") ? 1 : op.Equals("<") ? 2 : 7;
                    CodeNode fr2Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr2Node);
                    byte fr2 = fr2Node.ByteToReturn;
                    // FR2 := mask;
                    // FR1 ?= FR0;
                    // FR2 &= FR1;
                    // FR0 = 1;
                    // FR1 = <true>;
                    // if FR2 goto FR1;
                    // FR0 := 0;
                    // <true>
                    // fr0
                    operationNode.Children.AddLast(new CodeNode("cond cmds 1", operationNode)
                                                   .Add(GenerateLDC(mask, fr2))
                                                   .Add(GenerateCND(fr0, fr1))
                                                   .Add(GenerateAND(fr1, fr2))
                                                   .Add(GenerateLDC(1, fr0)));

                    CodeNode labelDeclNode = new CodeNode("Label declaration", operationNode).Add(new byte[8]);
                    labelDeclNode.ByteToReturn = fr1;
                    CodeNode labelNode = new CodeNode("Label", operationNode);
                    labelNode.LabelDecl = labelDeclNode;

                    operationNode.Children.AddLast(labelDeclNode);
                    operationNode.Children.AddLast(new CodeNode("cond cmds 2", operationNode)
                                                   .Add(GenerateCBR(fr2, fr1))
                                                   .Add(GenerateLDC(0, fr0)));
                    operationNode.Children.AddLast(labelNode);
                    exprNode.ByteToReturn = fr0;
                    g.FreeReg(fr2);
                    break;
                }

                case "*":
                {
                    // WHAT A MONSTROSITY!
                    // -------------------
                    // FR2 := 0;
                    // FR2 := FR2 + 32;
                    // FR3 := mult (27);
                    // FR4 := add (27);
                    // FR5 := not_add (21);
                    // FR6 := 1; # Mask
                    // FR7 := 0; # For result
                    // FR8 := 1; # For iteration
                    // <mult>
                    // FR9 := 0; # For loop exit
                    // FR6 &= FR1;
                    // if FR6 goto FR4;
                    // if FR8 goto FR5;
                    // <add>
                    // FR7 += FR0;
                    // <not_add>
                    // FR6 := 1;
                    // FR8 := 1;
                    // FR0 <= FR0;
                    // FR1 >= FR1;
                    // FR2 -= FR8;
                    // FR9 ?= FR2;
                    // FR9 &= FR8;
                    // if FR9 goto FR3;
                    // FR0 := FR7;
                    // fr0
                    // ---
                    // Can be definitely optimized (in case of multiplying by power of 2, for example)

                    CodeNode fr2Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr2Node);
                    byte fr2 = fr2Node.ByteToReturn;

                    CodeNode fr3Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr3Node);
                    byte fr3 = fr3Node.ByteToReturn;

                    CodeNode fr4Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr4Node);
                    byte fr4 = fr4Node.ByteToReturn;

                    CodeNode fr5Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr5Node);
                    byte fr5 = fr5Node.ByteToReturn;

                    CodeNode fr6Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr6Node);
                    byte fr6 = fr6Node.ByteToReturn;

                    CodeNode fr7Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr7Node);
                    byte fr7 = fr7Node.ByteToReturn;

                    CodeNode fr8Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr8Node);
                    byte fr8 = fr8Node.ByteToReturn;

                    CodeNode fr9Node = GetFreeRegisterNode(aastNode, operationNode);
                    operationNode.Children.AddLast(fr9Node);
                    byte fr9 = fr9Node.ByteToReturn;

                    operationNode.Children.AddLast(new CodeNode("mult 1", operationNode)
                                                   .Add(GenerateLDC(0, fr2))
                                                   .Add(GenerateLDA(fr2, fr2, 32)));

                    CodeNode fr3LabelDeclNode = new CodeNode("Label declaration", operationNode).Add(new byte[8]);
                    fr3LabelDeclNode.ByteToReturn = fr3;
                    CodeNode fr3LabelNode = new CodeNode("Label", operationNode);
                    fr3LabelNode.LabelDecl = fr3LabelDeclNode;

                    CodeNode fr4LabelDeclNode = new CodeNode("Label declaration", operationNode).Add(new byte[8]);
                    fr4LabelDeclNode.ByteToReturn = fr4;
                    CodeNode fr4LabelNode = new CodeNode("Label", operationNode);
                    fr4LabelNode.LabelDecl = fr4LabelDeclNode;

                    CodeNode fr5LabelDeclNode = new CodeNode("Label declaration", operationNode).Add(new byte[8]);
                    fr5LabelDeclNode.ByteToReturn = fr5;
                    CodeNode fr5LabelNode = new CodeNode("Label", operationNode);
                    fr5LabelNode.LabelDecl = fr5LabelDeclNode;

                    operationNode.Children.AddLast(fr3LabelDeclNode);
                    operationNode.Children.AddLast(fr4LabelDeclNode);
                    operationNode.Children.AddLast(fr5LabelDeclNode);

                    operationNode.Children.AddLast(new CodeNode("mult 2", operationNode)
                                                   .Add(GenerateLDC(1, fr6))
                                                   .Add(GenerateLDC(0, fr7))
                                                   .Add(GenerateLDC(1, fr8)));

                    operationNode.Children.AddLast(fr3LabelNode);

                    operationNode.Children.AddLast(new CodeNode("mult 3", operationNode)
                                                   .Add(GenerateLDC(0, fr9))
                                                   .Add(GenerateAND(fr1, fr6))
                                                   .Add(GenerateCBR(fr6, fr4))
                                                   .Add(GenerateCBR(fr8, fr5)));

                    operationNode.Children.AddLast(fr4LabelNode);

                    operationNode.Children.AddLast(new CodeNode("mult 4", operationNode)
                                                   .Add(GenerateADD(fr0, fr7)));

                    operationNode.Children.AddLast(fr5LabelNode);

                    operationNode.Children.AddLast(new CodeNode("mult 5", operationNode)
                                                   .Add(GenerateLDC(1, fr6))
                                                   .Add(GenerateLDC(1, fr8))
                                                   .Add(GenerateLSL(fr0, fr0))
                                                   .Add(GenerateLSR(fr1, fr1))
                                                   .Add(GenerateSUB(fr8, fr2))
                                                   .Add(GenerateCND(fr2, fr9))
                                                   .Add(GenerateAND(fr8, fr9))
                                                   .Add(GenerateCBR(fr9, fr3))
                                                   .Add(GenerateMOV(fr7, fr0)));

                    exprNode.ByteToReturn = fr0;
                    g.FreeReg(fr2);
                    g.FreeReg(fr3);
                    g.FreeReg(fr4);
                    g.FreeReg(fr5);
                    g.FreeReg(fr6);
                    g.FreeReg(fr7);
                    g.FreeReg(fr8);
                    g.FreeReg(fr9);
                    break;
                }

                default:
                    break;
                }
                exprNode.Children.AddLast(operationNode);

                // 4) Free the other register (the resulting register is freed upper in the call stack)
                g.FreeReg(fr1);
            }

            return(exprNode);
        }
Beispiel #5
0
        public override CodeNode Construct(AASTNode aastNode, CodeNode?parent)
        {
            CodeNode programNode = new CodeNode(aastNode, parent);

            CodeNode vptNode      = new CodeNode("Version/padding/tech bytes", programNode); // Used for simulator
            CodeNode staticNode   = new CodeNode("Static bytes", programNode);               // All static data
            CodeNode unitsNode    = new CodeNode("Units' addresses node", programNode);      // Code that puts proper unit addresses in static data
            CodeNode codeNode     = new CodeNode("Actual program code", programNode);
            CodeNode skipStopNode = new CodeNode("Skip/Stop", programNode);

            programNode.Children.AddLast(vptNode);
            programNode.Children.AddLast(staticNode);
            programNode.Children.AddLast(unitsNode);
            programNode.Children.AddLast(codeNode);
            programNode.Children.AddLast(skipStopNode);

            staticNode.Add(GetConstBytes(Program.config.MemorySize))
            .Add(GetLList(new byte[aastNode.AASTValue]));

            int staticLength = (staticNode.Count() + staticNode.Count() % 2) / 2; // We count in words (2 bytes) (???) DECISION: ok

            // Identify all data blocks beforehand and populate static data with its values
            foreach (AASTNode child in aastNode.Children)
            {
                if (child.ASTType.Equals("Data"))
                {
                    LinkedList <byte> data = new LinkedList <byte>();
                    for (int i = 1; i < child.Children.Count; i++)
                    {
                        foreach (byte b in GetConstBytes(((AASTNode)child.Children[i]).AASTValue))
                        {
                            data.AddLast(b);
                        }
                    }
                    staticNode.Replace(aastNode.Context.GetStaticOffset(child.Children[0].Token.Value) + 4, data);
                }
            }

            // First unit offset - to store correct addresses inside static frame
            int techOffset = 16; // LDA(SB), LDA(SB + codeOffset), 27 = ->27, if 27 goto 27

            // Identify all modules and routines
            int modulesAndRoutines = 0;

            foreach (AASTNode child in aastNode.Children)
            {
                if (child.ASTType.Equals("Routine") || child.ASTType.Equals("Module") || child.ASTType.Equals("Code"))
                {
                    modulesAndRoutines++;
                }
            }

            techOffset += modulesAndRoutines * 16;
            CodeNode dummyNode = new CodeNode("dummy. Do not add it anywhere in a CodeNode tree. Used for label resolution.", null);

            unitsNode.Add(new byte[techOffset]); // Just fill bytes with zeros for a while (due to label resolution).

            // Identify all code data
            int staticSize = staticNode.Count();
            int codeSize   = 0;

            foreach (AASTNode child in aastNode.Children)
            {
                if (child.ASTType.Equals("Routine") || child.ASTType.Equals("Module") || child.ASTType.Equals("Code"))
                {
                    dummyNode.Add(GenerateLDA(SB, 27, aastNode.Context.GetStaticOffset(child.Context.Name)))
                    .Add(GenerateLDC(0, 26))
                    .Add(GenerateLDA(26, 26, staticSize + techOffset + codeSize))
                    .Add(GenerateST(26, 27));
                }

                codeNode.Children.AddLast(base.Construct(child, codeNode));
                codeSize += codeNode.Children.Last.Value.Count();
            }

            unitsNode.Bytes.Clear();
            unitsNode.Add(GenerateLDA(SB, SB, 4));

            // Put the actual units' code after it has been processed
            unitsNode.Add(dummyNode.Bytes);

            // Go to code module uncoditionally
            unitsNode.Add(GenerateLDA(SB, 27, aastNode.Context.GetStaticOffset("code")))
            .Add(GenerateLD(27, 27))
            .Add(GenerateCBR(27, 27));

            #region GOTO resolution
            List <CodeNode> gotoNodes = new List <CodeNode>();
            FindAllCodeNodesWithName(programNode, "Goto", gotoNodes);
            foreach (CodeNode gotoNode in gotoNodes)
            {
                int      ctxNum          = -1; // minus one since Program context does not have a stack allocated. It is static or global.
                string   labelName       = gotoNode.AASTLink.Children[0].Token.Value;
                AASTNode mainContextNode = gotoNode.AASTLink;
                // If we jump from some contexts, we have to deallocate stack, heap, and other related memory
                while (true)
                {
                    if (mainContextNode.Parent == null)
                    {
                        throw new CompilationErrorException("No label \'" + labelName + "\' found in the current context!!!\r\n" +
                                                            "  At (Line: " + gotoNode.AASTLink.Token.Position.Line +
                                                            ", Char: " + gotoNode.AASTLink.Token.Position.Char + ").");
                    }
                    if (mainContextNode.Context != null)
                    {
                        ctxNum++;
                        if (mainContextNode.Context.IsVarDeclaredInThisContext(labelName))
                        {
                            break;
                        }
                        gotoNode.Children.AddLast(GetDynamicMemoryDeallocationNode(mainContextNode, gotoNode));
                        if (mainContextNode.ASTType.Equals("For"))
                        {
                            gotoNode.Children.AddLast(GetHeapTopChangeNode(gotoNode, 16));
                        }
                        if (mainContextNode.ASTType.Equals("While"))
                        {
                            gotoNode.Children.AddLast(GetHeapTopChangeNode(gotoNode, 12));
                        }
                        if (mainContextNode.ASTType.Equals("Loop While"))
                        {
                            gotoNode.Children.AddLast(GetHeapTopChangeNode(gotoNode, 4));
                        }
                    }
                    mainContextNode = (AASTNode)mainContextNode.Parent;
                }
                for (int i = 0; i < ctxNum; i++)
                {
                    gotoNode.Children.AddLast(new CodeNode("Return stack back", gotoNode)
                                              .Add(GenerateLDA(FP, FP, -4))
                                              .Add(GenerateMOV(FP, SP))
                                              .Add(GenerateLD(FP, FP)));
                }

                CodeNode?gotoLabelNode = gotoNode;
                while (true)
                {
                    if (gotoLabelNode == null)
                    {
                        throw new CompilationErrorException("No label \'" + labelName + "\' found in the current context!!!\r\n" +
                                                            "  At (Line: " + gotoNode.AASTLink.Token.Position.Line +
                                                            ", Char: " + gotoNode.AASTLink.Token.Position.Char + ").");
                    }
                    bool found = false;
                    foreach (CodeNode child in gotoLabelNode.Children)
                    {
                        if (child.Name.Equals("Statement") && child.Children.First.Value.Name.Equals("Goto label") &&
                            child.Children.First.Value.AASTLink.Children[0].Token.Value.Equals(labelName))
                        {
                            gotoLabelNode = child.Children.First.Value;
                            found         = true;
                            break;
                        }
                    }
                    if (found)
                    {
                        break;
                    }
                    gotoLabelNode = gotoLabelNode.Parent;
                }

                CodeNode labelDecl = new CodeNode("Label declaration", gotoNode).Add(new byte[8]);
                labelDecl.ByteToReturn = 27;
                gotoNode.Children.AddLast(labelDecl);
                gotoNode.Children.AddLast(new CodeNode("goto jump", gotoNode).Add(GenerateCBR(27, 27)));

                CodeNode labelNode = new CodeNode("Label", gotoLabelNode);
                labelNode.LabelDecl = labelDecl;
                gotoLabelNode.Children.AddLast(labelNode);
                gotoLabelNode.Children.AddLast(GetRegisterAllocationNode((AASTNode)gotoLabelNode.AASTLink.Parent, gotoLabelNode));
            }
            #endregion

            #region Label resolution

            /*List<CodeNode> labels = new List<CodeNode>();
             * FindAllCodeNodesWithName(programNode, "Label", labels);
             * foreach (CodeNode label in labels)
             * {
             *  int labelAddr = GetCurrentBinarySize(label); // Always the first child
             *  label.LabelDecl.Bytes.Clear();
             *  label.LabelDecl.Add(GenerateLDL(label.LabelDecl.ByteToReturn, labelAddr));
             * }*/
            ResolveLabels(programNode);
            #endregion

            // Move code data by the static data length
            codeAddrBase += staticSize;
            int codeLength = (unitsNode.Count() + codeNode.Count() + codeNode.Count() % 2) / 2 + 2;

            // Convert static data and code lengths to chunks of four bytes
            vptNode.Add(0x00, 0x01);
            vptNode.Add(GetConstBytes(staticDataAddrBase))
            .Add(GetConstBytes(staticLength))
            .Add(GetConstBytes(codeAddrBase))
            .Add(GetConstBytes(codeLength));

            skipStopNode.Add(GenerateSKIP()).Add(GenerateSTOP());

            return(programNode);
        }