/// <summary> /// Creates a new CheckManual instance /// </summary> public CheckerManual() { lib = Vnvd.Library; }
private UserMethod DefineMethod(UserType type, String name, List <string> modifiers, String _return, String[] parTypes, String[] parNames) { bool overrid = modifiers.Remove("override"); if (overrid) { modifiers.Add("virtual"); } if (!type.IsAbstract && modifiers.Contains("abstract")) { throw new CheckerException("Cannot declare abstract method " + name + " in a non-abstract class: " + type.Name); } if (modifiers.Contains("abstract")) { modifiers.Add("virtual"); } MethodAttributes attr = MethodAttributes.HideBySig; foreach (String s in modifiers) { attr |= (MethodAttributes)Enum.Parse(typeof(MethodAttributes), s, true); } IdEntry[] pars = new IdEntry[parTypes.Length]; for (int i = 0; i < parTypes.Length; i++) { pars[i] = this.GetTypeIdEntry(parTypes[i]); } IdEntry ret = KeywordToType(_return) != null ? new IdEntry() { ReflectionObject = KeywordToType(_return) } : this.GetTypeIdEntry(_return); if (overrid) { MethodInfo m = type.BaseType.GetMethod(name, BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, LibraryChecker.ToArray <Type>(pars), null); if (m == null || m.ReturnType != ret.ReflectionObject) { throw new CheckerException("No suitable method found to override: " + name); } if (!m.IsVirtual) { throw new CheckerException("Cannot override a non-virtual method: " + m.Name); } } else { MethodInfo m = type.GetMethod(name, BindingFlags.FlattenHierarchy | BindingFlags.ExactBinding | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, LibraryChecker.ToArray <Type>(pars), null); if (m != null) { throw new CheckerException("Method already exists: " + m.Name); } if (type.GetInterfaceMethod(name, LibraryChecker.ToArray <Type>(pars)) != null) { attr |= MethodAttributes.NewSlot | MethodAttributes.Virtual; } } UserMethod metb = type.DefineMethod(name, attr, ret, pars, parNames); return(metb); }
/// <summary> /// The main function of Vnvd. This runs the compiler. /// </summary> /// <param name="args">The command line arguments given to Vnvd.</param> public static void Main(String[] args) { Console.Out.WriteLine("Vnvd Compiler v" + Assembly.GetExecutingAssembly().GetName().Version); Console.Out.WriteLine("======================"); Console.Out.WriteLine(); ParseOptions(args); try { lib = new LibraryChecker(refs.ToArray()); } catch (ArgumentException ex) { Console.WriteLine(ex.Message); Environment.Exit(1); } List <TreeNode> trees = new List <TreeNode>(); bool error = false; foreach (String filename in filenames) { VnvdLexer lexer = new VnvdLexer(new ANTLRFileStream(filename)); CommonTokenStream tokens = new CommonTokenStream(lexer); VnvdParser parser = new VnvdParser(tokens); parser.TreeAdaptor = new TreeNodeAdaptor(); VnvdParser.program_return result = parser.program(); TreeNode tree = (TreeNode)result.Tree; trees.Add(tree); if (parser.NumberOfSyntaxErrors > 0) { error = true; } } if (!error) { VnvdTreeWalker checker = null; if (!opt_nochecker) { // check the AST CheckerManual manual = new CheckerManual(); try { foreach (TreeNode tree in trees) { manual.WalkClasses(tree); } manual.WalkClassExtendation(); manual.WalkClassMembers(); for (int i = 0; i < trees.Count; i++) { TreeNode tree = trees[i]; ITreeNodeStream nodes = new CommonTreeNodeStream(tree); CheckerHelper helper = new CheckerHelper(); checker = new VnvdTreeWalker(helper, nodes); checker.Filename = filenames[i]; checker.TreeAdaptor = new TreeNodeAdaptor(); helper.Walker = checker; checker.program(); if (checker.SemanticErrorCount > 0 || checker.NumberOfSyntaxErrors > 0) { error = true; } } } catch (CheckerException ex) { Console.WriteLine(ex.ToString()); error = true; } } if (!error) { if (!opt_nogenerator) { AssemblyName aName = new AssemblyName(); aName.Name = Vnvd.OutputFile.Substring(0, Vnvd.OutputFile.LastIndexOf('.')); AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly( aName, AssemblyBuilderAccess.Save); // For a single-module assembly, the module name is usually // the assembly name plus an extension. mb = ab.DefineDynamicModule(aName.Name, Vnvd.OutputFile); GeneratorManual manualWalker = new GeneratorManual(mb, ab); foreach (TreeNode tree in trees) { manualWalker.WalkTypes(tree); } manualWalker.WalkTypeMembers(); foreach (TreeNode tree in trees) { ITreeNodeStream nodes = new CommonTreeNodeStream(tree); VnvdTreeWalker generator = new VnvdTreeWalker(new GeneratorHelper(), nodes); generator.program(); } foreach (TypeBuilder t in manualWalker.AllTypes) { t.CreateType(); } try { ab.Save(OutputFile); } catch (IOException) { Console.WriteLine("Error while saving the assembly. The output file is in use."); } } } if (opt_ast) { // print the AST as string StringBuilder sb = new StringBuilder(); foreach (TreeNode tree in trees) { String s = tree.ToStringTree(); int indent = 0; foreach (char c in s) { if (c == '(') { sb.Append('\n'); indent += 3; for (int i = 0; i < indent; i++) { sb.Append(' '); } } else if (c == ')') { indent -= 3; } sb.Append(c); } sb.AppendLine(); sb.AppendLine(); } //Console.WriteLine(sb.ToString()); Console.WriteLine("AST was written to ast.txt"); StreamWriter sw = new StreamWriter("ast.txt"); sw.Write(sb.ToString()); sw.Close(); } else if (opt_dot) { // print the AST as DOT specification DOTTreeGenerator gen = new DOTTreeGenerator(); Console.WriteLine("Graphviz AST graph (only first tree) was written to ast.dot"); StringTemplate st = gen.ToDOT(trees[0]); StreamWriter sw = new StreamWriter("ast.dot"); sw.Write(st.ToString()); sw.Close(); } } if (wait) { Console.Read(); } }