private void SetMacroReferenced(string inMacro) { int hash = MacroUtil.Hash(inMacro); if (!m_KnownMacros.Contains(inMacro) && !MacroContainedInLinked(hash)) { m_UnknownMacros.Add(inMacro); } }
private Macro CompileSimpleMacro(string inString) { int macroId; if (MacroUtil.IsMacroKey(ref inString, out macroId)) { return(new Macro(new CompilerInstruction(OpCode.CallMacroDirect, macroId))); } return(new Macro(new CompilerInstruction(OpCode.AppendStringDirect, AddString(inString)))); }
private void SetMacroKnown(string inMacro) { m_KnownMacros.Add(inMacro); m_UnknownMacros.Remove(inMacro); int hash = MacroUtil.Hash(inMacro); m_KnownMacroHashes.Add(hash); m_UnknownMacroHashes.Remove(hash); }
/// <summary> /// Evalutes the macro with the given name and returns the result. /// </summary> /// <param name="inMacroName">Name of the macro.</param> /// <param name="inBankSet">Set of compiled string banks.</param> /// <param name="inContext">Additional compiled string bank.</param> public string Evaluate(string inMacroName, MacroBankSet inBankSet, MacroBank inContext, out bool outbSuccess) { int argMacro = MacroUtil.Hash(inMacroName); State state = new State() { Stack = m_SharedStack, BankSet = inBankSet, Context = inContext }; outbSuccess = true; if (!TryExecuteMacro(ref state, argMacro, ref outbSuccess)) { Debug.LogWarningFormat(ERROR_LOG, inMacroName); return(ERROR_STACK); } return(m_SharedStack.Pop()); }
private void CompileEntry(string inKey, string inString) { ClearCompileState(); SetMacroKnown(inKey); m_StringBuilder.Append(inString); ReplaceRules(m_StringBuilder); ParseTokens(m_StringBuilder, ref m_Tokens); CompileInstructions(m_Tokens, ref m_Instructions, ref m_SequenceLinkers); int keyHash = MacroUtil.Hash(inKey); Macro macro = new Macro(m_Instructions.ToArray()); m_MacroDictionary.Add(keyHash, macro); m_CompiledMacroNames.Add(inKey); ClearCompileState(); }
private void CompileMacro(List <Token> inTokens, ref List <CompilerInstruction> ioInstructions, ref int ioPtr) { for (; ioPtr < inTokens.Count; ++ioPtr) { Token token = inTokens[ioPtr]; switch (token.Type) { case TokenType.MACRO: { // We can combine the CallMacroDirect and AppendString opcodes // since in the context of a string macro they usually go together int macroHash = MacroUtil.Hash(token.Value); ioInstructions.Add(new CompilerInstruction(OpCode.AppendMacroDirect, macroHash)); SetMacroReferenced(token.Value); } break; case TokenType.ID: { int macroHash = int.Parse(token.Value); ioInstructions.Add(new CompilerInstruction(OpCode.AppendMacroDirect, macroHash)); SetMacroReferenced(macroHash); } break; case TokenType.END_MACRO_OR_TAG: { // AppendString used to be here } return; } } }
public bool Contains(string inKey) { return(GetMacros().ContainsKey(MacroUtil.Hash(inKey))); }
private void CompileTag(List <Token> inTokens, ref List <CompilerInstruction> ioInstructions, ref Stack <SequenceLinker> ioSequences, ref int ioPtr) { bool bTruthMode = true; for (; ioPtr < inTokens.Count; ++ioPtr) { Token token = inTokens[ioPtr]; switch (token.Type) { case TokenType.IF: { SequenceLinker linker = new SequenceLinker(); ioSequences.Push(linker); linker.Begin(); } break; case TokenType.NOT: { bTruthMode = !bTruthMode; } break; case TokenType.ELIF: case TokenType.ELSE: { SequenceLinker linker = ioSequences.Peek(); ioInstructions.Add(new CompilerInstruction(OpCode.Jump, -1)); linker.PointToEnd(ioInstructions.Count - 1); linker.Advance(ioInstructions.Count, ref ioInstructions); } break; case TokenType.ENDIF: { SequenceLinker linker = ioSequences.Pop(); linker.End(ioInstructions.Count, ref ioInstructions); } break; case TokenType.MACRO: { SetMacroReferenced(token.Value); int macroHash = MacroUtil.Hash(token.Value); ioInstructions.Add(new CompilerInstruction(OpCode.CallMacroDirect, macroHash)); if (bTruthMode) { ioInstructions.Add(new CompilerInstruction(OpCode.JumpIfFalse, -1)); } else { ioInstructions.Add(new CompilerInstruction(OpCode.JumpIfTrue, -1)); } SequenceLinker linker = ioSequences.Peek(); linker.PointToNext(ioInstructions.Count - 1); } break; case TokenType.ID: { int macroHash = int.Parse(token.Value); SetMacroReferenced(macroHash); ioInstructions.Add(new CompilerInstruction(OpCode.CallMacroDirect, macroHash)); if (bTruthMode) { ioInstructions.Add(new CompilerInstruction(OpCode.JumpIfFalse, -1)); } else { ioInstructions.Add(new CompilerInstruction(OpCode.JumpIfTrue, -1)); } SequenceLinker linker = ioSequences.Peek(); linker.PointToNext(ioInstructions.Count - 1); } break; case TokenType.END_MACRO_OR_TAG: { } return; } } }
// 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(); }