Beispiel #1
0
 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));
 }
Beispiel #2
0
        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]);
        }
Beispiel #3
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);
        }
Beispiel #4
0
        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.");
        }
Beispiel #5
0
        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);
                }
            }
        }
Beispiel #6
0
 private static string GetCoreFunctionSignatureManifest()
 {
     return(PastelUtil.ReadAssemblyFileText(typeof(CoreFunctionUtil).Assembly, "CoreFunctionSignatures.txt"));
 }