public override String AttrPrint()
        {
            String retVal;

            retVal = String.Format("\nType: {0} Named {1}", Utilities.TypeDescToString(this.attrRef), this.attrRef.typeInfo.Name);
            // Modifiers
            retVal += "\nModifiers: ";
            MethodDclTypeDescp mtd = this.attrRef.typeInfo;

            for (int i = mtd.Modifiers.Count - 1; i >= 0; i--)
            {
                retVal += mtd.Modifiers[i] + " ";
            }
            // Return
            retVal += String.Format("\nReturn: {0}\n", mtd.returnType);

            // Class
            retVal += String.Format("Defined in class: {0}\n", mtd.isDefinedIn);

            // Params done in AST body
            if (mtd.paramList.Names.Count == 0)
            {
                retVal += "No parameters";
            }
            else
            {
                retVal += "See Tree below for parameter type info. Summarized here: \n";
                for (int i = 0; i < mtd.paramList.Names.Count; i++)
                {
                    retVal += mtd.paramList.Types[i] + " named " + mtd.paramList.Names[i] + " ";
                }
            }

            return(retVal);
        }
        public SymbolTable()
        {
            symTableIdx = 0;
            symTables.Add(new SymTable_Type());

            // Add some basic things to the symbol table
            Attributes a;

            // Integer
            IntegerTypeDescriptor ITD = new IntegerTypeDescriptor();

            a          = new Attributes("Type");
            a.typeInfo = ITD;
            symTables[0].Add("int32", a);

            // Java types
            JaveTypeTypeDescriptor JTD = new JaveTypeTypeDescriptor();

            a          = new Attributes("Some Java Thing");
            a.typeInfo = JTD;
            symTables[0].Add("java.io.PrintStream", a);

            // Some methods

            string[] knownMethods = { "Write",
                                      "WriteLine",
                                      "ps.print", };
            foreach (string s in knownMethods)
            {
                a = new Attributes("MethodCall");
                MethodDclTypeDescp MTD = new MethodDclTypeDescp();
                a.typeInfo       = MTD;
                MTD.nameSpaceVar = "[mscorlib]System.Console";
                MTD.Name         = s;
                MTD.returnType   = "void";
                symTables[0].Add(s, a);
            }
        }
        protected void VisitNode(MethodDcl node)
        {
            // Get a type descriptor for this method dcl
            MethodDclTypeDescp m  = node.attrRef.typeInfo as MethodDclTypeDescp;
            StringBuilder      sb = new StringBuilder();

            Byte[] info;

            methodName = m.Name;

            // Build modifier list
            string modList = "";

            foreach (string modifier in m.Modifiers)
            {
                modList += modifier + " ";
            }
            modList = modList.ToLower();

            // Build parameter list
            string theFunctArgs   = "";
            int    numberOfParams = 0;
            // Correlates variable names with stack position
            Dictionary <string, int> localArgs = new Dictionary <string, int>();

            if (m.paramList != null)
            {
                int localArgIdx = 0;
                foreach (string name in m.paramList.Names)
                {
                    localArgs.Add(name, localArgIdx++);
                    string entry = m.paramList.Types[numberOfParams] + " " + name;
                    if (numberOfParams++ > 0)
                    {
                        entry += ",";
                    }
                    theFunctArgs += entry + "\n";
                }
            }
            localArgNumber.Add(methodName, localArgs);

            sb.AppendLine(String.Format(".method {0}{1} \n {2} ({3}) cil managed", modList, m.returnType.ToLower(), m.Name, theFunctArgs));
            info = new UTF8Encoding(true).GetBytes(sb.ToString());
            TCCLParser.currentFileStream.Write(info, 0, info.Length);

            InsertIntoFile("{\n");

            if (m.Name.Contains("main") || m.Name.Contains("Main"))
            {
                InsertIntoFile(".entrypoint\n");
            }
            InsertIntoFile(".maxstack 1000 // Should be using sethi ullman algorithm here!\n"); // for now

            // If field decls, do them here too
            Utilities.VisitSpecificChild(node, typeof(LocalVarDecls), this);

            // Visi LocalVarsDeclsAndStatments
            // See if we have any fields
            Utilities.VisitSpecificChild(node, typeof(LocalVarDeclsAndStmts), this);

            // Visit Method Calls


            // Etc?
            InsertIntoFile("ret\n");

            InsertIntoFile("}\n");
        }
        protected void VisitNode(MethodCall node)
        {
            // deal with arguments first
            // Arguments are in the arglist node's type descriptor.
            // If arguments were provided
            // We'll need one of these to understand what we're looking at
            MethodCallTypeDescriptor mtd = null;

            ArgListTypeDescriptor atd = null;
            ArgList proposedArgs      = null;

            // "If the arg list for this has errors" is what we're trying to get at with this block
            // If we aren't error type descriptor try to get the args root
            if (Utilities.attrToType(node.attrRef) != "ErrorTypeDescriptor")
            {
                proposedArgs = node.attrRef.typeInfo.argsRoot;

                // If arguments are invalid
                if (proposedArgs != null && proposedArgs.attrRef.typeInfo.GetType() == typeof(ErrorTypeDescriptor))
                {
                    Console.WriteLine("Error in code generator. ErrorTypeDescriptor encountered.");
                }
                // If arguments are valid


                mtd = node.attrRef.typeInfo;
                string paramResult = "";
                if (proposedArgs != null)
                {
                    atd = mtd.argsRoot.attrRef.typeInfo;
                }
                // Keep track of how many arguments we're loading onto the stack prior to a function call
                if (atd != null)
                {
                    foreach (var element in atd.Params)
                    {
                        if (Utilities.attrToType(element.attrRef).Contains("String"))
                        {
                            paramResult += "string";
                            // Overhead of pushing string to the stack
                            InsertIntoFile(String.Format("ldstr\t\t \"{0}\"\n", element.Name));
                        }
                        else if (Utilities.attrToType(element.attrRef).Contains("Integer"))
                        {
                            paramResult += "int32";

                            // If Identifier, use the number directly
                            if (element.NodeType.Name == "Identifier")
                            {
                                InsertIntoFile(String.Format("ldc.i4\t\t {0}\n", element.Name));
                            }

                            // If Qualified Name use variable name
                            else if (element.NodeType.Name == "QualifiedName")
                            {
                                int varNumber = 0;
                                // Either this is coming from function args (see here).
                                Dictionary <string, int> localArgs = new Dictionary <string, int>();
                                localArgNumber.TryGetValue(methodName, out localArgs);
                                if (localArgs.ContainsKey(element.Name))
                                {
                                    varNumber = GetArgPosit(element.Name);
                                    InsertIntoFile(String.Format("ldarg {0}\t\t //{1}\n", varNumber, element.Name));
                                }
                                else
                                {
                                    varNumber = GetStackPosit(element.Name);
                                    InsertIntoFile(String.Format("ldloc {0}\t\t //{1}\n", varNumber, element.Name));
                                }

                                // Or this is coming from function local vars (see here)
                            }

                            // If Expr, generate instructions to evaluate expr
                            else if (element.NodeType.Name == "Expr")
                            {
                                // Visit all expr nodes and have them generate the code. The other way to do this
                                // would be as defined in this comment block which I was told not to do in class
                                // (But works!)

                                /*
                                 * Expr e = element as Expr;
                                 * int expressionEval = e.eval();
                                 * InsertIntoFile(String.Format("ldc.i4\t\t {0}\n", expressionEval));
                                 */
                                element.Accept(this);
                            }
                        }

                        else
                        {
                            paramResult += "DEFAULT uh oh";
                        }
                    }
                }

                // call method
                String nameSpaceString = mtd.nameSpaceVar;
                InsertIntoFile(String.Format("call {0} {1} :: {2}({3})\n", mtd.returnType.ToLower(),
                                             mtd.nameSpaceVar, mtd.name, paramResult));
            }


#if false // Get a type descriptor for this method dcl
            MethodDclTypeDescp m  = node.attrRef.typeInfo as MethodDclTypeDescp;
            StringBuilder      sb = new StringBuilder();
            Byte[]             info;


            // Build modifier list
            string modList = "";
            foreach (string modifier in m.Modifiers)
            {
                modList += modifier + " ";
            }
            modList = modList.ToLower();

            // Build parameter list
            string theFunctArgs   = "";
            int    numberOfParams = 0;
            if (m.paramList != null)
            {
                foreach (string name in m.paramList.Names)
                {
                    string entry = name + " " + m.paramList.Types;
                    if (numberOfParams++ > 0)
                    {
                        entry += ",";
                    }
                    theFunctArgs += entry + "\n";
                }
            }
            sb.AppendLine(String.Format(".method {0}{1} \n {2} ({3}) cil managed", modList, m.returnType, m.Name, theFunctArgs));
            info = new UTF8Encoding(true).GetBytes(sb.ToString());
            TCCLParser.currentFileStream.Write(info, 0, info.Length);

            InsertIntoFile("{\n");

            if (m.Name.Contains("main") || m.Name.Contains("Main"))
            {
                InsertIntoFile(".entrypoint\n");
            }
            InsertIntoFile(".maxstack 1000\n"); // for now

            // If field decls, do them here too
            // Visit children
            Utilities.CodeGenVisitAllChildren(node, this);
#endif
        }
Beispiel #5
0
        public void VisitNode(MethodDcl node)
        {
            /* --------- Gather some info --------------*/
            // Get Name
            String name = GetMethodDclName(node);
            // Get Return TYpe
            String returnType = GetMethodDclRetType(node);
            // Get class name that owns this method
            String definedInClass = currentClassName;

            // Get modifiers
            // Create a list of all modifier children
            List <Modifier> modifierChildren = Utilities.GetChildren(node, typeof(Modifier)).Cast <Modifier>().ToList();
            // Process modifier children
            List <String> listOfModifiers = new List <String>();

            foreach (Modifier m in modifierChildren)
            {
                listOfModifiers.Add(m.Name);
            }

            // Get parameters
            List <string> types = new List <string>();
            List <string> names = new List <string>();

            GetMethodDclParams(node, ref types, ref names);

            // Create a type descriptor for the method
            MethodDclTypeDescp typeRef = new MethodDclTypeDescp();
            // Create a new attributes structure
            Attributes attr = new Attributes("method");

            /* ------------ Configure Attributes ----------------*/
            // Put the descriptor in the attributes structure
            attr.typeInfo = typeRef;

            /* --------- Configure Type Descriptor --------------*/
            // Put a new symbol table into Type Descriptor
            typeRef.MethodSymbolTable = new SymbolTable();
            // Put the name into Type Descriptor
            typeRef.Name = name;
            // Put the retury type into Type Descriptor
            typeRef.returnType = returnType;
            // Put the list of modifiers into Type Descriptor
            typeRef.Modifiers = listOfModifiers;
            // Put the owning class into Type Descriptor
            typeRef.isDefinedIn = definedInClass;
            // Put the list of param types into Type Descriptor
            typeRef.paramList.Types = types;
            // Put the list of param names into Type Descriptor
            typeRef.paramList.Names = names;
            // Namespace
            typeRef.nameSpaceVar = typeRef.isDefinedIn; //was confused between the two until this was the easier solution

            // Throw all of the arguments into the symbol table;
            currentSymbolTable.incrNestLevel();
            for (int i = 0; i < names.Count; i++)
            {
                // If type exists in symbol table
                Attributes aa = currentSymbolTable.lookup(types[i]);
                if (aa != null)
                {
                    currentSymbolTable.enter(names[i], aa);
                }
            }

            /* ------ Ready to record into symbol table ---------*/
            // Record ourselves into the symbol table
            currentSymbolTable.enter(name, attr);
            // Decorate AST with attrRef
            node.attrRef = attr;

            /* --------------- Visit All Fields -----------------*/
            // currentSymbolTable = typeRef.MethodSymbolTable;

            // Create a list of Block children (should only be one)
            List <Block> methodBodyChildren = Utilities.GetChildren(node, typeof(Block)).Cast <Block>().ToList();

            foreach (Block b in methodBodyChildren)
            {
                this.VisitNode(b);
            }
            // Put symbol table back when we're done
            currentSymbolTable.decrNestLevel();
        }