Ejemplo n.º 1
0
 public FieldDefinition(PastelContext context, PType type, Token name, ClassDefinition classDef)
 {
     this.Context   = context;
     this.FieldType = type;
     this.NameToken = name;
     this.ClassDef  = classDef;
 }
Ejemplo n.º 2
0
 public ClassDefinition(PastelContext context, Token classToken, Token nameToken)
 {
     this.Context     = context;
     this.FirstToken  = classToken;
     this.NameToken   = nameToken;
     this.ParentClass = null;
 }
Ejemplo n.º 3
0
 public ConstructorDefinition(PastelContext context, Token constructorToken, IList <PType> argTypes, IList <Token> argNames, ClassDefinition classDef)
 {
     this.Context    = context;
     this.FirstToken = constructorToken;
     this.ArgTypes   = argTypes.ToArray();
     this.ArgNames   = argNames.ToArray();
     this.ClassDef   = classDef;
 }
Ejemplo n.º 4
0
 public VariableDeclaration(
     PType type,
     Token variableNameToken,
     Token equalsToken,
     Expression assignmentValue,
     PastelContext context) : base(type.FirstToken)
 {
     this.Context           = context;
     this.Type              = type;
     this.VariableNameToken = variableNameToken;
     this.EqualsToken       = equalsToken;
     this.Value             = assignmentValue;
 }
Ejemplo n.º 5
0
 public FunctionDefinition(
     Token nameToken,
     PType returnType,
     IList <PType> argTypes,
     IList <Token> argNames,
     PastelContext context,
     ClassDefinition nullableClassOwner) // null if not associated with a class
 {
     this.Context    = context;
     this.FirstToken = returnType.FirstToken;
     this.NameToken  = nameToken;
     this.ReturnType = returnType;
     this.ArgTypes   = argTypes.ToArray();
     this.ArgNames   = argNames.ToArray();
     this.ClassDef   = nullableClassOwner;
 }
Ejemplo n.º 6
0
        private PastelContext GenerateCoreVmParseTree(
            Platform.AbstractPlatform platform,
            IInlineImportCodeLoader codeLoader,
            Dictionary <string, object> constantFlags)
        {
            using (new PerformanceSection("VmGenerator.GenerateCoreVmParseTree"))
            {
                PastelContext context = new PastelContext(platform.Language, codeLoader);
                foreach (string key in constantFlags.Keys)
                {
                    context.SetConstant(key, constantFlags[key]);
                }
                foreach (string file in INTERPRETER_BASE_FILES)
                {
                    context.CompileFile(file);
                }
                context.FinalizeCompilation();

                return(context);
            }
        }
Ejemplo n.º 7
0
        private Platform.LibraryForExport CreateLibraryForExport(
            string libraryName,
            string libraryVersion,
            PastelContext nullableLibaryPastelContext,
            LibraryResourceDatabase libResDb)
        {
            using (new PerformanceSection("VmGenerator.CreateLibraryForExport"))
            {
                Multimap <string, Platform.ExportEntity> exportEntities = libResDb.ExportEntities;

                string[] dotNetLibs = libResDb.DotNetLibs.OrderBy(s => s.ToLower()).ToArray();

                return(new Platform.LibraryForExport()
                {
                    Name = libraryName,
                    Version = libraryVersion,
                    PastelContext = nullableLibaryPastelContext,
                    ExportEntities = exportEntities,
                    DotNetLibs = dotNetLibs,
                    LibProjectNamesAndGuids = libResDb.ProjectReferenceToGuid,
                });
            }
        }
Ejemplo n.º 8
0
 public EnumDefinition(Token enumToken, Token nameToken, PastelContext context)
 {
     this.FirstToken = enumToken;
     this.NameToken  = nameToken;
     this.Context    = context;
 }
Ejemplo n.º 9
0
        public static void GenerateTemplatesForVmExport(
            TemplateStorage templates,
            PastelContext vmContext)
        {
            if (vmContext.UsesStringTable)
            {
                vmContext.GetTranspilerContext().StringTableBuilder = new Pastel.Transpilers.StringTableBuilder("VM");
            }

            string vmGlobalsCode = vmContext.GetCodeForGlobals();

            templates.AddPastelTemplate("vm:globals", vmGlobalsCode);

            if (vmContext.UsesFunctionDeclarations)
            {
                string functionDeclarationCode = vmContext.GetCodeForFunctionDeclarations();
                templates.AddPastelTemplate("vm:functionsdecl", functionDeclarationCode);
            }

            string functionCode = vmContext.GetCodeForFunctions();

            templates.AddPastelTemplate("vm:functions", functionCode);

            if (vmContext.UsesStructDefinitions)
            {
                Dictionary <string, string> structLookup = vmContext.GetCodeForStructs();
                foreach (string structName in structLookup.Keys)
                {
                    templates.AddPastelTemplate("vm:struct:" + structName, structName, structLookup[structName]);
                }

                if (vmContext.UsesStructDeclarations)
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (string structKey in templates.GetTemplateKeysWithPrefix("vm:struct:"))
                    {
                        string structName = templates.GetName(structKey);
                        sb.Append(vmContext.GetCodeForStructDeclaration(structName));
                    }
                    templates.AddPastelTemplate("vm:structsdecl", sb.ToString().Trim());
                }
            }

            if (vmContext.Language == Language.C)
            {
                templates.AddPastelTemplate("vm:struct:Value", "Value", string.Join("\n", new string[] {
                    "struct Value {",
                    "\tint type;",
                    "\tunion {",
                    "\t\tint null_internalValue; // not used",
                    "\t\tint bool_internalValue;",
                    "\t\tint int_internalValue;",
                    "\t\tdouble double_internalValue;",
                    "\t\tint* str_internalValue;",
                    "\t\tList* list_internalValue;",
                    "\t\tDictImpl* dict_internalValue;",
                    "\t\tObjectInstance* obj_internalValue;",
                    "\t\tClassValue* class_internalValue;",
                    "\t\tFunctionPointer* func_internalValue;",
                    "\t};",
                    "};",
                }));
            }

            if (vmContext.UsesStringTable)
            {
                templates.AddPastelTemplate(
                    "vm:stringtable",
                    vmContext.GetStringConstantTable());
            }
        }
Ejemplo n.º 10
0
        public static void GenerateTemplatesForLibraryExport(
            TemplateStorage templates,
            LibraryForExport library)
        {
            string        libraryName = library.Name;
            PastelContext libContext  = library.PastelContext;

            libContext.GetTranspilerContext().UniquePrefixForNonCollisions = libraryName.ToLower();

            if (libContext.Language == Language.PYTHON ||
                libContext.Language == Language.JAVASCRIPT ||
                libContext.Language == Language.JAVA)
            {
                bool   changeManifestFuncName       = libContext.Language == Language.JAVASCRIPT;
                string newManifestFunctionNameIfAny = changeManifestFuncName
                    ? "lib_" + libraryName.ToLower() + "_manifest"
                    : null;

                string manifestFunction = library.PastelContext.GetFunctionCodeForSpecificFunctionAndPopItFromFutureSerialization(
                    "lib_manifest_RegisterFunctions",
                    newManifestFunctionNameIfAny);
                templates.AddPastelTemplate("library:" + libraryName + ":manifestfunc", manifestFunction);
            }

            if (libContext.Language == Language.JAVA)
            {
                Dictionary <string, string> lookup = libContext.GetCodeForFunctionsLookup();
                StringBuilder sb = new StringBuilder();
                string        reflectionCalledPrefix       = "lib_" + library.Name.ToLower() + "_function_";
                libContext.GetTranspilerContext().TabDepth = 1;
                foreach (string functionName in lookup.Keys.OrderBy(k => k))
                {
                    string functionCode            = lookup[functionName];
                    bool   isFunctionPointerObject = functionName.StartsWith(reflectionCalledPrefix);

                    if (isFunctionPointerObject)
                    {
                        // This is kind of hacky, BUT...

                        // If the generated function needs to be used as a function pointer, (i.e. it's one
                        // of the library's VM-native bridge methods) change the name to "invoke" and then
                        // wrap it in a dummy class that extends LibraryFunctionPointer. The manifest
                        // function will simply instantiate this in lieu of a performant way to do
                        // function pointers in Java.
                        functionCode = functionCode.Replace(
                            "public static Value v_" + functionName + "(Value[] ",
                            "public Value invoke(Value[] ");
                        functionCode =
                            "  public static class FP_" + functionName + " extends LibraryFunctionPointer {\n" +
                            "  " + functionCode.Replace("\n", "\n  ").TrimEnd() + "\n" +
                            "  }";
                    }
                    sb.Append(functionCode);
                    sb.Append("\n");
                }
                libContext.GetTranspilerContext().TabDepth = 0;
                templates.AddPastelTemplate("library:" + library.Name + ":functions", sb.ToString().Trim());
            }
            else
            {
                string allFunctionCode = libContext.GetCodeForFunctions();
                templates.AddPastelTemplate("library:" + library.Name + ":functions", allFunctionCode);
            }

            if (libContext.UsesStructDefinitions)
            {
                Dictionary <string, string> libStructLookup = libContext.GetCodeForStructs();
                foreach (string structName in libStructLookup.Keys)
                {
                    templates.AddPastelTemplate(
                        "library:" + library.Name + ":struct:" + structName,
                        structName,
                        libStructLookup[structName]);
                }
            }
        }
Ejemplo n.º 11
0
        public void ExportProjectImpl(
            Dictionary <string, FileOutput> output,
            TemplateStorage templates,
            IList <LibraryForExport> libraries,
            ResourceDatabase resourceDatabase,
            Options options)
        {
            List <string> jsExtraHead = new List <string>()
            {
                options.GetStringOrEmpty(ExportOptionKey.JS_HEAD_EXTRAS)
            };
            bool fullPage = options.GetBool(ExportOptionKey.JS_FULL_PAGE);

            // There's a double-check here so that you can || them together and then have multiple options added here.
            if (fullPage)
            {
                jsExtraHead.Add(
                    "<script type=\"text/javascript\">"
                    + (fullPage ? "C$common$globalOptions['fullscreen'] = true;" : "")
                    + "</script>");
            }
            options.SetOption(ExportOptionKey.JS_HEAD_EXTRAS, string.Join("\n", jsExtraHead));

            Dictionary <string, string> replacements = this.GenerateReplacementDictionary(options, resourceDatabase);

            output["vm.js"] = new FileOutput()
            {
                Type        = FileOutputType.Text,
                TextContent = templates.GetCode("vm:globals") + this.NL + this.NL + templates.GetCode("vm:functions"),
            };

            List <LibraryForExport> librariesWithCode = new List <LibraryForExport>();

            foreach (LibraryForExport library in libraries)
            {
                if (library.HasPastelCode)
                {
                    string        libraryName = library.Name;
                    PastelContext libContext  = library.PastelContext;

                    List <string> libraryLines = new List <string>();
                    libraryLines.Add(templates.GetCode("library:" + libraryName + ":manifestfunc"));
                    libraryLines.Add("");
                    libraryLines.Add(templates.GetCode("library:" + libraryName + ":functions"));
                    libraryLines.Add("");
                    libraryLines.Add("C$common$scrapeLibFuncNames('" + libraryName.ToLower() + "');");
                    libraryLines.Add("");

                    // add helper functions after the scrape.

                    foreach (ExportEntity embedCode in library.ExportEntities["EMBED_CODE"])
                    {
                        libraryLines.Add(embedCode.StringValue);
                    }

                    output["libs/lib_" + libraryName.ToLower() + ".js"] = new FileOutput()
                    {
                        Type        = FileOutputType.Text,
                        TextContent = string.Join("\n", libraryLines),
                    };
                    librariesWithCode.Add(library);
                }
            }

            Dictionary <string, string> htmlReplacements = new Dictionary <string, string>(replacements);

            replacements["JS_LIB_INCLUSIONS"] = GenerateJsLibInclusionHtml(output.Keys);

            this.CopyResourceAsText(output, "index.html", "Resources/HostHtml.txt", replacements);

            this.CopyResourceAsText(output, "common.js", "Resources/Common.txt", replacements);

            TODO.JavaScriptDeGamification();
            output["lib_supplemental.js"] = new FileOutput()
            {
                Type        = FileOutputType.Text,
                TextContent = this.LoadTextResource("Resources/ImageResource.txt", replacements),
            };

            StringBuilder resourcesJs = new StringBuilder();

            foreach (FileOutput textResource in resourceDatabase.TextResources)
            {
                resourcesJs.Append("C$common$addTextRes(");
                resourcesJs.Append(Util.ConvertStringValueToCode(textResource.CanonicalFileName));
                resourcesJs.Append(", ");
                resourcesJs.Append(Util.ConvertStringValueToCode(textResource.TextContent));
                resourcesJs.Append(");\n");
            }

            foreach (FileOutput fontResource in resourceDatabase.FontResources)
            {
                resourcesJs.Append("C$common$addBinaryRes(");
                resourcesJs.Append(Util.ConvertStringValueToCode(fontResource.CanonicalFileName));
                resourcesJs.Append(", '");
                resourcesJs.Append(Util.ConvertByteArrayToBase64(fontResource.GetFinalBinaryContent()));
                resourcesJs.Append("');\n");
            }

            FileOutput imageSheetManifest = resourceDatabase.ImageSheetManifestFile;

            resourcesJs.Append("C$common$addTextRes('image_sheets.txt', ");
            resourcesJs.Append(imageSheetManifest == null ? "''" : Util.ConvertStringValueToCode(imageSheetManifest.TextContent));
            resourcesJs.Append(");\n");

            resourcesJs.Append("C$common$resourceManifest = ");
            resourcesJs.Append(Util.ConvertStringValueToCode(resourceDatabase.ResourceManifestFile.TextContent));
            resourcesJs.Append(";\n");

            string filePrefix = options.GetStringOrNull(ExportOptionKey.JS_FILE_PREFIX);

            if (filePrefix != null)
            {
                resourcesJs.Append("C$common$jsFilePrefix = ");
                resourcesJs.Append(Util.ConvertStringValueToCode(filePrefix));
                resourcesJs.Append(";\n");
            }

            output["resources.js"] = new FileOutput()
            {
                Type        = FileOutputType.Text,
                TextContent = resourcesJs.ToString(),
            };

            output["bytecode.js"] = new FileOutput()
            {
                Type        = FileOutputType.Text,
                TextContent = "C$bytecode = " + Util.ConvertStringValueToCode(resourceDatabase.ByteCodeFile.TextContent) + ";",
            };

            foreach (string imageResourceFile in resourceDatabase.ImageSheetFiles.Keys)
            {
                FileOutput file = resourceDatabase.ImageSheetFiles[imageResourceFile];
                output["resources/images/" + imageResourceFile] = file;
            }

            foreach (FileOutput audioResourceFile in resourceDatabase.AudioResources)
            {
                output["resources/audio/" + audioResourceFile.CanonicalFileName] = audioResourceFile;
            }

            // TODO: minify JavaScript across all of output dictionary
        }
Ejemplo n.º 12
0
 public StructDefinition(Token structToken, Token name, IList <PType> argTypes, IList <Token> argNames, Token parentName, PastelContext context)
 {
     this.Context               = context;
     this.FirstToken            = structToken;
     this.NameToken             = name;
     this.ParentName            = parentName;
     this.LocalFieldTypes       = argTypes.ToArray();
     this.LocalFieldNames       = argNames.ToArray();
     this.LocalFieldIndexByName = new Dictionary <string, int>();
     for (int i = this.LocalFieldNames.Length - 1; i >= 0; --i)
     {
         string argName = this.LocalFieldNames[i].Value;
         this.LocalFieldIndexByName[argName] = i;
     }
 }
Ejemplo n.º 13
0
        public void TranslateExpression(TranspilerContext sb, Expression expression)
        {
            string typeName = expression.GetType().Name;

            switch (typeName)
            {
            case "CastExpression": this.TranslateCast(sb, ((CastExpression)expression).Type, ((CastExpression)expression).Expression); break;

            case "FunctionReference": this.TranslateFunctionReference(sb, (FunctionReference)expression); break;

            case "FunctionPointerInvocation": this.TranslateFunctionPointerInvocation(sb, (FunctionPointerInvocation)expression); break;

            case "CoreFunctionInvocation": this.TranslateCoreFunctionInvocation(sb, (CoreFunctionInvocation)expression); break;

            case "OpChain":
                OpChain oc = (OpChain)expression;
                if (oc.IsStringConcatenation)
                {
                    this.TranslateStringConcatenation(sb, oc.Expressions);
                }
                else
                {
                    this.TranslateOpChain(sb, oc);
                }
                break;

            case "ExtensibleFunctionInvocation":
                this.TranslateExtensibleFunctionInvocation(
                    sb,
                    (ExtensibleFunctionInvocation)expression);
                break;

            case "InlineIncrement":
                InlineIncrement ii = (InlineIncrement)expression;
                this.TranslateInlineIncrement(sb, ii.Expression, ii.IsPrefix, ii.IncrementToken.Value == "++");
                break;

            case "FunctionInvocation":
                FunctionInvocation funcInvocation = (FunctionInvocation)expression;
                string             prefix         = null;
                FunctionDefinition funcDef        = ((FunctionReference)funcInvocation.Root).Function;
                PastelContext      targetContext  = funcDef.Context;
                PastelContext      callerContext  = funcInvocation.Owner.Context;
                if (targetContext != callerContext)
                {
                    prefix = callerContext.GetDependencyExportPrefix(targetContext);
                }

                if (prefix != null)
                {
                    this.TranslateFunctionInvocationWithPrefix(sb, prefix, (FunctionReference)funcInvocation.Root, funcInvocation.Args);
                }
                else
                {
                    this.TranslateFunctionInvocation(sb, (FunctionReference)funcInvocation.Root, funcInvocation.Args);
                }
                break;

            case "Variable":
                Variable v = (Variable)expression;
                this.TranslateVariable(sb, v);
                break;

            case "ConstructorInvocation":
                ConstructorInvocation constructor = (ConstructorInvocation)expression;
                string rootType = constructor.Type.RootValue;
                switch (rootType)
                {
                case "Array":
                    if (constructor.Type.Generics.Length != 1)
                    {
                        throw new Pastel.ParserException(constructor.Type.FirstToken, "Array constructor requires exactly 1 generic type.");
                    }
                    this.TranslateArrayNew(sb, constructor.Type.Generics[0], constructor.Args[0]);
                    break;

                case "List":
                    if (constructor.Type.Generics.Length != 1)
                    {
                        throw new Pastel.ParserException(constructor.Type.FirstToken, "List constructor requires exactly 1 generic type.");
                    }
                    this.TranslateListNew(sb, constructor.Type.Generics[0]);
                    break;

                case "Dictionary":
                    if (constructor.Type.Generics.Length != 2)
                    {
                        throw new Pastel.ParserException(constructor.Type.FirstToken, "Dictionary constructor requires exactly 2 generic types.");
                    }
                    PType dictionaryKeyType   = constructor.Type.Generics[0];
                    PType dictionaryValueType = constructor.Type.Generics[1];
                    this.TranslateDictionaryNew(sb, dictionaryKeyType, dictionaryValueType);
                    break;

                case "StringBuilder":
                    if (constructor.Type.Generics.Length != 0)
                    {
                        throw new ParserException(constructor.Type.FirstToken, "StringBuilder constructor does not have any generics.");
                    }
                    this.TranslateStringBuilderNew(sb);
                    break;

                default:
                    // TODO: throw an exception (in the parser) if generics exist.
                    this.TranslateConstructorInvocation(sb, constructor);
                    break;
                }
                break;

            case "DotField":
                DotField         df        = (DotField)expression;
                StructDefinition structDef = df.StructType;
                ClassDefinition  classDef  = df.ClassType;
                string           fieldName = df.FieldName.Value;
                if (classDef != null)
                {
                    this.TranslateInstanceFieldDereference(sb, df.Root, classDef, fieldName);
                }
                else if (structDef != null)
                {
                    int fieldIndex = structDef.FlatFieldIndexByName[fieldName];
                    this.TranslateStructFieldDereference(sb, df.Root, structDef, fieldName, fieldIndex);
                }
                else
                {
                    throw new InvalidOperationException();     // should have been thrown by the compiler
                }
                break;

            case "InlineConstant":
                InlineConstant ic = (InlineConstant)expression;
                switch (ic.ResolvedType.RootValue)
                {
                case "bool": this.TranslateBooleanConstant(sb, (bool)ic.Value); break;

                case "char": this.TranslateCharConstant(sb, ((string)ic.Value)[0]); break;

                case "double": this.TranslateFloatConstant(sb, (double)ic.Value); break;

                case "int": this.TranslateIntegerConstant(sb, (int)ic.Value); break;

                case "null": this.TranslateNullConstant(sb); break;

                case "string": this.TranslateStringConstant(sb, (string)ic.Value); break;

                default: throw new NotImplementedException();
                }
                break;

            case "ThisExpression":
                this.TranslateThis(sb, (ThisExpression)expression);
                break;

            case "UnaryOp":
                UnaryOp uo = (UnaryOp)expression;
                if (uo.OpToken.Value == "-")
                {
                    this.TranslateNegative(sb, uo);
                }
                else
                {
                    this.TranslateBooleanNot(sb, uo);
                }
                break;

            case "ForcedParenthesis":
                sb.Append('(');
                this.TranslateExpression(sb, ((ForcedParenthesis)expression).Expression);
                sb.Append(')');
                break;

            default: throw new NotImplementedException(typeName);
            }
        }
Ejemplo n.º 14
0
        private List <Platform.LibraryForExport> GetLibrariesForExport(
            Platform.AbstractPlatform platform,
            Dictionary <string, LibraryMetadata> librariesById,
            Dictionary <string, object> constantFlags,
            IInlineImportCodeLoader codeLoader,
            PastelContext vm)
        {
            using (new PerformanceSection("VmGenerator.GetLibrariesForExport"))
            {
                Dictionary <string, PastelContext> libraryCompilation = this.GenerateLibraryParseTree(
                    platform,
                    constantFlags,
                    codeLoader,
                    librariesById.Values,
                    vm);

                List <Platform.LibraryForExport>     libraries     = new List <Platform.LibraryForExport>();
                Dictionary <string, LibraryExporter> libraryByName = new Dictionary <string, LibraryExporter>();
                foreach (string libraryId in libraryCompilation.Keys.OrderBy(s => s))
                {
                    LibraryExporter library = LibraryExporter.Get(librariesById[libraryId], platform);
                    libraryByName[library.Metadata.ID] = library;
                    PastelContext libraryPastelContext = libraryCompilation.ContainsKey(library.Metadata.ID)
                        ? libraryCompilation[library.Metadata.ID]
                        : null;
                    Platform.LibraryForExport libraryForExport = this.CreateLibraryForExport(
                        library.Metadata.ID,
                        library.Metadata.Version,
                        libraryPastelContext,
                        library.Resources);
                    libraries.Add(libraryForExport);
                }

                // Now that all libraries are read and initialized, go through and resolve all deferred DLL's that required all libraries to be loaded.
                foreach (Platform.LibraryForExport lfe in libraries)
                {
                    foreach (Platform.ExportEntity ee in lfe.ExportEntities.GetValueEnumerator())
                    {
                        if (ee.DeferredFileOutputBytesLibraryName != null)
                        {
                            LibraryExporter sourceLibrary;
                            if (!libraryByName.TryGetValue(ee.DeferredFileOutputBytesLibraryName, out sourceLibrary))
                            {
                                throw new InvalidOperationException("The library '" + lfe.Name + "' makes reference to another library '" + ee.DeferredFileOutputBytesLibraryName + "' which could not be found.");
                            }

                            string resourcePath = "resources/" + ee.DeferredFileOutputBytesLibraryPath;
                            byte[] dllFile      = sourceLibrary.Metadata.ReadFileBytes(resourcePath);
                            if (dllFile == null)
                            {
                                throw new InvalidOperationException("Could not find file: '" + resourcePath + "' in library '" + sourceLibrary.Metadata.ID + "'");
                            }
                            ee.FileOutput = new FileOutput()
                            {
                                Type          = FileOutputType.Binary,
                                BinaryContent = dllFile
                            };
                        }
                    }
                }

                return(libraries);
            }
        }
Ejemplo n.º 15
0
        private Dictionary <string, PastelContext> GenerateLibraryParseTree(
            Platform.AbstractPlatform platform,
            Dictionary <string, object> constantFlags,
            IInlineImportCodeLoader codeLoader,
            ICollection <LibraryMetadata> relevantLibraries,
            PastelContext sharedScope)
        {
            using (new PerformanceSection("VmGenerator.GenerateLibraryParseTree"))
            {
                Dictionary <string, PastelContext> libraries = new Dictionary <string, PastelContext>();

                foreach (LibraryMetadata libraryMetadata in relevantLibraries)
                {
                    LibraryExporter library = LibraryExporter.Get(libraryMetadata, platform);

                    Dictionary <string, object> constantsLookup = Util.MergeDictionaries <string, object>(constantFlags, library.CompileTimeConstants);

                    List <ExtensibleFunction> libraryFunctions = library.GetPastelExtensibleFunctions();

                    if (!libraryMetadata.IsMoreThanJustEmbedCode)
                    {
                        continue;
                    }

                    PastelContext context = new PastelContext(platform.Language, codeLoader);
                    Dictionary <string, string> exFnTranslations = library.GetExtensibleFunctionTranslations(platform);
                    foreach (ExtensibleFunction exFn in libraryFunctions)
                    {
                        string exFnTranslation = null;
                        if (exFnTranslations.ContainsKey(exFn.Name))
                        {
                            exFnTranslation = exFnTranslations[exFn.Name];
                        }
                        else if (exFnTranslations.ContainsKey("$" + exFn.Name))
                        {
                            exFnTranslation = exFnTranslations["$" + exFn.Name];
                        }

                        context.AddExtensibleFunction(exFn, exFnTranslation);
                    }
                    context.AddDependency(sharedScope);
                    foreach (string constKey in constantsLookup.Keys)
                    {
                        context.SetConstant(constKey, constantsLookup[constKey]);
                    }

                    libraries[library.Metadata.ID] = context;

                    Dictionary <string, string> supplementalCode = library.Metadata.GetSupplementalTranslatedCode();
                    Dictionary <string, string> translatedCode   = library.GetNativeCode();
                    Dictionary <string, string> structCode       = library.Metadata.GetStructFilesCode();
                    // need to load from the actual Library instance, which could have come from either CRAYON_HOME or source

                    string registryCode = library.Metadata.GetRegistryCode();
                    if (registryCode == null)
                    {
                        if (supplementalCode.Count > 0 || translatedCode.Count > 0)
                        {
                            throw new InvalidOperationException("The library '" + library.Metadata.ID + "' has translated code but no function_registry.pst file.");
                        }
                    }
                    else
                    {
                        string filename = "LIB:" + library.Metadata.ID + "/function_registry.pst";
                        context.CompileCode(filename, registryCode);

                        foreach (string structFile in structCode.Keys)
                        {
                            filename = "LIB:" + library.Metadata.ID + "/structs/" + structFile;
                            context.CompileCode(filename, structCode[structFile]);
                        }

                        foreach (string supplementalFile in supplementalCode.Keys)
                        {
                            filename = "LIB:" + library.Metadata.ID + "/supplemental/" + supplementalFile;
                            context.CompileCode(filename, supplementalCode[supplementalFile]);
                        }
                        foreach (string translatedFile in translatedCode.Keys)
                        {
                            filename = "LIB:" + library.Metadata.ID + "/translate/" + translatedFile;
                            context.CompileCode(filename, translatedCode[translatedFile]);
                        }

                        context.FinalizeCompilation();
                    }
                }

                return(libraries);
            }
        }
Ejemplo n.º 16
0
        public void GenerateVmSourceCodeForPlatform(
            Dictionary <string, FileOutput> output,
            Platform.AbstractPlatform platform,
            CompilationBundle nullableCompilationBundle,
            ResourceDatabase resourceDatabase,
            ICollection <LibraryMetadata> relevantLibraries,
            string verifiedAbsoluteOutputPath,
            IInlineImportCodeLoader codeLoader,
            VmGenerationMode mode)
        {
            using (new PerformanceSection("VmGenerator.GenerateVmSourceCodeForPlatform"))
            {
                Options options = new Options();
                Dictionary <string, object> constantFlags = platform.GetFlattenedConstantFlags() ?? new Dictionary <string, object>();

                this.AddTypeEnumsToConstants(constantFlags);

                PastelContext vmPastelContext = this.GenerateCoreVmParseTree(platform, codeLoader, constantFlags);

                Dictionary <string, LibraryMetadata> librariesByID = relevantLibraries.ToDictionary(lib => lib.ID);
                List <Platform.LibraryForExport>     libraries     = this.GetLibrariesForExport(platform, librariesByID, constantFlags, codeLoader, vmPastelContext);

                Platform.TemplateStorage templates = new Platform.TemplateStorage();

                Platform.TemplateGenerator.GenerateTemplatesForVmExport(templates, vmPastelContext);
                foreach (Platform.LibraryForExport library in libraries.Where(lib => lib.HasPastelCode))
                {
                    Platform.TemplateGenerator.GenerateTemplatesForLibraryExport(templates, library);
                }

                if (mode == VmGenerationMode.EXPORT_SELF_CONTAINED_PROJECT_SOURCE)
                {
                    options
                    .SetOption(ExportOptionKey.PROJECT_ID, nullableCompilationBundle.ProjectID)
                    .SetOption(ExportOptionKey.DESCRIPTION, nullableCompilationBundle.Description)
                    .SetOption(ExportOptionKey.VERSION, nullableCompilationBundle.Version)
                    .SetOption(ExportOptionKey.EMBED_BYTE_CODE, nullableCompilationBundle.GuidSeed)
                    .SetOption(ExportOptionKey.EMBED_BYTE_CODE, true)
                    .SetOption(ExportOptionKey.DEFAULT_TITLE, nullableCompilationBundle.DefaultTitle)
                    .SetOption(ExportOptionKey.LIBRARIES_USED, libraries.Cast <object>().ToArray())
                    .SetOption(ExportOptionKey.HAS_ICON, nullableCompilationBundle.IconPath != null)
                    .SetOption(ExportOptionKey.HAS_LAUNCHSCREEN, nullableCompilationBundle.LaunchScreenPath != null)
                    .SetOption(ExportOptionKey.IOS_BUNDLE_PREFIX, nullableCompilationBundle.IosBundlePrefix)
                    .SetOption(ExportOptionKey.JAVA_PACKAGE, nullableCompilationBundle.JavaPackage)
                    .SetOption(ExportOptionKey.JS_FILE_PREFIX, nullableCompilationBundle.JsFilePrefix)
                    .SetOption(ExportOptionKey.JS_FULL_PAGE, nullableCompilationBundle.JsFullPage)
                    .SetOption(ExportOptionKey.SUPPORTED_ORIENTATION, nullableCompilationBundle.Orientations);

                    if (options.GetBool(ExportOptionKey.HAS_ICON))
                    {
                        options.SetOption(ExportOptionKey.ICON_PATH, nullableCompilationBundle.IconPath);
                    }
                    if (options.GetBool(ExportOptionKey.HAS_LAUNCHSCREEN))
                    {
                        options.SetOption(ExportOptionKey.LAUNCHSCREEN_PATH, nullableCompilationBundle.LaunchScreenPath);
                    }

                    platform.GleanInformationFromPreviouslyExportedProject(options, verifiedAbsoluteOutputPath);

                    platform.ExportProject(
                        output,
                        templates,
                        libraries,
                        resourceDatabase,
                        options);
                }
                else
                {
                    platform.ExportStandaloneVm(
                        output,
                        templates,
                        libraries);
                }
            }
        }