private ScriptVarLink Condition(ref bool execute)
        {
            ScriptVarLink a = Shift(ref execute);

            while (_currentLexer.TokenType == ScriptLex.LexTypes.Equal ||
                   _currentLexer.TokenType == ScriptLex.LexTypes.NEqual ||
                   _currentLexer.TokenType == ScriptLex.LexTypes.TypeEqual ||
                   _currentLexer.TokenType == ScriptLex.LexTypes.NTypeEqual ||
                   _currentLexer.TokenType == ScriptLex.LexTypes.LEqual ||
                   _currentLexer.TokenType == ScriptLex.LexTypes.GEqual ||
                   _currentLexer.TokenType == (ScriptLex.LexTypes) '>' ||
                   _currentLexer.TokenType == (ScriptLex.LexTypes) '<'
                   )
            {
                ScriptLex.LexTypes op = _currentLexer.TokenType;
                _currentLexer.Match(op);
                ScriptVarLink b = Shift(ref execute);

                if (execute)
                {
                    ScriptVar res = a.Var.MathsOp(b.Var, op);

                    if (a.Owned)
                    {
                        a = new ScriptVarLink(res, null);
                    }
                    else
                    {
                        a.ReplaceWith(res);
                    }
                }
            }

            return(a);
        }
Пример #2
0
        private ScriptVarLink Term(ref bool execute)
        {
            ScriptVarLink a = Unary(ref execute);

            while (_currentLexer.TokenType == (ScriptLex.LexTypes) '*' ||
                   _currentLexer.TokenType == (ScriptLex.LexTypes) '/' ||
                   _currentLexer.TokenType == (ScriptLex.LexTypes) '%')
            {
                ScriptLex.LexTypes op = _currentLexer.TokenType;
                _currentLexer.Match(_currentLexer.TokenType);

                ScriptVarLink b = Unary(ref execute);
                if (execute)
                {
                    ScriptVar res = a.Var.MathsOp(b.Var, op);

                    if (a.Owned)
                    {
                        a = new ScriptVarLink(res, null);
                    }
                    else
                    {
                        a.ReplaceWith(res);
                    }
                }
            }

            return(a);
        }
Пример #3
0
        private ScriptVarLink Base(ref bool execute)
        {
            ScriptVarLink a = Ternary(ref execute);

            if (_currentLexer.TokenType == (ScriptLex.LexTypes) '=' ||
                _currentLexer.TokenType == ScriptLex.LexTypes.PlusEqual ||
                _currentLexer.TokenType == ScriptLex.LexTypes.MinusEqual)
            {
                if (execute && a.Owned)
                {
                    if (a.Name.Length > 0)
                    {
                        ScriptVarLink aReal = Root.AddChildNoDup(a.Name, a.Var);
                        a = aReal;
                    }
                    else
                    {
                        // Hit an unknow error here
#if !WINDOWS_UWP
                        System.Diagnostics.Trace.TraceWarning("Trying to assign to an unnamed type...");
#endif
                    }
                }


                ScriptLex.LexTypes op = _currentLexer.TokenType;
                _currentLexer.Match(op);

                ScriptVarLink b = Base(ref execute);

                if (execute)
                {
                    switch (op)
                    {
                    case (ScriptLex.LexTypes) '=':
                        a.ReplaceWith(b);
                        break;

                    case ScriptLex.LexTypes.PlusEqual:
                    {
                        ScriptVar res = a.Var.MathsOp(b.Var, (ScriptLex.LexTypes) '+');
                        a.ReplaceWith(res);
                    }
                    break;

                    case ScriptLex.LexTypes.MinusEqual:
                    {
                        ScriptVar res = a.Var.MathsOp(b.Var, (ScriptLex.LexTypes) '-');
                        a.ReplaceWith(res);
                    }
                    break;

                    default:
                        throw new ScriptException("Base broke");
                    }
                }
            }

            return(a);
        }
Пример #4
0
        private ScriptVarLink Shift(ref bool execute)
        {
            ScriptVarLink a = Expression(ref execute);

            if (_currentLexer.TokenType == ScriptLex.LexTypes.LShift ||
                _currentLexer.TokenType == ScriptLex.LexTypes.RShift ||
                _currentLexer.TokenType == ScriptLex.LexTypes.RShiftUnsigned)
            {
                ScriptLex.LexTypes op = _currentLexer.TokenType;
                _currentLexer.Match(op);
                ScriptVarLink b = Base(ref execute);

                Int32 shift = execute ? b.Var.GetInt() : 0;

                if (execute)
                {
                    if (op == ScriptLex.LexTypes.LShift)
                    {
                        a.Var.SetInt(a.Var.GetInt() << shift);
                    }

                    if (op == ScriptLex.LexTypes.RShift)
                    {
                        a.Var.SetInt(a.Var.GetInt() >> shift);
                    }

                    if (op == ScriptLex.LexTypes.RShiftUnsigned)
                    {
                        a.Var.SetInt((int)(((uint)a.Var.GetInt()) >> shift));
                    }
                }
            }

            return(a);
        }
Пример #5
0
        private ScriptVarLink ParseDefinition(ScriptLex.LexTypes lexType)
        {
            currentLexer.Match(lexType);
            var funcName = string.Empty;

            //named function
            if (currentLexer.TokenType == ScriptLex.LexTypes.Id)
            {
                funcName = currentLexer.TokenString;
                currentLexer.Match(ScriptLex.LexTypes.Id);
            }

            var funcVar = new ScriptVarLink(new ScriptVar(null, ScriptVar.Flags.Function), funcName);

            if (lexType == ScriptLex.LexTypes.RFunction || lexType == ScriptLex.LexTypes.RCatch)
            {
                ParseFunctionArguments(funcVar.Var);
            }

            var funcBegin = currentLexer.TokenStart;
            var noExecute = false;

            Block(ref noExecute);
            funcVar.Var.SetData(currentLexer.GetSubString(funcBegin));

            return(funcVar);
        }
Пример #6
0
        public ScriptVar MathsOp(ScriptVar b, ScriptLex.LexTypes op)
        {
            ScriptVar a = this;

            char opc = (char)op;

            if (op == ScriptLex.LexTypes.TypeEqual || op == ScriptLex.LexTypes.NTypeEqual)
            {
                bool equal = ((a._flags & Flags.VarTypeMask) == (b._flags & Flags.VarTypeMask));

                if (equal)
                {
                    ScriptVar contents = a.MathsOp(b, ScriptLex.LexTypes.Equal);
                    if (!contents.GetBool())
                    {
                        equal = false;
                    }
                }

                if (op == ScriptLex.LexTypes.TypeEqual)
                {
                    return(new ScriptVar(equal));
                }

                return(new ScriptVar(!equal));
            }

            if (a.IsUndefined && b.IsUndefined)
            {
                if (op == ScriptLex.LexTypes.Equal)
                {
                    return(new ScriptVar(true));
                }
                if (op == ScriptLex.LexTypes.NEqual)
                {
                    return(new ScriptVar(false));
                }

                return(new ScriptVar());
            }

            if ((a.IsNumeric || a.IsUndefined) && (b.IsNumeric || b.IsUndefined))
            {
                if (!a.IsDouble && !b.IsDouble)
                {
                    //ints
                    int da = a.GetInt();
                    int db = b.GetInt();

                    switch (opc)
                    {
                    case '+': return(new ScriptVar(da + db));

                    case '-': return(new ScriptVar(da - db));

                    case '*': return(new ScriptVar(da * db));

                    case '/': return(new ScriptVar(da / db));

                    case '&': return(new ScriptVar(da & db));

                    case '|': return(new ScriptVar(da | db));

                    case '^': return(new ScriptVar(da ^ db));

                    case '%': return(new ScriptVar(da % db));

                    case (char)ScriptLex.LexTypes.Equal: return(new ScriptVar(da == db));

                    case (char)ScriptLex.LexTypes.NEqual: return(new ScriptVar(da != db));

                    case '<': return(new ScriptVar(da < db));

                    case (char)ScriptLex.LexTypes.LEqual: return(new ScriptVar(da <= db));

                    case '>': return(new ScriptVar(da > db));

                    case (char)ScriptLex.LexTypes.GEqual: return(new ScriptVar(da >= db));

                    default: throw new ScriptException("Operation not supported on the Int datatype");
                    }
                }
                else
                {
                    //doubles
                    double da = a.GetDouble();
                    double db = b.GetDouble();

                    switch (opc)
                    {
                    case '+': return(new ScriptVar(da + db));

                    case '-': return(new ScriptVar(da - db));

                    case '*': return(new ScriptVar(da * db));

                    case '/': return(new ScriptVar(da / db));

                    case (char)ScriptLex.LexTypes.Equal: return(new ScriptVar(da == db));

                    case (char)ScriptLex.LexTypes.NEqual: return(new ScriptVar(da != db));

                    case '<': return(new ScriptVar(da < db));

                    case (char)ScriptLex.LexTypes.LEqual: return(new ScriptVar(da <= db));

                    case '>': return(new ScriptVar(da > db));

                    case (char)ScriptLex.LexTypes.GEqual: return(new ScriptVar(da >= db));

                    default: throw new ScriptException("Operation not supported on the Int datatype");
                    }
                }
            }

            if (a.IsArray)
            {
                switch (op)
                {
                case ScriptLex.LexTypes.Equal: return(new ScriptVar(a == b));

                case ScriptLex.LexTypes.NEqual: return(new ScriptVar(a != b));

                default: throw new ScriptException("Operation not supported on the Array datatype");
                }
            }

            if (a.IsObject)
            {
                switch (op)
                {
                case ScriptLex.LexTypes.Equal: return(new ScriptVar(a == b));

                case ScriptLex.LexTypes.NEqual: return(new ScriptVar(a != b));

                default: throw new ScriptException("Operation not supported on the Object datatype");
                }
            }

            string sda = a.GetString();
            string sdb = b.GetString();

            switch (opc)
            {
            case '+': return(new ScriptVar(sda + sdb, Flags.String));

            case (char)ScriptLex.LexTypes.Equal: return(new ScriptVar(sda == sdb));

            case (char)ScriptLex.LexTypes.NEqual: return(new ScriptVar(sda != sdb));

            case '<': return(new ScriptVar(String.CompareOrdinal(sda, sdb) < 0));

            case (char)ScriptLex.LexTypes.LEqual: return(new ScriptVar((String.CompareOrdinal(sda, sdb) < 0) || sda == sdb));

            case '>': return(new ScriptVar(String.CompareOrdinal(sda, sdb) > 0));

            case (char)ScriptLex.LexTypes.GEqual: return(new ScriptVar((String.CompareOrdinal(sda, sdb) > 0) || sda == sdb));

            default: throw new ScriptException("Operation not supported on the String datatype");
            }
        }
        private ScriptVarLink Expression(ref bool execute)
        {
            bool negate = false;

            if (_currentLexer.TokenType == (ScriptLex.LexTypes) '-')
            {
                _currentLexer.Match((ScriptLex.LexTypes) '-');
                negate = true;
            }

            ScriptVarLink a = Term(ref execute);

            if (negate)
            {
                ScriptVar zero = new ScriptVar(0);
                ScriptVar res  = zero.MathsOp(a.Var, (ScriptLex.LexTypes) '-');

                if (a.Owned)
                {
                    a = new ScriptVarLink(res, null);
                }
                else
                {
                    a.ReplaceWith(res);
                }
            }

            while (_currentLexer.TokenType == (ScriptLex.LexTypes) '+' ||
                   _currentLexer.TokenType == (ScriptLex.LexTypes) '-' ||
                   _currentLexer.TokenType == ScriptLex.LexTypes.PlusPlus ||
                   _currentLexer.TokenType == ScriptLex.LexTypes.MinusMinus)
            {
                ScriptLex.LexTypes op = _currentLexer.TokenType;
                _currentLexer.Match(op);

                if (op == ScriptLex.LexTypes.PlusPlus || op == ScriptLex.LexTypes.MinusMinus)
                {
                    if (execute)
                    {
                        ScriptVar     one    = new ScriptVar(1);
                        ScriptVar     res    = a.Var.MathsOp(one, (ScriptLex.LexTypes)(op == ScriptLex.LexTypes.PlusPlus ? '+' : '-'));
                        ScriptVarLink oldVal = new ScriptVarLink(a.Var, null);

                        a.ReplaceWith(res);
                        a = oldVal;
                    }
                }
                else
                {
                    ScriptVarLink b = Term(ref execute);
                    if (execute)
                    {
                        ScriptVar res = a.Var.MathsOp(b.Var, op);

                        if (a.Owned)
                        {
                            a = new ScriptVarLink(res, null);
                        }
                        else
                        {
                            a.ReplaceWith(res);
                        }
                    }
                }
            }

            return(a);
        }
Пример #8
0
        private ScriptVarLink Logic(ref bool execute)
        {
            ScriptVarLink a = Condition(ref execute);

            while (_currentLexer.TokenType == (ScriptLex.LexTypes) '&' ||
                   _currentLexer.TokenType == (ScriptLex.LexTypes) '|' ||
                   _currentLexer.TokenType == (ScriptLex.LexTypes) '^' ||
                   _currentLexer.TokenType == ScriptLex.LexTypes.AndAnd ||
                   _currentLexer.TokenType == ScriptLex.LexTypes.OrOr)
            {
                ScriptLex.LexTypes op = _currentLexer.TokenType;
                _currentLexer.Match(op);

                bool shortcut = false;
                bool isBool   = false;

                if (op == ScriptLex.LexTypes.AndAnd)
                {
                    op       = (ScriptLex.LexTypes) '&';
                    shortcut = !a.Var.GetBool();
                    isBool   = true;
                }
                else if (op == ScriptLex.LexTypes.OrOr)
                {
                    op       = (ScriptLex.LexTypes) '|';
                    shortcut = a.Var.GetBool();
                    isBool   = true;
                }

                bool          condition = !shortcut && execute;
                ScriptVarLink b         = Condition(ref condition);

                if (execute && !shortcut)
                {
                    if (isBool)
                    {
                        ScriptVar newA = new ScriptVar(a.Var.GetBool());
                        ScriptVar newB = new ScriptVar(b.Var.GetBool());

                        if (a.Owned)
                        {
                            a = new ScriptVarLink(newA, null);
                        }
                        else
                        {
                            a.ReplaceWith(newA);
                        }

                        if (b.Owned)
                        {
                            b = new ScriptVarLink(newB, null);
                        }
                        else
                        {
                            b.ReplaceWith(newA);
                        }
                    }

                    ScriptVar res = a.Var.MathsOp(b.Var, op);

                    if (a.Owned)
                    {
                        a = new ScriptVarLink(res, null);
                    }
                    else
                    {
                        a.ReplaceWith(res);
                    }
                }
            }

            return(a);
        }