static void Main(string[] args)
        {
            int  n = 0, i;
            bool patchFlag;
            List <GPLCSource> progName = new List <GPLCSource>();
            List <GPLCSource> valueBlock = new List <GPLCSource>();
            List <GPLCSource> codeBlock = new List <GPLCSource>();
            List <Binding>    bs = new List <Binding>();
            List <string>     errorLog = new List <string>();
            string            progNameString;
            GenerateBytecode  programSet = new GenerateBytecode();
            string            source = File.ReadAllText(args[0]) + " ";
            string            structure = File.ReadAllText(args[1]) + " ";
            List <GPLCSource> blocks = GPLCParser.Parser(source);
            List <GPLCSource> structureBlocks = GPLCParser.Parser(structure);
            List <GPLCSource> body = new List <GPLCSource>();

            for (i = 0; i <= blocks.Count; i++)
            {
                if (n == 3 || i == blocks.Count)
                {
                    if (errorLog.Count > 0)
                    {
                        foreach (string error in errorLog)
                        {
                            Console.Write(error);
                        }
                        Console.Write("\n\nCompilation aborted at code block transformation stage.");
                        Console.ReadLine();
                        Environment.Exit(1);
                    }
                    Console.Write("\n\nCompiling program: ");
                    progNameString = subBlocksToString(progName);
                    Console.Write(progNameString);
                    bs = ValueBinder.BindValues(valueBlock, ValueBinder.DetermineOffset(codeBlock), errorLog);
                    GPLCProgramIn prog = new GPLCProgramIn(progNameString, codeBlock, bs);
                    programSet.TransformProgram(prog, errorLog);
                    if (i == blocks.Count)
                    {
                        break;
                    }
                    progName   = new List <GPLCSource>();
                    valueBlock = new List <GPLCSource>();
                    codeBlock  = new List <GPLCSource>();
                    n          = 0;
                    i--;
                }
                else if (blocks[i].content == "~")
                {
                    n++;
                }
                else if (n == 0)
                {
                    progName.Add(blocks[i]);
                }
                else if (n == 1)
                {
                    valueBlock.Add(blocks[i]);
                }
                else
                {
                    codeBlock.Add(blocks[i]);
                }
            }
            using (StreamWriter h = new StreamWriter(args[2]))
            {
                for (i = 0; i <= structureBlocks.Count; i++)
                {
                    if (i == structureBlocks.Count || structureBlocks[i].content == "~")
                    {
                        List <int> header = new List <int> {
                            Convert.ToInt32(body[0].content), Convert.ToInt32(body[1].content), Convert.ToInt32(body[2].content), Convert.ToInt32(body[3].content)
                        };
                        if (body[4].content == "0")
                        {
                            h.Write(body[0].content + ", " + body[1].content + ", " + body[2].content + ", " + body[3].content + ", " + body[4].content + ", ");
                        }
                        else
                        {
                            if (body[5].content == "n")
                            {
                                patchFlag = false;
                            }
                            else
                            {
                                patchFlag = true;
                            }
                            h.Write(programSet.GetProgramOut(patchFlag, header, body, Convert.ToInt32(body[4].content) - 1) + ", ");
                        }
                        header = new List <int>();
                        body   = new List <GPLCSource>();
                    }
                    else
                    {
                        body.Add(structureBlocks[i]);
                    }
                }
            }
            Console.ReadLine();
        }
        public void TransformProgram(GPLCProgramIn progIn, List <string> errorLog)
        {
            int        offset = 0, blockSize = 0, i, n;
            List <int> sigBlock  = new List <int>();
            List <int> codeBlock = new List <int>();
            List <int> result    = new List <int> {
                0, 0, 0
            };
            string errorDetail;
            bool   blockStart = true;

            for (i = 0; i < progIn.subBlocks.Count;)
            {
                if (blockStart == true && progIn.subBlocks[i].content != "--signal")
                {
                    errorDetail = "\n\nError at line " + Convert.ToString(progIn.subBlocks[i].line) + " column " + Convert.ToString(progIn.subBlocks[i].column) + ".  Every block of code must begin with --signal x, where x is the integer signal to be handled by the block.";
                    errorLog.Add(errorDetail);
                    break;
                }
                else if (blockStart == true)
                {
                    try
                    {
                        sigBlock.Add(Convert.ToInt32(progIn.subBlocks[i + 1].content));
                        sigBlock.Add(offset);
                        blockStart = false;
                        i          = i + 2;
                    }
                    catch (FormatException)
                    {
                        errorDetail = "\n\nError at line " + Convert.ToString(progIn.subBlocks[i + 1].line) + " column " + Convert.ToString(progIn.subBlocks[i + 1].column) + ".  The second term in a signal handler statement must be an integer.";
                        errorLog.Add(errorDetail);
                        break;
                    }
                }
                else
                {
                    if (progIn.subBlocks[i].content == "if")
                    {
                        List <int> mode = new List <int> {
                            2, 0, 0, 2, 2
                        };
                        List <int> thisLine = new List <int> {
                            1
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 6;
                        offset    = offset + 6;
                        blockSize = blockSize + 6;
                    }
                    else if (progIn.subBlocks[i].content == "chg_state")
                    {
                        List <int> mode = new List <int> {
                            0, 0, 0, 0, 0, 0, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            2
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 10;
                        offset    = offset + 10;
                        blockSize = blockSize + 10;
                    }
                    else if (progIn.subBlocks[i].content == "chg_grid")
                    {
                        List <int> mode = new List <int> {
                            0, 0, 0, 0, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            3
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 8;
                        offset    = offset + 8;
                        blockSize = blockSize + 8;
                    }
                    else if (progIn.subBlocks[i].content == "send_signal")
                    {
                        List <int> mode = new List <int> {
                            0, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            4
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 5;
                        offset    = offset + 5;
                        blockSize = blockSize + 5;
                    }
                    else if (progIn.subBlocks[i].content == "chg_value")
                    {
                        List <int> mode = new List <int> {
                            1, 0, 0, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            5
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 7;
                        offset    = offset + 7;
                        blockSize = blockSize + 7;
                    }
                    else if (progIn.subBlocks[i].content == "chg_value_")
                    {
                        List <int> mode = new List <int> {
                            2, 0, 0, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            5
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 7;
                        offset    = offset + 7;
                        blockSize = blockSize + 7;
                    }
                    else if (progIn.subBlocks[i].content == "chg_floor")
                    {
                        List <int> mode = new List <int> {
                            0, 0, 0, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            6
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 7;
                        offset    = offset + 7;
                        blockSize = blockSize + 7;
                    }
                    else if (progIn.subBlocks[i].content == "chg_ps1")
                    {
                        List <int> mode = new List <int> {
                            0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            7
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 4;
                        offset    = offset + 4;
                        blockSize = blockSize + 4;
                    }
                    else if (progIn.subBlocks[i].content == "chg_obj_type")
                    {
                        List <int> mode = new List <int> {
                            0, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            8
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 5;
                        offset    = offset + 5;
                        blockSize = blockSize + 5;
                    }
                    else if (progIn.subBlocks[i].content == "chg_grid_")
                    {
                        List <int> mode = new List <int> {
                            0, 0, 0, 0, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            10
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 8;
                        offset    = offset + 8;
                        blockSize = blockSize + 8;
                    }
                    else if (progIn.subBlocks[i].content == "copy_ps1")
                    {
                        List <int> mode = new List <int> {
                            1, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            11
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 5;
                        offset    = offset + 5;
                        blockSize = blockSize + 5;
                    }
                    else if (progIn.subBlocks[i].content == "copy_lstate")
                    {
                        List <int> mode = new List <int> {
                            1, 0, 0, 0, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            12
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 8;
                        offset    = offset + 8;
                        blockSize = blockSize + 8;
                    }
                    else if (progIn.subBlocks[i].content == "pass_msg")
                    {
                        List <int> mode = new List <int> {
                            0
                        };
                        List <int> thisLine = new List <int> {
                            13
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i + 1));
                        for (n = 3; n <= SafeArgumentHandler.ReadLiteral(progIn.subBlocks[i + 1], errorLog, 1); n++)
                        {
                            thisLine.Add(SafeArgumentHandler.ReadLiteral(progIn.subBlocks[i + n], errorLog, 1));
                        }
                        codeBlock.AddRange(thisLine);
                        i         = i + n;
                        offset    = offset + n - 1;
                        blockSize = blockSize + n - 1;
                    }
                    else if (progIn.subBlocks[i].content == "chg_ps0")
                    {
                        List <int> mode = new List <int> {
                            0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            14
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 4;
                        offset    = offset + 4;
                        blockSize = blockSize + 4;
                    }
                    else if (progIn.subBlocks[i].content == "copy_ps0")
                    {
                        List <int> mode = new List <int> {
                            1, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            15
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 5;
                        offset    = offset + 5;
                        blockSize = blockSize + 5;
                    }
                    else if (progIn.subBlocks[i].content == "binary_dice")
                    {
                        List <int> mode = new List <int> {
                            0, 0, 0, 0, 0, 2
                        };
                        List <int> thisLine = new List <int> {
                            16
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 7;
                        offset    = offset + 7;
                        blockSize = blockSize + 7;
                    }
                    else if (progIn.subBlocks[i].content == "project_init")
                    {
                        List <int> mode = new List <int> {
                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0
                        };
                        List <int> thisLine = new List <int> {
                            17
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 14;
                        offset    = offset + 14;
                        blockSize = blockSize + 14;
                    }
                    else if (progIn.subBlocks[i].content == "project_update")
                    {
                        List <int> mode = new List <int> {
                            0, 1, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            18
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 6;
                        offset    = offset + 6;
                        blockSize = blockSize + 6;
                    }
                    else if (progIn.subBlocks[i].content == "init_npc")
                    {
                        List <int> mode = new List <int> {
                            0, 0
                        };
                        List <int> thisLine = new List <int> {
                            19
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 3;
                        offset    = offset + 3;
                        blockSize = blockSize + 3;
                    }
                    else if (progIn.subBlocks[i].content == "npc_decision")
                    {
                        List <int> mode = new List <int> {
                            1
                        };
                        List <int> thisLine = new List <int> {
                            20
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 2;
                        offset    = offset + 2;
                        blockSize = blockSize + 2;
                    }
                    else if (progIn.subBlocks[i].content == "npc_move")
                    {
                        List <int> mode = new List <int> {
                            1
                        };
                        List <int> thisLine = new List <int> {
                            21
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 2;
                        offset    = offset + 2;
                        blockSize = blockSize + 2;
                    }
                    else if (progIn.subBlocks[i].content == "npc_damage")
                    {
                        List <int> mode = new List <int> {
                            2
                        };
                        List <int> thisLine = new List <int> {
                            22
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 2;
                        offset    = offset + 2;
                        blockSize = blockSize + 2;
                    }
                    else if (progIn.subBlocks[i].content == "cpede_move")
                    {
                        List <int> mode = new List <int> {
                            1, 2
                        };
                        List <int> thisLine = new List <int> {
                            23
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 3;
                        offset    = offset + 3;
                        blockSize = blockSize + 3;
                    }
                    else if (progIn.subBlocks[i].content == "block")
                    {
                        List <int> mode = new List <int> {
                            2, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            5, 536870910, 0
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 5;
                        offset    = offset + 7;
                        blockSize = blockSize + 7;
                    }
                    else if (progIn.subBlocks[i].content == "place_light")
                    {
                        List <int> mode = new List <int> {
                            0, 0, 0, 0, 0, 0
                        };
                        List <int> thisLine = new List <int> {
                            9
                        };
                        thisLine.AddRange(TransformArguments(progIn.subBlocks, progIn.bs, mode, errorLog, i));
                        codeBlock.AddRange(thisLine);
                        i         = i + 7;
                        offset    = offset + 7;
                        blockSize = blockSize + 7;
                    }
                    else if (progIn.subBlocks[i].content == "--signal")
                    {
                        sigBlock.Add(blockSize);
                        blockSize  = 0;
                        blockStart = true;
                    }
                    else
                    {
                        errorDetail = "\n\nError at line " + Convert.ToString(progIn.subBlocks[i].line) + " column " + Convert.ToString(progIn.subBlocks[i].column) + ".  " + progIn.subBlocks[i].content + " is an invalid GPLC op - code.";
                        errorLog.Add(errorDetail);
                        break;
                    }
                }
            }
            List <int> dataBlock = new List <int>(AddDataBlock(progIn.bs));

            sigBlock.Add(blockSize);
            result.AddRange(sigBlock); result.Add(536870911); result.AddRange(codeBlock); result.Add(536870911); result.AddRange(dataBlock);
            result[0] = result.Count - 1;
            GPLCProgramOut thisProg = new GPLCProgramOut(progIn.progName, result, progIn.bs);

            progGroup.Add(thisProg);
        }