Пример #1
0
        private string EmitOutputBase(DisplayVerb display, WriteStatement writeStatement)
        {
            string          r         = "";
            string          className = "__CobolProgram";
            DataDescription dde       = null;

            //Build the format string and param types list...
            string fmt     = "";
            int    objects = 0;

            ArrayList sources;

            if (display != null)
            {
                sources = display.Sources;
            }
            else
            {
                dde = GetDDEByName(writeStatement.RecordName.Name);
                if (dde == null)
                {
                    Console.WriteLine("dde is NULL");
                }

                r += "        " + ILAddress(1) + "ldarg.0\n";
                r += "        " + ILAddress(5);
                r += "ldfld class [mscorlib]System.IO.StreamWriter " + className + "::_writer_" + ILIdentifier(dde.FSDE.Name.Name) + "\n";

                sources = new ArrayList();
                if (writeStatement.RecordName != null)
                {
                    sources.Add(writeStatement.RecordName);
                }
                //TODO: What should be done when there are no FROM identifiers?
            }

            for (int i = 0; i < sources.Count; i++)
            {
                Source source = sources[i] as Source;
                if (IsGroup(source))
                {
                    Identifier             id   = source as Identifier;
                    List <DataDescription> ddes = ListElements(id.Definition);
                    foreach (DataDescription dd in ddes)
                    {
                        fmt += "{" + objects + ",-" + dd.Size + "}";
                        objects++;
                    }
                }
                else
                {
                    //TODO:
                    //If the source specifies a substring, then that size should be used in the
                    //brackets rather than the definition's size. Simply using the definition's
                    //size breaks the 99 bottles output because the buffer variable is large
                    //and we only want one character from it.
                    //See testdisp.cbl and its output.

                    if (source.GetType() == typeof(Identifier))
                    {
                        Identifier id = source as Identifier;
                        if (id.UsesSubstring)
                        {
                            Console.WriteLine("UsesSubstring = true : " + id.Name);
                            fmt += "{" + objects + "}";
                        }
                        else
                        {
                            //Console.WriteLine("UsesSubstring = false : "+id.Name);
                            fmt += "{" + objects + ",-" + id.Definition.Size + "}";
                        }
                    }
                    else
                    {
                        fmt += "{" + objects + "}";
                    }
                    objects++;
                }
            }

            //Load the format string...
            r += "        " + ILAddress(5);
            r += "ldstr \"" + fmt + "\"\n";

            //Create an array
            r += "        " + ILAddress(5);
            r += "ldc.i4 " + objects + "\n";
            r += "        " + ILAddress(5);
            r += "newarr [mscorlib]System.Object\n";

            //Load the values...
            int obj = 0;

            foreach (Source source in sources)
            {
                if (IsGroup(source))
                {
                    Identifier id = source as Identifier;
                    //Plan:
                    // 1. Load a format string based on all of the group element sizes (and types?)
                    // 2. Load each element
                    // 3. String.Format
                    // 4. Build an object array of the elements
                    // 5. Use the format string and array in WriteLine
                    List <DataDescription> ddes = ListElements(id.Definition);

                    foreach (DataDescription dd in ddes)
                    {
                        Identifier tmp = new Identifier();
                        tmp.Name       = dd.Name;
                        tmp.Definition = dd;
                        r += "        " + ILAddress(1) + "dup\n";
                        r += "        " + ILAddress(5) + "ldc.i4 " + obj + "\n";
                        r += EmitLoadSource(tmp as Source, false, true);
                        r += "        " + ILAddress(1) + "stelem.ref\n";
                        obj++;
                    }
                }
                else
                {
                    r += "        " + ILAddress(1) + "dup\n";
                    r += "        " + ILAddress(5) + "ldc.i4 " + obj + "\n";
                    r += EmitLoadSource(source, false, true);
                    r += "        " + ILAddress(1) + "stelem.ref\n";
                    obj++;
                }
            }

            if (display != null)
            {
                //Call Write or WriteLine...
                r += "        " + ILAddress(5);
                string parms = "string, object[]";
                if (display.NoAdvancing)
                {
                    r += "call void class [mscorlib]System.Console::Write(" + parms + ")";
                }
                else
                {
                    r += "call void class [mscorlib]System.Console::WriteLine(" + parms + ")";
                }
                r += "\n";
            }
            else
            {
                //Write...
                r += "        " + ILAddress(5);
                r += "callvirt instance void class [mscorlib]System.IO.StreamWriter::WriteLine(string,object[])\n";

                //Flush...
                r += "        " + ILAddress(1) + "ldarg.0\n";
                r += "        " + ILAddress(5);
                r += "ldfld class [mscorlib]System.IO.StreamWriter " + className + "::_writer_" + ILIdentifier(dde.FSDE.Name.Name) + "\n";
                r += "        " + ILAddress(5);
                r += "callvirt instance void class [mscorlib]System.IO.StreamWriter::Flush()\n";
            }
            return(r);
        }
Пример #2
0
 private string EmitDisplayVerb(DisplayVerb display)
 {
     return(EmitOutputBase(display, null));
 }