Пример #1
0
        /// <summary>
        /// Evalutes the macro with the given name and returns the result.
        /// </summary>
        /// <param name="inMacroId">ID of the macro.</param>
        /// <param name="inBankSet">Set of compiled string banks.</param>
        /// <param name="inContext">Additional compiled string bank.</param>
        public string Evaluate(int inMacroId, MacroBankSet inBankSet, MacroBank inContext, out bool outbSuccess)
        {
            State state = new State()
            {
                Stack   = m_SharedStack,
                BankSet = inBankSet,
                Context = inContext
            };

            outbSuccess = true;
            if (!TryExecuteMacro(ref state, inMacroId, ref outbSuccess))
            {
                Debug.LogWarningFormat(ERROR_LOG, inMacroId);
                return(ERROR_STACK);
            }

            return(m_SharedStack.Pop());
        }
Пример #2
0
        // Attempts to execute a macro with the given id.
        private bool TryExecuteMacro(ref State ioState, int inMacroID, ref bool iobSuccess)
        {
            Macro     macro      = null;
            MacroBank bank       = null;
            bool      foundMacro = (ioState.Context != null && (bank = ioState.Context).TryGetMacro(inMacroID, out macro)) ||
                                   (ioState.BankSet.Variables != null && (bank = ioState.BankSet.Variables).TryGetMacro(inMacroID, out macro)) ||
                                   (ioState.BankSet.LocalizationLocal != null && (bank = ioState.BankSet.LocalizationLocal).TryGetMacro(inMacroID, out macro)) ||
                                   (ioState.BankSet.LocalizationGlobal != null && (bank = ioState.BankSet.LocalizationGlobal).TryGetMacro(inMacroID, out macro)) ||
                                   (ioState.BankSet.Global != null && (bank = ioState.BankSet.Global).TryGetMacro(inMacroID, out macro));

            if (foundMacro)
            {
                ExecuteMacro(ref ioState, macro, bank, ref iobSuccess);
            }
            else
            {
                iobSuccess = false;
            }

            return(foundMacro);
        }
Пример #3
0
        // Executes a macro
        private void ExecuteMacro(ref State ioState, Macro inMacro, MacroBank inMacroBank, ref bool iobSuccess)
        {
            // If no instructions, just return an empty string
            if (inMacro.Operations == null || inMacro.Operations.Length == 0)
            {
                ioState.Stack.Push(string.Empty);
                return;
            }

            // We can optimize for a single instruction of certain types.
            // This means we don't have to request a StringBuilder.
            if (inMacro.Operations.Length == 1)
            {
                OpCode operation = inMacro.Operations[0];
                switch (operation)
                {
                case OpCode.AppendStringDirect:
                    string str;
                    if (!inMacroBank.TryGetString(inMacro.Args[0], out str))
                    {
                        Debug.LogWarningFormat(ERROR_STRING_LOG, inMacro.Args[0]);
                        ioState.Stack.Push(ERROR_STACK);
                        iobSuccess = false;
                    }
                    ioState.Stack.Push(str);
                    return;

                case OpCode.CallMacroDirect:
                    if (!TryExecuteMacro(ref ioState, inMacro.Args[0], ref iobSuccess))
                    {
                        Debug.LogWarningFormat(ERROR_LOG, inMacro.Args[0]);
                        ioState.Stack.Push(ERROR_STACK);
                    }
                    return;
                }
            }

            StringBuilder stringBuilder = GetStringBuilder();

            for (int ptr = 0; ptr < inMacro.Operations.Length; ++ptr)
            {
                OpCode operation = inMacro.Operations[ptr];
                switch (operation)
                {
                case OpCode.PushString:
                {
                    string str;
                    if (!inMacroBank.TryGetString(inMacro.Args[ptr], out str))
                    {
                        Debug.LogWarningFormat(ERROR_STRING_LOG, inMacro.Args[ptr]);
                        ioState.Stack.Push(ERROR_STACK);
                        iobSuccess = false;
                    }
                    ioState.Stack.Push(str);
                }
                break;

                case OpCode.AppendString:
                {
                    stringBuilder.Append(ioState.Stack.Pop());
                }
                break;

                case OpCode.AppendStringDirect:
                {
                    string str;
                    if (!inMacroBank.TryGetString(inMacro.Args[ptr], out str))
                    {
                        Debug.LogWarningFormat(ERROR_STRING_LOG, inMacro.Args[ptr]);
                        ioState.Stack.Push(ERROR_STACK);
                        iobSuccess = false;
                    }
                    stringBuilder.Append(str);
                }
                break;

                case OpCode.CallMacro:
                {
                    string macro = ioState.Stack.Pop();
                    int    hash  = MacroUtil.Hash(ioState.Stack.Pop());
                    if (!TryExecuteMacro(ref ioState, hash, ref iobSuccess))
                    {
                        Debug.LogWarningFormat(ERROR_LOG, macro);
                        ioState.Stack.Push(ERROR_STACK);
                    }
                }
                break;

                case OpCode.CallMacroDirect:
                {
                    if (!TryExecuteMacro(ref ioState, inMacro.Args[ptr], ref iobSuccess))
                    {
                        Debug.LogWarningFormat(ERROR_LOG, inMacro.Args[ptr]);
                        ioState.Stack.Push(ERROR_STACK);
                    }
                }
                break;

                case OpCode.AppendMacroDirect:
                {
                    if (!TryExecuteMacro(ref ioState, inMacro.Args[ptr], ref iobSuccess))
                    {
                        Debug.LogWarningFormat(ERROR_LOG, inMacro.Args[ptr]);
                        stringBuilder.Append(ERROR_STACK);
                    }
                    else
                    {
                        stringBuilder.Append(ioState.Stack.Pop());
                    }
                }
                break;

                case OpCode.JumpIfTrue:
                {
                    if (!string.IsNullOrEmpty(ioState.Stack.Pop()))
                    {
                        ptr = inMacro.Args[ptr] - 1;
                    }
                }
                break;

                case OpCode.JumpIfFalse:
                {
                    if (string.IsNullOrEmpty(ioState.Stack.Pop()))
                    {
                        ptr = inMacro.Args[ptr] - 1;
                    }
                }
                break;

                case OpCode.Jump:
                {
                    ptr = inMacro.Args[ptr] - 1;
                }
                break;
                }
            }

            ioState.Stack.Push(stringBuilder.ToString());
            ReleaseStringBuilder();
        }