/// <summary> /// Parses a string as an array. /// </summary> internal new static SObject Parse(ScriptProcessor processor, string exp) { // Format: [item1, item2, ... itemn] if (Regex.IsMatch(exp, RegexEmptyArray)) { return(processor.CreateArray(0)); } exp = exp.Remove(exp.Length - 1, 1).Remove(0, 1).Trim(); // Remove [ and ]. var elements = new List <SObject>(); var elementStart = 0; var index = 0; var depth = 0; StringEscapeHelper escaper = new LeftToRightStringEscapeHelper(exp, 0); string element; while (index < exp.Length) { var t = exp[index]; escaper.CheckStartAt(index); if (!escaper.IsString) { if (t == '{' || t == '[' || t == '(') { depth++; } else if (t == '}' || t == ']' || t == ')') { depth--; } else if (t == ',' && depth == 0) { element = exp.Substring(elementStart, index - elementStart); elements.Add(string.IsNullOrWhiteSpace(element) ? processor.Undefined : processor.ExecuteStatement(new ScriptStatement(element))); elementStart = index + 1; } } index++; } element = exp.Substring(elementStart, index - elementStart); elements.Add(string.IsNullOrWhiteSpace(element) ? processor.Undefined : processor.ExecuteStatement(new ScriptStatement(element))); return(processor.CreateArray(elements.ToArray())); }
/// <summary> /// Parses a string as an array. /// </summary> internal new static SObject Parse(ScriptProcessor processor, string exp) { // Format: [item1, item2, ... itemn] if (Regex.IsMatch(exp, REGEX_EMPTY_ARRAY)) return processor.CreateArray(0); exp = exp.Remove(exp.Length - 1, 1).Remove(0, 1).Trim(); // Remove [ and ]. var elements = new List<SObject>(); var elementStart = 0; var index = 0; var depth = 0; StringEscapeHelper escaper = new LeftToRightStringEscapeHelper(exp, 0); string element; while (index < exp.Length) { var t = exp[index]; escaper.CheckStartAt(index); if (!escaper.IsString) { if (t == '{' || t == '[' || t == '(') { depth++; } else if (t == '}' || t == ']' || t == ')') { depth--; } else if (t == ',' && depth == 0) { element = exp.Substring(elementStart, index - elementStart); if (string.IsNullOrWhiteSpace(element)) elements.Add(processor.Undefined); else elements.Add(processor.ExecuteStatement(new ScriptStatement(element))); elementStart = index + 1; } } index++; } element = exp.Substring(elementStart, index - elementStart); if (string.IsNullOrWhiteSpace(element)) elements.Add(processor.Undefined); else elements.Add(processor.ExecuteStatement(new ScriptStatement(element))); return processor.CreateArray(elements.ToArray()); }
private static string Interpolate(ScriptProcessor processor, string val) { // string interpolation // replaces the following pattern: {variable}. // {something} has to written as {{something}}. // string interpolation can be turned on by putting a $ in front of the string literal. if (val.Contains("{") && val.Contains("}")) { var searchOffset = 0; while (val.IndexOf("{", searchOffset, StringComparison.Ordinal) > -1 && val.IndexOf("}", searchOffset, StringComparison.Ordinal) > -1) { var startIndex = val.IndexOf("{", searchOffset, StringComparison.Ordinal); if (startIndex < val.Length - 2) { if (val[startIndex + 1] == '{') { val = val.Remove(startIndex + 1) + val.Remove(0, startIndex + 2); // find closing bracket and remove it: var level = 1; var i = startIndex + 1; var foundClosing = false; while (!foundClosing && i < val.Length) { var token = val[i]; switch (token) { case '{': level++; break; case '}': level--; if (level == 0) { val = val.Remove(i) + val.Remove(0, i + 1); foundClosing = true; } break; } i++; } searchOffset = startIndex + 1; } else { var endIndex = val.IndexOf("}", startIndex, StringComparison.Ordinal); if (endIndex > -1) { var interpolationSequence = val.Substring(startIndex, endIndex - startIndex + 1); interpolationSequence = processor.ExecuteStatement(new ScriptStatement(interpolationSequence.Remove(interpolationSequence.Length - 1, 1).Remove(0, 1))).ToString(processor).Value; val = val.Remove(startIndex) + interpolationSequence + val.Remove(0, endIndex + 1); searchOffset = startIndex + interpolationSequence.Length; } else { searchOffset = startIndex + 1; } } } } } return(val); }
/// <summary> /// Parses an anonymous object. /// </summary> internal static SProtoObject Parse(ScriptProcessor processor, string source) { var prototype = new Prototype(LITERAL_OBJECT); source = source.Trim(); // Format: { member1 : content1, member2 : content2 } // Remove "{" and "}": source = source.Remove(source.Length - 1, 1).Remove(0, 1).Trim(); if (source.Length == 0) { return(prototype.CreateInstance(processor, null, false)); } var index = 0; var identifier = ""; var content = ""; SObject contentObj = null; while (index < source.Length) { var nextSeperatorIndex = source.IndexOf(",", index); if (nextSeperatorIndex == -1) { nextSeperatorIndex = source.Length; } else { //Let's find the correct ",": nextSeperatorIndex = index; var depth = 0; StringEscapeHelper escaper = new LeftToRightStringEscapeHelper(source, nextSeperatorIndex, true); var foundSeperator = false; while (!foundSeperator && nextSeperatorIndex < source.Length) { var t = source[nextSeperatorIndex]; escaper.CheckStartAt(nextSeperatorIndex); if (!escaper.IsString) { if (t == '{' || t == '[' || t == '(') { depth++; } else if (t == '}' || t == ']' || t == ')') { depth--; } else if (t == ',' && depth == 0) { foundSeperator = true; nextSeperatorIndex--; // it adds one to the index at the end of the while loop, but we need the index where we stopped searching, so we subtract 1 here to accommodate for that. } } nextSeperatorIndex++; } } var member = source.Substring(index, nextSeperatorIndex - index); if (member.Contains(":")) { identifier = member.Remove(member.IndexOf(":")).Trim(); content = member.Remove(0, member.IndexOf(":") + 1); contentObj = processor.ExecuteStatement(new ScriptStatement(content)); } else { identifier = member.Trim(); contentObj = processor.Undefined; } if (!ScriptProcessor.IsValidIdentifier(identifier)) { processor.ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_MISSING_VAR_NAME); } prototype.AddMember(processor, new PrototypeMember(identifier, contentObj)); index = nextSeperatorIndex + 1; } return(prototype.CreateInstance(processor, null, false)); }
private static string Interpolate(ScriptProcessor processor, string val) { // string interpolation // replaces the following pattern: {variable}. // {something} has to written as {{something}}. // string interpolation can be turned on by putting a $ in front of the string literal. if (val.Contains("{") && val.Contains("}")) { var searchOffset = 0; while (val.IndexOf("{", searchOffset) > -1 && val.IndexOf("}", searchOffset) > -1) { var startIndex = val.IndexOf("{", searchOffset); if (startIndex < val.Length - 2) { if (val[startIndex + 1] == '{') { val = val.Remove(startIndex + 1) + val.Remove(0, startIndex + 2); // find closing bracket and remove it: var level = 1; var i = startIndex + 1; var foundClosing = false; while (!foundClosing && i < val.Length) { var token = val[i]; switch (token) { case '{': level++; break; case '}': level--; if (level == 0) { val = val.Remove(i) + val.Remove(0, i + 1); foundClosing = true; } break; } i++; } searchOffset = startIndex + 1; } else { var endIndex = val.IndexOf("}", startIndex); if (endIndex > -1) { var interpolationSequence = val.Substring(startIndex, endIndex - startIndex + 1); interpolationSequence = processor.ExecuteStatement(new ScriptStatement(interpolationSequence.Remove(interpolationSequence.Length - 1, 1).Remove(0, 1))).ToString(processor).Value; val = val.Remove(startIndex) + interpolationSequence + val.Remove(0, endIndex + 1); searchOffset = startIndex + interpolationSequence.Length; } else { searchOffset = startIndex + 1; } } } } } return val; }
/// <summary> /// Parses an anonymous object. /// </summary> internal static SProtoObject Parse(ScriptProcessor processor, string source) { Prototype prototype = new Prototype(LITERAL_OBJECT); source = source.Trim(); // Format: { member1 : content1, member2 : content2 } // Remove "{" and "}": source = source.Remove(source.Length - 1, 1).Remove(0, 1).Trim(); if (source.Length == 0) return prototype.CreateInstance(processor, null, false); int index = 0; string identifier = ""; string content = ""; SObject contentObj = null; while (index < source.Length) { int nextSeperatorIndex = source.IndexOf(",", index); if (nextSeperatorIndex == -1) { nextSeperatorIndex = source.Length - 1; } else { //Let's find the correct ",": nextSeperatorIndex = index; int depth = 0; StringEscapeHelper escaper = new LeftToRightStringEscapeHelper(source, nextSeperatorIndex, true); bool foundSeperator = false; while (!foundSeperator && nextSeperatorIndex < source.Length) { char t = source[nextSeperatorIndex]; escaper.CheckStartAt(nextSeperatorIndex); if (!escaper.IsString) { if (t == '{' || t == '[' || t == '(') { depth++; } else if (t == '}' || t == ']' || t == ')') { depth--; } else if (t == ',' && depth == 0) { foundSeperator = true; nextSeperatorIndex--; // it adds one to the index at the end of the while loop, but we need the index where we stopped searching, so we subtract 1 here to accommodate for that. } } nextSeperatorIndex++; } } string member = source.Substring(index, nextSeperatorIndex - index); if (member.Contains(":")) { identifier = member.Remove(member.IndexOf(":")).Trim(); content = member.Remove(0, member.IndexOf(":") + 1); contentObj = processor.ExecuteStatement(new ScriptStatement(content)); } else { identifier = member.Trim(); contentObj = processor.Undefined; } if (!ScriptProcessor.IsValidIdentifier(identifier)) processor.ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_MISSING_VAR_NAME); prototype.AddMember(processor, new PrototypeMember(identifier, contentObj)); index = nextSeperatorIndex + 1; } return prototype.CreateInstance(processor, null, false); }