Esempio n. 1
0
        public override void GenerateAbstractCode(List <C.CsStmt> code)
        {
            code.Add(new C.SimpleStmt($"{Name} {Target}"));
            var ite = new C.IfThenElse($"Main.Peek() is {Name}", $"{Target} = {"Main.Pop()".CastAs(Name)}");

            ite.AddElse($"ERROR = \"the top of the stack is not of type {Name}\"");
            ite.AddElse($"{Target} = {Name.DefaultValue()}");
            code.Add(ite);
        }
Esempio n. 2
0
        public override void GenerateAbstractCode(List <C.CsStmt> code)
        {
            code.Add(new C.SimpleStmt($"{Name} almost{Target}"));
            var cond = $"Main.Peek() is {Name}";
            var ite  = new C.IfThenElse(cond, $"almost{Target} = {"Main.Pop()".CastAs(Name)}");

            // TODO: not always ".value", must get the type right
            ite.AddToBranch(cond, $"var {Target} = almost{Target}.value");
            ite.AddElse($"ERROR = \"the top of the stack is not of type {Name}\"");
            ite.AddElse($"{Target} = {Name.DefaultValue()}");
            code.Add(ite);
        }
Esempio n. 3
0
        public override void GenerateAbstractCode(List <C.CsStmt> code)
        {
            // initialise lists
            GenerateInitialisationCode(code);
            foreach (var sa in SiblingActions)
            {
                if (sa is PopSeveral ps)
                {
                    ps.GenerateInitialisationCode(code);
                }
            }

            var loop = new C.WhileStmt {
                Condition = "Main.Count > 0"
            };
            var ite = new C.IfThenElse($"Main.Peek() is {Name}", $"{Target}.Add(Main.Pop() as {Name})");

            foreach (var sa in SiblingActions)
            {
                if (sa is PopSeveral ps)
                {
                    ite.AddBranch($"Main.Peek() is {ps.Name}", $"{ps.Target}.Add(Main.Pop() as {ps.Name})");
                }
            }
            ite.AddElse(new C.SimpleStmt("break"));
            loop.Code.Add(ite);
            code.Add(loop);

            // reverse the order because of stack vs list differences
            code.Add(new C.SimpleStmt($"{Target}.Reverse()"));
            foreach (var sa in SiblingActions)
            {
                if (sa is PopSeveral ps)
                {
                    code.Add(new C.SimpleStmt($"{ps.Target}.Reverse()"));
                }
            }

            // produce the rest of the code (usually push new)
            foreach (var sa in SiblingActions)
            {
                if (!(sa is PopSeveral))
                {
                    sa.GenerateAbstractCode(code);
                }
            }
        }
Esempio n. 4
0
        private static void GenerateLexBranch(SwitchCaseStmt swLex, string hpk, IReadOnlyList <string> guardFlags,
                                              IReadOnlyList <List <HandleAction> > recipes, TokenPlan reactOn, bool matchChar)
        {
            var branchLex = new List <C.CsStmt>();

            Console.WriteLine($"[IR] in '{hpk}', handle {reactOn.Value}");
            bool onlyWraps = true;
            var  ite       = new C.IfThenElse();

            for (int i = 0; i < guardFlags.Count; i++)
            {
                if (!String.IsNullOrEmpty(guardFlags[i]))
                {
                    ite.AddBranch(guardFlags[i]);
                }
                var target
                    = String.IsNullOrEmpty(guardFlags[i])
                        ? branchLex
                        : ite.GetThenBranch(guardFlags[i]);
                foreach (var action in recipes[i])
                {
                    if (!(action is WrapOne))
                    {
                        onlyWraps = false;
                    }
                    if (action != null)
                    {
                        if (action is WrapOne)
                        {
                            var fake = new List <CsStmt>();
                            action.GenerateAbstractCode(fake);
                            if (fake.Count == 1 && fake[0] is IfThenElse ite2)
                            {
                                var newcond = guardFlags[i] + " && " + ite2.FirstThenBranchKey();
                                ite.RenameBranch(guardFlags[i], newcond);
                                foreach (CsStmt stmt in ite2.FirstThenBranchValue())
                                {
                                    ite.AddToBranch(newcond, stmt);
                                }
                            }
                            else
                            {
                                Console.WriteLine("[ERR] This particular usage of WRAP is not supported yet");
                            }
                        }
                        else
                        {
                            action.GenerateAbstractCode(target);
                        }
                    }
                    else
                    {
                        Console.WriteLine($"[B2C] Warning: no action to handle '{hpk}'/{reactOn.Value}");
                    }
                }
            }

            string flags;

            if (guardFlags.Count == 1)
            {
                flags = "flag " + guardFlags[0] + " is not";
            }
            else
            {
                flags = "neither of the flags " + String.Join(", ", guardFlags) + " are";
            }
            branchLex.Add(ite);
            if (!onlyWraps)
            {
                if (guardFlags.Any(f => !String.IsNullOrEmpty(f)))
                {
                    ite.AddElse($"ERROR = \"{flags} lifted when expected\"");
                }
            }
            if (matchChar)
            {
                swLex.Branches["'" + reactOn.Value + "'"] = branchLex;
            }
            else
            {
                swLex.Branches['"' + reactOn.Value + '"'] = branchLex;
            }
        }