private static void ParseFile(string projectPath, string path, string file, string nspace, string outputPath, string outFile, bool supportsGC, ICodeGen codeGen, string fileNameSuffix) { string languagePath = Path.Combine(projectPath, path); Directory.SetCurrentDirectory(languagePath); Queue <Token> tokenList = LanguageParser.TokenizeString(File.ReadAllText(Path.Combine(languagePath, file))); Node root = TokenAnalyzer.Analyze(tokenList); Node rootEnumNode = new Node(); Node rootMessageNode = new Node(); // this is now heavily c# based code // anyone looking to modify JavaGen or crate a different generator has their work cut out for them rootEnumNode.childNodes.AddRange(root.childNodes.Where(n => n is EnumNode)); rootMessageNode.childNodes.AddRange(root.childNodes.Where(n => n is ClassNode)); StringBuilder enumBuilder = new StringBuilder(); StringBuilder messageBuilder = new StringBuilder(); CodeGenerator.EmitCode(rootEnumNode, codeGen, enumBuilder, nspace, supportsGC, false); CodeGenerator.EmitCode(rootMessageNode, codeGen, messageBuilder, nspace + ".Internal", supportsGC, true); string outputEnumFile = Path.Combine(outputPath, outFile + "." + fileNameSuffix); string outputMessageFile = Path.Combine(outputPath, outFile + "Internal." + fileNameSuffix); string enumFilePath = Path.Combine(projectPath, outputEnumFile); Directory.CreateDirectory(Path.GetDirectoryName(enumFilePath)); File.WriteAllText(enumFilePath, enumBuilder.ToString()); string messageFilePath = Path.Combine(projectPath, outputMessageFile); Directory.CreateDirectory(Path.GetDirectoryName(messageFilePath)); File.WriteAllText(messageFilePath, messageBuilder.ToString()); }
public static Node Analyze(Queue <Token> tokens) { Node root = new Node(); while (tokens.Count > 0) { Token cur = tokens.Dequeue(); switch (cur.Name) { case "EOF": break; case "preprocess": Token text = Expect(tokens, "string"); if (cur.Value == "import") { Queue <Token> parentTokens = LanguageParser.TokenizeString(File.ReadAllText(text.Value), text.Value); Node newRoot = Analyze(parentTokens); foreach (Node child in newRoot.childNodes) { root.childNodes.Add(child); } } break; case "identifier": switch (cur.Value) { case "class": { Token name = Expect(tokens, "identifier"); Token ident = null, parent = null; Token op1 = Optional(tokens, "operator", "<"); if (op1 != null) { ident = Expect(tokens, "identifier"); Token op2 = Expect(tokens, "operator", ">"); } Token expect = Optional(tokens, "identifier", "expects"); if (expect != null) { parent = Expect(tokens, "identifier"); } Token removed = Optional(tokens, "identifier", "removed"); ClassNode cnode = new ClassNode(); cnode.Name = name.Value; if (ident != null) { cnode.Ident = SymbolLocator.LookupSymbol(root, ident.Value, false); } if (parent != null) { //cnode.Parent = SymbolLocator.LookupSymbol(root, parent.Value, true); } if (removed != null) { cnode.Emit = false; } else { cnode.Emit = true; } root.childNodes.Add(cnode); ParseInnerScope(tokens, cnode, root); } break; case "enum": { Token name = Expect(tokens, "identifier"); Token datatype = null; Token op1 = Optional(tokens, "operator", "<"); if (op1 != null) { datatype = Expect(tokens, "identifier"); Token op2 = Expect(tokens, "operator", ">"); } Token flag = Optional(tokens, "identifier", "flags"); EnumNode enode = new EnumNode(); enode.Name = name.Value; if (flag != null) { enode.Flags = flag.Value; } if (datatype != null) { enode.Type = SymbolLocator.LookupSymbol(root, datatype.Value, false); } root.childNodes.Add(enode); ParseInnerScope(tokens, enode, root); } break; } break; } } return(root); }