RAPTOR Code Generation

The RAPTOR Generate menu is extensible.  To add a generator, create a C# class that implements the interface generate_interface.typ (from interpreter.dll).  Place a DLL containing this type in the same folder as raptor.exe.  RAPTOR will automatically detect this and install it in the menu using the name given by the method Get_Menu_Name (ampersand indicates which character is underlined as a keyboard shortcut).

Here is an example code generator (for C#):

using System;

using System.Collections;

using System.Collections.Generic;

using System.Text;

using System.IO;

 

namespace GeneratorSample

{

    public class CsharpGenerator : generate_interface.typ

    {

        private string main_name;

        private string current_method;

        private int indent_level = 0;

        private StreamWriter stream;

        private System.Collections.Hashtable variables = new System.Collections.Hashtable();

        private System.Collections.Hashtable strings = new System.Collections.Hashtable();

        private System.Collections.Hashtable arrays = new System.Collections.Hashtable();

        private System.Collections.Hashtable arrays_2d = new System.Collections.Hashtable();

        private string file_name;

        public CsharpGenerator()

        {

        }

        public CsharpGenerator(string filename)

        {

            main_name = Path.GetFileNameWithoutExtension(filename);

            file_name = System.IO.Path.Combine(

                System.IO.Path.GetDirectoryName(filename),

                main_name + ".cs");

            stream = File.CreateText(file_name);

            stream.WriteLine("using System;");

            stream.WriteLine("using System.IO;");

            stream.WriteLine("using System.Text;");

            stream.WriteLine();

            stream.WriteLine("namespace " + main_name);

            stream.WriteLine("{");

            indent_level = 3;

            Indent();

            stream.WriteLine("public class main_class");

            Indent();

            stream.WriteLine("{");

            indent_level += 3;

            Indent();

            stream.WriteLine("static System.Random random_generator = new System.Random();");

        }

        #region generate_interface.typ Members

 

        public bool Is_Postfix()

        {

            return false;

        }

 

        public string Get_Menu_Name()

        {

            return "C&#";

        }

        private System.Collections.Generic.Dictionary<string, MethodInformation>

            Procedures = new Dictionary<string, MethodInformation>();

        private class MethodInformation

        {

            public bool[] args_are_input;

            public bool[] args_are_output;

            public string[] arg_names;

            public MethodInformation(string[] args, bool[] arg_is_input, bool[] arg_is_output)

            {

                arg_names = args;

                args_are_input = arg_is_input;

                args_are_output = arg_is_output;

            }

        }

        public void Declare_Procedure(string name, string[] args, bool[] arg_is_input, bool[] arg_is_output)

        {

            Procedures.Add(name, new MethodInformation(args, arg_is_input, arg_is_output));

        }

        private void Indent()

        {

            for (int i = 0; i < indent_level; i++)

            {

                stream.Write(" ");

            }

        }

        public void Start_Method(string name)

        {

            if (name != "Main")

            {

                Indent();

                stream.Write("public static void " + name);

                if (Procedures[name].arg_names != null &&

                    Procedures[name].arg_names.Length > 0)

                {

                    stream.WriteLine(" (");

                }

                indent_level += 3;

            }

            else

            {

                Indent();

                stream.WriteLine("public static void Main(string[] args)");

                Indent();

                stream.WriteLine("{");

                indent_level += 3;

            }

            variables.Clear();

            arrays.Clear();

            arrays_2d.Clear();

            strings.Clear();

            current_method = name;

        }

 

        public void Declare_As_2D_Array(string name)

        {

            arrays_2d.Add(name.ToLower(), null);

        }

 

        public void Declare_As_1D_Array(string name)

        {

            arrays.Add(name.ToLower(), null);

        }

 

        public void Declare_As_Variable(string name)

        {

            variables.Add(name.ToLower(), null);

        }

 

        public void Declare_String_Variable(string name)

        {

            strings.Add(name.ToLower(), null);

        }

        public void WriteParameters()

        {

            MethodInformation mi = Procedures[current_method];

            if (mi.arg_names != null && mi.arg_names.Length > 0)

            {

                indent_level += 3;

                for (int i = 0; i < mi.arg_names.Length; i++)

                {

                    Indent();

                    if (mi.args_are_output[i])

                    {

                        stream.Write("ref ");

                    }

                    if (variables.Contains(mi.arg_names[i].ToLower()))

                    {

                        stream.Write(" ??_Variable");

                        variables.Remove(mi.arg_names[i]);

                    }

                    else if (arrays.Contains(current_method.ToLower()))

                    {

                        stream.Write(" ??_Array");

                        arrays.Remove(mi.arg_names[i]);

                    }

                    else if (arrays_2d.Contains(current_method.ToLower()))

                    {

                        stream.Write(" ??_Array_2D");

                        arrays_2d.Remove(mi.arg_names[i]);

                    }

                    else

                    {

                        stream.Write(" ??");

                    }

                    stream.Write(" " + mi.arg_names[i]);

 

                    if (i < mi.arg_names.Length - 1)

                    {

                        stream.WriteLine(";");

                    }

                    else

                    {

                        stream.WriteLine(")");

                    }

                }

                indent_level -= 3;

 

                indent_level -= 3;

                Indent();

                stream.WriteLine("{");

                indent_level += 3;

            }

            else

            {

                stream.WriteLine(" {");

            }

        }

        public void WriteVariables()

        {

            IDictionaryEnumerator e = strings.GetEnumerator();

            e.Reset();

            while (e.MoveNext())

            {

                Indent();

                stream.WriteLine("string " + ((string)e.Key) + ";");

            }

            e = variables.GetEnumerator();

            e.Reset();

            while (e.MoveNext())

            {

                Indent();

                stream.WriteLine("?? " + ((string)e.Key) + ";");

            }

            e = arrays.GetEnumerator();

            e.Reset();

            while (e.MoveNext())

            {

                Indent();

                stream.WriteLine("??[] " + ((string)e.Key) + " = new ??[??+1];");

            }

            e = arrays_2d.GetEnumerator();

            e.Reset();

            while (e.MoveNext())

            {

                Indent();

                stream.WriteLine("??[,] " + ((string)e.Key) + " = new ??[??+1,??+1];");

            }

        }

        public void Done_Variable_Declarations()

        {

            if (current_method != "Main")

            {

                WriteParameters();

            }

            WriteVariables();

            indent_level -= 3;

            Indent();

            stream.WriteLine("");

            indent_level += 3;

        }

 

        public void Emit_Left_Paren()

        {

            stream.Write("(");

        }

 

        public void Emit_Right_Paren()

        {

            stream.Write(")");

        }

 

        private class subprogram

        {

            public bool is_function;

            public subprogram(int o)

            {

                if (lexer_pkg.is_procedure(o))

                {

                    is_function = false;

                }

                else

                {

                    is_function = true;

                }

            }

            public subprogram()

            {

                is_function = false;

            }

        }

        public object Emit_Call_Method(int name)

        {

            if (lexer_pkg.is_procedure(name))

            {

                Indent();

            }

            stream.Write(lexer_pkg.get_image(name));

            if (lexer_pkg.has_parameters(name))

            {

                stream.Write("(");

            }

            return new subprogram(name);

        }

 

        public object Emit_Call_Subchart(string name)

        {

            Indent();

            stream.Write(name);

            if (Procedures[name].arg_names != null &&

                Procedures[name].arg_names.Length > 0)

            {

                stream.Write("(");

            }

            return new subprogram();

        }

 

        public void Emit_Next_Parameter(object o)

        {

            stream.Write(",");

        }

 

        public void Emit_Last_Parameter(object o)

        {

            // somehow check if o is a function here

            if (!(o as subprogram).is_function)

            {

                stream.WriteLine(");");

            }

            else

            {

                stream.Write(")");

            }

        }

 

        public void Emit_No_Parameters(object o)

        {

            // somehow check if o is a function here

            if (!(o as subprogram).is_function)

            {

                stream.WriteLine(";");

            }

        }

       

        public void Emit_Is_Array2D(string name)

        {

            if (arrays_2d.Contains(name.ToLower()))

            {

                stream.Write("true");

            }

            else

            {

                stream.Write("false");

            }

        }

 

        public void Emit_Is_Array(string name)

        {

            if (arrays.Contains(name.ToLower()))

            {

                stream.Write("true");

            }

            else

            {

                stream.Write("false");

            }

        }

 

        public void Emit_Is_String(string name)

        {

            stream.Write("Is_String(" + name + ")");

        }

 

        public void Emit_Is_Number(string name)

        {

            stream.Write("Is_String(" + name + ")");

        }

 

        public void Emit_Or_Shortcut(parse_tree.boolean2 left, parse_tree.boolean_expression right)

        {

            left.emit_code(this, 0);

            stream.Write(" || ");

            right.emit_code(this, 0);

        }

 

        public void Emit_And_Shortcut(parse_tree.boolean_parseable left,

            parse_tree.boolean2 right, bool left_negated)

        {

            if (left_negated)

            {

                Emit_Not();

            }

            left.emit_code(this, 0);

            stream.Write(" && ");

            right.emit_code(this, 0);

        }

 

        public void Emit_Random()

        {

            stream.Write("random_generator.NextDouble()");

        }

 

        public void Emit_Random_2(double first, double last)

        {

            stream.Write("To_Color(random_generator.NextDouble()*" + (last-first) + "+" +first + ")");

        }

 

        public void Emit_Times()

        {

            stream.Write("*");

        }

 

        public void Emit_Divide()

        {

            stream.Write("/");

        }

 

        public void Emit_Plus()

        {

            stream.Write("+");

        }

 

        public void Emit_Unary_Minus()

        {

            stream.Write("-");

        }

 

        public void Emit_Minus()

        {

            stream.Write("-");

        }

 

        public void Emit_Mod()

        {

            stream.Write(" % ");

        }

 

        public void Emit_Rem()

        {

            stream.Write(" % ");

        }

 

        public void Emit_Exponentiation()

        {

            stream.Write(" ** ");

        }

 

        public void Emit_Get_Mouse_Button()

        {

            stream.WriteLine(");");

        }

 

        public void Emit_Get_Click(int x_or_y)

        {

            if (x_or_y == 0)

            {

                stream.Write("Get_Click_X");

            }

            else

            {

                stream.Write("Get_Click_Y");

            }

        }

 

        public void Emit_Array_Size(string name)

        {

            stream.Write(name + "'Length");

        }

 

        public void Emit_String_Length()

        {

            stream.Write("'Length");

        }

 

        public void Emit_Load(string name)

        {

            stream.Write(name);

        }

 

        public void Emit_Load_Array_Start(string name)

        {

            stream.Write(name + "(");

        }

        public void Emit_Load_Array_After_Index(string name)

        {

            stream.Write(")");

        }

 

        public void Emit_Load_Array_2D_Start(string name)

        {

            stream.Write(name + "(");

        }

        public void Emit_Load_Array_2D_Between_Indices()

        {

            stream.Write(",");

        }

        public void Emit_Load_Array_2D_After_Indices(string name)

        {

            stream.Write(")");

        }

 

        public void Emit_Relation(int relation)

        {

            switch (relation)

            {

                case 1: //gt

                    stream.Write(">");

                    break;

                case 2: //ge

                    stream.Write(">=");

                    break;

                case 3: //lt

                    stream.Write("<");

                    break;

                case 4: //le

                    stream.Write("<=");

                    break;

                case 5: //eq

                    stream.Write("==");

                    break;

                case 6: //ne

                    stream.Write("!=");

                    break;

            }

        }

 

        public void Emit_Sleep()

        {

            Indent();

            stream.Write("System.Threading.Thread.Sleep(");