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 }
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(); }