public PastelCompiler( Language language, IList <PastelCompiler> includedScopes, IDictionary <string, object> constants, IInlineImportCodeLoader inlineImportCodeLoader, ICollection <ExtensibleFunction> extensibleFunctions) { this.CodeLoader = inlineImportCodeLoader; this.Transpiler = LanguageUtil.GetTranspiler(language); this.IncludedScopes = includedScopes.ToArray(); this.ExtensibleFunctions = extensibleFunctions == null ? new Dictionary <string, ExtensibleFunction>() : extensibleFunctions.ToDictionary(ef => ef.Name); this.StructDefinitions = new Dictionary <string, StructDefinition>(); this.EnumDefinitions = new Dictionary <string, EnumDefinition>(); this.Globals = new Dictionary <string, VariableDeclaration>(); this.ConstantDefinitions = new Dictionary <string, VariableDeclaration>(); this.FunctionDefinitions = new Dictionary <string, FunctionDefinition>(); this.interpreterParser = new PastelParser(constants, inlineImportCodeLoader); }
public PastelContext(string dir, string languageId, IInlineImportCodeLoader codeLoader) : this(dir, LanguageUtil.ParseLanguage(languageId), codeLoader) { }
private static void ParseImpl(ProjectConfig config, string configContents, string originalPath) { string directory = System.IO.Path.GetFullPath(System.IO.Path.GetDirectoryName(originalPath)); string[] lines = configContents.Split('\n'); for (int i = 0; i < lines.Length; ++i) { string line = lines[i].Trim(); if (line.Length == 0 || line[0] == '#') { continue; } string[] parts = SplitOnColon(line); if (parts == null) { throw new InvalidOperationException("Invalid syntax on line " + (i + 1) + " of " + originalPath + ":\n" + line); } string type = parts[0]; string data = parts[1]; switch (type) { case "IMPORT": string importedConfig = CanonicalizeDirectory(directory, data); if (!System.IO.File.Exists(importedConfig)) { throw new InvalidOperationException("Config file does not exist: " + importedConfig); } string importedConfigContents = System.IO.File.ReadAllText(importedConfig); ParseImpl(config, importedConfigContents, importedConfig); break; case "LANGUAGE": config.Language = LanguageUtil.ParseLanguage(data); break; case "SOURCE": config.Source = CanonicalizeDirectory(directory, data); break; case "DEPENDENCY": parts = SplitOnColon(data); if (parts == null) { throw new InvalidOperationException("Dependency requires a namespace in " + originalPath + " on line " + (i + 1) + ":\n" + line); } string depNamespace = parts[0]; string path = CanonicalizeDirectory(directory, parts[1]); config.DependenciesByPrefix[depNamespace] = Parse(path); break; case "FLAG": parts = SplitOnColon(data); if (parts.Length != 2) { throw new InvalidOperationException("Invalid flag definition: " + line); } config.Flags[parts[0]] = PastelUtil.StringToBool(parts[1]); break; case "OUTPUT-STRUCTS": config.OutputDirStructs = CanonicalizeDirectory(directory, data); break; case "OUTPUT-FUNCTIONS": config.OutputFileFunctions = CanonicalizeDirectory(directory, data); break; // TODO: I have not found value in distinguishing these two aside from this is just how // I started things and have to maintain it. Merge the two namespaces and then change // these to just "NAMESPACE". case "NAMESPACE-FUNCTIONS": config.NamespaceForFunctions = data; break; case "NAMESPACE-STRUCTS": config.NamespaceForStructs = data; break; case "FUNCTION-WRAPPER-CLASS": config.WrappingClassNameForFunctions = data; break; case "EXT": parts = SplitOnColon(data); config.ExtensionPlatformValues[parts[0]] = parts[1]; config.ExtensionPlatformValuesDefinitionTokens[parts[0]] = new Token("", originalPath, i, 0, true); break; case "EXT-TYPE": config.ExtensionTypeDefinitions.Add(data); break; case "CODE-IMPORT": config.Imports.Add(data); break; case "INCLUDE-PUBLIC-PASTEL-UTIL": config.IncludePublicPastelUtil = PastelUtil.StringToBool(data); break; case "PHP-FILE-INCLUDE": case "PHP-FILE-INCLUDE-OPTIONAL": string phpFilePath = CanonicalizeDirectory(directory, data); config.PhpFileIncludes.Add(phpFilePath); config.PhpFileIncludeIsOptional.Add(phpFilePath); break; default: throw new InvalidOperationException("Unrecognized project config command '" + type + "' on line " + (i + 1) + " of " + originalPath + ":\n" + line); } } }
private static Dictionary <string, string> GenerateFiles(ProjectConfig config, PastelContext context) { Dictionary <string, string> output = new Dictionary <string, string>(); if (context.UsesClassDefinitions) { Dictionary <string, string> classDefinitions = context.GetCodeForClasses(); foreach (string className in classDefinitions.Keys.OrderBy(k => k)) { string classCode = classDefinitions[className]; if (context.ClassDefinitionsInSeparateFiles) { GenerateClassImplementation(config, className, classCode); } else { output["class_def:" + className] = classCode; } } if (!context.ClassDefinitionsInSeparateFiles) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (string key in output.Keys.Where(k => k.StartsWith("class_def:")).OrderBy(k => k)) { sb.Append(output[key]); sb.Append("\n\n"); } string code = sb.ToString().Trim(); if (code.Length > 0) { string classOutputDir = System.IO.Path.GetDirectoryName(config.OutputFileFunctions); string path = System.IO.Path.Combine(classOutputDir, "Classes" + LanguageUtil.GetFileExtension(config.Language)); System.IO.File.WriteAllText(path, code + "\n"); } } } if (context.UsesStructDefinitions) { Dictionary <string, string> structDefinitions = context.GetCodeForStructs(); string[] structOrder = structDefinitions.Keys.OrderBy(k => k.ToLower()).ToArray(); if (context.HasStructsInSeparateFiles) { foreach (string structName in structOrder) { GenerateStructImplementation(config, structName, structDefinitions[structName]); } } else { GenerateStructBundleImplementation(config, structOrder, structDefinitions); } if (context.UsesStructDeclarations) { Dictionary <string, string> structDeclarations = structOrder.ToDictionary(k => context.GetCodeForStructDeclaration(k)); foreach (string structName in structOrder) { output["struct_decl:" + structName] = structDeclarations[structName]; } } } if (context.UsesFunctionDeclarations) { string funcDeclarations = context.GetCodeForFunctionDeclarations(); throw new NotImplementedException(); } GenerateFunctionImplementation(config, context.GetCodeForFunctions()); return(output); }
private static void GenerateFunctionImplementation(ProjectConfig config, string funcCode) { Transpilers.AbstractTranspiler transpiler = LanguageUtil.GetTranspiler(config.Language); funcCode = transpiler.WrapCodeForFunctions(config, funcCode); System.IO.File.WriteAllText(config.OutputFileFunctions, funcCode); }
public PastelContext(Language language, IInlineImportCodeLoader codeLoader) { this.CodeLoader = codeLoader; this.Language = language; this.Transpiler = LanguageUtil.GetTranspiler(language); }