Example #1
0
        public CSTranslationClass TranslateBHAV(StructuredBHAV bhav)
        {
            var csClass = new CSTranslationClass();

            csClass.ClassName      = CSTranslationContext.FormatName(bhav.Source.ChunkLabel) + "_" + bhav.Source.ChunkID;
            csClass.Structure      = bhav;
            csClass.InlineFunction = !bhav.Yields;
            csClass.ArgCount       = Math.Max(4, (int)bhav.Source.Args); //possible to make this tighter by analysing func
            Context.CurrentBHAV    = bhav.Source;
            Context.CurrentClass   = csClass;

            csClass.Instructions = bhav.Instructions.ToDictionary(x => x.Key, x =>
            {
                var inst = x.Value;
                return(new CSTranslationInstruction(inst.Translator.CodeGen(Context), inst.ReturnType, inst.Yields));
            });

            return(csClass);
        }
Example #2
0
        public string TranslateIff(IffFile file)
        {
            Context.Filename      = CSTranslationContext.FormatName(file.Filename.Replace(".iff", ""));
            Context.ModuleName    = Context.Filename + "Module";
            Context.NamespaceName = "FSO.Scripts." + Context.Filename;
            Context.CurrentFile   = file;

            var bhavs = file.List <BHAV>() ?? new List <BHAV>();

            foreach (var bhav in bhavs)
            {
                Context.CurrentBHAV = bhav;
                var sbhav = new StructuredBHAV(bhav);
                sbhav.Analyse(Context);
                Context.BHAVInfo[bhav.ChunkID] = sbhav;
            }

            foreach (var bhav in Context.BHAVInfo.Values)
            {
                PropagateYieldFromCalls(bhav);
            }

            foreach (var bhav in Context.BHAVInfo.Values)
            {
                foreach (var inst in bhav.Instructions.Values)
                {
                    (inst.Translator as CSSubroutinePrimitive)?.InitInfo(Context);
                }
            }

            foreach (var bhav in Context.BHAVInfo.Values)
            {
                bhav.BuildStructure();
            }

            foreach (var bhav in Context.BHAVInfo.Values)
            {
                Context.AllClasses.Add(TranslateBHAV(bhav));
            }

            return(BuildCSFile());
        }
Example #3
0
        private bool PropagateYieldFromCalls(StructuredBHAV bhav)
        {
            bhav.VisitCount++;
            if (bhav.Yields)
            {
                return(true);
            }
            bool yields = false;

            foreach (var call in bhav.Calls)
            {
                SimAnticsModule      module;
                CSTranslationContext ctx2;
                //find the bhav.
                if (call < 4096)
                {
                    //global
                    module = Context.GlobalModule;
                    ctx2   = (CSTranslationContext)Context.GlobalContext;
                }
                else if (call < 8192)
                {
                    //local (can only be us)
                    module = null;
                    ctx2   = null;
                }
                else
                {
                    //semiglobal
                    module = Context.SemiGlobalModule;
                    ctx2   = (CSTranslationContext)Context.SemiGlobalContext;
                }

                if (ctx2 != null)
                {
                    //in previously compiled context
                    StructuredBHAV newBHAV;
                    if (ctx2.BHAVInfo.TryGetValue(call, out newBHAV))
                    {
                        if (newBHAV.Yields)
                        {
                            yields = true;
                            break;
                        }
                    }
                    else
                    {
                        yields = true; //if we don't know if it yields, err on the side of caution.
                        break;
                    }
                }
                else if (module != null)
                {
                    if (module.FunctionYields(call) != false)
                    {
                        yields = true; //also true if we're missing the function
                        break;
                    }
                }
                else
                {
                    StructuredBHAV newBHAV;
                    if (Context.BHAVInfo.TryGetValue(call, out newBHAV))
                    {
                        if (newBHAV.VisitCount == 0)
                        {
                            if (PropagateYieldFromCalls(newBHAV))
                            {
                                yields = true;
                                break;
                            }
                        }
                        else
                        {
                            //already evaluated (or is being evaluated), take its word for it.
                            if (newBHAV.Yields)
                            {
                                yields = true;
                                break;
                            }
                        }
                    }
                    else
                    {
                        yields = true; //if we don't know if it yields, err on the side of caution.
                        break;
                    }
                }
            }
            bhav.Yields = yields;
            return(yields);
        }