ThrowError() public method

Throws an error with the given ErrorType and error message.
public ThrowError ( ErrorType errorType, string message ) : SObject
errorType ErrorType
message string
return Pokemon3D.Scripting.Types.SObject
コード例 #1
0
        private SObject ExecuteImport(ScriptStatement statement)
        {
            // import apiClass from "moduleName"

            var exp   = statement.Code;
            var parts = exp.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length < 4 || parts[0] != "import" || parts[2] != "from")
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_INVALID_IMPORT_STATEMENT));
            }

            var apiClass   = parts[1];
            var moduleName = exp.Remove(0, exp.IndexOf("\""));

            moduleName = moduleName.Trim('\"');

            if (!IsValidIdentifier(apiClass))
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_MISSING_VAR_NAME));
            }

            var apiUsing = new SAPIUsing(apiClass, moduleName);

            Context.AddAPIUsing(apiUsing);
            return(apiUsing);
        }
コード例 #2
0
        private SObject ExecuteClass(ScriptStatement statement)
        {
            var exp = statement.Code;

            // The function's body is the next statement:

            _index++;

            if (_index < _statements.Length)
            {
                var classBodyStatement = _statements[_index];

                if (classBodyStatement.IsCompoundStatement)
                {
                    exp += classBodyStatement.Code;

                    var prototype = (Prototype)Prototype.Parse(this, exp);
                    Context.AddPrototype(prototype);

                    return(prototype);
                }
                else
                {
                    return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_COMPOUND, classBodyStatement.Code[0]));
                }
            }
            else
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "end of script"));
            }
        }
コード例 #3
0
        private SObject ExecuteVar(ScriptStatement statement)
        {
            var exp = statement.Code;

            var identifier = exp.Remove(0, "var ".Length).Trim();
            var data       = Undefined;

            if (identifier.Contains("="))
            {
                var assignment = identifier.Remove(0, identifier.IndexOf("=") + 1).Trim();
                identifier = identifier.Remove(identifier.IndexOf("=")).Trim();

                data = SObject.Unbox(ExecuteStatement(new ScriptStatement(assignment)));
            }

            if (!IsValidIdentifier(identifier))
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_MISSING_VAR_NAME));
            }

            var variable = new SVariable(identifier, data);

            Context.AddVariable(variable);

            return(variable);
        }
コード例 #4
0
        private SObject ExecuteElse(ScriptStatement statement)
        {
            // Search for an if statement:
            var searchIndex = _index - 2;
            var foundIf     = false;

            while (searchIndex >= 0 && !foundIf)
            {
                if (_statements[searchIndex].StatementType == StatementType.If)
                {
                    foundIf = true;
                }

                searchIndex -= 2;
            }

            if (!foundIf)
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "keyword \'else\'"));
            }

            _index++;

            if (_statements.Length > _index)
            {
                var executeStatement = _statements[_index];
                return(ExecuteStatement(executeStatement));
            }
            else
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "end of script"));
            }
        }
コード例 #5
0
        private SObject ExecuteLink(ScriptStatement statement)
        {
            if (Context.HasCallback(CallbackType.ScriptPipeline))
            {
                var exp = statement.Code;
                exp = exp.Remove(0, "link ".Length).Trim();

                var callback = (DScriptPipeline)Context.GetCallback(CallbackType.ScriptPipeline);
                var task     = Task <string> .Factory.StartNew(() => callback(this, exp));

                task.Wait();

                var code = task.Result;

                var statements = StatementProcessor.GetStatements(this, code);

                // Convert the current statements into a list, so we can modify them.
                var tempStatements = _statements.ToList();
                // Remove the "link" statement, because we don't want to step into it again if we are in a loop.
                tempStatements.RemoveAt(_index);

                // Insert class, using and link statements right after the current statement.
                var insertIndex = _index;

                for (var i = 0; i < statements.Length; i++)
                {
                    if (statements[i].StatementType == StatementType.Class)
                    {
                        // The class statement needs its body, so we add the class statement and the one afterwards:
                        if (statements.Length > i + 1)
                        {
                            tempStatements.Insert(insertIndex, statements[i]);
                            tempStatements.Insert(insertIndex + 1, statements[i + 1]);

                            insertIndex += 2;
                        }
                        else
                        {
                            ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "end of script");
                        }
                    }
                    else if (statements[i].StatementType == StatementType.Import || statements[i].StatementType == StatementType.Link)
                    {
                        tempStatements.Insert(insertIndex, statements[i]);
                        insertIndex += 1;
                    }
                }

                // Convert the temp statement list back and reduce the index by one, because we deleted the current statement.
                _statements = tempStatements.ToArray();
                _index--;

                return(Undefined);
            }
            else
            {
                return(ErrorHandler.ThrowError(ErrorType.APIError, ErrorHandler.MESSAGE_API_NOT_SUPPORTED));
            }
        }
コード例 #6
0
        private SObject ExecuteWhile(ScriptStatement statement)
        {
            var exp = statement.Code;

            var condition = exp.Remove(0, exp.IndexOf("while") + "while".Length).Trim().Remove(0, 1); // Remove "while" and "(".

            condition = condition.Remove(condition.Length - 1, 1).Trim();                             // Remove ")".

            if (condition.Length == 0)
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, ")"));
            }

            _index++;

            if (_statements.Length > _index)
            {
                var stayInWhile      = true;
                var executeStatement = _statements[_index];
                var returnObject     = Undefined;

                while (stayInWhile)
                {
                    var conditionResult = ExecuteStatement(new ScriptStatement(condition));

                    if (conditionResult is SBool)
                    {
                        stayInWhile = ((SBool)conditionResult).Value;
                    }
                    else
                    {
                        stayInWhile = conditionResult.ToBool(this).Value;
                    }

                    if (stayInWhile)
                    {
                        returnObject = ExecuteStatement(executeStatement);

                        if (_returnIssued || _breakIssued)
                        {
                            _breakIssued = false;
                            stayInWhile  = false;
                        }
                    }
                }

                return(returnObject);
            }
            else
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "end of script"));
            }
        }
コード例 #7
0
        private SObject ExecuteElseIf(ScriptStatement statement)
        {
            // Search for an if statement:
            var searchIndex = _index - 2;
            var foundIf     = false;

            while (searchIndex >= 0 && !foundIf)
            {
                if (_statements[searchIndex].StatementType == StatementType.If)
                {
                    foundIf = true;
                }

                searchIndex -= 2;
            }

            return(foundIf ?
                   ExecuteIf(statement) :
                   ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "keyword \'else if\'"));
        }
コード例 #8
0
        private SObject ExecuteFunction(ScriptStatement statement)
        {
            // function <name> ()
            var exp = statement.Code;

            exp = exp.Remove(0, "function".Length).Trim();
            var functionName = exp.Remove(exp.IndexOf("("));

            if (!IsValidIdentifier(functionName))
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_MISSING_VAR_NAME));
            }

            var functionExpression = "function " + exp.Remove(0, exp.IndexOf("("));

            // The function's body is the next statement:

            _index++;

            if (_index < _statements.Length)
            {
                var functionBodyStatement = _statements[_index];

                var functionBody = functionBodyStatement.Code;
                if (!functionBodyStatement.IsCompoundStatement)
                {
                    functionBody = "{" + functionBody + "}";
                }

                functionExpression += functionBody;

                var function = new SFunction(this, functionExpression);
                Context.AddVariable(functionName, function);

                return(function);
            }
            else
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "end of script"));
            }
        }
コード例 #9
0
        private SObject ExecuteThrow(ScriptStatement statement)
        {
            var exp = statement.Code;

            if (exp == "throw")
            {
                return(ErrorHandler.ThrowError(ErrorType.UserError, ErrorHandler.MESSAGE_USER_ERROR));
            }
            else
            {
                exp = exp.Remove(0, "throw ".Length).Trim();

                var errorObject = ExecuteStatement(new ScriptStatement(exp));

                // Set the line number if the object is an error object:
                if (errorObject.TypeOf() == SObject.LITERAL_TYPE_ERROR)
                {
                    ((SError)errorObject).SetMember(ErrorPrototype.MEMBER_NAME_LINE, CreateNumber(GetLineNumber()));
                }

                return(ErrorHandler.ThrowError(errorObject));
            }
        }
コード例 #10
0
        private SObject ExecuteAssignment(ScriptStatement statement)
        {
            var exp = statement.Code;

            var leftSide           = "";
            var rightSide          = "";
            var assignmentOperator = "";

            // Get left and right side of the assignment:
            {
                var depth = 0;
                var index = 0;
                StringEscapeHelper escaper = new LeftToRightStringEscapeHelper(exp, 0);

                while (index < exp.Length && assignmentOperator.Length == 0)
                {
                    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)
                        {
                            var previous = ' ';
                            if (index > 0)
                            {
                                previous = exp[index - 1];
                            }

                            if (previous == '+' || previous == '-' || previous == '/' || previous == '*')
                            {
                                assignmentOperator = previous.ToString();
                                leftSide           = exp.Substring(0, index - 1).TrimEnd();
                            }
                            else
                            {
                                assignmentOperator = "=";
                                leftSide           = exp.Substring(0, index).TrimEnd();
                            }

                            rightSide = exp.Substring(index + 1).TrimStart();
                        }
                    }

                    index++;
                }
            }

            // This means it's a function call, which cannot be assigned to:
            if (leftSide.EndsWith(")") || leftSide.Length == 0)
            {
                return(ErrorHandler.ThrowError(ErrorType.ReferenceError, ErrorHandler.MESSAGE_REFERENCE_INVALID_ASSIGNMENT_LEFT));
            }

            SObject memberHost = null;
            SObject accessor   = null;
            SObject value      = null;
            var     isIndexer  = false;
            var     host       = "";
            var     member     = "";

            if (leftSide.EndsWith("]"))
            {
                var indexerStartIndex = 0;
                var index             = leftSide.Length - 1;
                var depth             = 0;

                StringEscapeHelper escaper = new RightToLeftStringEscapeHelper(leftSide, index);
                while (index > 0 && !isIndexer)
                {
                    var t = leftSide[index];
                    escaper.CheckStartAt(index);

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

                    index--;
                }

                if (isIndexer)
                {
                    member = leftSide.Substring(indexerStartIndex + 1);
                    member = member.Remove(member.Length - 1, 1);
                    host   = leftSide.Remove(indexerStartIndex);
                }
            }
            else
            {
                var foundMember = false;

                if (leftSide.Contains("."))
                {
                    var index = leftSide.Length - 1;
                    var depth = 0;
                    StringEscapeHelper escaper = new RightToLeftStringEscapeHelper(leftSide, index);

                    while (index > 0 && !foundMember)
                    {
                        var t = leftSide[index];
                        escaper.CheckStartAt(index);

                        if (!escaper.IsString)
                        {
                            if (t == '(' || t == '[' || t == '{')
                            {
                                depth--;
                            }
                            else if (t == ')' || t == ']' || t == '}')
                            {
                                depth++;
                            }
                            else if (t == '.' && depth == 0)
                            {
                                foundMember = true;
                                host        = leftSide.Substring(0, index);
                                member      = leftSide.Remove(0, index + 1);
                            }
                        }

                        index--;
                    }
                }

                if (!foundMember)
                {
                    host   = SObject.LITERAL_THIS;
                    member = leftSide;
                }
            }

            // When it's an indexer, we parse it as statement:
            accessor = isIndexer ? SObject.Unbox(ExecuteStatement(new ScriptStatement(member))) : CreateString(member);

            memberHost = ExecuteStatement(new ScriptStatement(host));
            value      = SObject.Unbox(ExecuteStatement(new ScriptStatement(rightSide)));

            if (assignmentOperator == "=")
            {
                memberHost.SetMember(this, accessor, isIndexer, value);
            }
            else
            {
                var memberContent = memberHost.GetMember(this, accessor, isIndexer);

                var result = "";

                switch (assignmentOperator)
                {
                case "+":
                    result = ObjectOperators.AddOperator(this, memberContent, value);
                    break;

                case "-":
                    result = ObjectOperators.SubtractOperator(this, memberContent, value);
                    break;

                case "*":
                    result = ObjectOperators.MultiplyOperator(this, memberContent, value);
                    break;

                case "/":
                    result = ObjectOperators.DivideOperator(this, memberContent, value);
                    break;
                }

                memberHost.SetMember(this, accessor, isIndexer, ToScriptObject(result));
            }

            return(value);
        }
コード例 #11
0
        private SObject ExecuteFor(ScriptStatement statement)
        {
            var exp = statement.Code;

            var forCode = exp.Remove(0, exp.IndexOf("for") + "for".Length).Trim().Remove(0, 1); // Remove "for" and "(".

            forCode = forCode.Remove(forCode.Length - 1, 1);                                    // Remove ")".

            var forStatements = StatementProcessor.GetStatements(this, forCode);

            if (forStatements.Length == 0)
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, ")"));
            }
            else if (forStatements.Length == 1)
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_MISSING_FOR_INITIALIZER));
            }
            else if (forStatements.Length == 2)
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_MISSING_FOR_CONDITION));
            }
            else if (forStatements.Length > 3)
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_MISSING_FOR_CONTROL));
            }

            var processor = new ScriptProcessor(Context, GetLineNumber());

            var forInitializer = forStatements[0];
            var forCondition   = forStatements[1];
            var forControl     = forStatements[2];

            if (forInitializer.Code.Length > 0)
            {
                processor.ExecuteStatement(forInitializer);
            }

            _index++;

            if (_statements.Length > _index)
            {
                var stayInFor        = true;
                var executeStatement = _statements[_index];
                var returnObject     = Undefined;

                while (stayInFor)
                {
                    if (forCondition.Code.Length > 0)
                    {
                        var conditionResult = processor.ExecuteStatement(forCondition);

                        if (conditionResult is SBool)
                        {
                            stayInFor = ((SBool)conditionResult).Value;
                        }
                        else
                        {
                            stayInFor = conditionResult.ToBool(this).Value;
                        }
                    }

                    if (stayInFor)
                    {
                        returnObject = processor.ExecuteStatement(executeStatement);

                        if (processor._returnIssued || processor._breakIssued)
                        {
                            _breakIssued  = false;
                            _returnIssued = processor._returnIssued;
                            stayInFor     = false;
                        }
                        else if (forControl.Code.Length > 0)
                        {
                            processor.ExecuteStatement(forControl);
                        }
                    }
                }

                return(returnObject);
            }
            else
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "end of script"));
            }
        }
コード例 #12
0
ファイル: ScriptProcessor.cs プロジェクト: JoNMii/Pokemon3D
        private SObject InvokeMethod(SObject owner, string methodName)
        {
            var exp   = methodName;
            var index = exp.Length - 1;
            var argumentStartIndex = -1;
            var This = owner;

            if (exp.EndsWith("()"))
            {
                argumentStartIndex = exp.Length - 2;
                index = argumentStartIndex - 1;
            }
            else
            {
                var depth                  = 0;
                var foundArguments         = false;
                StringEscapeHelper escaper = new RightToLeftStringEscapeHelper(exp, index);

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

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

                        if (depth == 0)
                        {
                            if (index > 0)
                            {
                                foundArguments     = true;
                                argumentStartIndex = index;
                            }
                        }
                    }

                    index--;
                }
            }

            methodName = exp.Remove(argumentStartIndex);
            var argumentCode = exp.Remove(0, argumentStartIndex + 1);

            argumentCode = argumentCode.Remove(argumentCode.Length - 1, 1).Trim();
            var parameters = ParseParameters(argumentCode);

            if (methodName == CALL_LITERAL && owner is SFunction)
            {
                This = Context.This;
            }

            // If it has an indexer, parse it again:
            if (index > 0 && exp[index] == ']')
            {
                var member = InvokeMemberOrMethod(owner, methodName);

                if ((member as SVariable)?.Data is SFunction)
                {
                    return(owner.ExecuteMethod(this, ((SVariable)member).Identifier, owner, This, parameters));
                }
                else
                {
                    return(ErrorHandler.ThrowError(ErrorType.TypeError, ErrorHandler.MESSAGE_TYPE_NOT_A_FUNCTION, methodName));
                }
            }
            else
            {
                return(owner.ExecuteMethod(this, methodName, owner, This, parameters));
            }
        }
コード例 #13
0
 private SObject ExecuteFinally(ScriptStatement statement)
 {
     // The script processor can only reach this, when a finally statement exists without a try statement:
     return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_FINALLY_WITHOUT_TRY));
 }
コード例 #14
0
ファイル: ScriptProcessor.cs プロジェクト: JoNMii/Pokemon3D
        /// <summary>
        /// Converts a string expression into a script object.
        /// </summary>
        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:

                    var depth                  = 0;
                    var index                  = exp.Length - 2;
                    var indexerStartIndex      = 0;
                    var foundIndexer           = false;
                    StringEscapeHelper escaper = new RightToLeftStringEscapeHelper(exp, index);

                    while (index > 0 && !foundIndexer)
                    {
                        var 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;
                                        foundIndexer      = true;
                                    }
                                }
                                else
                                {
                                    depth--;
                                }
                            }
                        }

                        index--;
                    }

                    if (foundIndexer)
                    {
                        var indexerCode = exp.Substring(indexerStartIndex + 1, exp.Length - indexerStartIndex - 2);

                        var identifier = exp.Remove(indexerStartIndex);

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

            // Normal object return procedure:

            // Negative number:
            var 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, false);
            }
            else if (exp.StartsWith("$\"") && exp.EndsWith("\"") || exp.StartsWith("$\'") && exp.EndsWith("\'"))
            {
                returnObject = CreateString(exp.Remove(exp.Length - 1, 1).Remove(0, 2), true, true);
            }
            else if (exp.StartsWith("@\"") && exp.EndsWith("\"") || exp.StartsWith("@\'") && exp.EndsWith("\'"))
            {
                returnObject = CreateString(exp.Remove(exp.Length - 1, 1).Remove(0, 2), false, 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(ObjectBuffer.OBJ_PREFIX))
            {
                var strId = exp.Remove(0, ObjectBuffer.OBJ_PREFIX.Length);
                var 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, exp);
                }
            }
            else
            {
                returnObject = ErrorHandler.ThrowError(ErrorType.ReferenceError, ErrorHandler.MESSAGE_REFERENCE_NOT_DEFINED, exp);
            }

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

            return(returnObject);
        }
コード例 #15
0
ファイル: ScriptProcessor.cs プロジェクト: JoNMii/Pokemon3D
        private string EvaluateOperator(string exp, string op)
        {
            var ops = GetOperatorPositions(exp, op);

            for (var i = 0; i < ops.Length; i++)
            {
                var cOp = ops[i];

                var needRight = !(op == "++" || op == "--");

                var captureLeft = CaptureLeft(exp, cOp - 1);
                var elementLeft = captureLeft.Identifier.Trim();

                if (!(op == "-" && elementLeft.Length == 0))
                {
                    var result = "";

                    if (string.IsNullOrWhiteSpace(elementLeft))
                    {
                        ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, op);
                    }

                    var objectLeft = ToScriptObject(elementLeft);

                    ElementCapture captureRight;
                    string         elementRight;
                    SObject        objectRight = null;

                    if (needRight)
                    {
                        captureRight = CaptureRight(exp, cOp + op.Length);
                        elementRight = captureRight.Identifier.Trim();

                        if (string.IsNullOrWhiteSpace(elementRight))
                        {
                            ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "end of script");
                        }

                        if (op != ".")
                        {
                            objectRight = ToScriptObject(elementRight);
                        }
                    }
                    else
                    {
                        elementRight = "";
                        captureRight = new ElementCapture()
                        {
                            Length = 0
                        };
                    }

                    if (op != "." || !IsDotOperatorDecimalSeparator(elementLeft, elementRight))
                    {
                        switch (op)
                        {
                        case ".":
                            result = InvokeMemberOrMethod(objectLeft, elementRight).ToScriptObject();
                            break;

                        case "+":
                            result = ObjectOperators.AddOperator(this, objectLeft, objectRight);
                            break;

                        case "-":
                            result = ObjectOperators.SubtractOperator(this, objectLeft, objectRight);
                            break;

                        case "*":
                            result = ObjectOperators.MultiplyOperator(this, objectLeft, objectRight);
                            break;

                        case "/":
                            result = ObjectOperators.DivideOperator(this, objectLeft, objectRight);
                            break;

                        case "%":
                            result = ObjectOperators.ModulusOperator(this, objectLeft, objectRight);
                            break;

                        case "**":
                            result = ObjectOperators.ExponentOperator(this, objectLeft, objectRight);
                            break;

                        case "==":
                            result = ObjectOperators.EqualsOperator(this, objectLeft, objectRight);
                            break;

                        case "===":
                            result = ObjectOperators.TypeEqualsOperator(this, objectLeft, objectRight);
                            break;

                        case "!=":
                            result = ObjectOperators.NotEqualsOperator(this, objectLeft, objectRight);
                            break;

                        case "!==":
                            result = ObjectOperators.TypeNotEqualsOperator(this, objectLeft, objectRight);
                            break;

                        case "<=":
                            result = ObjectOperators.SmallerOrEqualsOperator(this, objectLeft, objectRight);
                            break;

                        case "<":
                            result = ObjectOperators.SmallerOperator(this, objectLeft, objectRight);
                            break;

                        case ">=":
                            result = ObjectOperators.LargerOrEqualsOperator(this, objectLeft, objectRight);
                            break;

                        case ">":
                            result = ObjectOperators.LargerOperator(this, objectLeft, objectRight);
                            break;

                        case "&&":
                            result = ObjectOperators.AndOperator(this, objectLeft, objectRight);
                            break;

                        case "||":
                            result = ObjectOperators.OrOperator(this, objectLeft, objectRight);
                            break;

                        case "++":
                            result = ObjectOperators.IncrementOperator(this, objectLeft);
                            break;

                        case "--":
                            result = ObjectOperators.DecrementOperator(this, objectLeft);
                            break;
                        }

                        exp = exp.Remove(captureLeft.StartIndex, op.Length + captureLeft.Length + captureRight.Length);
                        exp = exp.Insert(captureLeft.StartIndex, result);

                        var offset = result.Length - (op.Length + captureLeft.Length + captureRight.Length);
                        for (var j = i + 1; j < ops.Length; j++)
                        {
                            ops[j] += offset;
                        }
                    }
                }
            }

            return(exp);
        }
コード例 #16
0
        private SObject ExecuteIf(ScriptStatement statement)
        {
            var exp = statement.Code;

            var condition = exp.Remove(0, exp.IndexOf("if") + "if".Length).Trim().Remove(0, 1); // Remove "if" and "(".

            condition = condition.Remove(condition.Length - 1, 1).Trim();                       // Remove ")".

            if (condition.Length == 0)
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, ")"));
            }

            var conditionResult = ExecuteStatement(new ScriptStatement(condition));

            statement.StatementResult = conditionResult;

            bool conditionEval;

            if (conditionResult is SBool)
            {
                conditionEval = ((SBool)conditionResult).Value;
            }
            else
            {
                conditionEval = conditionResult.ToBool(this).Value;
            }

            _index++;

            if (_statements.Length > _index)
            {
                var executeStatement = _statements[_index];

                if (conditionEval)
                {
                    var returnObject = ExecuteStatement(executeStatement);

                    // Jump over all "else if" and "else" statements that follow this if / else if:

                    var searchIndex = _index + 1;
                    var foundIfs    = true;

                    while (searchIndex < _statements.Length && foundIfs)
                    {
                        if (_statements[searchIndex].StatementType == StatementType.ElseIf || _statements[searchIndex].StatementType == StatementType.Else)
                        {
                            _index += 2;
                        }
                        else
                        {
                            foundIfs = false;
                        }

                        searchIndex += 2;
                    }

                    return(returnObject);
                }
                else
                {
                    return(Undefined);
                }
            }
            else
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "end of script"));
            }
        }
コード例 #17
0
        private SObject ExecuteTry(ScriptStatement statement)
        {
            var exp = statement.Code;

            if (exp != "try")
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_MISSING_BEFORE_TRY));
            }

            _index++;
            if (_statements.Length > _index)
            {
                var     executeStatement   = _statements[_index];
                var     encounteredError   = false;
                var     foundCatch         = false;
                var     foundFinally       = false;
                var     foundMatchingCatch = false;
                SObject errorObject        = null;
                var     returnObject       = Undefined;

                try
                {
                    returnObject = ExecuteStatement(executeStatement);
                }
                catch (ScriptException ex)
                {
                    encounteredError = true;
                    errorObject      = ex.ErrorObject;
                }

                if (encounteredError)
                {
                    var endedCatchSearch = false;
                    var findCatchIndex   = _index + 1;
                    while (findCatchIndex < _statements.Length && !endedCatchSearch)
                    {
                        if (_statements[findCatchIndex].StatementType == StatementType.Catch)
                        {
                            _index = findCatchIndex + 1;

                            if (_statements.Length > _index)
                            {
                                if (!foundMatchingCatch)
                                {
                                    var catchExecuteStatement = _statements[_index];
                                    foundCatch = true;

                                    var catchCode    = _statements[findCatchIndex].Code;
                                    var errorVarName = "";

                                    if (catchCode != "catch")
                                    {
                                        catchCode    = catchCode.Remove(0, "catch".Length).Trim().Remove(0, 1);
                                        catchCode    = catchCode.Remove(catchCode.Length - 1, 1);
                                        errorVarName = catchCode.Trim();
                                    }

                                    if (Regex.IsMatch(catchCode, REGEX_CATCHCONDITION))
                                    {
                                        errorVarName = catchCode.Remove(catchCode.IndexOf(" "));
                                        string conditionCode = catchCode.Remove(0, catchCode.IndexOf("if") + 3);

                                        var processor = new ScriptProcessor(Context, GetLineNumber());
                                        processor.Context.AddVariable(errorVarName, errorObject);

                                        var conditionResult = processor.ExecuteStatement(new ScriptStatement(conditionCode));

                                        if (conditionResult is SBool)
                                        {
                                            foundMatchingCatch = ((SBool)conditionResult).Value;
                                        }
                                        else
                                        {
                                            foundMatchingCatch = conditionResult.ToBool(this).Value;
                                        }

                                        if (foundMatchingCatch)
                                        {
                                            returnObject = processor.ExecuteStatement(catchExecuteStatement);
                                        }
                                    }
                                    else
                                    {
                                        foundMatchingCatch = true;
                                        var processor = new ScriptProcessor(Context, GetLineNumber());
                                        processor.Context.AddVariable(errorVarName, errorObject);
                                        returnObject = processor.ExecuteStatement(catchExecuteStatement);
                                    }
                                }
                            }
                            else
                            {
                                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "end of script"));
                            }
                        }
                        else
                        {
                            // end search if different statement type appears:
                            endedCatchSearch = true;
                        }

                        findCatchIndex += 2;
                    }
                }
                else
                {
                    var findCatchIndex = _index + 1;
                    while (findCatchIndex < _statements.Length)
                    {
                        if (_statements[findCatchIndex].StatementType == StatementType.Catch)
                        {
                            foundCatch = true;
                            _index     = findCatchIndex + 1;
                        }
                        else
                        {
                            findCatchIndex = _statements.Length;
                        }

                        findCatchIndex += 2;
                    }
                }

                // if no matching catch was found when an error occurred, it was not caught: throw it!
                if (encounteredError && !foundMatchingCatch)
                {
                    return(ErrorHandler.ThrowError(errorObject));
                }

                // now, try to find finally statement:
                var findFinallyIndex = _index + 1;
                while (findFinallyIndex < _statements.Length && !foundFinally)
                {
                    if (_statements[findFinallyIndex].StatementType == StatementType.Finally)
                    {
                        _index = findFinallyIndex + 1;

                        if (_statements.Length > _index)
                        {
                            var finallyExecuteStatement = _statements[_index];
                            foundFinally = true;

                            returnObject = ExecuteStatement(finallyExecuteStatement);
                        }
                        else
                        {
                            return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "end of script"));
                        }
                    }
                    else
                    {
                        findFinallyIndex = _statements.Length;
                    }

                    findFinallyIndex += 2;
                }

                if (!foundCatch && !foundFinally) // when no catch or finally block has been found, throw an error.
                {
                    return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_MISSING_CATCH_OR_FINALLY));
                }
                else
                {
                    return(returnObject);
                }
            }
            else
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "end of script"));
            }
        }
コード例 #18
0
ファイル: ScriptProcessor.cs プロジェクト: JoNMii/Pokemon3D
        private SObject InvokeMember(SObject owner, string memberName)
        {
            // When we have an indexer at the end of the member name, we get the member variable, then apply the indexer:

            if (memberName.Last() == ']')
            {
                var exp = memberName;

                var depth             = 0;
                var index             = exp.Length - 2;
                var indexerStartIndex = 0;
                var foundIndexer      = false;
                var escaper           = new RightToLeftStringEscapeHelper(exp, index);

                while (index > 0 && !foundIndexer)
                {
                    var 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;
                                    foundIndexer      = true;
                                }
                            }
                            else
                            {
                                depth--;
                            }
                        }
                    }
                }

                if (foundIndexer)
                {
                    var indexerCode = exp.Substring(indexerStartIndex + 1, exp.Length - indexerStartIndex - 2);
                    var identifier  = exp.Remove(indexerStartIndex);

                    var indexerObject = ExecuteStatement(new ScriptStatement(indexerCode));

                    return(InvokeMemberOrMethod(owner, identifier).GetMember(this, indexerObject, true));
                }
                else
                {
                    return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_EXPECTED_EXPRESSION, "end of string"));
                }
            }
            else
            {
                return(owner.GetMember(this, CreateString(memberName), false));
            }
        }