Example #1
0
        public ScriptVarLink AddChildNoDup(String childName, ScriptVar child)
        {
            ScriptVar c = child ?? new ScriptVar();

            ScriptVarLink v = FindChild(childName);

            if (v != null)
            {
                v.ReplaceWith(c);
            }
            else
            {
                v = AddChild(childName, c);
            }

            return(v);
        }
Example #2
0
        public void SetArrayIndex(Int32 idx, ScriptVar value)
        {
            ScriptVarLink link = FindChild(String.Format("{0}", idx));

            if (link != null)
            {
                if (value.IsUndefined)
                {
                    RemoveLink(link);
                }
                else
                {
                    link.ReplaceWith(value);
                }
            }
            else
            {
                if (!value.IsUndefined)
                {
                    AddChild(String.Format("{0}", idx), value);
                }
            }
        }
        private void Statement(ref bool execute)
        {
            if (_currentLexer.TokenType == ScriptLex.LexTypes.Id ||
                _currentLexer.TokenType == ScriptLex.LexTypes.Int ||
                _currentLexer.TokenType == ScriptLex.LexTypes.Float ||
                _currentLexer.TokenType == ScriptLex.LexTypes.Str ||
                _currentLexer.TokenType == (ScriptLex.LexTypes) '-')
            {
                //execite a basic statement
                Base(ref execute);
                _currentLexer.Match((ScriptLex.LexTypes) ';');
            }
            else if (_currentLexer.TokenType == (ScriptLex.LexTypes) '{')
            {
                //code block
                Block(ref execute);
            }
            else if (_currentLexer.TokenType == (ScriptLex.LexTypes) ';')
            {
                //allow for multiple semi colon such as ;;;
                _currentLexer.Match((ScriptLex.LexTypes) ';');
            }
            else if (_currentLexer.TokenType == ScriptLex.LexTypes.RVar)
            {
                //creating variables
                //TODO: make this less shit

                _currentLexer.Match(ScriptLex.LexTypes.RVar);

                while (_currentLexer.TokenType != (ScriptLex.LexTypes) ';')
                {
                    ScriptVarLink a = null;
                    if (execute)
                    {
                        a = _scopes.Peek().FindChildOrCreate(_currentLexer.TokenString);
                    }

                    _currentLexer.Match(ScriptLex.LexTypes.Id);

                    //get through the dots
                    while (_currentLexer.TokenType == (ScriptLex.LexTypes) '.')
                    {
                        _currentLexer.Match((ScriptLex.LexTypes) '.');
                        if (execute)
                        {
                            ScriptVarLink aLast = a;
                            if (aLast != null)
                            {
                                a = aLast.Var.FindChildOrCreate(_currentLexer.TokenString);
                            }
                        }

                        _currentLexer.Match(ScriptLex.LexTypes.Id);
                    }

                    //initialiser
                    if (_currentLexer.TokenType == (ScriptLex.LexTypes) '=')
                    {
                        _currentLexer.Match((ScriptLex.LexTypes) '=');
                        ScriptVarLink varLink = Base(ref execute);
                        if (execute)
                        {
                            if (a != null)
                            {
                                a.ReplaceWith(varLink);
                            }
                        }
                    }

                    if (_currentLexer.TokenType != (ScriptLex.LexTypes) ';')
                    {
                        _currentLexer.Match((ScriptLex.LexTypes) ',');
                    }
                }

                _currentLexer.Match((ScriptLex.LexTypes) ';');
            }
            else if (_currentLexer.TokenType == ScriptLex.LexTypes.RIf)
            {
                //if condition
                _currentLexer.Match(ScriptLex.LexTypes.RIf);
                _currentLexer.Match((ScriptLex.LexTypes) '(');
                ScriptVarLink varLink = Base(ref execute);
                _currentLexer.Match((ScriptLex.LexTypes) ')');

                bool condition = execute && varLink.Var.GetBool();
                bool noExecute = false;
                if (condition)
                {
                    Statement(ref execute);
                }
                else
                {
                    Statement(ref noExecute);
                }

                if (_currentLexer.TokenType == ScriptLex.LexTypes.RElse)
                {
                    //else part of an if
                    _currentLexer.Match(ScriptLex.LexTypes.RElse);

                    if (condition)
                    {
                        Statement(ref noExecute);
                    }
                    else
                    {
                        Statement(ref execute);
                    }
                }
            }
            else if (_currentLexer.TokenType == ScriptLex.LexTypes.RWhile)
            {
                //while loop
                _currentLexer.Match(ScriptLex.LexTypes.RWhile);
                _currentLexer.Match((ScriptLex.LexTypes) '(');

                Int32         whileConditionStart = _currentLexer.TokenStart;
                ScriptVarLink condition           = Base(ref execute);
                bool          loopCondition       = execute && condition.Var.GetBool();

                ScriptLex whileCond = _currentLexer.GetSubLex(whileConditionStart);
                _currentLexer.Match((ScriptLex.LexTypes) ')');

                Int32 whileBodyStart = _currentLexer.TokenStart;

                Statement(ref loopCondition);

                ScriptLex whileBody = _currentLexer.GetSubLex(whileBodyStart);
                ScriptLex oldLex    = _currentLexer;

                //TODO: possible maximum itteration limit?
                while (loopCondition)
                {
                    whileCond.Reset();

                    _currentLexer = whileCond;

                    condition = Base(ref execute);

                    loopCondition = condition.Var.GetBool();

                    if (loopCondition)
                    {
                        whileBody.Reset();
                        _currentLexer = whileBody;
                        Statement(ref execute);
                    }
                }

                _currentLexer = oldLex;
            }
            else if (_currentLexer.TokenType == ScriptLex.LexTypes.RFor)
            {
                //for loop
                _currentLexer.Match(ScriptLex.LexTypes.RFor);
                _currentLexer.Match((ScriptLex.LexTypes) '(');

                Statement(ref execute);                 //init

                int           forConditionStart = _currentLexer.TokenStart;
                ScriptVarLink condition         = Base(ref execute);
                bool          noExecute         = false;
                bool          loopCondition     = execute && condition.Var.GetBool();

                ScriptLex forCondition = _currentLexer.GetSubLex(forConditionStart);

                _currentLexer.Match((ScriptLex.LexTypes) ';');

                int forIterStart = _currentLexer.TokenStart;

                Base(ref noExecute);

                ScriptLex forIter = _currentLexer.GetSubLex(forIterStart);

                _currentLexer.Match((ScriptLex.LexTypes) ')');

                int forBodyStart = _currentLexer.TokenStart;

                if (loopCondition)
                {
                    Statement(ref execute);
                }
                else
                {
                    Statement(ref noExecute);
                }

                ScriptLex forBody = _currentLexer.GetSubLex(forBodyStart);
                ScriptLex oldLex  = _currentLexer;
                if (loopCondition)
                {
                    forIter.Reset();
                    _currentLexer = forIter;

                    Base(ref execute);
                }

                //TODO: limit number of iterations?
                while (execute && loopCondition)
                {
                    forCondition.Reset();
                    _currentLexer = forCondition;

                    condition = Base(ref execute);

                    loopCondition = condition.Var.GetBool();

                    if (execute && loopCondition)
                    {
                        forBody.Reset();
                        _currentLexer = forBody;

                        Statement(ref execute);
                    }

                    if (execute && loopCondition)
                    {
                        forIter.Reset();
                        _currentLexer = forIter;

                        Base(ref execute);
                    }
                }

                _currentLexer = oldLex;
            }
            else if (_currentLexer.TokenType == ScriptLex.LexTypes.RReturn)
            {
                _currentLexer.Match(ScriptLex.LexTypes.RReturn);

                ScriptVarLink res = null;
                if (_currentLexer.TokenType != (ScriptLex.LexTypes) ';')
                {
                    res = Base(ref execute);
                }
                if (execute)
                {
                    ScriptVarLink resultVar = _scopes.Peek().FindChild(ScriptVar.ReturnVarName);
                    if (resultVar != null)
                    {
                        resultVar.ReplaceWith(res);
                    }
                    else
                    {
                        //return statement outside of function???
                        System.Diagnostics.Trace.TraceWarning("Return statement outside of a function, what is going on?");
                    }
                }

                execute = false;
                _currentLexer.Match((ScriptLex.LexTypes) ';');
            }
            else if (_currentLexer.TokenType == ScriptLex.LexTypes.RFunction)
            {
                //function
                ScriptVarLink funcVar = ParseFunctionDefinition();
                if (execute)
                {
                    if (funcVar.Name == String.Empty)
                    {
                        //functions must have a name at statement level
                    }
                    else
                    {
                        ScriptVar v = _scopes.Peek();
                        v.AddChildNoDup(funcVar.Name, funcVar.Var);
                    }
                }
            }
            else
            {
                _currentLexer.Match(ScriptLex.LexTypes.Eof);
            }
        }
Example #4
0
        private void Statement(ref bool execute)
        {
            if (currentLexer.TokenType == (ScriptLex.LexTypes) '{')
            {
                //code block
                Block(ref execute);
            }
            else if (currentLexer.TokenType == (ScriptLex.LexTypes) ';')
            {
                //allow for multiple semi colon such as ;;;
                currentLexer.Match((ScriptLex.LexTypes) ';');
            }
            else if (currentLexer.TokenType == ScriptLex.LexTypes.RVar || currentLexer.TokenType == ScriptLex.LexTypes.RConst)
            {
                //creating variables
                //TODO: make this less shit

                var readOnly = currentLexer.TokenType == ScriptLex.LexTypes.RConst;

                currentLexer.Match(currentLexer.TokenType);

                while (currentLexer.TokenType != (ScriptLex.LexTypes) ';')
                {
                    ScriptVarLink a = null;
                    if (execute)
                    {
                        a = scopes.Back().FindChildOrCreate(currentLexer.TokenString, ScriptVar.Flags.Undefined, readOnly);
                    }

                    currentLexer.Match(ScriptLex.LexTypes.Id);

                    //get through the dots
                    while (currentLexer.TokenType == (ScriptLex.LexTypes) '.')
                    {
                        currentLexer.Match((ScriptLex.LexTypes) '.');
                        if (execute)
                        {
                            var aLast = a;
                            if (aLast != null)
                            {
                                a = aLast.Var.FindChildOrCreate(currentLexer.TokenString);
                            }
                        }

                        currentLexer.Match(ScriptLex.LexTypes.Id);
                    }

                    //initialiser
                    if (currentLexer.TokenType == (ScriptLex.LexTypes) '=')
                    {
                        currentLexer.Match((ScriptLex.LexTypes) '=');
                        var varLink = Base(ref execute);
                        if (execute)
                        {
                            if (a != null)
                            {
                                a.ReplaceWith(varLink);
                            }
                        }
                    }

                    if (currentLexer.TokenType != (ScriptLex.LexTypes) ';')
                    {
                        currentLexer.Match((ScriptLex.LexTypes) ',');
                    }
                }

                currentLexer.Match((ScriptLex.LexTypes) ';');
            }
            else if (currentLexer.TokenType == ScriptLex.LexTypes.RIf)
            {
                //if condition
                currentLexer.Match(ScriptLex.LexTypes.RIf);
                currentLexer.Match((ScriptLex.LexTypes) '(');
                var varLink = Base(ref execute);
                currentLexer.Match((ScriptLex.LexTypes) ')');

                bool condition = execute && varLink.Var.Bool;
                bool noExecute = false;
                if (condition)
                {
                    Statement(ref execute);
                }
                else
                {
                    Statement(ref noExecute);
                }

                if (currentLexer.TokenType == ScriptLex.LexTypes.RElse)
                {
                    //else part of an if
                    currentLexer.Match(ScriptLex.LexTypes.RElse);

                    if (condition)
                    {
                        Statement(ref noExecute);
                    }
                    else
                    {
                        Statement(ref execute);
                    }
                }
            }
            else if (currentLexer.TokenType == ScriptLex.LexTypes.RWhile)
            {
                //while loop
                currentLexer.Match(ScriptLex.LexTypes.RWhile);
                currentLexer.Match((ScriptLex.LexTypes) '(');

                var whileConditionStart = currentLexer.TokenStart;
                var noExecute           = false;
                var condition           = Base(ref execute);
                var loopCondition       = execute && condition.Var.Bool;

                var whileCond = currentLexer.GetSubLex(whileConditionStart);
                currentLexer.Match((ScriptLex.LexTypes) ')');

                var whileBodyStart = currentLexer.TokenStart;

                if (loopCondition)
                {
                    Statement(ref execute);
                }
                else
                {
                    Statement(ref noExecute);
                }

                var whileBody = currentLexer.GetSubLex(whileBodyStart);
                var oldLex    = currentLexer;

                //TODO: possible maximum itteration limit?
                while (loopCondition)
                {
                    whileCond.Reset();

                    currentLexer = whileCond;

                    condition = Base(ref execute);

                    loopCondition = execute && condition.Var.Bool;

                    if (loopCondition)
                    {
                        whileBody.Reset();
                        currentLexer = whileBody;
                        Statement(ref execute);
                    }
                }

                currentLexer = oldLex;
            }
            else if (currentLexer.TokenType == ScriptLex.LexTypes.RFor)
            {
                //for loop
                currentLexer.Match(ScriptLex.LexTypes.RFor);
                currentLexer.Match((ScriptLex.LexTypes) '(');

                Statement(ref execute); //init

                var forConditionStart = currentLexer.TokenStart;
                var condition         = Base(ref execute);
                var noExecute         = false;
                var loopCondition     = execute && condition.Var.Bool;

                var forCondition = currentLexer.GetSubLex(forConditionStart);

                currentLexer.Match((ScriptLex.LexTypes) ';');

                var forIterStart = currentLexer.TokenStart;

                Base(ref noExecute);

                var forIter = currentLexer.GetSubLex(forIterStart);

                currentLexer.Match((ScriptLex.LexTypes) ')');

                var forBodyStart = currentLexer.TokenStart;

                if (loopCondition)
                {
                    Statement(ref execute);
                }
                else
                {
                    Statement(ref noExecute);
                }

                var forBody = currentLexer.GetSubLex(forBodyStart);
                var oldLex  = currentLexer;
                if (loopCondition)
                {
                    forIter.Reset();
                    currentLexer = forIter;

                    Base(ref execute);
                }

                //TODO: limit number of iterations?
                while (execute && loopCondition)
                {
                    forCondition.Reset();
                    currentLexer = forCondition;

                    condition = Base(ref execute);

                    loopCondition = condition.Var.Bool;

                    if (execute && loopCondition)
                    {
                        forBody.Reset();
                        currentLexer = forBody;

                        Statement(ref execute);
                    }

                    if (execute && loopCondition)
                    {
                        forIter.Reset();
                        currentLexer = forIter;

                        Base(ref execute);
                    }
                }

                currentLexer = oldLex;
            }
            else if (currentLexer.TokenType == ScriptLex.LexTypes.RReturn)
            {
                currentLexer.Match(ScriptLex.LexTypes.RReturn);

                ScriptVarLink res = null;
                if (currentLexer.TokenType != (ScriptLex.LexTypes) ';')
                {
                    res = Base(ref execute);
                }
                if (execute)
                {
                    var resultVar = scopes.Back().FindChild(ScriptVar.ReturnVarName);
                    if (resultVar != null)
                    {
                        resultVar.ReplaceWith(res);
                    }
                    else
                    {
                        //return statement outside of function???
                        System.Diagnostics.Trace.TraceWarning("Return statement outside of a function, what is going on?");
                    }
                    execute = false;
                }

                currentLexer.Match((ScriptLex.LexTypes) ';');
            }
            else if (currentLexer.TokenType == ScriptLex.LexTypes.RFunction)
            {
                //function
                var funcVar = ParseFunctionDefinition();
                if (execute)
                {
                    if (funcVar.Name == string.Empty)
                    {
                        //functions must have a name at statement level
                    }
                    else
                    {
                        var v = scopes.Back();
                        v.AddChildNoDup(funcVar.Name, funcVar.Var);
                    }
                }
            }
            else if (currentLexer.TokenType == ScriptLex.LexTypes.RTry)
            {
                var           tryBlock = ParseDefinition(ScriptLex.LexTypes.RTry);
                ScriptVarLink catchBlock = null, finallyBlock = null;

                var originalLexer = currentLexer;

                if (currentLexer.TokenType == ScriptLex.LexTypes.RCatch)
                {
                    catchBlock = ParseDefinition(ScriptLex.LexTypes.RCatch);
                }

                if (currentLexer.TokenType == ScriptLex.LexTypes.RFinally)
                {
                    finallyBlock = ParseDefinition(ScriptLex.LexTypes.RFinally);
                }

                try
                {
                    var oldLex = currentLexer;
                    var newLex = new ScriptLex(tryBlock.Var.String);
                    currentLexer = newLex;

                    Block(ref execute);

                    execute = true;

                    currentLexer = oldLex;
                }
                catch (JITException ex)
                {
                    if (catchBlock != null)
                    {
                        var catchScope = new ScriptVar(null, ScriptVar.Flags.Object);

                        var v = catchBlock?.Var?.FirstChild;
                        if (v != null)
                        {
                            catchScope.AddChild(v.Name, ex.VarObj);
                        }

                        var oldLex = currentLexer;
                        var newLex = new ScriptLex(catchBlock.Var.String);
                        currentLexer = newLex;

                        scopes.PushBack(catchScope);

                        Block(ref execute);

                        scopes.PopBack();

                        execute = true;

                        currentLexer = oldLex;
                    }
                    else
                    {
                        throw new ScriptException(ex.Message, ex);
                    }
                }
                finally
                {
                    if (finallyBlock != null)
                    {
                        var oldLex = currentLexer;
                        var newLex = new ScriptLex(finallyBlock.Var.String);
                        currentLexer = newLex;

                        Block(ref execute);

                        execute = true;

                        currentLexer = oldLex;
                    }
                }

                currentLexer = originalLexer;
            }
            else if (currentLexer.TokenType == ScriptLex.LexTypes.RThrow)
            {
                currentLexer.Match(ScriptLex.LexTypes.RThrow);

                ScriptVar message = new ScriptVar();

                if (currentLexer.TokenType == (ScriptLex.LexTypes) ';')
                {
                    currentLexer.Match((ScriptLex.LexTypes) ';');
                }
                else
                {
                    var res = Base(ref execute);
                    message = res.Var;
                }

                throw new JITException(message);
            }
            else
            {
                //execute a basic statement
                Base(ref execute);
                currentLexer.Match((ScriptLex.LexTypes) ';');
            }
        }