예제 #1
0
    public void ZeroReturnsFalse()
    {
        var parsed = MoLangParser.Parse("return 0 ?? 'test'");
        var result = _runtime.Execute(parsed);

        Assert.AreEqual(result.AsString(), "test");
    }
예제 #2
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                        JsonSerializer serializer)
        {
            JToken token = JToken.Load(reader);

            if (token.Type == JTokenType.String)
            {
                string molang = token.Value <string>();
                return(MoLangParser.Parse(molang));
            }
            else if (token.Type == JTokenType.Integer)
            {
                return(new NumberExpression(token.Value <double>()));
            }
            else if (token.Type == JTokenType.Float)
            {
                return(new NumberExpression(token.Value <double>()));
            }
            else if (token.Type == JTokenType.Boolean)
            {
                return(new BooleanExpression(token.Value <bool>()));
            }

            return(existingValue);
        }
예제 #3
0
        /// <inheritdoc />
        public override IExpression Parse(MoLangParser parser, Token token)
        {
            IExpression expr   = parser.ParseExpression();
            var         result = parser.ConsumeToken(TokenType.BracketRight);

            return(expr);
        }
예제 #4
0
    public void ZeroVariableReturnsFalse()
    {
        _runtime.Environment.SetValue(new MoPath("variable.lastNumber"), new DoubleValue(0));
        var parsed = MoLangParser.Parse("return variable.lastNumber ?? 'test'");
        var result = _runtime.Execute(parsed);

        Assert.AreEqual(result.AsString(), "test");
    }
예제 #5
0
        /// <inheritdoc />
        public override IExpression Parse(MoLangParser parser, Token token, IExpression leftExpr)
        {
            IExpression index = parser.ParseExpression(Precedence);

            parser.ConsumeToken(TokenType.ArrayRight);

            return(new ArrayAccessExpression(leftExpr, index));
        }
예제 #6
0
        /// <inheritdoc />
        public override IExpression Parse(MoLangParser parser, Token token)
        {
            if (double.TryParse(token.Text, NumberStyle, Culture, out var result))
            {
                return(new NumberExpression(result));
            }

            throw new MoLangParserException($"Could not parse \'{token.Text.ToString()}\' as a double");
        }
예제 #7
0
        /// <inheritdoc />
        public override IExpression Parse(MoLangParser parser, Token token)
        {
            if (!parser.TryParseArgs(out var expressions) || expressions.Length != 3)
            {
                throw new MoLangParserException($"ForEach: Expected 3 argument, {(expressions?.Length ?? 0)} argument given");
            }

            return(new ForEachExpression(expressions[0], expressions[1], expressions[2]));
        }
예제 #8
0
        /// <inheritdoc />
        public override IExpression Parse(MoLangParser parser, Token token)
        {
            var path = parser.FixNameShortcut(new MoPath(token.Text));

            if (parser.TryParseArgs(out var expressions))
            {
                return(new FuncCallExpression(path, expressions));
            }

            return(new NameExpression(path));
        }
예제 #9
0
    public void ArithmeticsDivision()
    {
        const double a = 1200;
        const double b = 800;
        const double expectedResult = a / b;

        var expression = MoLangParser.Parse("v.a / v.b");
        var runtime    = Setup(a, b);

        var result = runtime.Execute(expression);

        Assert.AreEqual(expectedResult, result.AsDouble());
    }
예제 #10
0
    public void PropertyWrite()
    {
        var expression = MoLangParser.Parse("query.life_time = 5");

        MoLangRuntime runtime = new MoLangRuntime();

        var testStruct = new TestClass(Environment.TickCount);

        runtime.Environment.Structs.TryAdd(
            "query", new InteropStruct(testStruct));

        runtime.Execute(expression);
        Assert.AreEqual(5d, testStruct.Lifetime);
    }
예제 #11
0
    public void PropertyRead()
    {
        var expression = MoLangParser.Parse("query.life_time");

        var           expected = Environment.TickCount * 3.5d;
        MoLangRuntime runtime  = new MoLangRuntime();

        runtime.Environment.Structs.TryAdd(
            "query", new InteropStruct(new TestClass(expected)));

        var result = runtime.Execute(expression);

        Assert.AreEqual(expected, result.AsDouble());
    }
    public void MathFunctions()
    {
        MoLangParser parser = new MoLangParser(new TokenIterator("math.floor(10.1 + 20.1)"));

        parser.ExpressionTraverser.Visitors.Add(new MathOptimizationVisitor());

        var expr = parser.Parse();

        Assert.IsInstanceOfType(expr, typeof(NumberExpression));

        MoLangRuntime runtime = new MoLangRuntime();
        var           result  = runtime.Execute(expr);

        Assert.AreEqual(30, result.AsDouble());
    }
    public void Constants()
    {
        MoLangParser parser = new MoLangParser(new TokenIterator("7 + 2 * (6 + 3) / 3 - 7"));

        parser.ExpressionTraverser.Visitors.Add(new MathOptimizationVisitor());

        var expr = parser.Parse();

        Assert.IsInstanceOfType(expr, typeof(NumberExpression));

        MoLangRuntime runtime = new MoLangRuntime();
        var           result  = runtime.Execute(expr);

        Assert.AreEqual(6, result.AsDouble());
    }
예제 #14
0
    public void OrderOfOperations()
    {
        var runtime = Setup(10, 20);

        var expr   = MoLangParser.Parse("v.b + (7 + 2 * (6 + 3) / 3 - 7) + v.a");
        var result = runtime.Execute(expr);

        Assert.AreEqual(36, result.AsDouble());

        result = runtime.Execute(MoLangParser.Parse("10 * 2 - (7 + 9)"));
        Assert.AreEqual(4, result.AsDouble());

        result = runtime.Execute(MoLangParser.Parse("12 + 2 * 44"));
        Assert.AreEqual(100, result.AsDouble());
    }
예제 #15
0
    public void EqualityOperatorTest()
    {
        var parsed = MoLangParser.Parse(@"
t.a = 10;
loop(10, {
t.a = t.a - 1;
t.a == 5 ? break : continue;
});
return t.a;
");

        Assert.IsNotNull(parsed);

        var result = _runtime.Execute(parsed);

        Assert.AreEqual(5, result.AsDouble());
    }
예제 #16
0
    public void BiggerOrEqualTest()
    {
        var parsed = MoLangParser.Parse(@"
t.a = 1;
loop(10, {
t.a = t.a + 1;
t.a >= 5 ? break : continue;
});
return t.a;
");

        Assert.IsNotNull(parsed);

        var result = _runtime.Execute(parsed);

        Assert.AreEqual(5, result.AsDouble());
    }
예제 #17
0
        /// <inheritdoc />
        public override IExpression Parse(MoLangParser parser, Token token, IExpression leftExpr)
        {
            if (parser.MatchToken(TokenType.Colon))
            {
                return(new TernaryExpression(leftExpr, null, parser.ParseExpression(Precedence)));
            }
            else
            {
                IExpression thenExpr = parser.ParseExpression(Precedence);

                if (!parser.MatchToken(TokenType.Colon))
                {
                    return(new TernaryExpression(leftExpr, thenExpr, null));
                }
                else
                {
                    return(new TernaryExpression(leftExpr, thenExpr, parser.ParseExpression(Precedence)));
                }
            }
        }
예제 #18
0
        /// <inheritdoc />
        public override IExpression Parse(MoLangParser parser, Token token)
        {
            List <IExpression> exprs = new List <IExpression>();

            if (!parser.MatchToken(TokenType.CurlyBracketRight))
            {
                do
                {
                    if (parser.MatchToken(TokenType.CurlyBracketRight, false))
                    {
                        break;
                    }

                    exprs.Add(parser.ParseExpression(Precedence.Scope));
                } while (parser.MatchToken(TokenType.Semicolon));

                parser.ConsumeToken(TokenType.CurlyBracketRight);
            }

            return(new StatementExpression(exprs.ToArray()));
        }
예제 #19
0
    public void ScriptRun()
    {
        _sw.Start();
        var parsed = MoLangParser.Parse(@"
        t.a = 213 + 2 / 0.5 + 5 + 2 * 3;

        query.debug_output(1 + 2 * 3);

        array.test.0 = 100;
        array.test[1] = 200;
        array.test[2] = 10.5;

        query.debug_output(array.test[1]);

        t.b = 3;

        loop(10, {
	        array.test[t.b] = array.test[t.b - 1] + 2;
	        t.b = t.b + 1;
        });

        for_each(v.r, array.test, {
            t.a = t.a + v.r;
            query.debug_output('hello1', t.a, v.r);
        });

        t.b = 0;

        loop(100, {
            t.b = t.b + 1;
            t.a = t.a + math.cos((Math.PI / 180.0f) * 270) + t.b;
            query.debug_output(array.test[t.b]);
            query.debug_output('hello', 'test', t.a, array.test[2], t.b);
        });

        query.debug_output(query.life_time());
        return t.a;
");

        _sw.Stop();
        var timeElapsedOnParsing = _sw.Elapsed;

        Assert.IsNotNull(parsed);

        Console.WriteLine($"Parser completed in {timeElapsedOnParsing.TotalMilliseconds}ms");

        const int runs       = 1000;
        const int warmupRuns = 10;

        TimeSpan totalElapsed = TimeSpan.Zero;
        TimeSpan max          = TimeSpan.Zero;
        TimeSpan min          = TimeSpan.MaxValue;

        for (int i = 0; i < runs + warmupRuns; i++)
        {
            _sw.Restart();
            _runtime.Execute(parsed);
            _sw.Stop();

            if (i >= warmupRuns)
            {
                totalElapsed += _sw.Elapsed;

                if (_sw.Elapsed < min)
                {
                    min = _sw.Elapsed;
                }

                if (_sw.Elapsed > max)
                {
                    max = _sw.Elapsed;
                }
            }
        }

        Console.WriteLine($"Executed {runs} runs. Total={totalElapsed.TotalMilliseconds}ms Avg={totalElapsed.TotalMilliseconds / runs}ms Max={max.TotalMilliseconds}ms Min={min.TotalMilliseconds}ms");
    }
예제 #20
0
 /// <inheritdoc />
 public override IExpression Parse(MoLangParser parser, Token token)
 {
     return(new ContinueExpression());
 }
예제 #21
0
 /// <inheritdoc />
 public override IExpression Parse(MoLangParser parser, Token token, IExpression leftExpr)
 {
     return(new AssignExpression(leftExpr, parser.ParseExpression(Precedence)));
 }
예제 #22
0
 /// <inheritdoc />
 public override IExpression Parse(MoLangParser parser, Token token)
 {
     return(new ReturnExpression(parser.ParseExpression()));
 }
예제 #23
0
        /// <inheritdoc />
        public override IExpression Parse(MoLangParser parser, Token token, IExpression leftExpr)
        {
            IExpression rightExpr = parser.ParseExpression(Precedence);

            if (token.Type.Equals(TokenType.Arrow))
            {
                return(new ArrowExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.And))
            {
                return(new BooleanAndExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.Or))
            {
                return(new BooleanOrExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.Coalesce))
            {
                return(new CoalesceExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.Slash))
            {
                return(new DivideExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.EqualsEquals))
            {
                return(new EqualExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.Greater))
            {
                return(new GreaterExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.GreaterOrEquals))
            {
                return(new GreaterOrEqualExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.Minus))
            {
                return(new MinusExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.NotEquals))
            {
                return(new NotEqualExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.Plus))
            {
                return(new PlusExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.Asterisk))
            {
                return(new PowExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.Smaller))
            {
                return(new SmallerExpression(leftExpr, rightExpr));
            }

            if (token.Type.Equals(TokenType.SmallerOrEquals))
            {
                return(new SmallerOrEqualExpression(leftExpr, rightExpr));
            }

            return(null);
        }
예제 #24
0
 /// <inheritdoc />
 public override IExpression Parse(MoLangParser parser, Token token)
 {
     return(new BreakExpression());
 }
예제 #25
0
 /// <inheritdoc />
 public override IExpression Parse(MoLangParser parser, Token token)
 {
     return(new UnaryMinusExpression(parser.ParseExpression(Precedence.Prefix)));
 }
예제 #26
0
 /// <inheritdoc />
 public override IExpression Parse(MoLangParser parser, Token token)
 {
     return(new BooleanNotExpression(parser.ParseExpression(Precedence.Prefix)));
 }
예제 #27
0
 /// <inheritdoc />
 public override IExpression Parse(MoLangParser parser, Token token)
 {
     return(new StringExpression(token.Text));
 }
예제 #28
0
 /// <inheritdoc />
 public override IExpression Parse(MoLangParser parser, Token token)
 {
     return(new BooleanExpression(bool.Parse(token.Text)));
 }