Exemple #1
0
        public static void SolveDoubleJumps(SchemeFunction function)
        {
            bool changed = true;

            var commands = function.Commands;

            while (changed)
            {
                changed = false;

                for (int i = 0; i < commands.Count; ++i)
                {
                    ISchemeCommand cmd = commands[i];
                    if (cmd is CommandJumpBase)
                    {
                        CommandJumpBase jumpCmd = (cmd as CommandJumpBase);
                        int             line    = jumpCmd.Line;
                        if (line < commands.Count && commands[line] is CommandJump)
                        {
                            CommandJump jumpCmd2 = commands[line] as CommandJump;
                            if (jumpCmd.Line != jumpCmd2.Line)
                            {
                                jumpCmd.SetLine(jumpCmd2.Line);
                                changed = true;
                            }
                        }
                    }
                }
            }
        }
Exemple #2
0
        private void Test()
        {
            SchemeFunction f = new SchemeFunction();

            f.AddCommand(new CommandAddAction("grab"));
            f.AddCommand(new CommandAddAction("examine"));

            f.AddCommand(new CommandRemoveAction("grab"));
            f.AddCommand(new CommandAddAction("drop"));

            MapObject @object = new MapObject();

            @object.Name = "some_object";
            @object.Variables.Add(new ObjectVariable("logical", "isDwarf", false));
            @object.Variables.Add(new ObjectVariable("logical", "isElf", false));

            @object.Scheme = new Scheme("some_scheme");
            @object.Scheme.CompiledScheme = new CompiledScheme();
            @object.Scheme.CompiledScheme.AddAction(new SchemeFunction("grab"));
            @object.Scheme.CompiledScheme.AddAction(new SchemeFunction("examine"));
            @object.Scheme.CompiledScheme.AddAction(new SchemeFunction("drop"));

            Config config = new Config();

            config.AddScheme(@object.Scheme);

            Game game = new Game(config);

            game._AddObject(@object);

            //Execute function on object
            f.Execute(@object, new Character(), game);
        }
Exemple #3
0
 public override object VisitEnd_of_action([NotNull] scheme_langParser.End_of_actionContext context)
 {
     //Add completed action to scheme
     CompiledScheme.AddAction(currentFunc);
     currentFunc = null;
     VariableManager.EndBlock();
     return(base.VisitEnd_of_action(context));
 }
Exemple #4
0
            /* *** */

            public Visitor(Scheme scheme, Config config)
            {
                Scheme = scheme;
                Config = config;
                Scheme.CompiledScheme = CompiledScheme;

                bodyFunction = new SchemeFunction("_body");
                CompiledScheme.SetBody(bodyFunction);

                currentFunc = bodyFunction;
            }
Exemple #5
0
        public int ExecuteAction(string actionName, Object actor, Game game)
        {
            SchemeFunction action = Scheme?.GetFunctionByName(actionName);

            if (action == null)
            {
                throw new GameException("Given action does not exist.");
            }

            return(action.Execute(this, actor, game));
        }
Exemple #6
0
        public static void Optimize(SchemeFunction function)
        {
            if (function == null)
            {
                return;
            }

            SolveDoubleJumps(function);
            SolveSimpleValueRegs(function);
            SolveRegisterBuffers(function);
            SolveDeadCode(function);
        }
Exemple #7
0
        private static void RemoveCommandsAt(SchemeFunction function, HashSet <int> indexes)
        {
            var commands = function.Commands;

            for (int i = commands.Count - 1; i >= 0; --i)
            {
                if (indexes.Contains(i))
                {
                    commands.RemoveAt(i);
                    DecreaseJumpLocations(commands, i);
                }
            }
        }
Exemple #8
0
            public override object VisitInit_block([NotNull] scheme_langParser.Init_blockContext context)
            {
                if (CompiledScheme.GetFunctionByName("init") != null)
                {
                    Errors.Add(new ErrorDescriptor($"This scheme already contains an init block.", context));
                }

                //Sign start of init block
                currentFunc = new SchemeFunction("init");
                VariableManager.NewBlock();

                return(base.VisitInit_block(context));
            }
Exemple #9
0
        public int GetMovementCost(SquareType squareType, Config config)
        {
            if (Scheme == null || squareType.ActionName == null || squareType.ActionName == "")
            {
                return(config.CharacterConfig.MovementActionPoints);
            }

            SchemeFunction action = Scheme.GetFunctionByName(squareType.ActionName);

            if (action == null)
            {
                return(config.CharacterConfig.MovementActionPoints);
            }

            return(action.ActionPoints);
        }
Exemple #10
0
        public void ExecuteSquareAction(SquareType squareType, Character actor, Game game)
        {
            if (squareType == null || Scheme == null || squareType.ActionName == null || squareType.ActionName == "")
            {
                return;
            }

            SchemeFunction action = Scheme.GetFunctionByName(squareType.ActionName);

            if (action == null)
            {
                throw new GameException($"No such action in map: {squareType.ActionName}");
            }

            action.Execute(SchemeObject, actor, game);
        }
Exemple #11
0
        private Scheme GetLeverScheme()
        {
            Scheme leverScheme = new Scheme();

            leverScheme.CompiledScheme = new CompiledScheme();

            SchemeFunction use = new SchemeFunction();

            use.Name = "use";
            use.AddCommand(new CommandOf("ready", "box", "_0"));
            use.AddCommand(new CommandNot("_0", "_0"));
            use.AddCommand(new CommandSetOf("ready", "box", "_0"));
            use.AddCommand(new CommandDesc("LEVER_DESC_2"));

            leverScheme.CompiledScheme.AddAction(use);

            return(leverScheme);
        }
Exemple #12
0
        //Returns starting position of each basic block in the given function's code
        private static HashSet <int> GetBlockPositions(SchemeFunction function)
        {
            HashSet <int> positions = new HashSet <int>();

            var commands = function.Commands;

            for (int i = 0; i < commands.Count; ++i)
            {
                ISchemeCommand cmd = commands[i];

                if (cmd is CommandJumpBase)
                {
                    int line = ((CommandJumpBase)cmd).Line;
                    positions.Add(line);
                    positions.Add(i + 1);
                }
            }

            return(positions);
        }
Exemple #13
0
        private Scheme GetBoxScheme()
        {
            Scheme boxScheme = new Scheme();

            boxScheme.CompiledScheme = new CompiledScheme();

            boxScheme.CompiledScheme.AddVariable(new ObjectVariable(VariableTypes.Logical, "ready", false));

            SchemeFunction pickup = new SchemeFunction();

            pickup.Name         = "pickup";
            pickup.ActionPoints = 1;
            pickup.AddCommand(new CommandJumpIfFalse("ready", 3));
            pickup.AddCommand(new CommandPrint("Picked up"));
            pickup.AddCommand(new CommandJump(4));
            pickup.AddCommand(new CommandPrint("Box is stuck"));

            boxScheme.CompiledScheme.AddAction(pickup);

            return(boxScheme);
        }
Exemple #14
0
        public static void SolveSimpleValueRegs(SchemeFunction function)
        {
            //We iterate commands
            //If we find a SET(<reg>, <simple value>) command, we
            //    //remove this SET command
            //    //Iterate over the subsequent commands in the base block
            //    //If we find any command with input <reg> we change it to <simple value>
            //    //If we find any command with output <reg> we stop and goto 1. (continuing from the SET command we found)

            var           commands         = function.Commands;
            HashSet <int> removableIndexes = new HashSet <int>();

            for (int i = 0; i < commands.Count; ++i)
            {
                ISchemeCommand cmd = commands[i];

                if (cmd is CommandSetVariable)
                {
                    CommandSetVariable cmdSet    = (CommandSetVariable)cmd;
                    string             targetVar = cmdSet.GetVariableName();
                    string             value     = cmdSet.GetValue();

                    if (SchemeExecutor.IsRegister(targetVar))
                    {
                        removableIndexes.Add(i);
                        for (int i2 = i + 1; i2 < commands.Count; ++i2)
                        {
                            ISchemeCommand cmd2 = commands[i2];
                            cmd2.ChangeInputs(targetVar, value);
                            if (cmd2 is CommandJumpBase || cmd2.HasOutput(targetVar))
                            {
                                break;
                            }
                        }
                    }
                }
            }

            RemoveCommandsAt(function, removableIndexes);
        }
Exemple #15
0
            public override object VisitAction_block([NotNull] scheme_langParser.Action_blockContext context)
            {
                //Sign start of action
                string name         = context.action_name()?.GetText();
                int    actionPoints = 0;

                if (context.action_point() != null)
                {
                    int.TryParse(context.action_point().GetText(), out actionPoints);
                }
                //else
                //Errors.Add(new ErrorDescriptor("Missing action points"));

                if (CompiledScheme.GetFunctionByName(name) != null)
                {
                    Errors.Add(new ErrorDescriptor($"This scheme already contains an action named '{name}'.", context.action_name()));
                }

                currentFunc = new SchemeFunction(name, actionPoints);
                VariableManager.NewBlock();

                return(base.VisitAction_block(context));
            }
Exemple #16
0
        public SchemeFunction GetFunctionByName(string functionName)
        {
            SchemeFunction matchingFunction = CompiledScheme.GetFunctionByName(functionName);

            //If given name was not found in this scheme, we try the parents
            if (matchingFunction == null)
            {
                foreach (Scheme parent in Parents)
                {
                    matchingFunction = parent.GetFunctionByName(functionName);
                    if (matchingFunction != null)
                    {
                        return(matchingFunction);
                    }
                }
            }
            else
            {
                return(matchingFunction);
            }

            return(null);
        }
Exemple #17
0
        public static void SolveRegisterBuffers(SchemeFunction function)
        {
            // if an operation stores its result in a register <reg>, and it is followed by a SET(<var>, <reg>) command
            //      we delete the SET command and set the opperation's output to <var>
            //      we iterate over the following commands and change any <reg> to <var>
            //      we stop if <reg> is set again or we leave the block

            var           commands         = function.Commands;
            HashSet <int> removableIndexes = new HashSet <int>();

            for (int i = 0; i < commands.Count; ++i)
            {
                ISchemeCommand cmd = commands[i];

                var outputs = cmd.GetOutputs();

                if (outputs == null)
                {
                    continue;
                }

                // check if any output is a register
                foreach (var reg in outputs)
                {
                    if (SchemeExecutor.IsRegister(reg))
                    {
                        string variable = null;
                        for (int j = i + 1; j < commands.Count; ++j)
                        {
                            ISchemeCommand cmd2 = commands[j];

                            if (cmd2 is CommandJumpBase)
                            {
                                break;                          // break if we leave the block
                            }
                            if (cmd2.HasOutput(reg))
                            {
                                break;                       // break if the register is set again
                            }
                            if (cmd2 is CommandSetVariable && cmd2.HasInput(reg))
                            {
                                CommandSetVariable setCmd = (CommandSetVariable)cmd2;
                                variable = setCmd.GetVariableName();
                                if (SchemeExecutor.IsRegister(variable))
                                {
                                    variable = null;
                                }
                                else
                                {
                                    cmd.ChangeOutput(reg, variable);
                                    removableIndexes.Add(j);
                                }
                            }

                            if (variable != null && cmd2.HasInput(reg))
                            {
                                cmd2.ChangeInputs(reg, variable);
                            }
                        }
                    }
                }
            }

            RemoveCommandsAt(function, removableIndexes);
        }
Exemple #18
0
 public void AddAction(SchemeFunction action)
 {
     ActionFunctions.Add(action);
 }
Exemple #19
0
 public void SetInit(SchemeFunction init)
 {
     InitFunction = init;
 }
Exemple #20
0
 public void SetBody(SchemeFunction bodyFunction)
 {
     BodyFunction = bodyFunction;
 }
Exemple #21
0
        public static void SolveDeadCode(SchemeFunction function)
        {
            //For each command C:
            //. If C uses local variable X that is in V, as input, we remove X from V and the corresponding line from L
            //. If C has local variable output X that is in V, then we remove the line of code that is connected to X (found in L)
            //. If C has local variable output, we store the output variable's name in array V, and the code line in L
            //. If we reach new basic block, we clear V and L

            bool changed = true;

            while (changed)
            {
                changed = false;

                HashSet <int> blocks = GetBlockPositions(function);

                var           commands         = function.Commands;
                HashSet <int> removableIndexes = new HashSet <int>();

                Dictionary <string, int> lastSetLines = new Dictionary <string, int>();

                for (int i = 0; i < commands.Count; ++i)
                {
                    if (blocks.Contains(i))
                    {
                        lastSetLines.Clear();
                    }

                    ISchemeCommand cmd = commands[i];

                    if (cmd is CommandCreateVariable)
                    {
                        continue;                               //We don't want to remove CREATE commands
                    }
                    List <string> inputs  = cmd.GetInputs();
                    List <string> outputs = cmd.GetOutputs();

                    if (inputs != null)
                    {
                        foreach (string input in inputs)
                        {
                            if (SchemeExecutor.IsVariable(input))
                            {
                                lastSetLines.Remove(input);
                            }
                        }
                    }

                    if (outputs != null)
                    {
                        foreach (string output in outputs)
                        {
                            if (SchemeExecutor.IsVariable(output))
                            {
                                if (lastSetLines.ContainsKey(output))
                                {
                                    removableIndexes.Add(lastSetLines[output]);
                                }
                                lastSetLines[output] = i;
                            }
                        }
                    }
                }

                if (removableIndexes.Count > 0)
                {
                    changed = true;
                    RemoveCommandsAt(function, removableIndexes);
                }
            }
        }