public static string ReadAssemblyFileText(System.Reflection.Assembly assembly, string path, bool failSilently) { byte[] bytes = PastelUtil.ReadAssemblyFileBytes(assembly, path, failSilently); if (bytes == null) { return(null); } return(MysteryTextDecoder.DecodeArbitraryBytesAsAppropriatelyAsPossible(bytes)); }
private ICompilationEntity[] ParseTopLevelInlineImport(Token atToken, TokenStream tokens) { string sourceFile = null; string functionName = tokens.PeekValue(); switch (functionName) { case "import": tokens.PopExpected("import"); tokens.PopExpected("("); Token stringToken = tokens.Pop(); tokens.PopExpected(")"); tokens.PopExpected(";"); sourceFile = PastelUtil.ConvertStringTokenToValue(stringToken.Value); break; case "importIfTrue": case "importIfFalse": tokens.Pop(); tokens.PopExpected("("); Token constantExpression = tokens.Pop(); string constantValue = PastelUtil.ConvertStringTokenToValue(constantExpression.Value); tokens.PopExpected(","); Token pathToken = tokens.Pop(); tokens.PopExpected(")"); tokens.PopExpected(";"); object value = this.GetConstant(constantValue, false); if (!(value is bool)) { value = false; } bool valueBool = (bool)value; if (functionName == "importIfFalse") { valueBool = !valueBool; } if (valueBool) { sourceFile = PastelUtil.ConvertStringTokenToValue(pathToken.Value); } break; default: // intentional crash... tokens.PopExpected("import"); break; } if (sourceFile != null) { string code = this.importCodeLoader.LoadCode(atToken, sourceFile); return(this.ParseText(sourceFile, code)); } return(new ICompilationEntity[0]); }
private Dictionary <string, string> GetCodeChunks(AbstractTranspiler transpiler, string userCode) { string resourcePath = transpiler.HelperCodeResourcePath; Dictionary <string, string> output = new Dictionary <string, string>(); if (resourcePath == null) { return(output); } string helperCode = PastelUtil.ReadAssemblyFileText(typeof(AbstractTranspiler).Assembly, resourcePath); string currentId = null; List <string> currentChunk = new List <string>(); foreach (string lineRaw in helperCode.Split('\n')) { string line = lineRaw.TrimEnd(); if (line.Contains("PASTEL_ENTITY_ID")) { if (currentId != null) { output[currentId] = string.Join("\n", currentChunk).Trim(); } currentId = line.Split(':')[1].Trim(); currentChunk.Clear(); } else { currentChunk.Add(lineRaw); } } if (currentId != null) { output[currentId] = string.Join("\n", currentChunk).Trim(); } output[""] = userCode; return(output); }
private Expression ParseEntityRoot(TokenStream tokens) { string next = tokens.PeekValue(); switch (next) { case "true": case "false": return(new InlineConstant(PType.BOOL, tokens.Pop(), next == "true", this.currentCodeOwner)); case "null": return(new InlineConstant(PType.NULL, tokens.Pop(), null, this.currentCodeOwner)); case ".": Token dotToken = tokens.Pop(); Token numToken = tokens.Pop(); EnsureInteger(tokens.Pop(), false, false); string strValue = "0." + numToken.Value; double dblValue; if (!numToken.HasWhitespacePrefix && double.TryParse(strValue, out dblValue)) { return(new InlineConstant(PType.DOUBLE, dotToken, dblValue, this.currentCodeOwner)); } throw new ParserException(dotToken, "Unexpected '.'"); default: break; } char firstChar = next[0]; switch (firstChar) { case '\'': return(new InlineConstant(PType.CHAR, tokens.Pop(), PastelUtil.ConvertStringTokenToValue(next), this.currentCodeOwner)); case '"': return(new InlineConstant(PType.STRING, tokens.Pop(), PastelUtil.ConvertStringTokenToValue(next), this.currentCodeOwner)); case '@': Token atToken = tokens.PopExpected("@"); Token compileTimeFunction = EnsureTokenIsValidName(tokens.Pop(), "Expected compile time function name."); if (!tokens.IsNext("(")) { tokens.PopExpected("("); } return(new CompileTimeFunctionReference(atToken, compileTimeFunction, this.currentCodeOwner)); } if (firstChar >= '0' && firstChar <= '9') { Token numToken = tokens.Pop(); if (tokens.IsNext(".")) { EnsureInteger(numToken, false, false); Token dotToken = tokens.Pop(); if (dotToken.HasWhitespacePrefix) { throw new ParserException(dotToken, "Unexpected '.'"); } Token decimalToken = tokens.Pop(); EnsureInteger(decimalToken, false, false); if (decimalToken.HasWhitespacePrefix) { throw new ParserException(decimalToken, "Unexpected '" + decimalToken.Value + "'"); } double dblValue; if (double.TryParse(numToken.Value + "." + decimalToken.Value, out dblValue)) { return(new InlineConstant(PType.DOUBLE, numToken, dblValue, this.currentCodeOwner)); } throw new ParserException(decimalToken, "Unexpected token."); } else { int numValue = EnsureInteger(numToken, true, true); return(new InlineConstant(PType.INT, numToken, numValue, this.currentCodeOwner)); } } if (tokens.IsNext("this")) { return(new ThisExpression(tokens.Pop(), this.currentCodeOwner)); } if (IsValidName(tokens.PeekValue())) { return(new Variable(tokens.Pop(), this.currentCodeOwner)); } throw new ParserException(tokens.Peek(), "Unrecognized expression."); }
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 string GetCoreFunctionSignatureManifest() { return(PastelUtil.ReadAssemblyFileText(typeof(CoreFunctionUtil).Assembly, "CoreFunctionSignatures.txt")); }