private static List <ScriptLine> ParseScriptText(string scriptName, string scriptText, List <DefineScriptLine> globalDefines, bool ignoreErrors) { var scriptDefines = new LiteralMap <string>(); if (globalDefines != null && globalDefines.Count > 0) { foreach (var define in globalDefines) { if (!string.IsNullOrEmpty(define.DefineKey) && !string.IsNullOrEmpty(define.DefineValue)) { scriptDefines[define.DefineKey] = define.DefineValue; } } } var scriptLines = new List <ScriptLine>(); var scriptLinesText = scriptText?.TrimFull()?.SplitByNewLine() ?? new[] { string.Empty }; for (int i = 0; i < scriptLinesText.Length; i++) { var scriptLineText = scriptLinesText[i].TrimFull(); var scriptLineType = ResolveLineType(scriptLineText); var scriptLine = Activator.CreateInstance(scriptLineType, scriptName, i, scriptLineText, scriptDefines, ignoreErrors) as ScriptLine; scriptLines.Add(scriptLine); } return(scriptLines); }
/// <summary> /// Replaces all occurences of replace defined expressions in the provided string with the provided values. /// </summary> /// <remarks> /// Defines collection should be passed by reference to all the line constructors by line order; /// <see cref="DefineScriptLine"/> will add values to the collection, while the subsequent lines /// will use this method to replace the expressions in their <see cref="Text"/>. /// </remarks> protected virtual string ReplaceDefines(string lineText, LiteralMap <string> defines) { foreach (var define in defines) { lineText = lineText.Replace($"{{{define.Key}}}", define.Value); } return(lineText); }
public ScriptLine(string scriptName, int lineIndex, string lineText, LiteralMap <string> scriptDefines = null, bool ignoreParseErrors = false) { ScriptName = scriptName; LineIndex = lineIndex; Text = scriptDefines != null?ReplaceDefines(lineText, scriptDefines) : lineText; LineText = lineText; IgnoreParseErrors = ignoreParseErrors; }
protected override string ReplaceDefines(string lineText, LiteralMap <string> defines) { foreach (var define in defines) // Actor names in generic text lines doesn't require replace literal to be replaced. { if (lineText.StartsWithFast($"{define.Key}: ")) { lineText = lineText.Replace($"{define.Key}: ", $"{define.Value}: "); break; } } return(base.ReplaceDefines(lineText, defines)); }
} // For reflection to work properly. public CommandScriptLine(string scriptName, int lineIndex, string lineText, LiteralMap <string> scriptDefines = null, int inlineIndex = 0, bool ignoreErrors = false) : base(scriptName, lineIndex, lineText, scriptDefines, ignoreErrors) { CommandName = ParseCommandName(Text); var nameValid = !string.IsNullOrWhiteSpace(CommandName); CommandParameters = ParseCommandParameters(Text, out var isError, IgnoreParseErrors); var parametersValid = !isError; InlineIndex = inlineIndex; var inlineIndexValid = InlineIndex >= 0; Valid = nameValid && parametersValid && inlineIndexValid; if (!Valid && !IgnoreParseErrors) { Debug.LogError(ParseErrorMessage); } }
public DefineScriptLine(string scriptName, int lineIndex, string lineText, LiteralMap <string> scriptDefines = null, bool ignoreErrors = false) : base(scriptName, lineIndex, lineText, scriptDefines, ignoreErrors) { DefineKey = ParseDefineKey(Text); DefineValue = ParseDefineValue(Text, DefineKey); if (string.IsNullOrEmpty(DefineKey) || string.IsNullOrEmpty(DefineValue)) { if (!IgnoreParseErrors) { Debug.LogError(ParseErrorMessage); } Valid = false; } if (scriptDefines != null) { //if (scriptDefines.ContainsKey(DefineKey)) Debug.LogWarning($"Multiple assigns to `{DefineKey}` define key detected in '{ScriptName}' script at line #{LineNumber}. Define value will be overwritten."); scriptDefines[DefineKey] = DefineValue; } }
public CommentScriptLine(string scriptName, int lineIndex, string lineText, LiteralMap <string> scriptDefines = null, bool ignoreErrors = false) : base(scriptName, lineIndex, lineText, scriptDefines, ignoreErrors) { CommentText = ParseComment(Text); }
// Don't allow to replace the define expressions themselves. protected override string ReplaceDefines(string lineText, LiteralMap <string> defines) => lineText;
private List <CommandScriptLine> ExtractInlinedCommandLines(string lineText, LiteralMap <string> scriptDefines = null) { // When actor name is present at the start of the line: extract it and cut from the line. var actorId = lineText.GetBefore(ActorIdLiteral); if (!string.IsNullOrEmpty(actorId) && !actorId.Any(char.IsWhiteSpace) && !actorId.StartsWithFast("\"")) { lineText = lineText.GetAfterFirst(ActorIdLiteral); } else { actorId = null; } // Collect all inlined command strings (text inside square brackets). var inlinedCommandMatches = Regex.Matches(lineText, "\\[.*?\\]").Cast <Match>().ToList(); // In case no inlined commands found, just add a single @print command line. if (inlinedCommandMatches.Count == 0) { var printLineText = TransformGenericToPrintText(lineText, actorId); var printLine = new CommandScriptLine(ScriptName, LineIndex, printLineText, scriptDefines, ignoreErrors: IgnoreParseErrors); return(new List <CommandScriptLine> { printLine }); } var result = new List <CommandScriptLine>(); var printedTextBefore = false; for (int i = 0; i < inlinedCommandMatches.Count; i++) { // Check if we need to print any text before the current inlined command. var precedingGenericText = StringUtils.TrySubset(lineText, i > 0 ? inlinedCommandMatches[i - 1].GetEndIndex() + 1 : 0, inlinedCommandMatches[i].Index - 1); if (!string.IsNullOrEmpty(precedingGenericText)) { var printLineText = TransformGenericToPrintText(precedingGenericText, actorId, printedTextBefore ? (bool?)false : null, false); var printLine = new CommandScriptLine(ScriptName, LineIndex, printLineText, scriptDefines, result.Count, IgnoreParseErrors); result.Add(printLine); printedTextBefore = true; } // Extract inlined command script line. var commandLineText = CommandScriptLine.IdentifierLiteral + inlinedCommandMatches[i].ToString().GetBetween("[", "]").TrimFull(); var commandLine = new CommandScriptLine(ScriptName, LineIndex, commandLineText, scriptDefines, result.Count, IgnoreParseErrors); result.Add(commandLine); } // Check if we need to print any text after the last inlined command. var lastGenericText = StringUtils.TrySubset(lineText, inlinedCommandMatches.Last().GetEndIndex() + 1, lineText.Length - 1); if (!string.IsNullOrEmpty(lastGenericText)) { var printLineText = TransformGenericToPrintText(lastGenericText, actorId, printedTextBefore ? (bool?)false : null, false); var printLine = new CommandScriptLine(ScriptName, LineIndex, printLineText, scriptDefines, result.Count, IgnoreParseErrors); result.Add(printLine); } // Add wait input command at the end; except when generic text contains a [skipInput] command. if (lineText?.IndexOf(nameof(SkipInput), StringComparison.OrdinalIgnoreCase) == -1) { var waitCommandLineText = CommandScriptLine.IdentifierLiteral + typeof(WaitForInput).Name; var waitCommandLine = new CommandScriptLine(ScriptName, LineIndex, waitCommandLineText, scriptDefines, result.Count, IgnoreParseErrors); result.Add(waitCommandLine); } return(result); }
public GenericTextScriptLine(string scriptName, int lineNumber, string lineText, LiteralMap <string> scriptDefines = null, bool ignoreErrors = false) : base(scriptName, lineNumber, lineText, scriptDefines, ignoreErrors) { InlinedCommandLines = ExtractInlinedCommandLines(Text, scriptDefines); }
public LabelScriptLine(string scriptName, int lineIndex, string lineText, LiteralMap <string> scriptDefines = null, bool ignoreErrors = false) : base(scriptName, lineIndex, lineText, scriptDefines, ignoreErrors) { LabelText = ParseLabel(Text); }
private static LiteralMap <string> ParseCommandParameters(string scriptLineText, out bool isError, bool ignoreErrors = false) { isError = false; var cmdParams = new LiteralMap <string>(); var paramPairs = ExtractParamPairsFromScriptLine(scriptLineText); if (paramPairs is null) { return(cmdParams); // No params in the line. } foreach (var paramPair in paramPairs) { var paramName = string.Empty; var paramValue = string.Empty; if (IsParamPairNameless(paramPair)) // Corner case for nameless params. { if (cmdParams.ContainsKey(string.Empty)) { isError = true; if (ignoreErrors) { continue; } Debug.LogError("There could be only one nameless parameter per command."); return(cmdParams); } paramValue = paramPair; } else { paramName = paramPair.GetBefore(AssignLiteral); paramValue = paramPair.GetAfterFirst(AssignLiteral); } if (paramName is null || paramValue is null) { isError = true; return(cmdParams); } // Trim quotes in case parameter value is wrapped in them. if (paramValue.WrappedIn("\"")) { paramValue = paramValue.Substring(1, paramValue.Length - 2); } // Restore escaped quotes. paramValue = paramValue.Replace("\\\"", "\""); if (cmdParams.ContainsKey(paramName)) { isError = true; if (!ignoreErrors) { Debug.LogError($"Dublicate parameter with ID `{paramName}`."); } continue; } else { cmdParams.Add(paramName, paramValue); } } return(cmdParams); }
public CommandScriptLine(string scriptName, int lineIndex, string lineText, LiteralMap <string> scriptDefines = null, bool ignoreErrors = false) : this(scriptName, lineIndex, lineText, scriptDefines, 0, ignoreErrors) { } // For reflection to work properly.