Пример #1
0
        /// <summary>
        /// Captures an element left from the starting index.
        /// </summary>
        private ElementCapture CaptureLeft(string exp, int index)
        {
            if (string.IsNullOrWhiteSpace(exp))
                return new ElementCapture() { Length = 0, StartIndex = 0, Identifier = "", Depth = 0 };

            string identifier = "";
            bool foundSeperatorChar = false;
            int depth = 0;
            StringEscapeHelper escaper = new RightToLeftStringEscapeHelper(exp, index);

            while (index >= 0 && !foundSeperatorChar)
            {
                char t = exp[index];
                escaper.CheckStartAt(index);

                if (!escaper.IsString)
                {
                    if (t == ')' || t == ']' || t == '}')
                    {
                        depth++;
                    }
                    else if (t == '(' || t == '[' || t == '{')
                    {
                        depth--;
                    }
                }

                if (depth < 0)
                {
                    // this is when we walk out of the capture area because we are inside some area and a )]} appeared.
                    foundSeperatorChar = true;
                }
                else
                {
                    if (!escaper.IsString && depth == 0)
                    {
                        if (t == '.')
                        {
                            // Check if the '.' is not a decimal seperator:
                            if (!Regex.IsMatch(identifier.Trim(), REGEX_NUMRIGHTDOT))
                            {
                                foundSeperatorChar = true;
                            }
                        }
                        else if (IDENTIFIER_SEPERATORS.Contains(t))
                        {
                            foundSeperatorChar = true;
                        }
                    }

                    // Append the char to the identifier:
                    if (!foundSeperatorChar)
                    {
                        identifier = t + identifier;
                    }
                }

                index--;
            }

            // Check for a minus in front of the identifier to indicate a negative number:
            if (index >= -1 && exp[index + 1] == '-' && !string.IsNullOrWhiteSpace(identifier))
            {
                identifier = "-" + identifier;
                index--;
            }

            if (foundSeperatorChar)
                return new ElementCapture() { StartIndex = index + 2, Length = identifier.Length, Identifier = identifier, Depth = depth };
            else
                return new ElementCapture() { StartIndex = index + 1, Length = identifier.Length, Identifier = identifier, Depth = depth };
        }
Пример #2
0
        private SObject ToScriptObject(string exp)
        {
            exp = exp.Trim();

            // This means it's either an indexer or an array
            if (exp.EndsWith("]"))
            {
                if (!(exp.StartsWith("[") && !exp.Remove(0, 1).Contains("["))) // When there's no "[" besides the start, and it starts with [, then it is an array. Otherwise, do real check.
                {
                    // It is possible that we are having a simple array declaration here.
                    // We check that by looking if we can find a "[" before the expression ends:

                    int depth = 0;
                    int index = exp.Length - 2;
                    int indexerStartIndex = 0;
                    bool hasIndexer = false;
                    StringEscapeHelper escaper = new RightToLeftStringEscapeHelper(exp, index);

                    while (index > 0 && !hasIndexer)
                    {
                        char t = exp[index];
                        escaper.CheckStartAt(index);

                        if (!escaper.IsString)
                        {
                            if (t == ')' || t == '}' || t == ']')
                            {
                                depth++;
                            }
                            else if (t == '(' || t == '{')
                            {
                                depth--;
                            }
                            else if (t == '[')
                            {
                                if (depth == 0)
                                {
                                    if (index > 0)
                                    {
                                        indexerStartIndex = index;
                                        hasIndexer = true;
                                    }
                                }
                                else
                                {
                                    depth--;
                                }
                            }
                        }
                    }

                    if (hasIndexer)
                    {
                        string indexerCode = exp.Remove(0, indexerStartIndex + 1);
                        indexerCode = indexerCode.Remove(indexerCode.Length - 1, 1);

                        string identifier = exp.Remove(indexerStartIndex);

                        SObject statementResult = ExecuteStatement(new ScriptStatement(indexerCode));
                        return ToScriptObject(identifier).GetMember(this, statementResult, true);
                    }
                }
            }

            // Normal object return procedure:

            // Negative number:
            bool isNegative = false;
            if (exp.StartsWith("-"))
            {
                exp = exp.Remove(0, 1);
                isNegative = true;
            }

            double dblResult;
            SObject returnObject;

            if (exp == SObject.LITERAL_NULL)
            {
                returnObject = Null;
            }
            else if (exp == SObject.LITERAL_UNDEFINED)
            {
                returnObject = Undefined;
            }
            else if (exp == SObject.LITERAL_BOOL_FALSE)
            {
                returnObject = CreateBool(false);
            }
            else if (exp == SObject.LITERAL_BOOL_TRUE)
            {
                returnObject = CreateBool(true);
            }
            else if (exp == SObject.LITERAL_NAN)
            {
                returnObject = CreateNumber(double.NaN);
            }
            else if (exp == SObject.LITERAL_THIS)
            {
                returnObject = Context.This;
            }
            else if (SNumber.TryParse(exp, out dblResult))
            {
                returnObject = CreateNumber(dblResult);
            }
            else if (exp.StartsWith("\"") && exp.EndsWith("\"") || exp.StartsWith("\'") && exp.EndsWith("\'"))
            {
                returnObject = CreateString(exp.Remove(exp.Length - 1, 1).Remove(0, 1), true);
            }
            else if (exp.StartsWith("@\"") && exp.EndsWith("\"") || exp.StartsWith("@\'") && exp.EndsWith("\'"))
            {
                returnObject = CreateString(exp.Remove(exp.Length - 1, 1).Remove(0, 2), false);
            }
            else if (exp.StartsWith("{") && exp.EndsWith("}"))
            {
                returnObject = SProtoObject.Parse(this, exp);
            }
            else if (exp.StartsWith("[") && exp.EndsWith("]"))
            {
                returnObject = SArray.Parse(this, exp);
            }
            else if (exp.StartsWith("function") && Regex.IsMatch(exp, REGEX_FUNCTION))
            {
                returnObject = new SFunction(this, exp);
            }
            else if (Context.IsAPIUsing(exp))
            {
                returnObject = Context.GetAPIUsing(exp);
            }
            else if (Context.IsVariable(exp))
            {
                returnObject = Context.GetVariable(exp);
            }
            else if (Context.This.HasMember(this, exp))
            {
                returnObject = Context.This.GetMember(this, CreateString(exp), false);
            }
            else if (Context.IsPrototype(exp))
            {
                returnObject = Context.GetPrototype(exp);
            }
            else if (exp.StartsWith("new "))
            {
                returnObject = Context.CreateInstance(exp);
            }
            else if (exp.StartsWith("$"))
            {
                string strId = exp.Remove(0, 1);
                int id = 0;

                if (int.TryParse(strId, out id) && ObjectBuffer.HasObject(id))
                {
                    returnObject = (SObject)ObjectBuffer.GetObject(id);
                }
                else
                {
                    returnObject = ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_INVALID_TOKEN, new object[] { exp });
                }
            }
            else
            {
                returnObject = ErrorHandler.ThrowError(ErrorType.ReferenceError, ErrorHandler.MESSAGE_REFERENCE_NOT_DEFINED, new object[] { exp });
            }

            if (isNegative)
                returnObject = ObjectOperators.NegateNumber(this, returnObject);

            return returnObject;
        }